2016-11-17 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob0645805770b04dcf706356ef23ab6e43d1633f9e
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 LZCNT suppoprt
179   UNSPEC_LZCNT
181   ;; For BMI support
182   UNSPEC_TZCNT
183   UNSPEC_BEXTR
185   ;; For BMI2 support
186   UNSPEC_PDEP
187   UNSPEC_PEXT
189   ;; For AVX512F support
190   UNSPEC_KMOV
192   UNSPEC_BNDMK
193   UNSPEC_BNDMK_ADDR
194   UNSPEC_BNDSTX
195   UNSPEC_BNDLDX
196   UNSPEC_BNDLDX_ADDR
197   UNSPEC_BNDCL
198   UNSPEC_BNDCU
199   UNSPEC_BNDCN
200   UNSPEC_MPX_FENCE
202   ;; IRET support
203   UNSPEC_INTERRUPT_RETURN
206 (define_c_enum "unspecv" [
207   UNSPECV_BLOCKAGE
208   UNSPECV_STACK_PROBE
209   UNSPECV_PROBE_STACK_RANGE
210   UNSPECV_ALIGN
211   UNSPECV_PROLOGUE_USE
212   UNSPECV_SPLIT_STACK_RETURN
213   UNSPECV_CLD
214   UNSPECV_NOPS
215   UNSPECV_RDTSC
216   UNSPECV_RDTSCP
217   UNSPECV_RDPMC
218   UNSPECV_LLWP_INTRINSIC
219   UNSPECV_SLWP_INTRINSIC
220   UNSPECV_LWPVAL_INTRINSIC
221   UNSPECV_LWPINS_INTRINSIC
222   UNSPECV_RDFSBASE
223   UNSPECV_RDGSBASE
224   UNSPECV_WRFSBASE
225   UNSPECV_WRGSBASE
226   UNSPECV_FXSAVE
227   UNSPECV_FXRSTOR
228   UNSPECV_FXSAVE64
229   UNSPECV_FXRSTOR64
230   UNSPECV_XSAVE
231   UNSPECV_XRSTOR
232   UNSPECV_XSAVE64
233   UNSPECV_XRSTOR64
234   UNSPECV_XSAVEOPT
235   UNSPECV_XSAVEOPT64
236   UNSPECV_XSAVES
237   UNSPECV_XRSTORS
238   UNSPECV_XSAVES64
239   UNSPECV_XRSTORS64
240   UNSPECV_XSAVEC
241   UNSPECV_XSAVEC64
243   ;; For atomic compound assignments.
244   UNSPECV_FNSTENV
245   UNSPECV_FLDENV
246   UNSPECV_FNSTSW
247   UNSPECV_FNCLEX
249   ;; For RDRAND support
250   UNSPECV_RDRAND
252   ;; For RDSEED support
253   UNSPECV_RDSEED
255   ;; For RTM support
256   UNSPECV_XBEGIN
257   UNSPECV_XEND
258   UNSPECV_XABORT
259   UNSPECV_XTEST
261   UNSPECV_NLGR
263   ;; For CLWB support
264   UNSPECV_CLWB
266   ;; For CLFLUSHOPT support
267   UNSPECV_CLFLUSHOPT
269   ;; For MONITORX and MWAITX support 
270   UNSPECV_MONITORX
271   UNSPECV_MWAITX
273   ;; For CLZERO support
274   UNSPECV_CLZERO
276   ;; For RDPKRU and WRPKRU support
277   UNSPECV_PKU
280 ;; Constants to represent rounding modes in the ROUND instruction
281 (define_constants
282   [(ROUND_FLOOR                 0x1)
283    (ROUND_CEIL                  0x2)
284    (ROUND_TRUNC                 0x3)
285    (ROUND_MXCSR                 0x4)
286    (ROUND_NO_EXC                0x8)
287   ])
289 ;; Constants to represent AVX512F embeded rounding
290 (define_constants
291   [(ROUND_NEAREST_INT                   0)
292    (ROUND_NEG_INF                       1)
293    (ROUND_POS_INF                       2)
294    (ROUND_ZERO                          3)
295    (NO_ROUND                            4)
296    (ROUND_SAE                           8)
297   ])
299 ;; Constants to represent pcomtrue/pcomfalse variants
300 (define_constants
301   [(PCOM_FALSE                  0)
302    (PCOM_TRUE                   1)
303    (COM_FALSE_S                 2)
304    (COM_FALSE_P                 3)
305    (COM_TRUE_S                  4)
306    (COM_TRUE_P                  5)
307   ])
309 ;; Constants used in the XOP pperm instruction
310 (define_constants
311   [(PPERM_SRC                   0x00)   /* copy source */
312    (PPERM_INVERT                0x20)   /* invert source */
313    (PPERM_REVERSE               0x40)   /* bit reverse source */
314    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
315    (PPERM_ZERO                  0x80)   /* all 0's */
316    (PPERM_ONES                  0xa0)   /* all 1's */
317    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
318    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
319    (PPERM_SRC1                  0x00)   /* use first source byte */
320    (PPERM_SRC2                  0x10)   /* use second source byte */
321    ])
323 ;; Registers by name.
324 (define_constants
325   [(AX_REG                       0)
326    (DX_REG                       1)
327    (CX_REG                       2)
328    (BX_REG                       3)
329    (SI_REG                       4)
330    (DI_REG                       5)
331    (BP_REG                       6)
332    (SP_REG                       7)
333    (ST0_REG                      8)
334    (ST1_REG                      9)
335    (ST2_REG                     10)
336    (ST3_REG                     11)
337    (ST4_REG                     12)
338    (ST5_REG                     13)
339    (ST6_REG                     14)
340    (ST7_REG                     15)
341    (ARGP_REG                    16)
342    (FLAGS_REG                   17)
343    (FPSR_REG                    18)
344    (FPCR_REG                    19)
345    (FRAME_REG                   20)
346    (XMM0_REG                    21)
347    (XMM1_REG                    22)
348    (XMM2_REG                    23)
349    (XMM3_REG                    24)
350    (XMM4_REG                    25)
351    (XMM5_REG                    26)
352    (XMM6_REG                    27)
353    (XMM7_REG                    28)
354    (MM0_REG                     29)
355    (MM1_REG                     30)
356    (MM2_REG                     31)
357    (MM3_REG                     32)
358    (MM4_REG                     33)
359    (MM5_REG                     34)
360    (MM6_REG                     35)
361    (MM7_REG                     36)
362    (R8_REG                      37)
363    (R9_REG                      38)
364    (R10_REG                     39)
365    (R11_REG                     40)
366    (R12_REG                     41)
367    (R13_REG                     42)
368    (R14_REG                     43)
369    (R15_REG                     44)
370    (XMM8_REG                    45)
371    (XMM9_REG                    46)
372    (XMM10_REG                   47)
373    (XMM11_REG                   48)
374    (XMM12_REG                   49)
375    (XMM13_REG                   50)
376    (XMM14_REG                   51)
377    (XMM15_REG                   52)
378    (XMM16_REG                   53)
379    (XMM17_REG                   54)
380    (XMM18_REG                   55)
381    (XMM19_REG                   56)
382    (XMM20_REG                   57)
383    (XMM21_REG                   58)
384    (XMM22_REG                   59)
385    (XMM23_REG                   60)
386    (XMM24_REG                   61)
387    (XMM25_REG                   62)
388    (XMM26_REG                   63)
389    (XMM27_REG                   64)
390    (XMM28_REG                   65)
391    (XMM29_REG                   66)
392    (XMM30_REG                   67)
393    (XMM31_REG                   68)
394    (MASK0_REG                   69)
395    (MASK1_REG                   70)
396    (MASK2_REG                   71)
397    (MASK3_REG                   72)
398    (MASK4_REG                   73)
399    (MASK5_REG                   74)
400    (MASK6_REG                   75)
401    (MASK7_REG                   76)
402    (BND0_REG                    77)
403    (BND1_REG                    78)
404    (BND2_REG                    79)
405    (BND3_REG                    80)
406    (FIRST_PSEUDO_REG            81)
407   ])
409 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
410 ;; from i386.c.
412 ;; In C guard expressions, put expressions which may be compile-time
413 ;; constants first.  This allows for better optimization.  For
414 ;; example, write "TARGET_64BIT && reload_completed", not
415 ;; "reload_completed && TARGET_64BIT".
418 ;; Processor type.
419 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
420                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
421                     bdver4,btver2,znver1"
422   (const (symbol_ref "ix86_schedule")))
424 ;; A basic instruction type.  Refinements due to arguments to be
425 ;; provided in other attributes.
426 (define_attr "type"
427   "other,multi,
428    alu,alu1,negnot,imov,imovx,lea,
429    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
430    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
431    push,pop,call,callv,leave,
432    str,bitmanip,
433    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
434    fxch,fistp,fisttp,frndint,
435    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
436    ssemul,sseimul,ssediv,sselog,sselog1,
437    sseishft,sseishft1,ssecmp,ssecomi,
438    ssecvt,ssecvt1,sseicvt,sseins,
439    sseshuf,sseshuf1,ssemuladd,sse4arg,
440    lwp,mskmov,msklog,
441    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
442    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
443   (const_string "other"))
445 ;; Main data type used by the insn
446 (define_attr "mode"
447   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
448   V2DF,V2SF,V1DF,V8DF"
449   (const_string "unknown"))
451 ;; The CPU unit operations uses.
452 (define_attr "unit" "integer,i387,sse,mmx,unknown"
453   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
454                           fxch,fistp,fisttp,frndint")
455            (const_string "i387")
456          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
457                           ssemul,sseimul,ssediv,sselog,sselog1,
458                           sseishft,sseishft1,ssecmp,ssecomi,
459                           ssecvt,ssecvt1,sseicvt,sseins,
460                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
461            (const_string "sse")
462          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
463            (const_string "mmx")
464          (eq_attr "type" "other")
465            (const_string "unknown")]
466          (const_string "integer")))
468 ;; The (bounding maximum) length of an instruction immediate.
469 (define_attr "length_immediate" ""
470   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
471                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
472                           mpxld,mpxst")
473            (const_int 0)
474          (eq_attr "unit" "i387,sse,mmx")
475            (const_int 0)
476          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
477                           rotate,rotatex,rotate1,imul,icmp,push,pop")
478            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
479          (eq_attr "type" "imov,test")
480            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
481          (eq_attr "type" "call")
482            (if_then_else (match_operand 0 "constant_call_address_operand")
483              (const_int 4)
484              (const_int 0))
485          (eq_attr "type" "callv")
486            (if_then_else (match_operand 1 "constant_call_address_operand")
487              (const_int 4)
488              (const_int 0))
489          ;; We don't know the size before shorten_branches.  Expect
490          ;; the instruction to fit for better scheduling.
491          (eq_attr "type" "ibr")
492            (const_int 1)
493          ]
494          (symbol_ref "/* Update immediate_length and other attributes! */
495                       gcc_unreachable (),1")))
497 ;; The (bounding maximum) length of an instruction address.
498 (define_attr "length_address" ""
499   (cond [(eq_attr "type" "str,other,multi,fxch")
500            (const_int 0)
501          (and (eq_attr "type" "call")
502               (match_operand 0 "constant_call_address_operand"))
503              (const_int 0)
504          (and (eq_attr "type" "callv")
505               (match_operand 1 "constant_call_address_operand"))
506              (const_int 0)
507          ]
508          (symbol_ref "ix86_attr_length_address_default (insn)")))
510 ;; Set when length prefix is used.
511 (define_attr "prefix_data16" ""
512   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
513            (const_int 0)
514          (eq_attr "mode" "HI")
515            (const_int 1)
516          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
517            (const_int 1)
518         ]
519         (const_int 0)))
521 ;; Set when string REP prefix is used.
522 (define_attr "prefix_rep" ""
523   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
524            (const_int 0)
525          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
526            (const_int 1)
527          (and (eq_attr "type" "ibr,call,callv")
528               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
529            (const_int 1)
530         ]
531         (const_int 0)))
533 ;; Set when 0f opcode prefix is used.
534 (define_attr "prefix_0f" ""
535   (if_then_else
536     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
537                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
538          (eq_attr "unit" "sse,mmx"))
539     (const_int 1)
540     (const_int 0)))
542 ;; Set when REX opcode prefix is used.
543 (define_attr "prefix_rex" ""
544   (cond [(not (match_test "TARGET_64BIT"))
545            (const_int 0)
546          (and (eq_attr "mode" "DI")
547               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
548                    (eq_attr "unit" "!mmx")))
549            (const_int 1)
550          (and (eq_attr "mode" "QI")
551               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
552            (const_int 1)
553          (match_test "x86_extended_reg_mentioned_p (insn)")
554            (const_int 1)
555          (and (eq_attr "type" "imovx")
556               (match_operand:QI 1 "ext_QIreg_operand"))
557            (const_int 1)
558         ]
559         (const_int 0)))
561 ;; There are also additional prefixes in 3DNOW, SSSE3.
562 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
563 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
564 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
565 (define_attr "prefix_extra" ""
566   (cond [(eq_attr "type" "ssemuladd,sse4arg")
567            (const_int 2)
568          (eq_attr "type" "sseiadd1,ssecvt1")
569            (const_int 1)
570         ]
571         (const_int 0)))
573 ;; Set when BND opcode prefix may be used.
574 (define_attr "maybe_prefix_bnd" "" (const_int 0))
576 ;; Prefix used: original, VEX or maybe VEX.
577 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
578   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
579            (const_string "vex")
580          (eq_attr "mode" "XI,V16SF,V8DF")
581            (const_string "evex")
582         ]
583         (const_string "orig")))
585 ;; VEX W bit is used.
586 (define_attr "prefix_vex_w" "" (const_int 0))
588 ;; The length of VEX prefix
589 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
590 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
591 ;; still prefix_0f 1, with prefix_extra 1.
592 (define_attr "length_vex" ""
593   (if_then_else (and (eq_attr "prefix_0f" "1")
594                      (eq_attr "prefix_extra" "0"))
595     (if_then_else (eq_attr "prefix_vex_w" "1")
596       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
597       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
598     (if_then_else (eq_attr "prefix_vex_w" "1")
599       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
600       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
602 ;; 4-bytes evex prefix and 1 byte opcode.
603 (define_attr "length_evex" "" (const_int 5))
605 ;; Set when modrm byte is used.
606 (define_attr "modrm" ""
607   (cond [(eq_attr "type" "str,leave")
608            (const_int 0)
609          (eq_attr "unit" "i387")
610            (const_int 0)
611          (and (eq_attr "type" "incdec")
612               (and (not (match_test "TARGET_64BIT"))
613                    (ior (match_operand:SI 1 "register_operand")
614                         (match_operand:HI 1 "register_operand"))))
615            (const_int 0)
616          (and (eq_attr "type" "push")
617               (not (match_operand 1 "memory_operand")))
618            (const_int 0)
619          (and (eq_attr "type" "pop")
620               (not (match_operand 0 "memory_operand")))
621            (const_int 0)
622          (and (eq_attr "type" "imov")
623               (and (not (eq_attr "mode" "DI"))
624                    (ior (and (match_operand 0 "register_operand")
625                              (match_operand 1 "immediate_operand"))
626                         (ior (and (match_operand 0 "ax_reg_operand")
627                                   (match_operand 1 "memory_displacement_only_operand"))
628                              (and (match_operand 0 "memory_displacement_only_operand")
629                                   (match_operand 1 "ax_reg_operand"))))))
630            (const_int 0)
631          (and (eq_attr "type" "call")
632               (match_operand 0 "constant_call_address_operand"))
633              (const_int 0)
634          (and (eq_attr "type" "callv")
635               (match_operand 1 "constant_call_address_operand"))
636              (const_int 0)
637          (and (eq_attr "type" "alu,alu1,icmp,test")
638               (match_operand 0 "ax_reg_operand"))
639              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
640          ]
641          (const_int 1)))
643 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
644   (cond [(eq_attr "modrm" "0")
645            (const_string "none")
646          (eq_attr "type" "alu,imul,ishift")
647            (const_string "op02")
648          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
649            (const_string "op01")
650          (eq_attr "type" "incdec")
651            (const_string "incdec")
652          (eq_attr "type" "push,pop")
653            (const_string "pushpop")]
654          (const_string "unknown")))
656 ;; The (bounding maximum) length of an instruction in bytes.
657 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
658 ;; Later we may want to split them and compute proper length as for
659 ;; other insns.
660 (define_attr "length" ""
661   (cond [(eq_attr "type" "other,multi,fistp,frndint")
662            (const_int 16)
663          (eq_attr "type" "fcmp")
664            (const_int 4)
665          (eq_attr "unit" "i387")
666            (plus (const_int 2)
667                  (plus (attr "prefix_data16")
668                        (attr "length_address")))
669          (ior (eq_attr "prefix" "evex")
670               (and (ior (eq_attr "prefix" "maybe_evex")
671                         (eq_attr "prefix" "maybe_vex"))
672                    (match_test "TARGET_AVX512F")))
673            (plus (attr "length_evex")
674                  (plus (attr "length_immediate")
675                        (plus (attr "modrm")
676                              (attr "length_address"))))
677          (ior (eq_attr "prefix" "vex")
678               (and (ior (eq_attr "prefix" "maybe_vex")
679                         (eq_attr "prefix" "maybe_evex"))
680                    (match_test "TARGET_AVX")))
681            (plus (attr "length_vex")
682                  (plus (attr "length_immediate")
683                        (plus (attr "modrm")
684                              (attr "length_address"))))]
685          (plus (plus (attr "modrm")
686                      (plus (attr "prefix_0f")
687                            (plus (attr "prefix_rex")
688                                  (plus (attr "prefix_extra")
689                                        (const_int 1)))))
690                (plus (attr "prefix_rep")
691                      (plus (attr "prefix_data16")
692                            (plus (attr "length_immediate")
693                                  (attr "length_address")))))))
695 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
696 ;; `store' if there is a simple memory reference therein, or `unknown'
697 ;; if the instruction is complex.
699 (define_attr "memory" "none,load,store,both,unknown"
700   (cond [(eq_attr "type" "other,multi,str,lwp")
701            (const_string "unknown")
702          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
703            (const_string "none")
704          (eq_attr "type" "fistp,leave")
705            (const_string "both")
706          (eq_attr "type" "frndint")
707            (const_string "load")
708          (eq_attr "type" "mpxld")
709            (const_string "load")
710          (eq_attr "type" "mpxst")
711            (const_string "store")
712          (eq_attr "type" "push")
713            (if_then_else (match_operand 1 "memory_operand")
714              (const_string "both")
715              (const_string "store"))
716          (eq_attr "type" "pop")
717            (if_then_else (match_operand 0 "memory_operand")
718              (const_string "both")
719              (const_string "load"))
720          (eq_attr "type" "setcc")
721            (if_then_else (match_operand 0 "memory_operand")
722              (const_string "store")
723              (const_string "none"))
724          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
725            (if_then_else (ior (match_operand 0 "memory_operand")
726                               (match_operand 1 "memory_operand"))
727              (const_string "load")
728              (const_string "none"))
729          (eq_attr "type" "ibr")
730            (if_then_else (match_operand 0 "memory_operand")
731              (const_string "load")
732              (const_string "none"))
733          (eq_attr "type" "call")
734            (if_then_else (match_operand 0 "constant_call_address_operand")
735              (const_string "none")
736              (const_string "load"))
737          (eq_attr "type" "callv")
738            (if_then_else (match_operand 1 "constant_call_address_operand")
739              (const_string "none")
740              (const_string "load"))
741          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
742               (match_operand 1 "memory_operand"))
743            (const_string "both")
744          (and (match_operand 0 "memory_operand")
745               (match_operand 1 "memory_operand"))
746            (const_string "both")
747          (match_operand 0 "memory_operand")
748            (const_string "store")
749          (match_operand 1 "memory_operand")
750            (const_string "load")
751          (and (eq_attr "type"
752                  "!alu1,negnot,ishift1,
753                    imov,imovx,icmp,test,bitmanip,
754                    fmov,fcmp,fsgn,
755                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
756                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
757                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
758               (match_operand 2 "memory_operand"))
759            (const_string "load")
760          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
761               (match_operand 3 "memory_operand"))
762            (const_string "load")
763         ]
764         (const_string "none")))
766 ;; Indicates if an instruction has both an immediate and a displacement.
768 (define_attr "imm_disp" "false,true,unknown"
769   (cond [(eq_attr "type" "other,multi")
770            (const_string "unknown")
771          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
772               (and (match_operand 0 "memory_displacement_operand")
773                    (match_operand 1 "immediate_operand")))
774            (const_string "true")
775          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
776               (and (match_operand 0 "memory_displacement_operand")
777                    (match_operand 2 "immediate_operand")))
778            (const_string "true")
779         ]
780         (const_string "false")))
782 ;; Indicates if an FP operation has an integer source.
784 (define_attr "fp_int_src" "false,true"
785   (const_string "false"))
787 ;; Defines rounding mode of an FP operation.
789 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
790   (const_string "any"))
792 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
793 (define_attr "use_carry" "0,1" (const_string "0"))
795 ;; Define attribute to indicate unaligned ssemov insns
796 (define_attr "movu" "0,1" (const_string "0"))
798 ;; Used to control the "enabled" attribute on a per-instruction basis.
799 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
800                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
801                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
802                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
803                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
804   (const_string "base"))
806 (define_attr "enabled" ""
807   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
808          (eq_attr "isa" "x64_sse4")
809            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
810          (eq_attr "isa" "x64_sse4_noavx")
811            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
812          (eq_attr "isa" "x64_avx")
813            (symbol_ref "TARGET_64BIT && TARGET_AVX")
814          (eq_attr "isa" "x64_avx512dq")
815            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
816          (eq_attr "isa" "x64_avx512bw")
817            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
818          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
819          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
820          (eq_attr "isa" "sse2_noavx")
821            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
822          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
823          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
824          (eq_attr "isa" "sse4_noavx")
825            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
826          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
827          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
828          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
829          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
830          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
831          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
832          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
833          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
834          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
835          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
836          (eq_attr "isa" "fma_avx512f")
837            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
838          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
839          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
840          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
841          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
842          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
843          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
844         ]
845         (const_int 1)))
847 (define_attr "preferred_for_size" "" (const_int 1))
848 (define_attr "preferred_for_speed" "" (const_int 1))
850 ;; Describe a user's asm statement.
851 (define_asm_attributes
852   [(set_attr "length" "128")
853    (set_attr "type" "multi")])
855 (define_code_iterator plusminus [plus minus])
857 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
859 (define_code_iterator multdiv [mult div])
861 ;; Base name for define_insn
862 (define_code_attr plusminus_insn
863   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
864    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
866 ;; Base name for insn mnemonic.
867 (define_code_attr plusminus_mnemonic
868   [(plus "add") (ss_plus "adds") (us_plus "addus")
869    (minus "sub") (ss_minus "subs") (us_minus "subus")])
870 (define_code_attr multdiv_mnemonic
871   [(mult "mul") (div "div")])
873 ;; Mark commutative operators as such in constraints.
874 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
875                         (minus "") (ss_minus "") (us_minus "")])
877 ;; Mapping of max and min
878 (define_code_iterator maxmin [smax smin umax umin])
880 ;; Mapping of signed max and min
881 (define_code_iterator smaxmin [smax smin])
883 ;; Mapping of unsigned max and min
884 (define_code_iterator umaxmin [umax umin])
886 ;; Base name for integer and FP insn mnemonic
887 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
888                               (umax "maxu") (umin "minu")])
889 (define_code_attr maxmin_float [(smax "max") (smin "min")])
891 (define_int_iterator IEEE_MAXMIN
892         [UNSPEC_IEEE_MAX
893          UNSPEC_IEEE_MIN])
895 (define_int_attr ieee_maxmin
896         [(UNSPEC_IEEE_MAX "max")
897          (UNSPEC_IEEE_MIN "min")])
899 ;; Mapping of logic operators
900 (define_code_iterator any_logic [and ior xor])
901 (define_code_iterator any_or [ior xor])
902 (define_code_iterator fpint_logic [and xor])
904 ;; Base name for insn mnemonic.
905 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
907 ;; Mapping of logic-shift operators
908 (define_code_iterator any_lshift [ashift lshiftrt])
910 ;; Mapping of shift-right operators
911 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
913 ;; Mapping of all shift operators
914 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
916 ;; Base name for define_insn
917 (define_code_attr shift_insn
918   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
920 ;; Base name for insn mnemonic.
921 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
922 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
924 ;; Mask variant left right mnemonics
925 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
927 ;; Mapping of rotate operators
928 (define_code_iterator any_rotate [rotate rotatert])
930 ;; Base name for define_insn
931 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
933 ;; Base name for insn mnemonic.
934 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
936 ;; Mapping of abs neg operators
937 (define_code_iterator absneg [abs neg])
939 ;; Base name for x87 insn mnemonic.
940 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
942 ;; Used in signed and unsigned widening multiplications.
943 (define_code_iterator any_extend [sign_extend zero_extend])
945 ;; Prefix for insn menmonic.
946 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
948 ;; Prefix for define_insn
949 (define_code_attr u [(sign_extend "") (zero_extend "u")])
950 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
951 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
953 ;; Used in signed and unsigned truncations.
954 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
955 ;; Instruction suffix for truncations.
956 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
958 ;; Used in signed and unsigned fix.
959 (define_code_iterator any_fix [fix unsigned_fix])
960 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
962 ;; Used in signed and unsigned float.
963 (define_code_iterator any_float [float unsigned_float])
964 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
966 ;; All integer modes.
967 (define_mode_iterator SWI1248x [QI HI SI DI])
969 ;; All integer modes with AVX512BW/DQ.
970 (define_mode_iterator SWI1248_AVX512BWDQ
971   [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
973 ;; All integer modes without QImode.
974 (define_mode_iterator SWI248x [HI SI DI])
976 ;; All integer modes without QImode and HImode.
977 (define_mode_iterator SWI48x [SI DI])
979 ;; All integer modes without SImode and DImode.
980 (define_mode_iterator SWI12 [QI HI])
982 ;; All integer modes without DImode.
983 (define_mode_iterator SWI124 [QI HI SI])
985 ;; All integer modes without QImode and DImode.
986 (define_mode_iterator SWI24 [HI SI])
988 ;; Single word integer modes.
989 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
991 ;; Single word integer modes without QImode.
992 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
994 ;; Single word integer modes without QImode and HImode.
995 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
997 ;; All math-dependant single and double word integer modes.
998 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
999                              (HI "TARGET_HIMODE_MATH")
1000                              SI DI (TI "TARGET_64BIT")])
1002 ;; Math-dependant single word integer modes.
1003 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1004                             (HI "TARGET_HIMODE_MATH")
1005                             SI (DI "TARGET_64BIT")])
1007 ;; Math-dependant integer modes without DImode.
1008 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1009                                (HI "TARGET_HIMODE_MATH")
1010                                SI])
1012 ;; Math-dependant integer modes with DImode.
1013 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1014                                  (HI "TARGET_HIMODE_MATH")
1015                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1017 ;; Math-dependant single word integer modes without QImode.
1018 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1019                                SI (DI "TARGET_64BIT")])
1021 ;; Double word integer modes.
1022 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1023                            (TI "TARGET_64BIT")])
1025 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1026 ;; compile time constant, it is faster to use <MODE_SIZE> than
1027 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1028 ;; command line options just use GET_MODE_SIZE macro.
1029 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1030                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1031                              (V16QI "16") (V32QI "32") (V64QI "64")
1032                              (V8HI "16") (V16HI "32") (V32HI "64")
1033                              (V4SI "16") (V8SI "32") (V16SI "64")
1034                              (V2DI "16") (V4DI "32") (V8DI "64")
1035                              (V1TI "16") (V2TI "32") (V4TI "64")
1036                              (V2DF "16") (V4DF "32") (V8DF "64")
1037                              (V4SF "16") (V8SF "32") (V16SF "64")])
1039 ;; Double word integer modes as mode attribute.
1040 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1041 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1043 ;; LEA mode corresponding to an integer mode
1044 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1046 ;; Half mode for double word integer modes.
1047 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1048                             (DI "TARGET_64BIT")])
1050 ;; Bound modes.
1051 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1052                            (BND64 "TARGET_LP64")])
1054 ;; Pointer mode corresponding to bound mode.
1055 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1057 ;; MPX check types
1058 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1060 ;; Check name
1061 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1062                            (UNSPEC_BNDCU "cu")
1063                            (UNSPEC_BNDCN "cn")])
1065 ;; Instruction suffix for integer modes.
1066 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1068 ;; Instruction suffix for masks.
1069 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1071 ;; Pointer size prefix for integer modes (Intel asm dialect)
1072 (define_mode_attr iptrsize [(QI "BYTE")
1073                             (HI "WORD")
1074                             (SI "DWORD")
1075                             (DI "QWORD")])
1077 ;; Register class for integer modes.
1078 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1080 ;; Immediate operand constraint for integer modes.
1081 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1083 ;; General operand constraint for word modes.
1084 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1086 ;; Immediate operand constraint for double integer modes.
1087 (define_mode_attr di [(SI "nF") (DI "Wd")])
1089 ;; Immediate operand constraint for shifts.
1090 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1092 ;; General operand predicate for integer modes.
1093 (define_mode_attr general_operand
1094         [(QI "general_operand")
1095          (HI "general_operand")
1096          (SI "x86_64_general_operand")
1097          (DI "x86_64_general_operand")
1098          (TI "x86_64_general_operand")])
1100 ;; General operand predicate for integer modes, where for TImode
1101 ;; we need both words of the operand to be general operands.
1102 (define_mode_attr general_hilo_operand
1103         [(QI "general_operand")
1104          (HI "general_operand")
1105          (SI "x86_64_general_operand")
1106          (DI "x86_64_general_operand")
1107          (TI "x86_64_hilo_general_operand")])
1109 ;; General sign extend operand predicate for integer modes,
1110 ;; which disallows VOIDmode operands and thus it is suitable
1111 ;; for use inside sign_extend.
1112 (define_mode_attr general_sext_operand
1113         [(QI "sext_operand")
1114          (HI "sext_operand")
1115          (SI "x86_64_sext_operand")
1116          (DI "x86_64_sext_operand")])
1118 ;; General sign/zero extend operand predicate for integer modes.
1119 (define_mode_attr general_szext_operand
1120         [(QI "general_operand")
1121          (HI "general_operand")
1122          (SI "x86_64_szext_general_operand")
1123          (DI "x86_64_szext_general_operand")])
1125 ;; Immediate operand predicate for integer modes.
1126 (define_mode_attr immediate_operand
1127         [(QI "immediate_operand")
1128          (HI "immediate_operand")
1129          (SI "x86_64_immediate_operand")
1130          (DI "x86_64_immediate_operand")])
1132 ;; Nonmemory operand predicate for integer modes.
1133 (define_mode_attr nonmemory_operand
1134         [(QI "nonmemory_operand")
1135          (HI "nonmemory_operand")
1136          (SI "x86_64_nonmemory_operand")
1137          (DI "x86_64_nonmemory_operand")])
1139 ;; Operand predicate for shifts.
1140 (define_mode_attr shift_operand
1141         [(QI "nonimmediate_operand")
1142          (HI "nonimmediate_operand")
1143          (SI "nonimmediate_operand")
1144          (DI "shiftdi_operand")
1145          (TI "register_operand")])
1147 ;; Operand predicate for shift argument.
1148 (define_mode_attr shift_immediate_operand
1149         [(QI "const_1_to_31_operand")
1150          (HI "const_1_to_31_operand")
1151          (SI "const_1_to_31_operand")
1152          (DI "const_1_to_63_operand")])
1154 ;; Input operand predicate for arithmetic left shifts.
1155 (define_mode_attr ashl_input_operand
1156         [(QI "nonimmediate_operand")
1157          (HI "nonimmediate_operand")
1158          (SI "nonimmediate_operand")
1159          (DI "ashldi_input_operand")
1160          (TI "reg_or_pm1_operand")])
1162 ;; SSE and x87 SFmode and DFmode floating point modes
1163 (define_mode_iterator MODEF [SF DF])
1165 ;; All x87 floating point modes
1166 (define_mode_iterator X87MODEF [SF DF XF])
1168 ;; SSE instruction suffix for various modes
1169 (define_mode_attr ssemodesuffix
1170   [(SF "ss") (DF "sd")
1171    (V16SF "ps") (V8DF "pd")
1172    (V8SF "ps") (V4DF "pd")
1173    (V4SF "ps") (V2DF "pd")
1174    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1175    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1176    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1178 ;; SSE vector suffix for floating point modes
1179 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1181 ;; SSE vector mode corresponding to a scalar mode
1182 (define_mode_attr ssevecmode
1183   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1184 (define_mode_attr ssevecmodelower
1185   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1187 ;; AVX512F vector mode corresponding to a scalar mode
1188 (define_mode_attr avx512fvecmode
1189   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1191 ;; Instruction suffix for REX 64bit operators.
1192 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1194 ;; This mode iterator allows :P to be used for patterns that operate on
1195 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1196 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1198 ;; This mode iterator allows :W to be used for patterns that operate on
1199 ;; word_mode sized quantities.
1200 (define_mode_iterator W
1201   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1203 ;; This mode iterator allows :PTR to be used for patterns that operate on
1204 ;; ptr_mode sized quantities.
1205 (define_mode_iterator PTR
1206   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1208 ;; Scheduling descriptions
1210 (include "pentium.md")
1211 (include "ppro.md")
1212 (include "k6.md")
1213 (include "athlon.md")
1214 (include "bdver1.md")
1215 (include "bdver3.md")
1216 (include "btver2.md")
1217 (include "znver1.md")
1218 (include "geode.md")
1219 (include "atom.md")
1220 (include "slm.md")
1221 (include "core2.md")
1222 (include "haswell.md")
1225 ;; Operand and operator predicates and constraints
1227 (include "predicates.md")
1228 (include "constraints.md")
1231 ;; Compare and branch/compare and store instructions.
1233 (define_expand "cbranch<mode>4"
1234   [(set (reg:CC FLAGS_REG)
1235         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1236                     (match_operand:SDWIM 2 "<general_operand>")))
1237    (set (pc) (if_then_else
1238                (match_operator 0 "ordered_comparison_operator"
1239                 [(reg:CC FLAGS_REG) (const_int 0)])
1240                (label_ref (match_operand 3))
1241                (pc)))]
1242   ""
1244   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1245     operands[1] = force_reg (<MODE>mode, operands[1]);
1246   ix86_expand_branch (GET_CODE (operands[0]),
1247                       operands[1], operands[2], operands[3]);
1248   DONE;
1251 (define_expand "cstore<mode>4"
1252   [(set (reg:CC FLAGS_REG)
1253         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1254                     (match_operand:SWIM 3 "<general_operand>")))
1255    (set (match_operand:QI 0 "register_operand")
1256         (match_operator 1 "ordered_comparison_operator"
1257           [(reg:CC FLAGS_REG) (const_int 0)]))]
1258   ""
1260   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1261     operands[2] = force_reg (<MODE>mode, operands[2]);
1262   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1263                      operands[2], operands[3]);
1264   DONE;
1267 (define_expand "cmp<mode>_1"
1268   [(set (reg:CC FLAGS_REG)
1269         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1270                     (match_operand:SWI48 1 "<general_operand>")))])
1272 (define_insn "*cmp<mode>_ccno_1"
1273   [(set (reg FLAGS_REG)
1274         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1275                  (match_operand:SWI 1 "const0_operand")))]
1276   "ix86_match_ccmode (insn, CCNOmode)"
1277   "@
1278    test{<imodesuffix>}\t%0, %0
1279    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1280   [(set_attr "type" "test,icmp")
1281    (set_attr "length_immediate" "0,1")
1282    (set_attr "modrm_class" "op0,unknown")
1283    (set_attr "mode" "<MODE>")])
1285 (define_insn "*cmp<mode>_1"
1286   [(set (reg FLAGS_REG)
1287         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1288                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1289   "ix86_match_ccmode (insn, CCmode)"
1290   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1291   [(set_attr "type" "icmp")
1292    (set_attr "mode" "<MODE>")])
1294 (define_insn "*cmp<mode>_minus_1"
1295   [(set (reg FLAGS_REG)
1296         (compare
1297           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1298                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1299           (const_int 0)))]
1300   "ix86_match_ccmode (insn, CCGOCmode)"
1301   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1302   [(set_attr "type" "icmp")
1303    (set_attr "mode" "<MODE>")])
1305 (define_insn "*cmpqi_ext_1"
1306   [(set (reg FLAGS_REG)
1307         (compare
1308           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1309           (subreg:QI
1310             (zero_extract:SI
1311               (match_operand 1 "ext_register_operand" "Q,Q")
1312               (const_int 8)
1313               (const_int 8)) 0)))]
1314   "ix86_match_ccmode (insn, CCmode)"
1315   "cmp{b}\t{%h1, %0|%0, %h1}"
1316   [(set_attr "isa" "*,nox64")
1317    (set_attr "type" "icmp")
1318    (set_attr "mode" "QI")])
1320 (define_insn "*cmpqi_ext_2"
1321   [(set (reg FLAGS_REG)
1322         (compare
1323           (subreg:QI
1324             (zero_extract:SI
1325               (match_operand 0 "ext_register_operand" "Q")
1326               (const_int 8)
1327               (const_int 8)) 0)
1328           (match_operand:QI 1 "const0_operand")))]
1329   "ix86_match_ccmode (insn, CCNOmode)"
1330   "test{b}\t%h0, %h0"
1331   [(set_attr "type" "test")
1332    (set_attr "length_immediate" "0")
1333    (set_attr "mode" "QI")])
1335 (define_expand "cmpqi_ext_3"
1336   [(set (reg:CC FLAGS_REG)
1337         (compare:CC
1338           (subreg:QI
1339             (zero_extract:SI
1340               (match_operand 0 "ext_register_operand")
1341               (const_int 8)
1342               (const_int 8)) 0)
1343           (match_operand:QI 1 "const_int_operand")))])
1345 (define_insn "*cmpqi_ext_3"
1346   [(set (reg FLAGS_REG)
1347         (compare
1348           (subreg:QI
1349             (zero_extract:SI
1350               (match_operand 0 "ext_register_operand" "Q,Q")
1351               (const_int 8)
1352               (const_int 8)) 0)
1353           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1354   "ix86_match_ccmode (insn, CCmode)"
1355   "cmp{b}\t{%1, %h0|%h0, %1}"
1356   [(set_attr "isa" "*,nox64")
1357    (set_attr "type" "icmp")
1358    (set_attr "modrm" "1")
1359    (set_attr "mode" "QI")])
1361 (define_insn "*cmpqi_ext_4"
1362   [(set (reg FLAGS_REG)
1363         (compare
1364           (subreg:QI
1365             (zero_extract:SI
1366               (match_operand 0 "ext_register_operand" "Q")
1367               (const_int 8)
1368               (const_int 8)) 0)
1369           (subreg:QI
1370             (zero_extract:SI
1371               (match_operand 1 "ext_register_operand" "Q")
1372               (const_int 8)
1373               (const_int 8)) 0)))]
1374   "ix86_match_ccmode (insn, CCmode)"
1375   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1376   [(set_attr "type" "icmp")
1377    (set_attr "mode" "QI")])
1379 ;; These implement float point compares.
1380 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1381 ;; which would allow mix and match FP modes on the compares.  Which is what
1382 ;; the old patterns did, but with many more of them.
1384 (define_expand "cbranchxf4"
1385   [(set (reg:CC FLAGS_REG)
1386         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1387                     (match_operand:XF 2 "nonmemory_operand")))
1388    (set (pc) (if_then_else
1389               (match_operator 0 "ix86_fp_comparison_operator"
1390                [(reg:CC FLAGS_REG)
1391                 (const_int 0)])
1392               (label_ref (match_operand 3))
1393               (pc)))]
1394   "TARGET_80387"
1396   ix86_expand_branch (GET_CODE (operands[0]),
1397                       operands[1], operands[2], operands[3]);
1398   DONE;
1401 (define_expand "cstorexf4"
1402   [(set (reg:CC FLAGS_REG)
1403         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1404                     (match_operand:XF 3 "nonmemory_operand")))
1405    (set (match_operand:QI 0 "register_operand")
1406               (match_operator 1 "ix86_fp_comparison_operator"
1407                [(reg:CC FLAGS_REG)
1408                 (const_int 0)]))]
1409   "TARGET_80387"
1411   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1412                      operands[2], operands[3]);
1413   DONE;
1416 (define_expand "cbranch<mode>4"
1417   [(set (reg:CC FLAGS_REG)
1418         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1419                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1420    (set (pc) (if_then_else
1421               (match_operator 0 "ix86_fp_comparison_operator"
1422                [(reg:CC FLAGS_REG)
1423                 (const_int 0)])
1424               (label_ref (match_operand 3))
1425               (pc)))]
1426   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1428   ix86_expand_branch (GET_CODE (operands[0]),
1429                       operands[1], operands[2], operands[3]);
1430   DONE;
1433 (define_expand "cstore<mode>4"
1434   [(set (reg:CC FLAGS_REG)
1435         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1436                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1437    (set (match_operand:QI 0 "register_operand")
1438               (match_operator 1 "ix86_fp_comparison_operator"
1439                [(reg:CC FLAGS_REG)
1440                 (const_int 0)]))]
1441   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1443   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444                      operands[2], operands[3]);
1445   DONE;
1448 (define_expand "cbranchcc4"
1449   [(set (pc) (if_then_else
1450               (match_operator 0 "comparison_operator"
1451                [(match_operand 1 "flags_reg_operand")
1452                 (match_operand 2 "const0_operand")])
1453               (label_ref (match_operand 3))
1454               (pc)))]
1455   ""
1457   ix86_expand_branch (GET_CODE (operands[0]),
1458                       operands[1], operands[2], operands[3]);
1459   DONE;
1462 (define_expand "cstorecc4"
1463   [(set (match_operand:QI 0 "register_operand")
1464               (match_operator 1 "comparison_operator"
1465                [(match_operand 2 "flags_reg_operand")
1466                 (match_operand 3 "const0_operand")]))]
1467   ""
1469   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1470                      operands[2], operands[3]);
1471   DONE;
1475 ;; FP compares, step 1:
1476 ;; Set the FP condition codes.
1478 ;; CCFPmode     compare with exceptions
1479 ;; CCFPUmode    compare with no exceptions
1481 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1482 ;; used to manage the reg stack popping would not be preserved.
1484 (define_insn "*cmp<mode>_0_i387"
1485   [(set (match_operand:HI 0 "register_operand" "=a")
1486         (unspec:HI
1487           [(compare:CCFP
1488              (match_operand:X87MODEF 1 "register_operand" "f")
1489              (match_operand:X87MODEF 2 "const0_operand"))]
1490         UNSPEC_FNSTSW))]
1491   "TARGET_80387"
1492   "* return output_fp_compare (insn, operands, false, false);"
1493   [(set_attr "type" "multi")
1494    (set_attr "unit" "i387")
1495    (set_attr "mode" "<MODE>")])
1497 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1498   [(set (reg:CCFP FLAGS_REG)
1499         (compare:CCFP
1500           (match_operand:X87MODEF 1 "register_operand" "f")
1501           (match_operand:X87MODEF 2 "const0_operand")))
1502    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1503   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1504   "#"
1505   "&& reload_completed"
1506   [(set (match_dup 0)
1507         (unspec:HI
1508           [(compare:CCFP (match_dup 1)(match_dup 2))]
1509         UNSPEC_FNSTSW))
1510    (set (reg:CC FLAGS_REG)
1511         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1512   ""
1513   [(set_attr "type" "multi")
1514    (set_attr "unit" "i387")
1515    (set_attr "mode" "<MODE>")])
1517 (define_insn "*cmpxf_i387"
1518   [(set (match_operand:HI 0 "register_operand" "=a")
1519         (unspec:HI
1520           [(compare:CCFP
1521              (match_operand:XF 1 "register_operand" "f")
1522              (match_operand:XF 2 "register_operand" "f"))]
1523           UNSPEC_FNSTSW))]
1524   "TARGET_80387"
1525   "* return output_fp_compare (insn, operands, false, false);"
1526   [(set_attr "type" "multi")
1527    (set_attr "unit" "i387")
1528    (set_attr "mode" "XF")])
1530 (define_insn_and_split "*cmpxf_cc_i387"
1531   [(set (reg:CCFP FLAGS_REG)
1532         (compare:CCFP
1533           (match_operand:XF 1 "register_operand" "f")
1534           (match_operand:XF 2 "register_operand" "f")))
1535    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1536   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1537   "#"
1538   "&& reload_completed"
1539   [(set (match_dup 0)
1540         (unspec:HI
1541           [(compare:CCFP (match_dup 1)(match_dup 2))]
1542         UNSPEC_FNSTSW))
1543    (set (reg:CC FLAGS_REG)
1544         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1545   ""
1546   [(set_attr "type" "multi")
1547    (set_attr "unit" "i387")
1548    (set_attr "mode" "XF")])
1550 (define_insn "*cmp<mode>_i387"
1551   [(set (match_operand:HI 0 "register_operand" "=a")
1552         (unspec:HI
1553           [(compare:CCFP
1554              (match_operand:MODEF 1 "register_operand" "f")
1555              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1556           UNSPEC_FNSTSW))]
1557   "TARGET_80387"
1558   "* return output_fp_compare (insn, operands, false, false);"
1559   [(set_attr "type" "multi")
1560    (set_attr "unit" "i387")
1561    (set_attr "mode" "<MODE>")])
1563 (define_insn_and_split "*cmp<mode>_cc_i387"
1564   [(set (reg:CCFP FLAGS_REG)
1565         (compare:CCFP
1566           (match_operand:MODEF 1 "register_operand" "f")
1567           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1568    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1569   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1570   "#"
1571   "&& reload_completed"
1572   [(set (match_dup 0)
1573         (unspec:HI
1574           [(compare:CCFP (match_dup 1)(match_dup 2))]
1575         UNSPEC_FNSTSW))
1576    (set (reg:CC FLAGS_REG)
1577         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1578   ""
1579   [(set_attr "type" "multi")
1580    (set_attr "unit" "i387")
1581    (set_attr "mode" "<MODE>")])
1583 (define_insn "*cmpu<mode>_i387"
1584   [(set (match_operand:HI 0 "register_operand" "=a")
1585         (unspec:HI
1586           [(compare:CCFPU
1587              (match_operand:X87MODEF 1 "register_operand" "f")
1588              (match_operand:X87MODEF 2 "register_operand" "f"))]
1589           UNSPEC_FNSTSW))]
1590   "TARGET_80387"
1591   "* return output_fp_compare (insn, operands, false, true);"
1592   [(set_attr "type" "multi")
1593    (set_attr "unit" "i387")
1594    (set_attr "mode" "<MODE>")])
1596 (define_insn_and_split "*cmpu<mode>_cc_i387"
1597   [(set (reg:CCFPU FLAGS_REG)
1598         (compare:CCFPU
1599           (match_operand:X87MODEF 1 "register_operand" "f")
1600           (match_operand:X87MODEF 2 "register_operand" "f")))
1601    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1602   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1603   "#"
1604   "&& reload_completed"
1605   [(set (match_dup 0)
1606         (unspec:HI
1607           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1608         UNSPEC_FNSTSW))
1609    (set (reg:CC FLAGS_REG)
1610         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1611   ""
1612   [(set_attr "type" "multi")
1613    (set_attr "unit" "i387")
1614    (set_attr "mode" "<MODE>")])
1616 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1617   [(set (match_operand:HI 0 "register_operand" "=a")
1618         (unspec:HI
1619           [(compare:CCFP
1620              (match_operand:X87MODEF 1 "register_operand" "f")
1621              (match_operator:X87MODEF 3 "float_operator"
1622                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1623           UNSPEC_FNSTSW))]
1624   "TARGET_80387
1625    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1626        || optimize_function_for_size_p (cfun))"
1627   "* return output_fp_compare (insn, operands, false, false);"
1628   [(set_attr "type" "multi")
1629    (set_attr "unit" "i387")
1630    (set_attr "fp_int_src" "true")
1631    (set_attr "mode" "<SWI24:MODE>")])
1633 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1634   [(set (reg:CCFP FLAGS_REG)
1635         (compare:CCFP
1636           (match_operand:X87MODEF 1 "register_operand" "f")
1637           (match_operator:X87MODEF 3 "float_operator"
1638             [(match_operand:SWI24 2 "memory_operand" "m")])))
1639    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1640   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1641    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1642        || optimize_function_for_size_p (cfun))"
1643   "#"
1644   "&& reload_completed"
1645   [(set (match_dup 0)
1646         (unspec:HI
1647           [(compare:CCFP
1648              (match_dup 1)
1649              (match_op_dup 3 [(match_dup 2)]))]
1650         UNSPEC_FNSTSW))
1651    (set (reg:CC FLAGS_REG)
1652         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1653   ""
1654   [(set_attr "type" "multi")
1655    (set_attr "unit" "i387")
1656    (set_attr "fp_int_src" "true")
1657    (set_attr "mode" "<SWI24:MODE>")])
1659 ;; FP compares, step 2
1660 ;; Move the fpsw to ax.
1662 (define_insn "x86_fnstsw_1"
1663   [(set (match_operand:HI 0 "register_operand" "=a")
1664         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1665   "TARGET_80387"
1666   "fnstsw\t%0"
1667   [(set_attr "length" "2")
1668    (set_attr "mode" "SI")
1669    (set_attr "unit" "i387")])
1671 ;; FP compares, step 3
1672 ;; Get ax into flags, general case.
1674 (define_insn "x86_sahf_1"
1675   [(set (reg:CC FLAGS_REG)
1676         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1677                    UNSPEC_SAHF))]
1678   "TARGET_SAHF"
1680 #ifndef HAVE_AS_IX86_SAHF
1681   if (TARGET_64BIT)
1682     return ASM_BYTE "0x9e";
1683   else
1684 #endif
1685   return "sahf";
1687   [(set_attr "length" "1")
1688    (set_attr "athlon_decode" "vector")
1689    (set_attr "amdfam10_decode" "direct")
1690    (set_attr "bdver1_decode" "direct")
1691    (set_attr "mode" "SI")])
1693 ;; Pentium Pro can do steps 1 through 3 in one go.
1694 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1695 ;; (these i387 instructions set flags directly)
1697 (define_mode_iterator FPCMP [CCFP CCFPU])
1698 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1700 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1701   [(set (reg:FPCMP FLAGS_REG)
1702         (compare:FPCMP
1703           (match_operand:MODEF 0 "register_operand" "f,v")
1704           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1705   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1706    || (TARGET_80387 && TARGET_CMOVE)"
1707   "* return output_fp_compare (insn, operands, true,
1708                                <FPCMP:MODE>mode == CCFPUmode);"
1709   [(set_attr "type" "fcmp,ssecomi")
1710    (set_attr "prefix" "orig,maybe_vex")
1711    (set_attr "mode" "<MODEF:MODE>")
1712    (set_attr "prefix_rep" "*,0")
1713    (set (attr "prefix_data16")
1714         (cond [(eq_attr "alternative" "0")
1715                  (const_string "*")
1716                (eq_attr "mode" "DF")
1717                  (const_string "1")
1718               ]
1719               (const_string "0")))
1720    (set_attr "athlon_decode" "vector")
1721    (set_attr "amdfam10_decode" "direct")
1722    (set_attr "bdver1_decode" "double")
1723    (set_attr "znver1_decode" "double")
1724    (set (attr "enabled")
1725      (if_then_else
1726        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1727        (if_then_else
1728          (eq_attr "alternative" "0")
1729          (symbol_ref "TARGET_MIX_SSE_I387")
1730          (symbol_ref "true"))
1731        (if_then_else
1732          (eq_attr "alternative" "0")
1733          (symbol_ref "true")
1734          (symbol_ref "false"))))])
1736 (define_insn "*cmpi<unord>xf_i387"
1737   [(set (reg:FPCMP FLAGS_REG)
1738         (compare:FPCMP
1739           (match_operand:XF 0 "register_operand" "f")
1740           (match_operand:XF 1 "register_operand" "f")))]
1741   "TARGET_80387 && TARGET_CMOVE"
1742   "* return output_fp_compare (insn, operands, true,
1743                                <MODE>mode == CCFPUmode);"
1744   [(set_attr "type" "fcmp")
1745    (set_attr "mode" "XF")
1746    (set_attr "athlon_decode" "vector")
1747    (set_attr "amdfam10_decode" "direct")
1748    (set_attr "bdver1_decode" "double")
1749    (set_attr "znver1_decode" "double")])
1751 ;; Push/pop instructions.
1753 (define_insn "*push<mode>2"
1754   [(set (match_operand:DWI 0 "push_operand" "=<")
1755         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1756   ""
1757   "#"
1758   [(set_attr "type" "multi")
1759    (set_attr "mode" "<MODE>")])
1761 (define_split
1762   [(set (match_operand:TI 0 "push_operand")
1763         (match_operand:TI 1 "general_operand"))]
1764   "TARGET_64BIT && reload_completed
1765    && !SSE_REG_P (operands[1])"
1766   [(const_int 0)]
1767   "ix86_split_long_move (operands); DONE;")
1769 (define_insn "*pushdi2_rex64"
1770   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1771         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1772   "TARGET_64BIT"
1773   "@
1774    push{q}\t%1
1775    #"
1776   [(set_attr "type" "push,multi")
1777    (set_attr "mode" "DI")])
1779 ;; Convert impossible pushes of immediate to existing instructions.
1780 ;; First try to get scratch register and go through it.  In case this
1781 ;; fails, push sign extended lower part first and then overwrite
1782 ;; upper part by 32bit move.
1783 (define_peephole2
1784   [(match_scratch:DI 2 "r")
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)"
1789   [(set (match_dup 2) (match_dup 1))
1790    (set (match_dup 0) (match_dup 2))])
1792 ;; We need to define this as both peepholer and splitter for case
1793 ;; peephole2 pass is not run.
1794 ;; "&& 1" is needed to keep it from matching the previous pattern.
1795 (define_peephole2
1796   [(set (match_operand:DI 0 "push_operand")
1797         (match_operand:DI 1 "immediate_operand"))]
1798   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1799    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1800   [(set (match_dup 0) (match_dup 1))
1801    (set (match_dup 2) (match_dup 3))]
1803   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1805   operands[1] = gen_lowpart (DImode, operands[2]);
1806   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1807                                                    GEN_INT (4)));
1810 (define_split
1811   [(set (match_operand:DI 0 "push_operand")
1812         (match_operand:DI 1 "immediate_operand"))]
1813   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1814                     ? epilogue_completed : reload_completed)
1815    && !symbolic_operand (operands[1], DImode)
1816    && !x86_64_immediate_operand (operands[1], DImode)"
1817   [(set (match_dup 0) (match_dup 1))
1818    (set (match_dup 2) (match_dup 3))]
1820   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1822   operands[1] = gen_lowpart (DImode, operands[2]);
1823   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1824                                                    GEN_INT (4)));
1827 (define_split
1828   [(set (match_operand:DI 0 "push_operand")
1829         (match_operand:DI 1 "general_operand"))]
1830   "!TARGET_64BIT && reload_completed
1831    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1832   [(const_int 0)]
1833   "ix86_split_long_move (operands); DONE;")
1835 (define_insn "*pushsi2"
1836   [(set (match_operand:SI 0 "push_operand" "=<")
1837         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1838   "!TARGET_64BIT"
1839   "push{l}\t%1"
1840   [(set_attr "type" "push")
1841    (set_attr "mode" "SI")])
1843 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1844 ;; "push a byte/word".  But actually we use pushl, which has the effect
1845 ;; of rounding the amount pushed up to a word.
1847 ;; For TARGET_64BIT we always round up to 8 bytes.
1848 (define_insn "*push<mode>2_rex64"
1849   [(set (match_operand:SWI124 0 "push_operand" "=X")
1850         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1851   "TARGET_64BIT"
1852   "push{q}\t%q1"
1853   [(set_attr "type" "push")
1854    (set_attr "mode" "DI")])
1856 (define_insn "*push<mode>2"
1857   [(set (match_operand:SWI12 0 "push_operand" "=X")
1858         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1859   "!TARGET_64BIT"
1860   "push{l}\t%k1"
1861   [(set_attr "type" "push")
1862    (set_attr "mode" "SI")])
1864 (define_insn "*push<mode>2_prologue"
1865   [(set (match_operand:W 0 "push_operand" "=<")
1866         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1867    (clobber (mem:BLK (scratch)))]
1868   ""
1869   "push{<imodesuffix>}\t%1"
1870   [(set_attr "type" "push")
1871    (set_attr "mode" "<MODE>")])
1873 (define_insn "*pop<mode>1"
1874   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1875         (match_operand:W 1 "pop_operand" ">"))]
1876   ""
1877   "pop{<imodesuffix>}\t%0"
1878   [(set_attr "type" "pop")
1879    (set_attr "mode" "<MODE>")])
1881 (define_insn "*pop<mode>1_epilogue"
1882   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1883         (match_operand:W 1 "pop_operand" ">"))
1884    (clobber (mem:BLK (scratch)))]
1885   ""
1886   "pop{<imodesuffix>}\t%0"
1887   [(set_attr "type" "pop")
1888    (set_attr "mode" "<MODE>")])
1890 (define_insn "*pushfl<mode>2"
1891   [(set (match_operand:W 0 "push_operand" "=<")
1892         (match_operand:W 1 "flags_reg_operand"))]
1893   ""
1894   "pushf{<imodesuffix>}"
1895   [(set_attr "type" "push")
1896    (set_attr "mode" "<MODE>")])
1898 (define_insn "*popfl<mode>1"
1899   [(set (match_operand:W 0 "flags_reg_operand")
1900         (match_operand:W 1 "pop_operand" ">"))]
1901   ""
1902   "popf{<imodesuffix>}"
1903   [(set_attr "type" "pop")
1904    (set_attr "mode" "<MODE>")])
1907 ;; Reload patterns to support multi-word load/store
1908 ;; with non-offsetable address.
1909 (define_expand "reload_noff_store"
1910   [(parallel [(match_operand 0 "memory_operand" "=m")
1911               (match_operand 1 "register_operand" "r")
1912               (match_operand:DI 2 "register_operand" "=&r")])]
1913   "TARGET_64BIT"
1915   rtx mem = operands[0];
1916   rtx addr = XEXP (mem, 0);
1918   emit_move_insn (operands[2], addr);
1919   mem = replace_equiv_address_nv (mem, operands[2]);
1921   emit_insn (gen_rtx_SET (mem, operands[1]));
1922   DONE;
1925 (define_expand "reload_noff_load"
1926   [(parallel [(match_operand 0 "register_operand" "=r")
1927               (match_operand 1 "memory_operand" "m")
1928               (match_operand:DI 2 "register_operand" "=r")])]
1929   "TARGET_64BIT"
1931   rtx mem = operands[1];
1932   rtx addr = XEXP (mem, 0);
1934   emit_move_insn (operands[2], addr);
1935   mem = replace_equiv_address_nv (mem, operands[2]);
1937   emit_insn (gen_rtx_SET (operands[0], mem));
1938   DONE;
1941 ;; Move instructions.
1943 (define_expand "movxi"
1944   [(set (match_operand:XI 0 "nonimmediate_operand")
1945         (match_operand:XI 1 "general_operand"))]
1946   "TARGET_AVX512F"
1947   "ix86_expand_vector_move (XImode, operands); DONE;")
1949 (define_expand "movoi"
1950   [(set (match_operand:OI 0 "nonimmediate_operand")
1951         (match_operand:OI 1 "general_operand"))]
1952   "TARGET_AVX"
1953   "ix86_expand_vector_move (OImode, operands); DONE;")
1955 (define_expand "movti"
1956   [(set (match_operand:TI 0 "nonimmediate_operand")
1957         (match_operand:TI 1 "general_operand"))]
1958   "TARGET_64BIT || TARGET_SSE"
1960   if (TARGET_64BIT)
1961     ix86_expand_move (TImode, operands);
1962   else
1963     ix86_expand_vector_move (TImode, operands);
1964   DONE;
1967 ;; This expands to what emit_move_complex would generate if we didn't
1968 ;; have a movti pattern.  Having this avoids problems with reload on
1969 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1970 ;; to have around all the time.
1971 (define_expand "movcdi"
1972   [(set (match_operand:CDI 0 "nonimmediate_operand")
1973         (match_operand:CDI 1 "general_operand"))]
1974   ""
1976   if (push_operand (operands[0], CDImode))
1977     emit_move_complex_push (CDImode, operands[0], operands[1]);
1978   else
1979     emit_move_complex_parts (operands[0], operands[1]);
1980   DONE;
1983 (define_expand "mov<mode>"
1984   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1985         (match_operand:SWI1248x 1 "general_operand"))]
1986   ""
1987   "ix86_expand_move (<MODE>mode, operands); DONE;")
1989 (define_insn "*mov<mode>_xor"
1990   [(set (match_operand:SWI48 0 "register_operand" "=r")
1991         (match_operand:SWI48 1 "const0_operand"))
1992    (clobber (reg:CC FLAGS_REG))]
1993   "reload_completed"
1994   "xor{l}\t%k0, %k0"
1995   [(set_attr "type" "alu1")
1996    (set_attr "modrm_class" "op0")
1997    (set_attr "mode" "SI")
1998    (set_attr "length_immediate" "0")])
2000 (define_insn "*mov<mode>_or"
2001   [(set (match_operand:SWI48 0 "register_operand" "=r")
2002         (match_operand:SWI48 1 "constm1_operand"))
2003    (clobber (reg:CC FLAGS_REG))]
2004   "reload_completed"
2005   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2006   [(set_attr "type" "alu1")
2007    (set_attr "mode" "<MODE>")
2008    (set_attr "length_immediate" "1")])
2010 (define_insn "*movxi_internal_avx512f"
2011   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2012         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2013   "TARGET_AVX512F
2014    && (register_operand (operands[0], XImode)
2015        || register_operand (operands[1], XImode))"
2017   switch (get_attr_type (insn))
2018     {
2019     case TYPE_SSELOG1:
2020       return standard_sse_constant_opcode (insn, operands[1]);
2022     case TYPE_SSEMOV:
2023       if (misaligned_operand (operands[0], XImode)
2024           || misaligned_operand (operands[1], XImode))
2025         return "vmovdqu32\t{%1, %0|%0, %1}";
2026       else
2027         return "vmovdqa32\t{%1, %0|%0, %1}";
2029     default:
2030       gcc_unreachable ();
2031     }
2033   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2034    (set_attr "prefix" "evex")
2035    (set_attr "mode" "XI")])
2037 (define_insn "*movoi_internal_avx"
2038   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2039         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2040   "TARGET_AVX
2041    && (register_operand (operands[0], OImode)
2042        || register_operand (operands[1], OImode))"
2044   switch (get_attr_type (insn))
2045     {
2046     case TYPE_SSELOG1:
2047       return standard_sse_constant_opcode (insn, operands[1]);
2049     case TYPE_SSEMOV:
2050       if (misaligned_operand (operands[0], OImode)
2051           || misaligned_operand (operands[1], OImode))
2052         {
2053           if (get_attr_mode (insn) == MODE_V8SF)
2054             return "vmovups\t{%1, %0|%0, %1}";
2055           else if (get_attr_mode (insn) == MODE_XI)
2056             return "vmovdqu32\t{%1, %0|%0, %1}";
2057           else
2058             return "vmovdqu\t{%1, %0|%0, %1}";
2059         }
2060       else
2061         {
2062           if (get_attr_mode (insn) == MODE_V8SF)
2063             return "vmovaps\t{%1, %0|%0, %1}";
2064           else if (get_attr_mode (insn) == MODE_XI)
2065             return "vmovdqa32\t{%1, %0|%0, %1}";
2066           else
2067             return "vmovdqa\t{%1, %0|%0, %1}";
2068         }
2070     default:
2071       gcc_unreachable ();
2072     }
2074   [(set_attr "isa" "*,avx2,*,*")
2075    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2076    (set_attr "prefix" "vex")
2077    (set (attr "mode")
2078         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2079                     (match_operand 1 "ext_sse_reg_operand"))
2080                  (const_string "XI")
2081                (and (eq_attr "alternative" "1")
2082                     (match_test "TARGET_AVX512VL"))
2083                  (const_string "XI")
2084                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2085                     (and (eq_attr "alternative" "3")
2086                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2087                  (const_string "V8SF")
2088               ]
2089               (const_string "OI")))])
2091 (define_insn "*movti_internal"
2092   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2093         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v"))]
2094   "(TARGET_64BIT
2095     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2096    || (TARGET_SSE
2097        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2098        && (register_operand (operands[0], TImode)
2099            || register_operand (operands[1], TImode)))"
2101   switch (get_attr_type (insn))
2102     {
2103     case TYPE_MULTI:
2104       return "#";
2106     case TYPE_SSELOG1:
2107       return standard_sse_constant_opcode (insn, operands[1]);
2109     case TYPE_SSEMOV:
2110       /* TDmode values are passed as TImode on the stack.  Moving them
2111          to stack may result in unaligned memory access.  */
2112       if (misaligned_operand (operands[0], TImode)
2113           || misaligned_operand (operands[1], TImode))
2114         {
2115           if (get_attr_mode (insn) == MODE_V4SF)
2116             return "%vmovups\t{%1, %0|%0, %1}";
2117           else if (get_attr_mode (insn) == MODE_XI)
2118             return "vmovdqu32\t{%1, %0|%0, %1}";
2119           else
2120             return "%vmovdqu\t{%1, %0|%0, %1}";
2121         }
2122       else
2123         {
2124           if (get_attr_mode (insn) == MODE_V4SF)
2125             return "%vmovaps\t{%1, %0|%0, %1}";
2126           else if (get_attr_mode (insn) == MODE_XI)
2127             return "vmovdqa32\t{%1, %0|%0, %1}";
2128           else
2129             return "%vmovdqa\t{%1, %0|%0, %1}";
2130         }
2132     default:
2133       gcc_unreachable ();
2134     }
2136   [(set_attr "isa" "x64,x64,*,sse2,*,*")
2137    (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
2138    (set (attr "prefix")
2139      (if_then_else (eq_attr "type" "sselog1,ssemov")
2140        (const_string "maybe_vex")
2141        (const_string "orig")))
2142    (set (attr "mode")
2143         (cond [(eq_attr "alternative" "0,1")
2144                  (const_string "DI")
2145                (ior (match_operand 0 "ext_sse_reg_operand")
2146                     (match_operand 1 "ext_sse_reg_operand"))
2147                  (const_string "XI")
2148                (and (eq_attr "alternative" "3")
2149                     (match_test "TARGET_AVX512VL"))
2150                  (const_string "XI")
2151                (ior (not (match_test "TARGET_SSE2"))
2152                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2153                          (and (eq_attr "alternative" "5")
2154                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2155                  (const_string "V4SF")
2156                (match_test "TARGET_AVX")
2157                  (const_string "TI")
2158                (match_test "optimize_function_for_size_p (cfun)")
2159                  (const_string "V4SF")
2160                ]
2161                (const_string "TI")))])
2163 (define_split
2164   [(set (match_operand:TI 0 "nonimmediate_operand")
2165         (match_operand:TI 1 "general_operand"))]
2166   "reload_completed
2167    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2168   [(const_int 0)]
2169   "ix86_split_long_move (operands); DONE;")
2171 (define_insn "*movdi_internal"
2172   [(set (match_operand:DI 0 "nonimmediate_operand"
2173     "=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")
2174         (match_operand:DI 1 "general_operand"
2175     "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"))]
2176   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2178   switch (get_attr_type (insn))
2179     {
2180     case TYPE_MSKMOV:
2181       return "kmovq\t{%1, %0|%0, %1}";
2183     case TYPE_MULTI:
2184       return "#";
2186     case TYPE_MMX:
2187       return "pxor\t%0, %0";
2189     case TYPE_MMXMOV:
2190       /* Handle broken assemblers that require movd instead of movq.  */
2191       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2192           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2193         return "movd\t{%1, %0|%0, %1}";
2194       return "movq\t{%1, %0|%0, %1}";
2196     case TYPE_SSELOG1:
2197       if (GENERAL_REG_P (operands[0]))
2198         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2200       return standard_sse_constant_opcode (insn, operands[1]);
2202     case TYPE_SSEMOV:
2203       switch (get_attr_mode (insn))
2204         {
2205         case MODE_DI:
2206           /* Handle broken assemblers that require movd instead of movq.  */
2207           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2208               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2209             return "%vmovd\t{%1, %0|%0, %1}";
2210           return "%vmovq\t{%1, %0|%0, %1}";
2211         case MODE_TI:
2212           return "%vmovdqa\t{%1, %0|%0, %1}";
2213         case MODE_XI:
2214           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2216         case MODE_V2SF:
2217           gcc_assert (!TARGET_AVX);
2218           return "movlps\t{%1, %0|%0, %1}";
2219         case MODE_V4SF:
2220           return "%vmovaps\t{%1, %0|%0, %1}";
2222         default:
2223           gcc_unreachable ();
2224         }
2226     case TYPE_SSECVT:
2227       if (SSE_REG_P (operands[0]))
2228         return "movq2dq\t{%1, %0|%0, %1}";
2229       else
2230         return "movdq2q\t{%1, %0|%0, %1}";
2232     case TYPE_LEA:
2233       return "lea{q}\t{%E1, %0|%0, %E1}";
2235     case TYPE_IMOV:
2236       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2237       if (get_attr_mode (insn) == MODE_SI)
2238         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2239       else if (which_alternative == 4)
2240         return "movabs{q}\t{%1, %0|%0, %1}";
2241       else if (ix86_use_lea_for_mov (insn, operands))
2242         return "lea{q}\t{%E1, %0|%0, %E1}";
2243       else
2244         return "mov{q}\t{%1, %0|%0, %1}";
2246     default:
2247       gcc_unreachable ();
2248     }
2250   [(set (attr "isa")
2251      (cond [(eq_attr "alternative" "0,1")
2252               (const_string "nox64")
2253             (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2254               (const_string "x64")
2255             (eq_attr "alternative" "18")
2256               (const_string "x64_sse4")
2257            ]
2258            (const_string "*")))
2259    (set (attr "type")
2260      (cond [(eq_attr "alternative" "0,1")
2261               (const_string "multi")
2262             (eq_attr "alternative" "6")
2263               (const_string "mmx")
2264             (eq_attr "alternative" "7,8,9,10,11")
2265               (const_string "mmxmov")
2266             (eq_attr "alternative" "12,18")
2267               (const_string "sselog1")
2268             (eq_attr "alternative" "13,14,15,16,17,19")
2269               (const_string "ssemov")
2270             (eq_attr "alternative" "20,21")
2271               (const_string "ssecvt")
2272             (eq_attr "alternative" "22,23,24,25")
2273               (const_string "mskmov")
2274             (and (match_operand 0 "register_operand")
2275                  (match_operand 1 "pic_32bit_operand"))
2276               (const_string "lea")
2277            ]
2278            (const_string "imov")))
2279    (set (attr "modrm")
2280      (if_then_else
2281        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2282          (const_string "0")
2283          (const_string "*")))
2284    (set (attr "length_immediate")
2285      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2286               (const_string "8")
2287             (eq_attr "alternative" "18")
2288               (const_string "1")
2289            ]
2290            (const_string "*")))
2291    (set (attr "prefix_rex")
2292      (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2293        (const_string "1")
2294        (const_string "*")))
2295    (set (attr "prefix_extra")
2296      (if_then_else (eq_attr "alternative" "18")
2297        (const_string "1")
2298        (const_string "*")))
2299    (set (attr "prefix")
2300      (if_then_else (eq_attr "type" "sselog1,ssemov")
2301        (const_string "maybe_vex")
2302        (const_string "orig")))
2303    (set (attr "prefix_data16")
2304      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2305        (const_string "1")
2306        (const_string "*")))
2307    (set (attr "mode")
2308      (cond [(eq_attr "alternative" "2")
2309               (const_string "SI")
2310             (eq_attr "alternative" "12,13")
2311               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2312                           (match_operand 1 "ext_sse_reg_operand"))
2313                        (const_string "XI")
2314                      (ior (not (match_test "TARGET_SSE2"))
2315                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2316                        (const_string "V4SF")
2317                      (match_test "TARGET_AVX")
2318                        (const_string "TI")
2319                      (match_test "optimize_function_for_size_p (cfun)")
2320                        (const_string "V4SF")
2321                     ]
2322                     (const_string "TI"))
2324             (and (eq_attr "alternative" "14,15,16")
2325                  (not (match_test "TARGET_SSE2")))
2326               (const_string "V2SF")
2327             (eq_attr "alternative" "18")
2328               (const_string "TI")
2329            ]
2330            (const_string "DI")))
2331    (set (attr "enabled")
2332      (cond [(eq_attr "alternative" "15")
2333               (if_then_else
2334                 (match_test "TARGET_STV && TARGET_SSE2")
2335                 (symbol_ref "false")
2336                 (const_string "*"))
2337             (eq_attr "alternative" "16")
2338               (if_then_else
2339                 (match_test "TARGET_STV && TARGET_SSE2")
2340                 (symbol_ref "true")
2341                 (symbol_ref "false"))
2342            ]
2343            (const_string "*")))])
2345 (define_split
2346   [(set (match_operand:DI 0 "nonimmediate_operand")
2347         (match_operand:DI 1 "general_operand"))]
2348   "!TARGET_64BIT && reload_completed
2349    && !(MMX_REG_P (operands[0])
2350         || SSE_REG_P (operands[0])
2351         || MASK_REG_P (operands[0]))
2352    && !(MMX_REG_P (operands[1])
2353         || SSE_REG_P (operands[1])
2354         || MASK_REG_P (operands[1]))"
2355   [(const_int 0)]
2356   "ix86_split_long_move (operands); DONE;")
2358 (define_insn "*movsi_internal"
2359   [(set (match_operand:SI 0 "nonimmediate_operand"
2360                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2361         (match_operand:SI 1 "general_operand"
2362                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2363   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2365   switch (get_attr_type (insn))
2366     {
2367     case TYPE_SSELOG1:
2368       if (GENERAL_REG_P (operands[0]))
2369         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2371       return standard_sse_constant_opcode (insn, operands[1]);
2373     case TYPE_MSKMOV:
2374       return "kmovd\t{%1, %0|%0, %1}";
2376     case TYPE_SSEMOV:
2377       switch (get_attr_mode (insn))
2378         {
2379         case MODE_SI:
2380           return "%vmovd\t{%1, %0|%0, %1}";
2381         case MODE_TI:
2382           return "%vmovdqa\t{%1, %0|%0, %1}";
2383         case MODE_XI:
2384           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2386         case MODE_V4SF:
2387           return "%vmovaps\t{%1, %0|%0, %1}";
2389         case MODE_SF:
2390           gcc_assert (!TARGET_AVX);
2391           return "movss\t{%1, %0|%0, %1}";
2393         default:
2394           gcc_unreachable ();
2395         }
2397     case TYPE_MMX:
2398       return "pxor\t%0, %0";
2400     case TYPE_MMXMOV:
2401       switch (get_attr_mode (insn))
2402         {
2403         case MODE_DI:
2404           return "movq\t{%1, %0|%0, %1}";
2405         case MODE_SI:
2406           return "movd\t{%1, %0|%0, %1}";
2408         default:
2409           gcc_unreachable ();
2410         }
2412     case TYPE_LEA:
2413       return "lea{l}\t{%E1, %0|%0, %E1}";
2415     case TYPE_IMOV:
2416       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2417       if (ix86_use_lea_for_mov (insn, operands))
2418         return "lea{l}\t{%E1, %0|%0, %E1}";
2419       else
2420         return "mov{l}\t{%1, %0|%0, %1}";
2422     default:
2423       gcc_unreachable ();
2424     }
2426   [(set (attr "isa")
2427      (if_then_else (eq_attr "alternative" "11")
2428        (const_string "sse4")
2429        (const_string "*")))
2430    (set (attr "type")
2431      (cond [(eq_attr "alternative" "2")
2432               (const_string "mmx")
2433             (eq_attr "alternative" "3,4,5")
2434               (const_string "mmxmov")
2435             (eq_attr "alternative" "6,11")
2436               (const_string "sselog1")
2437             (eq_attr "alternative" "7,8,9,10,12")
2438               (const_string "ssemov")
2439             (eq_attr "alternative" "13,14")
2440               (const_string "mskmov")
2441             (and (match_operand 0 "register_operand")
2442                  (match_operand 1 "pic_32bit_operand"))
2443               (const_string "lea")
2444            ]
2445            (const_string "imov")))
2446    (set (attr "length_immediate")
2447      (if_then_else (eq_attr "alternative" "11")
2448        (const_string "1")
2449        (const_string "*")))
2450    (set (attr "prefix_extra")
2451      (if_then_else (eq_attr "alternative" "11")
2452        (const_string "1")
2453        (const_string "*")))
2454    (set (attr "prefix")
2455      (if_then_else (eq_attr "type" "sselog1,ssemov")
2456        (const_string "maybe_vex")
2457        (const_string "orig")))
2458    (set (attr "prefix_data16")
2459      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2460        (const_string "1")
2461        (const_string "*")))
2462    (set (attr "mode")
2463      (cond [(eq_attr "alternative" "2,3")
2464               (const_string "DI")
2465             (eq_attr "alternative" "6,7")
2466               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2467                           (match_operand 1 "ext_sse_reg_operand"))
2468                        (const_string "XI")
2469                      (ior (not (match_test "TARGET_SSE2"))
2470                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2471                        (const_string "V4SF")
2472                      (match_test "TARGET_AVX")
2473                        (const_string "TI")
2474                      (match_test "optimize_function_for_size_p (cfun)")
2475                        (const_string "V4SF")
2476                     ]
2477                     (const_string "TI"))
2479             (and (eq_attr "alternative" "8,9")
2480                  (not (match_test "TARGET_SSE2")))
2481               (const_string "SF")
2482             (eq_attr "alternative" "11")
2483               (const_string "TI")
2484            ]
2485            (const_string "SI")))])
2487 (define_insn "kmovw"
2488   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2489         (unspec:HI
2490           [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2491           UNSPEC_KMOV))]
2492   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2493   "@
2494    kmovw\t{%k1, %0|%0, %k1}
2495    kmovw\t{%1, %0|%0, %1}";
2496   [(set_attr "mode" "HI")
2497    (set_attr "type" "mskmov")
2498    (set_attr "prefix" "vex")])
2501 (define_insn "*movhi_internal"
2502   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2503         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2504   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2506   switch (get_attr_type (insn))
2507     {
2508     case TYPE_IMOVX:
2509       /* movzwl is faster than movw on p2 due to partial word stalls,
2510          though not as fast as an aligned movl.  */
2511       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2513     case TYPE_MSKMOV:
2514       switch (which_alternative)
2515         {
2516         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2517         case 5: /* FALLTHRU */
2518         case 7: return "kmovw\t{%1, %0|%0, %1}";
2519         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2520         default: gcc_unreachable ();
2521         }
2523     default:
2524       if (get_attr_mode (insn) == MODE_SI)
2525         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2526       else
2527         return "mov{w}\t{%1, %0|%0, %1}";
2528     }
2530   [(set (attr "type")
2531      (cond [(eq_attr "alternative" "4,5,6,7")
2532               (const_string "mskmov")
2533             (match_test "optimize_function_for_size_p (cfun)")
2534               (const_string "imov")
2535             (and (eq_attr "alternative" "0")
2536                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2537                       (not (match_test "TARGET_HIMODE_MATH"))))
2538               (const_string "imov")
2539             (and (eq_attr "alternative" "1,2")
2540                  (match_operand:HI 1 "aligned_operand"))
2541               (const_string "imov")
2542             (and (match_test "TARGET_MOVX")
2543                  (eq_attr "alternative" "0,2"))
2544               (const_string "imovx")
2545            ]
2546            (const_string "imov")))
2547     (set (attr "prefix")
2548       (if_then_else (eq_attr "alternative" "4,5,6,7")
2549         (const_string "vex")
2550         (const_string "orig")))
2551     (set (attr "mode")
2552       (cond [(eq_attr "type" "imovx")
2553                (const_string "SI")
2554              (and (eq_attr "alternative" "1,2")
2555                   (match_operand:HI 1 "aligned_operand"))
2556                (const_string "SI")
2557              (and (eq_attr "alternative" "0")
2558                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2559                        (not (match_test "TARGET_HIMODE_MATH"))))
2560                (const_string "SI")
2561             ]
2562             (const_string "HI")))])
2564 ;; Situation is quite tricky about when to choose full sized (SImode) move
2565 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2566 ;; partial register dependency machines (such as AMD Athlon), where QImode
2567 ;; moves issue extra dependency and for partial register stalls machines
2568 ;; that don't use QImode patterns (and QImode move cause stall on the next
2569 ;; instruction).
2571 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2572 ;; register stall machines with, where we use QImode instructions, since
2573 ;; partial register stall can be caused there.  Then we use movzx.
2575 (define_insn "*movqi_internal"
2576   [(set (match_operand:QI 0 "nonimmediate_operand"
2577                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2578         (match_operand:QI 1 "general_operand"
2579                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2580   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2582   switch (get_attr_type (insn))
2583     {
2584     case TYPE_IMOVX:
2585       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2586       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2588     case TYPE_MSKMOV:
2589       switch (which_alternative)
2590         {
2591         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2592                                        : "kmovw\t{%k1, %0|%0, %k1}";
2593         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2594                                        : "kmovw\t{%1, %0|%0, %1}";
2595         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2596                                        : "kmovw\t{%1, %k0|%k0, %1}";
2597         case 10:
2598         case 11:
2599           gcc_assert (TARGET_AVX512DQ);
2600           return "kmovb\t{%1, %0|%0, %1}";
2601         default: gcc_unreachable ();
2602         }
2604     default:
2605       if (get_attr_mode (insn) == MODE_SI)
2606         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2607       else
2608         return "mov{b}\t{%1, %0|%0, %1}";
2609     }
2611   [(set (attr "isa")
2612      (if_then_else (eq_attr "alternative" "10,11")
2613        (const_string "avx512dq")
2614        (const_string "*")))
2615    (set (attr "type")
2616      (cond [(eq_attr "alternative" "7,8,9,10,11")
2617               (const_string "mskmov")
2618             (and (eq_attr "alternative" "5")
2619                  (not (match_operand:QI 1 "aligned_operand")))
2620               (const_string "imovx")
2621             (match_test "optimize_function_for_size_p (cfun)")
2622               (const_string "imov")
2623             (and (eq_attr "alternative" "3")
2624                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2625                       (not (match_test "TARGET_QIMODE_MATH"))))
2626               (const_string "imov")
2627             (eq_attr "alternative" "3,5")
2628               (const_string "imovx")
2629             (and (match_test "TARGET_MOVX")
2630                  (eq_attr "alternative" "2"))
2631               (const_string "imovx")
2632            ]
2633            (const_string "imov")))
2634    (set (attr "prefix")
2635      (if_then_else (eq_attr "alternative" "7,8,9")
2636        (const_string "vex")
2637        (const_string "orig")))
2638    (set (attr "mode")
2639       (cond [(eq_attr "alternative" "3,4,5")
2640                (const_string "SI")
2641              (eq_attr "alternative" "6")
2642                (const_string "QI")
2643              (eq_attr "type" "imovx")
2644                (const_string "SI")
2645              (and (eq_attr "type" "imov")
2646                   (and (eq_attr "alternative" "0,1")
2647                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2648                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2649                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2650                (const_string "SI")
2651              ;; Avoid partial register stalls when not using QImode arithmetic
2652              (and (eq_attr "type" "imov")
2653                   (and (eq_attr "alternative" "0,1")
2654                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2655                             (not (match_test "TARGET_QIMODE_MATH")))))
2656                (const_string "SI")
2657            ]
2658            (const_string "QI")))])
2660 ;; Stores and loads of ax to arbitrary constant address.
2661 ;; We fake an second form of instruction to force reload to load address
2662 ;; into register when rax is not available
2663 (define_insn "*movabs<mode>_1"
2664   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2665         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2666   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2668   /* Recover the full memory rtx.  */
2669   operands[0] = SET_DEST (PATTERN (insn));
2670   switch (which_alternative)
2671     {
2672     case 0:
2673       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2674     case 1:
2675       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2676     default:
2677       gcc_unreachable ();
2678     }
2680   [(set_attr "type" "imov")
2681    (set_attr "modrm" "0,*")
2682    (set_attr "length_address" "8,0")
2683    (set_attr "length_immediate" "0,*")
2684    (set_attr "memory" "store")
2685    (set_attr "mode" "<MODE>")])
2687 (define_insn "*movabs<mode>_2"
2688   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2689         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2690   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2692   /* Recover the full memory rtx.  */
2693   operands[1] = SET_SRC (PATTERN (insn));
2694   switch (which_alternative)
2695     {
2696     case 0:
2697       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2698     case 1:
2699       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2700     default:
2701       gcc_unreachable ();
2702     }
2704   [(set_attr "type" "imov")
2705    (set_attr "modrm" "0,*")
2706    (set_attr "length_address" "8,0")
2707    (set_attr "length_immediate" "0")
2708    (set_attr "memory" "load")
2709    (set_attr "mode" "<MODE>")])
2711 (define_insn "*swap<mode>"
2712   [(set (match_operand:SWI48 0 "register_operand" "+r")
2713         (match_operand:SWI48 1 "register_operand" "+r"))
2714    (set (match_dup 1)
2715         (match_dup 0))]
2716   ""
2717   "xchg{<imodesuffix>}\t%1, %0"
2718   [(set_attr "type" "imov")
2719    (set_attr "mode" "<MODE>")
2720    (set_attr "pent_pair" "np")
2721    (set_attr "athlon_decode" "vector")
2722    (set_attr "amdfam10_decode" "double")
2723    (set_attr "bdver1_decode" "double")])
2725 (define_insn "*swap<mode>"
2726   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2727         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2728    (set (match_dup 1)
2729         (match_dup 0))]
2730   ""
2731   "@
2732    xchg{<imodesuffix>}\t%1, %0
2733    xchg{l}\t%k1, %k0"
2734   [(set_attr "type" "imov")
2735    (set_attr "mode" "<MODE>,SI")
2736    (set (attr "preferred_for_size")
2737      (cond [(eq_attr "alternative" "0")
2738               (symbol_ref "false")]
2739            (symbol_ref "true")))
2740    ;; Potential partial reg stall on alternative 1.
2741    (set (attr "preferred_for_speed")
2742      (cond [(eq_attr "alternative" "1")
2743               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2744            (symbol_ref "true")))
2745    (set_attr "pent_pair" "np")
2746    (set_attr "athlon_decode" "vector")
2747    (set_attr "amdfam10_decode" "double")
2748    (set_attr "bdver1_decode" "double")])
2750 (define_expand "movstrict<mode>"
2751   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2752         (match_operand:SWI12 1 "general_operand"))]
2753   ""
2755   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2756     FAIL;
2757   if (SUBREG_P (operands[0])
2758       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2759     FAIL;
2760   /* Don't generate memory->memory moves, go through a register */
2761   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2762     operands[1] = force_reg (<MODE>mode, operands[1]);
2765 (define_insn "*movstrict<mode>_1"
2766   [(set (strict_low_part
2767           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2768         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2769   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2771   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2772   [(set_attr "type" "imov")
2773    (set_attr "mode" "<MODE>")])
2775 (define_insn "*movstrict<mode>_xor"
2776   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2777         (match_operand:SWI12 1 "const0_operand"))
2778    (clobber (reg:CC FLAGS_REG))]
2779   "reload_completed"
2780   "xor{<imodesuffix>}\t%0, %0"
2781   [(set_attr "type" "alu1")
2782    (set_attr "modrm_class" "op0")
2783    (set_attr "mode" "<MODE>")
2784    (set_attr "length_immediate" "0")])
2786 (define_expand "extv<mode>"
2787   [(set (match_operand:SWI24 0 "register_operand")
2788         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2789                             (match_operand:SI 2 "const_int_operand")
2790                             (match_operand:SI 3 "const_int_operand")))]
2791   ""
2793   /* Handle extractions from %ah et al.  */
2794   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2795     FAIL;
2797   if (! ext_register_operand (operands[1], VOIDmode))
2798     operands[1] = copy_to_reg (operands[1]);
2801 (define_insn "*extv<mode>"
2802   [(set (match_operand:SWI24 0 "register_operand" "=R")
2803         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2804                             (const_int 8)
2805                             (const_int 8)))]
2806   ""
2807   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2808   [(set_attr "type" "imovx")
2809    (set_attr "mode" "SI")])
2811 (define_insn "*extvqi"
2812   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2813         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2814                          (const_int 8)
2815                          (const_int 8)))]
2816   ""
2818   switch (get_attr_type (insn))
2819     {
2820     case TYPE_IMOVX:
2821       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2822     default:
2823       return "mov{b}\t{%h1, %0|%0, %h1}";
2824     }
2826   [(set_attr "isa" "*,*,nox64")
2827    (set (attr "type")
2828      (if_then_else (and (match_operand:QI 0 "register_operand")
2829                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2830                              (match_test "TARGET_MOVX")))
2831         (const_string "imovx")
2832         (const_string "imov")))
2833    (set (attr "mode")
2834      (if_then_else (eq_attr "type" "imovx")
2835         (const_string "SI")
2836         (const_string "QI")))])
2838 (define_expand "extzv<mode>"
2839   [(set (match_operand:SWI248 0 "register_operand")
2840         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2841                              (match_operand:SI 2 "const_int_operand")
2842                              (match_operand:SI 3 "const_int_operand")))]
2843   ""
2845   if (ix86_expand_pextr (operands))
2846     DONE;
2848   /* Handle extractions from %ah et al.  */
2849   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2850     FAIL;
2852   if (! ext_register_operand (operands[1], VOIDmode))
2853     operands[1] = copy_to_reg (operands[1]);
2856 (define_insn "*extzv<mode>"
2857   [(set (match_operand:SWI248 0 "register_operand" "=R")
2858         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2859                              (const_int 8)
2860                              (const_int 8)))]
2861   ""
2862   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2863   [(set_attr "type" "imovx")
2864    (set_attr "mode" "SI")])
2866 (define_insn "*extzvqi"
2867   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2868         (subreg:QI
2869           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2870                            (const_int 8)
2871                            (const_int 8)) 0))]
2872   ""
2874   switch (get_attr_type (insn))
2875     {
2876     case TYPE_IMOVX:
2877       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2878     default:
2879       return "mov{b}\t{%h1, %0|%0, %h1}";
2880     }
2882   [(set_attr "isa" "*,*,nox64")
2883    (set (attr "type")
2884      (if_then_else (and (match_operand:QI 0 "register_operand")
2885                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2886                              (match_test "TARGET_MOVX")))
2887         (const_string "imovx")
2888         (const_string "imov")))
2889    (set (attr "mode")
2890      (if_then_else (eq_attr "type" "imovx")
2891         (const_string "SI")
2892         (const_string "QI")))])
2894 (define_expand "insv<mode>"
2895   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2896                              (match_operand:SI 1 "const_int_operand")
2897                              (match_operand:SI 2 "const_int_operand"))
2898         (match_operand:SWI248 3 "register_operand"))]
2899   ""
2901   rtx dst;
2903   if (ix86_expand_pinsr (operands))
2904     DONE;
2906   /* Handle insertions to %ah et al.  */
2907   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2908     FAIL;
2910   dst = operands[0];
2911   
2912   if (!ext_register_operand (dst, VOIDmode))
2913     dst = copy_to_reg (dst);
2915   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2917   /* Fix up the destination if needed.  */
2918   if (dst != operands[0])
2919     emit_move_insn (operands[0], dst);
2921   DONE;
2924 (define_insn "insv<mode>_1"
2925   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2926                              (const_int 8)
2927                              (const_int 8))
2928         (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2929   ""
2931   if (CONST_INT_P (operands[1]))
2932     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2933   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2935   [(set_attr "isa" "*,nox64")
2936    (set_attr "type" "imov")
2937    (set_attr "mode" "QI")])
2939 (define_insn "*insvqi"
2940   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2941                          (const_int 8)
2942                          (const_int 8))
2943         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2944                      (const_int 8)))]
2945   ""
2946   "mov{b}\t{%h1, %h0|%h0, %h1}"
2947   [(set_attr "type" "imov")
2948    (set_attr "mode" "QI")])
2950 ;; Floating point push instructions.
2952 (define_insn "*pushtf"
2953   [(set (match_operand:TF 0 "push_operand" "=<,<")
2954         (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2955   "TARGET_64BIT || TARGET_SSE"
2957   /* This insn should be already split before reg-stack.  */
2958   gcc_unreachable ();
2960   [(set_attr "isa" "*,x64")
2961    (set_attr "type" "multi")
2962    (set_attr "unit" "sse,*")
2963    (set_attr "mode" "TF,DI")])
2965 ;; %%% Kill this when call knows how to work this out.
2966 (define_split
2967   [(set (match_operand:TF 0 "push_operand")
2968         (match_operand:TF 1 "sse_reg_operand"))]
2969   "TARGET_SSE && reload_completed"
2970   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2971    (set (match_dup 0) (match_dup 1))]
2973   /* Preserve memory attributes. */
2974   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2977 (define_insn "*pushxf"
2978   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2979         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2980   ""
2982   /* This insn should be already split before reg-stack.  */
2983   gcc_unreachable ();
2985   [(set_attr "type" "multi")
2986    (set_attr "unit" "i387,*,*,*")
2987    (set (attr "mode")
2988         (cond [(eq_attr "alternative" "1,2,3")
2989                  (if_then_else (match_test "TARGET_64BIT")
2990                    (const_string "DI")
2991                    (const_string "SI"))
2992               ]
2993               (const_string "XF")))
2994    (set (attr "preferred_for_size")
2995      (cond [(eq_attr "alternative" "1")
2996               (symbol_ref "false")]
2997            (symbol_ref "true")))])
2999 ;; %%% Kill this when call knows how to work this out.
3000 (define_split
3001   [(set (match_operand:XF 0 "push_operand")
3002         (match_operand:XF 1 "fp_register_operand"))]
3003   "reload_completed"
3004   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3005    (set (match_dup 0) (match_dup 1))]
3007   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
3008   /* Preserve memory attributes. */
3009   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3012 (define_insn "*pushdf"
3013   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3014         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
3015   ""
3017   /* This insn should be already split before reg-stack.  */
3018   gcc_unreachable ();
3020   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3021    (set_attr "type" "multi")
3022    (set_attr "unit" "i387,*,*,*,*,sse")
3023    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3024    (set (attr "preferred_for_size")
3025      (cond [(eq_attr "alternative" "1")
3026               (symbol_ref "false")]
3027            (symbol_ref "true")))
3028    (set (attr "preferred_for_speed")
3029      (cond [(eq_attr "alternative" "1")
3030               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3031            (symbol_ref "true")))])
3032    
3033 ;; %%% Kill this when call knows how to work this out.
3034 (define_split
3035   [(set (match_operand:DF 0 "push_operand")
3036         (match_operand:DF 1 "any_fp_register_operand"))]
3037   "reload_completed"
3038   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3039    (set (match_dup 0) (match_dup 1))]
3041   /* Preserve memory attributes. */
3042   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3045 (define_insn "*pushsf_rex64"
3046   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3047         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3048   "TARGET_64BIT"
3050   /* Anything else should be already split before reg-stack.  */
3051   gcc_assert (which_alternative == 1);
3052   return "push{q}\t%q1";
3054   [(set_attr "type" "multi,push,multi")
3055    (set_attr "unit" "i387,*,*")
3056    (set_attr "mode" "SF,DI,SF")])
3058 (define_insn "*pushsf"
3059   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3060         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3061   "!TARGET_64BIT"
3063   /* Anything else should be already split before reg-stack.  */
3064   gcc_assert (which_alternative == 1);
3065   return "push{l}\t%1";
3067   [(set_attr "type" "multi,push,multi")
3068    (set_attr "unit" "i387,*,*")
3069    (set_attr "mode" "SF,SI,SF")])
3071 ;; %%% Kill this when call knows how to work this out.
3072 (define_split
3073   [(set (match_operand:SF 0 "push_operand")
3074         (match_operand:SF 1 "any_fp_register_operand"))]
3075   "reload_completed"
3076   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3077    (set (match_dup 0) (match_dup 1))]
3079   rtx op = XEXP (operands[0], 0);
3080   if (GET_CODE (op) == PRE_DEC)
3081     {
3082       gcc_assert (!TARGET_64BIT);
3083       op = GEN_INT (-4);
3084     }
3085   else
3086     {
3087       op = XEXP (XEXP (op, 1), 1);
3088       gcc_assert (CONST_INT_P (op));
3089     }
3090   operands[2] = op;
3091   /* Preserve memory attributes. */
3092   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3095 (define_split
3096   [(set (match_operand:SF 0 "push_operand")
3097         (match_operand:SF 1 "memory_operand"))]
3098   "reload_completed
3099    && find_constant_src (insn)"
3100   [(set (match_dup 0) (match_dup 2))]
3101   "operands[2] = find_constant_src (curr_insn);")
3103 (define_split
3104   [(set (match_operand 0 "push_operand")
3105         (match_operand 1 "general_operand"))]
3106   "reload_completed
3107    && (GET_MODE (operands[0]) == TFmode
3108        || GET_MODE (operands[0]) == XFmode
3109        || GET_MODE (operands[0]) == DFmode)
3110    && !ANY_FP_REG_P (operands[1])"
3111   [(const_int 0)]
3112   "ix86_split_long_move (operands); DONE;")
3114 ;; Floating point move instructions.
3116 (define_expand "movtf"
3117   [(set (match_operand:TF 0 "nonimmediate_operand")
3118         (match_operand:TF 1 "nonimmediate_operand"))]
3119   "TARGET_64BIT || TARGET_SSE"
3120   "ix86_expand_move (TFmode, operands); DONE;")
3122 (define_expand "mov<mode>"
3123   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3124         (match_operand:X87MODEF 1 "general_operand"))]
3125   ""
3126   "ix86_expand_move (<MODE>mode, operands); DONE;")
3128 (define_insn "*movtf_internal"
3129   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3130         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3131   "(TARGET_64BIT || TARGET_SSE)
3132    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3133    && (lra_in_progress || reload_completed
3134        || !CONST_DOUBLE_P (operands[1])
3135        || ((optimize_function_for_size_p (cfun)
3136             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3137            && standard_sse_constant_p (operands[1], TFmode) == 1
3138            && !memory_operand (operands[0], TFmode))
3139        || (!TARGET_MEMORY_MISMATCH_STALL
3140            && memory_operand (operands[0], TFmode)))"
3142   switch (get_attr_type (insn))
3143     {
3144     case TYPE_SSELOG1:
3145       return standard_sse_constant_opcode (insn, operands[1]);
3147     case TYPE_SSEMOV:
3148       /* Handle misaligned load/store since we
3149          don't have movmisaligntf pattern. */
3150       if (misaligned_operand (operands[0], TFmode)
3151           || misaligned_operand (operands[1], TFmode))
3152         {
3153           if (get_attr_mode (insn) == MODE_V4SF)
3154             return "%vmovups\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 "vmovdqu64\t{%1, %0|%0, %1}";
3159           else
3160             return "%vmovdqu\t{%1, %0|%0, %1}";
3161         }
3162       else
3163         {
3164           if (get_attr_mode (insn) == MODE_V4SF)
3165             return "%vmovaps\t{%1, %0|%0, %1}";
3166           else if (TARGET_AVX512VL
3167                    && (EXT_REX_SSE_REG_P (operands[0])
3168                        || EXT_REX_SSE_REG_P (operands[1])))
3169             return "vmovdqa64\t{%1, %0|%0, %1}";
3170           else
3171             return "%vmovdqa\t{%1, %0|%0, %1}";
3172         }
3174     case TYPE_MULTI:
3175         return "#";
3177     default:
3178       gcc_unreachable ();
3179     }
3181   [(set_attr "isa" "*,*,*,x64,x64")
3182    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3183    (set (attr "prefix")
3184      (if_then_else (eq_attr "type" "sselog1,ssemov")
3185        (const_string "maybe_vex")
3186        (const_string "orig")))
3187    (set (attr "mode")
3188         (cond [(eq_attr "alternative" "3,4")
3189                  (const_string "DI")
3190                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3191                  (const_string "V4SF")
3192                (and (eq_attr "alternative" "2")
3193                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3194                  (const_string "V4SF")
3195                (match_test "TARGET_AVX")
3196                  (const_string "TI")
3197                (ior (not (match_test "TARGET_SSE2"))
3198                     (match_test "optimize_function_for_size_p (cfun)"))
3199                  (const_string "V4SF")
3200                ]
3201                (const_string "TI")))])
3203 (define_split
3204   [(set (match_operand:TF 0 "nonimmediate_operand")
3205         (match_operand:TF 1 "general_operand"))]
3206   "reload_completed
3207    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3208   [(const_int 0)]
3209   "ix86_split_long_move (operands); DONE;")
3211 ;; Possible store forwarding (partial memory) stall
3212 ;; in alternatives 4, 6, 7 and 8.
3213 (define_insn "*movxf_internal"
3214   [(set (match_operand:XF 0 "nonimmediate_operand"
3215          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o")
3216         (match_operand:XF 1 "general_operand"
3217          "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3218   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3219    && (lra_in_progress || reload_completed
3220        || !CONST_DOUBLE_P (operands[1])
3221        || ((optimize_function_for_size_p (cfun)
3222             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3223            && standard_80387_constant_p (operands[1]) > 0
3224            && !memory_operand (operands[0], XFmode))
3225        || (!TARGET_MEMORY_MISMATCH_STALL
3226            && memory_operand (operands[0], XFmode))
3227        || !TARGET_HARD_XF_REGS)"
3229   switch (get_attr_type (insn))
3230     {
3231     case TYPE_FMOV:
3232       if (which_alternative == 2)
3233         return standard_80387_constant_opcode (operands[1]);
3234       return output_387_reg_move (insn, operands);
3236     case TYPE_MULTI:
3237       return "#";
3239     default:
3240       gcc_unreachable ();
3241     }
3243   [(set (attr "isa")
3244         (cond [(eq_attr "alternative" "7")
3245                  (const_string "nox64")
3246                (eq_attr "alternative" "8")
3247                  (const_string "x64")
3248               ]
3249               (const_string "*")))
3250    (set (attr "type")
3251         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3252                  (const_string "multi")
3253               ]
3254               (const_string "fmov")))
3255    (set (attr "mode")
3256         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3257                  (if_then_else (match_test "TARGET_64BIT")
3258                    (const_string "DI")
3259                    (const_string "SI"))
3260               ]
3261               (const_string "XF")))
3262    (set (attr "preferred_for_size")
3263      (cond [(eq_attr "alternative" "3,4")
3264               (symbol_ref "false")]
3265            (symbol_ref "true")))
3266    (set (attr "enabled")
3267      (cond [(eq_attr "alternative" "9,10")
3268               (if_then_else
3269                 (match_test "TARGET_HARD_XF_REGS")
3270                 (symbol_ref "false")
3271                 (const_string "*"))
3272             (not (match_test "TARGET_HARD_XF_REGS"))
3273               (symbol_ref "false")
3274            ]
3275            (const_string "*")))])
3276    
3277 (define_split
3278   [(set (match_operand:XF 0 "nonimmediate_operand")
3279         (match_operand:XF 1 "general_operand"))]
3280   "reload_completed
3281    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3282   [(const_int 0)]
3283   "ix86_split_long_move (operands); DONE;")
3285 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3286 (define_insn "*movdf_internal"
3287   [(set (match_operand:DF 0 "nonimmediate_operand"
3288     "=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")
3289         (match_operand:DF 1 "general_operand"
3290     "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"))]
3291   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3292    && (lra_in_progress || reload_completed
3293        || !CONST_DOUBLE_P (operands[1])
3294        || ((optimize_function_for_size_p (cfun)
3295             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3296            && ((IS_STACK_MODE (DFmode)
3297                 && standard_80387_constant_p (operands[1]) > 0)
3298                || (TARGET_SSE2 && TARGET_SSE_MATH
3299                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3300            && !memory_operand (operands[0], DFmode))
3301        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3302            && memory_operand (operands[0], DFmode))
3303        || !TARGET_HARD_DF_REGS)"
3305   switch (get_attr_type (insn))
3306     {
3307     case TYPE_FMOV:
3308       if (which_alternative == 2)
3309         return standard_80387_constant_opcode (operands[1]);
3310       return output_387_reg_move (insn, operands);
3312     case TYPE_MULTI:
3313       return "#";
3315     case TYPE_IMOV:
3316       if (get_attr_mode (insn) == MODE_SI)
3317         return "mov{l}\t{%1, %k0|%k0, %1}";
3318       else if (which_alternative == 11)
3319         return "movabs{q}\t{%1, %0|%0, %1}";
3320       else
3321         return "mov{q}\t{%1, %0|%0, %1}";
3323     case TYPE_SSELOG1:
3324       return standard_sse_constant_opcode (insn, operands[1]);
3326     case TYPE_SSEMOV:
3327       switch (get_attr_mode (insn))
3328         {
3329         case MODE_DF:
3330           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3331             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3332           return "%vmovsd\t{%1, %0|%0, %1}";
3334         case MODE_V4SF:
3335           return "%vmovaps\t{%1, %0|%0, %1}";
3336         case MODE_V8DF:
3337           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3338         case MODE_V2DF:
3339           return "%vmovapd\t{%1, %0|%0, %1}";
3341         case MODE_V2SF:
3342           gcc_assert (!TARGET_AVX);
3343           return "movlps\t{%1, %0|%0, %1}";
3344         case MODE_V1DF:
3345           gcc_assert (!TARGET_AVX);
3346           return "movlpd\t{%1, %0|%0, %1}";
3348         case MODE_DI:
3349           /* Handle broken assemblers that require movd instead of movq.  */
3350           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3351               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3352             return "%vmovd\t{%1, %0|%0, %1}";
3353           return "%vmovq\t{%1, %0|%0, %1}";
3355         default:
3356           gcc_unreachable ();
3357         }
3359     default:
3360       gcc_unreachable ();
3361     }
3363   [(set (attr "isa")
3364         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3365                  (const_string "nox64")
3366                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3367                  (const_string "x64")
3368                (eq_attr "alternative" "12,13,14,15")
3369                  (const_string "sse2")
3370               ]
3371               (const_string "*")))
3372    (set (attr "type")
3373         (cond [(eq_attr "alternative" "0,1,2")
3374                  (const_string "fmov")
3375                (eq_attr "alternative" "3,4,5,6,7,22,23")
3376                  (const_string "multi")
3377                (eq_attr "alternative" "8,9,10,11,24,25")
3378                  (const_string "imov")
3379                (eq_attr "alternative" "12,16")
3380                  (const_string "sselog1")
3381               ]
3382               (const_string "ssemov")))
3383    (set (attr "modrm")
3384      (if_then_else (eq_attr "alternative" "11")
3385        (const_string "0")
3386        (const_string "*")))
3387    (set (attr "length_immediate")
3388      (if_then_else (eq_attr "alternative" "11")
3389        (const_string "8")
3390        (const_string "*")))
3391    (set (attr "prefix")
3392      (if_then_else (eq_attr "type" "sselog1,ssemov")
3393        (const_string "maybe_vex")
3394        (const_string "orig")))
3395    (set (attr "prefix_data16")
3396      (if_then_else
3397        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3398             (eq_attr "mode" "V1DF"))
3399        (const_string "1")
3400        (const_string "*")))
3401    (set (attr "mode")
3402         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3403                  (const_string "SI")
3404                (eq_attr "alternative" "8,9,11,20,21,24,25")
3405                  (const_string "DI")
3407                /* xorps is one byte shorter for non-AVX targets.  */
3408                (eq_attr "alternative" "12,16")
3409                  (cond [(not (match_test "TARGET_SSE2"))
3410                           (const_string "V4SF")
3411                         (match_test "TARGET_AVX512F")
3412                           (const_string "XI")
3413                         (match_test "TARGET_AVX")
3414                           (const_string "V2DF")
3415                         (match_test "optimize_function_for_size_p (cfun)")
3416                           (const_string "V4SF")
3417                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3418                           (const_string "TI")
3419                        ]
3420                        (const_string "V2DF"))
3422                /* For architectures resolving dependencies on
3423                   whole SSE registers use movapd to break dependency
3424                   chains, otherwise use short move to avoid extra work.  */
3426                /* movaps is one byte shorter for non-AVX targets.  */
3427                (eq_attr "alternative" "13,17")
3428                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3429                              (match_operand 1 "ext_sse_reg_operand"))
3430                           (const_string "V8DF")
3431                         (ior (not (match_test "TARGET_SSE2"))
3432                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3433                           (const_string "V4SF")
3434                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3435                           (const_string "V2DF")
3436                         (match_test "TARGET_AVX")
3437                           (const_string "DF")
3438                         (match_test "optimize_function_for_size_p (cfun)")
3439                           (const_string "V4SF")
3440                        ]
3441                        (const_string "DF"))
3443                /* For architectures resolving dependencies on register
3444                   parts we may avoid extra work to zero out upper part
3445                   of register.  */
3446                (eq_attr "alternative" "14,18")
3447                  (cond [(not (match_test "TARGET_SSE2"))
3448                           (const_string "V2SF")
3449                         (match_test "TARGET_AVX")
3450                           (const_string "DF")
3451                         (match_test "TARGET_SSE_SPLIT_REGS")
3452                           (const_string "V1DF")
3453                        ]
3454                        (const_string "DF"))
3456                (and (eq_attr "alternative" "15,19")
3457                     (not (match_test "TARGET_SSE2")))
3458                  (const_string "V2SF")
3459               ]
3460               (const_string "DF")))
3461    (set (attr "preferred_for_size")
3462      (cond [(eq_attr "alternative" "3,4")
3463               (symbol_ref "false")]
3464            (symbol_ref "true")))
3465    (set (attr "preferred_for_speed")
3466      (cond [(eq_attr "alternative" "3,4")
3467               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3468            (symbol_ref "true")))
3469    (set (attr "enabled")
3470      (cond [(eq_attr "alternative" "22,23,24,25")
3471               (if_then_else
3472                 (match_test "TARGET_HARD_DF_REGS")
3473                 (symbol_ref "false")
3474                 (const_string "*"))
3475             (not (match_test "TARGET_HARD_DF_REGS"))
3476               (symbol_ref "false")
3477            ]
3478            (const_string "*")))])
3480 (define_split
3481   [(set (match_operand:DF 0 "nonimmediate_operand")
3482         (match_operand:DF 1 "general_operand"))]
3483   "!TARGET_64BIT && reload_completed
3484    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3485   [(const_int 0)]
3486   "ix86_split_long_move (operands); DONE;")
3488 (define_insn "*movsf_internal"
3489   [(set (match_operand:SF 0 "nonimmediate_operand"
3490           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3491         (match_operand:SF 1 "general_operand"
3492           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3493   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3494    && (lra_in_progress || reload_completed
3495        || !CONST_DOUBLE_P (operands[1])
3496        || ((optimize_function_for_size_p (cfun)
3497             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3498            && ((IS_STACK_MODE (SFmode)
3499                 && standard_80387_constant_p (operands[1]) > 0)
3500                || (TARGET_SSE && TARGET_SSE_MATH
3501                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3502        || memory_operand (operands[0], SFmode)
3503        || !TARGET_HARD_SF_REGS)"
3505   switch (get_attr_type (insn))
3506     {
3507     case TYPE_FMOV:
3508       if (which_alternative == 2)
3509         return standard_80387_constant_opcode (operands[1]);
3510       return output_387_reg_move (insn, operands);
3512     case TYPE_IMOV:
3513       return "mov{l}\t{%1, %0|%0, %1}";
3515     case TYPE_SSELOG1:
3516       return standard_sse_constant_opcode (insn, operands[1]);
3518     case TYPE_SSEMOV:
3519       switch (get_attr_mode (insn))
3520         {
3521         case MODE_SF:
3522           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3523             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3524           return "%vmovss\t{%1, %0|%0, %1}";
3526         case MODE_V16SF:
3527           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3528         case MODE_V4SF:
3529           return "%vmovaps\t{%1, %0|%0, %1}";
3531         case MODE_SI:
3532           return "%vmovd\t{%1, %0|%0, %1}";
3534         default:
3535           gcc_unreachable ();
3536         }
3538     case TYPE_MMXMOV:
3539       switch (get_attr_mode (insn))
3540         {
3541         case MODE_DI:
3542           return "movq\t{%1, %0|%0, %1}";
3543         case MODE_SI:
3544           return "movd\t{%1, %0|%0, %1}";
3546         default:
3547           gcc_unreachable ();
3548         }
3550     default:
3551       gcc_unreachable ();
3552     }
3554   [(set (attr "type")
3555         (cond [(eq_attr "alternative" "0,1,2")
3556                  (const_string "fmov")
3557                (eq_attr "alternative" "3,4,16,17")
3558                  (const_string "imov")
3559                (eq_attr "alternative" "5")
3560                  (const_string "sselog1")
3561                (eq_attr "alternative" "11,12,13,14,15")
3562                  (const_string "mmxmov")
3563               ]
3564               (const_string "ssemov")))
3565    (set (attr "prefix")
3566      (if_then_else (eq_attr "type" "sselog1,ssemov")
3567        (const_string "maybe_vex")
3568        (const_string "orig")))
3569    (set (attr "prefix_data16")
3570      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3571        (const_string "1")
3572        (const_string "*")))
3573    (set (attr "mode")
3574         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3575                  (const_string "SI")
3576                (eq_attr "alternative" "11")
3577                  (const_string "DI")
3578                (eq_attr "alternative" "5")
3579                  (cond [(not (match_test "TARGET_SSE2"))
3580                           (const_string "V4SF")
3581                         (match_test "TARGET_AVX512F")
3582                           (const_string "V16SF")
3583                         (match_test "TARGET_AVX")
3584                           (const_string "V4SF")
3585                         (match_test "optimize_function_for_size_p (cfun)")
3586                           (const_string "V4SF")
3587                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3588                           (const_string "TI")
3589                        ]
3590                        (const_string "V4SF"))
3592                /* For architectures resolving dependencies on
3593                   whole SSE registers use APS move to break dependency
3594                   chains, otherwise use short move to avoid extra work.
3596                   Do the same for architectures resolving dependencies on
3597                   the parts.  While in DF mode it is better to always handle
3598                   just register parts, the SF mode is different due to lack
3599                   of instructions to load just part of the register.  It is
3600                   better to maintain the whole registers in single format
3601                   to avoid problems on using packed logical operations.  */
3602                (eq_attr "alternative" "6")
3603                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3604                               (match_operand 1 "ext_sse_reg_operand"))
3605                           (const_string "V16SF")
3606                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3607                              (match_test "TARGET_SSE_SPLIT_REGS"))
3608                           (const_string "V4SF")
3609                        ]
3610                        (const_string "SF"))
3611               ]
3612               (const_string "SF")))
3613    (set (attr "enabled")
3614      (cond [(eq_attr "alternative" "16,17")
3615               (if_then_else
3616                 (match_test "TARGET_HARD_SF_REGS")
3617                 (symbol_ref "false")
3618                 (const_string "*"))
3619             (not (match_test "TARGET_HARD_SF_REGS"))
3620               (symbol_ref "false")
3621            ]
3622            (const_string "*")))])
3624 (define_split
3625   [(set (match_operand 0 "any_fp_register_operand")
3626         (match_operand 1 "memory_operand"))]
3627   "reload_completed
3628    && (GET_MODE (operands[0]) == TFmode
3629        || GET_MODE (operands[0]) == XFmode
3630        || GET_MODE (operands[0]) == DFmode
3631        || GET_MODE (operands[0]) == SFmode)
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 (define_split
3637   [(set (match_operand 0 "any_fp_register_operand")
3638         (float_extend (match_operand 1 "memory_operand")))]
3639   "reload_completed
3640    && (GET_MODE (operands[0]) == TFmode
3641        || GET_MODE (operands[0]) == XFmode
3642        || GET_MODE (operands[0]) == DFmode)
3643    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3644   [(set (match_dup 0) (match_dup 2))]
3645   "operands[2] = find_constant_src (curr_insn);")
3647 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3648 (define_split
3649   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3650         (match_operand:X87MODEF 1 "immediate_operand"))]
3651   "reload_completed
3652    && (standard_80387_constant_p (operands[1]) == 8
3653        || standard_80387_constant_p (operands[1]) == 9)"
3654   [(set (match_dup 0)(match_dup 1))
3655    (set (match_dup 0)
3656         (neg:X87MODEF (match_dup 0)))]
3658   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3659     operands[1] = CONST0_RTX (<MODE>mode);
3660   else
3661     operands[1] = CONST1_RTX (<MODE>mode);
3664 (define_insn "swapxf"
3665   [(set (match_operand:XF 0 "register_operand" "+f")
3666         (match_operand:XF 1 "register_operand" "+f"))
3667    (set (match_dup 1)
3668         (match_dup 0))]
3669   "TARGET_80387"
3671   if (STACK_TOP_P (operands[0]))
3672     return "fxch\t%1";
3673   else
3674     return "fxch\t%0";
3676   [(set_attr "type" "fxch")
3677    (set_attr "mode" "XF")])
3679 (define_insn "*swap<mode>"
3680   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3681         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3682    (set (match_dup 1)
3683         (match_dup 0))]
3684   "TARGET_80387 || reload_completed"
3686   if (STACK_TOP_P (operands[0]))
3687     return "fxch\t%1";
3688   else
3689     return "fxch\t%0";
3691   [(set_attr "type" "fxch")
3692    (set_attr "mode" "<MODE>")])
3694 ;; Zero extension instructions
3696 (define_expand "zero_extendsidi2"
3697   [(set (match_operand:DI 0 "nonimmediate_operand")
3698         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3700 (define_insn "*zero_extendsidi2"
3701   [(set (match_operand:DI 0 "nonimmediate_operand"
3702                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x,*r")
3703         (zero_extend:DI
3704          (match_operand:SI 1 "x86_64_zext_operand"
3705                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m  ,*k")))]
3706   ""
3708   switch (get_attr_type (insn))
3709     {
3710     case TYPE_IMOVX:
3711       if (ix86_use_lea_for_mov (insn, operands))
3712         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3713       else
3714         return "mov{l}\t{%1, %k0|%k0, %1}";
3716     case TYPE_MULTI:
3717       return "#";
3719     case TYPE_MMXMOV:
3720       return "movd\t{%1, %0|%0, %1}";
3722     case TYPE_SSELOG1:
3723       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3725     case TYPE_SSEMOV:
3726       if (GENERAL_REG_P (operands[0]))
3727         return "%vmovd\t{%1, %k0|%k0, %1}";
3729       return "%vmovd\t{%1, %0|%0, %1}";
3731     case TYPE_MSKMOV:
3732       return "kmovd\t{%1, %k0|%k0, %1}";
3734     default:
3735       gcc_unreachable ();
3736     }
3738   [(set (attr "isa")
3739      (cond [(eq_attr "alternative" "0,1,2")
3740               (const_string "nox64")
3741             (eq_attr "alternative" "3,7")
3742               (const_string "x64")
3743             (eq_attr "alternative" "8")
3744               (const_string "x64_sse4")
3745             (eq_attr "alternative" "10")
3746               (const_string "sse2")
3747             (eq_attr "alternative" "11")
3748               (const_string "x64_avx512bw")
3749            ]
3750            (const_string "*")))
3751    (set (attr "type")
3752      (cond [(eq_attr "alternative" "0,1,2,4")
3753               (const_string "multi")
3754             (eq_attr "alternative" "5,6")
3755               (const_string "mmxmov")
3756             (eq_attr "alternative" "7,9,10")
3757               (const_string "ssemov")
3758             (eq_attr "alternative" "8")
3759               (const_string "sselog1")
3760             (eq_attr "alternative" "11")
3761               (const_string "mskmov")
3762            ]
3763            (const_string "imovx")))
3764    (set (attr "prefix_extra")
3765      (if_then_else (eq_attr "alternative" "8")
3766        (const_string "1")
3767        (const_string "*")))
3768    (set (attr "length_immediate")
3769      (if_then_else (eq_attr "alternative" "8")
3770        (const_string "1")
3771        (const_string "*")))
3772    (set (attr "prefix")
3773      (if_then_else (eq_attr "type" "ssemov,sselog1")
3774        (const_string "maybe_vex")
3775        (const_string "orig")))
3776    (set (attr "prefix_0f")
3777      (if_then_else (eq_attr "type" "imovx")
3778        (const_string "0")
3779        (const_string "*")))
3780    (set (attr "mode")
3781      (cond [(eq_attr "alternative" "5,6")
3782               (const_string "DI")
3783             (eq_attr "alternative" "7,8,9")
3784               (const_string "TI")
3785            ]
3786            (const_string "SI")))])
3788 (define_split
3789   [(set (match_operand:DI 0 "memory_operand")
3790         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3791   "reload_completed"
3792   [(set (match_dup 4) (const_int 0))]
3793   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3795 (define_split
3796   [(set (match_operand:DI 0 "general_reg_operand")
3797         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3798   "!TARGET_64BIT && reload_completed
3799    && REGNO (operands[0]) == REGNO (operands[1])"
3800   [(set (match_dup 4) (const_int 0))]
3801   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3803 (define_split
3804   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3805         (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3806   "!TARGET_64BIT && reload_completed
3807    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3808   [(set (match_dup 3) (match_dup 1))
3809    (set (match_dup 4) (const_int 0))]
3810   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3812 (define_mode_attr kmov_isa
3813   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3815 (define_insn "zero_extend<mode>di2"
3816   [(set (match_operand:DI 0 "register_operand" "=r,*r")
3817         (zero_extend:DI
3818          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3819   "TARGET_64BIT"
3820   "@
3821    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3822    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3823   [(set_attr "isa" "*,<kmov_isa>")
3824    (set_attr "type" "imovx,mskmov")
3825    (set_attr "mode" "SI")])
3827 (define_expand "zero_extend<mode>si2"
3828   [(set (match_operand:SI 0 "register_operand")
3829         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3830   ""
3832   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3833     {
3834       operands[1] = force_reg (<MODE>mode, operands[1]);
3835       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3836       DONE;
3837     }
3840 (define_insn_and_split "zero_extend<mode>si2_and"
3841   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3842         (zero_extend:SI
3843           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3844    (clobber (reg:CC FLAGS_REG))]
3845   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3846   "#"
3847   "&& reload_completed"
3848   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3849               (clobber (reg:CC FLAGS_REG))])]
3851   if (!REG_P (operands[1])
3852       || REGNO (operands[0]) != REGNO (operands[1]))
3853     {
3854       ix86_expand_clear (operands[0]);
3856       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3857       emit_insn (gen_movstrict<mode>
3858                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3859       DONE;
3860     }
3862   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3864   [(set_attr "type" "alu1")
3865    (set_attr "mode" "SI")])
3867 (define_insn "*zero_extend<mode>si2"
3868   [(set (match_operand:SI 0 "register_operand" "=r,*r")
3869         (zero_extend:SI
3870           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3871   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3872   "@
3873    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3874    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3875   [(set_attr "isa" "*,<kmov_isa>")
3876    (set_attr "type" "imovx,mskmov")
3877    (set_attr "mode" "SI,<MODE>")])
3879 (define_expand "zero_extendqihi2"
3880   [(set (match_operand:HI 0 "register_operand")
3881         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3882   ""
3884   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3885     {
3886       operands[1] = force_reg (QImode, operands[1]);
3887       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3888       DONE;
3889     }
3892 (define_insn_and_split "zero_extendqihi2_and"
3893   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3894         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3895    (clobber (reg:CC FLAGS_REG))]
3896   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3897   "#"
3898   "&& reload_completed"
3899   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3900               (clobber (reg:CC FLAGS_REG))])]
3902   if (!REG_P (operands[1])
3903       || REGNO (operands[0]) != REGNO (operands[1]))
3904     {
3905       ix86_expand_clear (operands[0]);
3907       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3908       emit_insn (gen_movstrictqi
3909                   (gen_lowpart (QImode, operands[0]), operands[1]));
3910       DONE;
3911     }
3913   operands[0] = gen_lowpart (SImode, operands[0]);
3915   [(set_attr "type" "alu1")
3916    (set_attr "mode" "SI")])
3918 ; zero extend to SImode to avoid partial register stalls
3919 (define_insn "*zero_extendqihi2"
3920   [(set (match_operand:HI 0 "register_operand" "=r,*r")
3921         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3922   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3923   "@
3924    movz{bl|x}\t{%1, %k0|%k0, %1}
3925    kmovb\t{%1, %k0|%k0, %1}"
3926   [(set_attr "type" "imovx,mskmov")
3927    (set_attr "isa" "*,avx512dq")
3928    (set_attr "mode" "SI,QI")])
3930 (define_insn_and_split "*zext<mode>_doubleword_and"
3931   [(set (match_operand:DI 0 "register_operand" "=&<r>")
3932         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3933   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3934    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3935   "#"
3936   "&& reload_completed && GENERAL_REG_P (operands[0])"
3937   [(set (match_dup 2) (const_int 0))]
3939   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3941   emit_move_insn (operands[0], const0_rtx);
3943   gcc_assert (!TARGET_PARTIAL_REG_STALL);
3944   emit_insn (gen_movstrict<mode>
3945              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3948 (define_insn_and_split "*zext<mode>_doubleword"
3949   [(set (match_operand:DI 0 "register_operand" "=r")
3950         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3951   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3952    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3953   "#"
3954   "&& reload_completed && GENERAL_REG_P (operands[0])"
3955   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3956    (set (match_dup 2) (const_int 0))]
3957   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3959 (define_insn_and_split "*zextsi_doubleword"
3960   [(set (match_operand:DI 0 "register_operand" "=r")
3961         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3962   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3963   "#"
3964   "&& reload_completed && GENERAL_REG_P (operands[0])"
3965   [(set (match_dup 0) (match_dup 1))
3966    (set (match_dup 2) (const_int 0))]
3967   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3969 ;; Sign extension instructions
3971 (define_expand "extendsidi2"
3972   [(set (match_operand:DI 0 "register_operand")
3973         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3974   ""
3976   if (!TARGET_64BIT)
3977     {
3978       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3979       DONE;
3980     }
3983 (define_insn "*extendsidi2_rex64"
3984   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3985         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3986   "TARGET_64BIT"
3987   "@
3988    {cltq|cdqe}
3989    movs{lq|x}\t{%1, %0|%0, %1}"
3990   [(set_attr "type" "imovx")
3991    (set_attr "mode" "DI")
3992    (set_attr "prefix_0f" "0")
3993    (set_attr "modrm" "0,1")])
3995 (define_insn "extendsidi2_1"
3996   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3997         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3998    (clobber (reg:CC FLAGS_REG))
3999    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4000   "!TARGET_64BIT"
4001   "#")
4003 ;; Split the memory case.  If the source register doesn't die, it will stay
4004 ;; this way, if it does die, following peephole2s take care of it.
4005 (define_split
4006   [(set (match_operand:DI 0 "memory_operand")
4007         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4008    (clobber (reg:CC FLAGS_REG))
4009    (clobber (match_operand:SI 2 "register_operand"))]
4010   "reload_completed"
4011   [(const_int 0)]
4013   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4015   emit_move_insn (operands[3], operands[1]);
4017   /* Generate a cltd if possible and doing so it profitable.  */
4018   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4019       && REGNO (operands[1]) == AX_REG
4020       && REGNO (operands[2]) == DX_REG)
4021     {
4022       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4023     }
4024   else
4025     {
4026       emit_move_insn (operands[2], operands[1]);
4027       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4028     }
4029   emit_move_insn (operands[4], operands[2]);
4030   DONE;
4033 ;; Peepholes for the case where the source register does die, after
4034 ;; being split with the above splitter.
4035 (define_peephole2
4036   [(set (match_operand:SI 0 "memory_operand")
4037         (match_operand:SI 1 "general_reg_operand"))
4038    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4039    (parallel [(set (match_dup 2)
4040                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4041                (clobber (reg:CC FLAGS_REG))])
4042    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4043   "REGNO (operands[1]) != REGNO (operands[2])
4044    && peep2_reg_dead_p (2, operands[1])
4045    && peep2_reg_dead_p (4, operands[2])
4046    && !reg_mentioned_p (operands[2], operands[3])"
4047   [(set (match_dup 0) (match_dup 1))
4048    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4049               (clobber (reg:CC FLAGS_REG))])
4050    (set (match_dup 3) (match_dup 1))])
4052 (define_peephole2
4053   [(set (match_operand:SI 0 "memory_operand")
4054         (match_operand:SI 1 "general_reg_operand"))
4055    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4056                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4057                (clobber (reg:CC FLAGS_REG))])
4058    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4059   "/* cltd is shorter than sarl $31, %eax */
4060    !optimize_function_for_size_p (cfun)
4061    && REGNO (operands[1]) == AX_REG
4062    && REGNO (operands[2]) == DX_REG
4063    && peep2_reg_dead_p (2, operands[1])
4064    && peep2_reg_dead_p (3, operands[2])
4065    && !reg_mentioned_p (operands[2], operands[3])"
4066   [(set (match_dup 0) (match_dup 1))
4067    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4068               (clobber (reg:CC FLAGS_REG))])
4069    (set (match_dup 3) (match_dup 1))])
4071 ;; Extend to register case.  Optimize case where source and destination
4072 ;; registers match and cases where we can use cltd.
4073 (define_split
4074   [(set (match_operand:DI 0 "register_operand")
4075         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4076    (clobber (reg:CC FLAGS_REG))
4077    (clobber (match_scratch:SI 2))]
4078   "reload_completed"
4079   [(const_int 0)]
4081   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4083   if (REGNO (operands[3]) != REGNO (operands[1]))
4084     emit_move_insn (operands[3], operands[1]);
4086   /* Generate a cltd if possible and doing so it profitable.  */
4087   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4088       && REGNO (operands[3]) == AX_REG
4089       && REGNO (operands[4]) == DX_REG)
4090     {
4091       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4092       DONE;
4093     }
4095   if (REGNO (operands[4]) != REGNO (operands[1]))
4096     emit_move_insn (operands[4], operands[1]);
4098   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4099   DONE;
4102 (define_insn "extend<mode>di2"
4103   [(set (match_operand:DI 0 "register_operand" "=r")
4104         (sign_extend:DI
4105          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4106   "TARGET_64BIT"
4107   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4108   [(set_attr "type" "imovx")
4109    (set_attr "mode" "DI")])
4111 (define_insn "extendhisi2"
4112   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4113         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4114   ""
4116   switch (get_attr_prefix_0f (insn))
4117     {
4118     case 0:
4119       return "{cwtl|cwde}";
4120     default:
4121       return "movs{wl|x}\t{%1, %0|%0, %1}";
4122     }
4124   [(set_attr "type" "imovx")
4125    (set_attr "mode" "SI")
4126    (set (attr "prefix_0f")
4127      ;; movsx is short decodable while cwtl is vector decoded.
4128      (if_then_else (and (eq_attr "cpu" "!k6")
4129                         (eq_attr "alternative" "0"))
4130         (const_string "0")
4131         (const_string "1")))
4132    (set (attr "znver1_decode")
4133      (if_then_else (eq_attr "prefix_0f" "0")
4134         (const_string "double")
4135         (const_string "direct")))
4136    (set (attr "modrm")
4137      (if_then_else (eq_attr "prefix_0f" "0")
4138         (const_string "0")
4139         (const_string "1")))])
4141 (define_insn "*extendhisi2_zext"
4142   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4143         (zero_extend:DI
4144          (sign_extend:SI
4145           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4146   "TARGET_64BIT"
4148   switch (get_attr_prefix_0f (insn))
4149     {
4150     case 0:
4151       return "{cwtl|cwde}";
4152     default:
4153       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4154     }
4156   [(set_attr "type" "imovx")
4157    (set_attr "mode" "SI")
4158    (set (attr "prefix_0f")
4159      ;; movsx is short decodable while cwtl is vector decoded.
4160      (if_then_else (and (eq_attr "cpu" "!k6")
4161                         (eq_attr "alternative" "0"))
4162         (const_string "0")
4163         (const_string "1")))
4164    (set (attr "modrm")
4165      (if_then_else (eq_attr "prefix_0f" "0")
4166         (const_string "0")
4167         (const_string "1")))])
4169 (define_insn "extendqisi2"
4170   [(set (match_operand:SI 0 "register_operand" "=r")
4171         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4172   ""
4173   "movs{bl|x}\t{%1, %0|%0, %1}"
4174    [(set_attr "type" "imovx")
4175     (set_attr "mode" "SI")])
4177 (define_insn "*extendqisi2_zext"
4178   [(set (match_operand:DI 0 "register_operand" "=r")
4179         (zero_extend:DI
4180           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4181   "TARGET_64BIT"
4182   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4183    [(set_attr "type" "imovx")
4184     (set_attr "mode" "SI")])
4186 (define_insn "extendqihi2"
4187   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4188         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4189   ""
4191   switch (get_attr_prefix_0f (insn))
4192     {
4193     case 0:
4194       return "{cbtw|cbw}";
4195     default:
4196       return "movs{bw|x}\t{%1, %0|%0, %1}";
4197     }
4199   [(set_attr "type" "imovx")
4200    (set_attr "mode" "HI")
4201    (set (attr "prefix_0f")
4202      ;; movsx is short decodable while cwtl is vector decoded.
4203      (if_then_else (and (eq_attr "cpu" "!k6")
4204                         (eq_attr "alternative" "0"))
4205         (const_string "0")
4206         (const_string "1")))
4207    (set (attr "modrm")
4208      (if_then_else (eq_attr "prefix_0f" "0")
4209         (const_string "0")
4210         (const_string "1")))])
4212 ;; Conversions between float and double.
4214 ;; These are all no-ops in the model used for the 80387.
4215 ;; So just emit moves.
4217 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4218 (define_split
4219   [(set (match_operand:DF 0 "push_operand")
4220         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4221   "reload_completed"
4222   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4223    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4225 (define_split
4226   [(set (match_operand:XF 0 "push_operand")
4227         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4228   "reload_completed"
4229   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4230    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4231   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4233 (define_expand "extendsfdf2"
4234   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4235         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4236   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4238   /* ??? Needed for compress_float_constant since all fp constants
4239      are TARGET_LEGITIMATE_CONSTANT_P.  */
4240   if (CONST_DOUBLE_P (operands[1]))
4241     {
4242       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4243           && standard_80387_constant_p (operands[1]) > 0)
4244         {
4245           operands[1] = simplify_const_unary_operation
4246             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4247           emit_move_insn_1 (operands[0], operands[1]);
4248           DONE;
4249         }
4250       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4251     }
4254 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4255    cvtss2sd:
4256       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4257       cvtps2pd xmm2,xmm1
4258    We do the conversion post reload to avoid producing of 128bit spills
4259    that might lead to ICE on 32bit target.  The sequence unlikely combine
4260    anyway.  */
4261 (define_split
4262   [(set (match_operand:DF 0 "sse_reg_operand")
4263         (float_extend:DF
4264           (match_operand:SF 1 "nonimmediate_operand")))]
4265   "TARGET_USE_VECTOR_FP_CONVERTS
4266    && optimize_insn_for_speed_p ()
4267    && reload_completed
4268    && (!EXT_REX_SSE_REG_P (operands[0])
4269        || TARGET_AVX512VL)"
4270    [(set (match_dup 2)
4271          (float_extend:V2DF
4272            (vec_select:V2SF
4273              (match_dup 3)
4274              (parallel [(const_int 0) (const_int 1)]))))]
4276   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4277   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4278   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4279      Try to avoid move when unpacking can be done in source.  */
4280   if (REG_P (operands[1]))
4281     {
4282       /* If it is unsafe to overwrite upper half of source, we need
4283          to move to destination and unpack there.  */
4284       if (REGNO (operands[0]) != REGNO (operands[1])
4285           || (EXT_REX_SSE_REG_P (operands[1])
4286               && !TARGET_AVX512VL))
4287         {
4288           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4289           emit_move_insn (tmp, operands[1]);
4290         }
4291       else
4292         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4293       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4294          =v, v, then vbroadcastss will be only needed for AVX512F without
4295          AVX512VL.  */
4296       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4297         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4298                                                operands[3]));
4299       else
4300         {
4301           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4302           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4303         }
4304     }
4305   else
4306     emit_insn (gen_vec_setv4sf_0 (operands[3],
4307                                   CONST0_RTX (V4SFmode), operands[1]));
4310 ;; It's more profitable to split and then extend in the same register.
4311 (define_peephole2
4312   [(set (match_operand:DF 0 "sse_reg_operand")
4313         (float_extend:DF
4314           (match_operand:SF 1 "memory_operand")))]
4315   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4316    && optimize_insn_for_speed_p ()"
4317   [(set (match_dup 2) (match_dup 1))
4318    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4319   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4321 (define_insn "*extendsfdf2"
4322   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4323         (float_extend:DF
4324           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4325   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4327   switch (which_alternative)
4328     {
4329     case 0:
4330     case 1:
4331       return output_387_reg_move (insn, operands);
4333     case 2:
4334       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4336     default:
4337       gcc_unreachable ();
4338     }
4340   [(set_attr "type" "fmov,fmov,ssecvt")
4341    (set_attr "prefix" "orig,orig,maybe_vex")
4342    (set_attr "mode" "SF,XF,DF")
4343    (set (attr "enabled")
4344      (if_then_else
4345        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4346        (if_then_else
4347          (eq_attr "alternative" "0,1")
4348          (symbol_ref "TARGET_MIX_SSE_I387")
4349          (symbol_ref "true"))
4350        (if_then_else
4351          (eq_attr "alternative" "0,1")
4352          (symbol_ref "true")
4353          (symbol_ref "false"))))])
4355 (define_expand "extend<mode>xf2"
4356   [(set (match_operand:XF 0 "nonimmediate_operand")
4357         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4358   "TARGET_80387"
4360   /* ??? Needed for compress_float_constant since all fp constants
4361      are TARGET_LEGITIMATE_CONSTANT_P.  */
4362   if (CONST_DOUBLE_P (operands[1]))
4363     {
4364       if (standard_80387_constant_p (operands[1]) > 0)
4365         {
4366           operands[1] = simplify_const_unary_operation
4367             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4368           emit_move_insn_1 (operands[0], operands[1]);
4369           DONE;
4370         }
4371       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4372     }
4375 (define_insn "*extend<mode>xf2_i387"
4376   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4377         (float_extend:XF
4378           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4379   "TARGET_80387"
4380   "* return output_387_reg_move (insn, operands);"
4381   [(set_attr "type" "fmov")
4382    (set_attr "mode" "<MODE>,XF")])
4384 ;; %%% This seems like bad news.
4385 ;; This cannot output into an f-reg because there is no way to be sure
4386 ;; of truncating in that case.  Otherwise this is just like a simple move
4387 ;; insn.  So we pretend we can output to a reg in order to get better
4388 ;; register preferencing, but we really use a stack slot.
4390 ;; Conversion from DFmode to SFmode.
4392 (define_expand "truncdfsf2"
4393   [(set (match_operand:SF 0 "nonimmediate_operand")
4394         (float_truncate:SF
4395           (match_operand:DF 1 "nonimmediate_operand")))]
4396   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4398   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4399     ;
4400   else if (flag_unsafe_math_optimizations)
4401     ;
4402   else
4403     {
4404       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4405       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4406       DONE;
4407     }
4410 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4411    cvtsd2ss:
4412       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4413       cvtpd2ps xmm2,xmm1
4414    We do the conversion post reload to avoid producing of 128bit spills
4415    that might lead to ICE on 32bit target.  The sequence unlikely combine
4416    anyway.  */
4417 (define_split
4418   [(set (match_operand:SF 0 "sse_reg_operand")
4419         (float_truncate:SF
4420           (match_operand:DF 1 "nonimmediate_operand")))]
4421   "TARGET_USE_VECTOR_FP_CONVERTS
4422    && optimize_insn_for_speed_p ()
4423    && reload_completed
4424    && (!EXT_REX_SSE_REG_P (operands[0])
4425        || TARGET_AVX512VL)"
4426    [(set (match_dup 2)
4427          (vec_concat:V4SF
4428            (float_truncate:V2SF
4429              (match_dup 4))
4430            (match_dup 3)))]
4432   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4433   operands[3] = CONST0_RTX (V2SFmode);
4434   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4435   /* Use movsd for loading from memory, unpcklpd for registers.
4436      Try to avoid move when unpacking can be done in source, or SSE3
4437      movddup is available.  */
4438   if (REG_P (operands[1]))
4439     {
4440       if (!TARGET_SSE3
4441           && REGNO (operands[0]) != REGNO (operands[1]))
4442         {
4443           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4444           emit_move_insn (tmp, operands[1]);
4445           operands[1] = tmp;
4446         }
4447       else if (!TARGET_SSE3)
4448         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4449       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4450     }
4451   else
4452     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4453                                    CONST0_RTX (DFmode)));
4456 ;; It's more profitable to split and then extend in the same register.
4457 (define_peephole2
4458   [(set (match_operand:SF 0 "sse_reg_operand")
4459         (float_truncate:SF
4460           (match_operand:DF 1 "memory_operand")))]
4461   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4462    && optimize_insn_for_speed_p ()"
4463   [(set (match_dup 2) (match_dup 1))
4464    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4465   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4467 (define_expand "truncdfsf2_with_temp"
4468   [(parallel [(set (match_operand:SF 0)
4469                    (float_truncate:SF (match_operand:DF 1)))
4470               (clobber (match_operand:SF 2))])])
4472 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4473 ;; because nothing we do there is unsafe.
4474 (define_insn "*truncdfsf_fast_mixed"
4475   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4476         (float_truncate:SF
4477           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4478   "TARGET_SSE2 && TARGET_SSE_MATH"
4480   switch (which_alternative)
4481     {
4482     case 0:
4483       return output_387_reg_move (insn, operands);
4484     case 1:
4485       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4486     default:
4487       gcc_unreachable ();
4488     }
4490   [(set_attr "type" "fmov,ssecvt")
4491    (set_attr "prefix" "orig,maybe_vex")
4492    (set_attr "mode" "SF")
4493    (set (attr "enabled")
4494      (cond [(eq_attr "alternative" "0")
4495               (symbol_ref "TARGET_MIX_SSE_I387
4496                            && flag_unsafe_math_optimizations")
4497            ]
4498            (symbol_ref "true")))])
4500 (define_insn "*truncdfsf_fast_i387"
4501   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4502         (float_truncate:SF
4503           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4504   "TARGET_80387 && flag_unsafe_math_optimizations"
4505   "* return output_387_reg_move (insn, operands);"
4506   [(set_attr "type" "fmov")
4507    (set_attr "mode" "SF")])
4509 (define_insn "*truncdfsf_mixed"
4510   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4511         (float_truncate:SF
4512           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4513    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4514   "TARGET_MIX_SSE_I387"
4516   switch (which_alternative)
4517     {
4518     case 0:
4519       return output_387_reg_move (insn, operands);
4520     case 1:
4521       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4523     default:
4524       return "#";
4525     }
4527   [(set_attr "isa" "*,sse2,*,*,*")
4528    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4529    (set_attr "unit" "*,*,i387,i387,i387")
4530    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4531    (set_attr "mode" "SF")])
4533 (define_insn "*truncdfsf_i387"
4534   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4535         (float_truncate:SF
4536           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4537    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4538   "TARGET_80387"
4540   switch (which_alternative)
4541     {
4542     case 0:
4543       return output_387_reg_move (insn, operands);
4545     default:
4546       return "#";
4547     }
4549   [(set_attr "type" "fmov,multi,multi,multi")
4550    (set_attr "unit" "*,i387,i387,i387")
4551    (set_attr "mode" "SF")])
4553 (define_insn "*truncdfsf2_i387_1"
4554   [(set (match_operand:SF 0 "memory_operand" "=m")
4555         (float_truncate:SF
4556           (match_operand:DF 1 "register_operand" "f")))]
4557   "TARGET_80387
4558    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4559    && !TARGET_MIX_SSE_I387"
4560   "* return output_387_reg_move (insn, operands);"
4561   [(set_attr "type" "fmov")
4562    (set_attr "mode" "SF")])
4564 (define_split
4565   [(set (match_operand:SF 0 "register_operand")
4566         (float_truncate:SF
4567          (match_operand:DF 1 "fp_register_operand")))
4568    (clobber (match_operand 2))]
4569   "reload_completed"
4570   [(set (match_dup 2) (match_dup 1))
4571    (set (match_dup 0) (match_dup 2))]
4572   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4574 ;; Conversion from XFmode to {SF,DF}mode
4576 (define_expand "truncxf<mode>2"
4577   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4578                    (float_truncate:MODEF
4579                      (match_operand:XF 1 "register_operand")))
4580               (clobber (match_dup 2))])]
4581   "TARGET_80387"
4583   if (flag_unsafe_math_optimizations)
4584     {
4585       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4586       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4587       if (reg != operands[0])
4588         emit_move_insn (operands[0], reg);
4589       DONE;
4590     }
4591   else
4592     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4595 (define_insn "*truncxfsf2_mixed"
4596   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4597         (float_truncate:SF
4598           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4599    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4600   "TARGET_80387"
4602   gcc_assert (!which_alternative);
4603   return output_387_reg_move (insn, operands);
4605   [(set_attr "type" "fmov,multi,multi,multi")
4606    (set_attr "unit" "*,i387,i387,i387")
4607    (set_attr "mode" "SF")])
4609 (define_insn "*truncxfdf2_mixed"
4610   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4611         (float_truncate:DF
4612           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4613    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4614   "TARGET_80387"
4616   gcc_assert (!which_alternative);
4617   return output_387_reg_move (insn, operands);
4619   [(set_attr "isa" "*,*,sse2,*")
4620    (set_attr "type" "fmov,multi,multi,multi")
4621    (set_attr "unit" "*,i387,i387,i387")
4622    (set_attr "mode" "DF")])
4624 (define_insn "truncxf<mode>2_i387_noop"
4625   [(set (match_operand:MODEF 0 "register_operand" "=f")
4626         (float_truncate:MODEF
4627           (match_operand:XF 1 "register_operand" "f")))]
4628   "TARGET_80387 && flag_unsafe_math_optimizations"
4629   "* return output_387_reg_move (insn, operands);"
4630   [(set_attr "type" "fmov")
4631    (set_attr "mode" "<MODE>")])
4633 (define_insn "*truncxf<mode>2_i387"
4634   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4635         (float_truncate:MODEF
4636           (match_operand:XF 1 "register_operand" "f")))]
4637   "TARGET_80387"
4638   "* return output_387_reg_move (insn, operands);"
4639   [(set_attr "type" "fmov")
4640    (set_attr "mode" "<MODE>")])
4642 (define_split
4643   [(set (match_operand:MODEF 0 "register_operand")
4644         (float_truncate:MODEF
4645           (match_operand:XF 1 "register_operand")))
4646    (clobber (match_operand:MODEF 2 "memory_operand"))]
4647   "TARGET_80387 && reload_completed"
4648   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4649    (set (match_dup 0) (match_dup 2))])
4651 (define_split
4652   [(set (match_operand:MODEF 0 "memory_operand")
4653         (float_truncate:MODEF
4654           (match_operand:XF 1 "register_operand")))
4655    (clobber (match_operand:MODEF 2 "memory_operand"))]
4656   "TARGET_80387"
4657   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4659 ;; Signed conversion to DImode.
4661 (define_expand "fix_truncxfdi2"
4662   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4663                    (fix:DI (match_operand:XF 1 "register_operand")))
4664               (clobber (reg:CC FLAGS_REG))])]
4665   "TARGET_80387"
4667   if (TARGET_FISTTP)
4668    {
4669      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4670      DONE;
4671    }
4674 (define_expand "fix_trunc<mode>di2"
4675   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4676                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4677               (clobber (reg:CC FLAGS_REG))])]
4678   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4680   if (TARGET_FISTTP
4681       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4682    {
4683      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4684      DONE;
4685    }
4686   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4687    {
4688      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4689      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4690      if (out != operands[0])
4691         emit_move_insn (operands[0], out);
4692      DONE;
4693    }
4696 ;; Signed conversion to SImode.
4698 (define_expand "fix_truncxfsi2"
4699   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4700                    (fix:SI (match_operand:XF 1 "register_operand")))
4701               (clobber (reg:CC FLAGS_REG))])]
4702   "TARGET_80387"
4704   if (TARGET_FISTTP)
4705    {
4706      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4707      DONE;
4708    }
4711 (define_expand "fix_trunc<mode>si2"
4712   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4713                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4714               (clobber (reg:CC FLAGS_REG))])]
4715   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4717   if (TARGET_FISTTP
4718       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4719    {
4720      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4721      DONE;
4722    }
4723   if (SSE_FLOAT_MODE_P (<MODE>mode))
4724    {
4725      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4726      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4727      if (out != operands[0])
4728         emit_move_insn (operands[0], out);
4729      DONE;
4730    }
4733 ;; Signed conversion to HImode.
4735 (define_expand "fix_trunc<mode>hi2"
4736   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4737                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4738               (clobber (reg:CC FLAGS_REG))])]
4739   "TARGET_80387
4740    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4742   if (TARGET_FISTTP)
4743    {
4744      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4745      DONE;
4746    }
4749 ;; Unsigned conversion to SImode.
4751 (define_expand "fixuns_trunc<mode>si2"
4752   [(parallel
4753     [(set (match_operand:SI 0 "register_operand")
4754           (unsigned_fix:SI
4755             (match_operand:MODEF 1 "nonimmediate_operand")))
4756      (use (match_dup 2))
4757      (clobber (match_scratch:<ssevecmode> 3))
4758      (clobber (match_scratch:<ssevecmode> 4))])]
4759   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4761   machine_mode mode = <MODE>mode;
4762   machine_mode vecmode = <ssevecmode>mode;
4763   REAL_VALUE_TYPE TWO31r;
4764   rtx two31;
4766   if (optimize_insn_for_size_p ())
4767     FAIL;
4769   real_ldexp (&TWO31r, &dconst1, 31);
4770   two31 = const_double_from_real_value (TWO31r, mode);
4771   two31 = ix86_build_const_vector (vecmode, true, two31);
4772   operands[2] = force_reg (vecmode, two31);
4775 (define_insn_and_split "*fixuns_trunc<mode>_1"
4776   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4777         (unsigned_fix:SI
4778           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4779    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4780    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4781    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4782   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4783    && optimize_function_for_speed_p (cfun)"
4784   "#"
4785   "&& reload_completed"
4786   [(const_int 0)]
4788   ix86_split_convert_uns_si_sse (operands);
4789   DONE;
4792 ;; Unsigned conversion to HImode.
4793 ;; Without these patterns, we'll try the unsigned SI conversion which
4794 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4796 (define_expand "fixuns_trunc<mode>hi2"
4797   [(set (match_dup 2)
4798         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4799    (set (match_operand:HI 0 "nonimmediate_operand")
4800         (subreg:HI (match_dup 2) 0))]
4801   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4802   "operands[2] = gen_reg_rtx (SImode);")
4804 ;; When SSE is available, it is always faster to use it!
4805 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4806   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4807         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4808   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4809    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4810   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4811   [(set_attr "type" "sseicvt")
4812    (set_attr "prefix" "maybe_vex")
4813    (set (attr "prefix_rex")
4814         (if_then_else
4815           (match_test "<SWI48:MODE>mode == DImode")
4816           (const_string "1")
4817           (const_string "*")))
4818    (set_attr "mode" "<MODEF:MODE>")
4819    (set_attr "athlon_decode" "double,vector")
4820    (set_attr "amdfam10_decode" "double,double")
4821    (set_attr "bdver1_decode" "double,double")])
4823 ;; Avoid vector decoded forms of the instruction.
4824 (define_peephole2
4825   [(match_scratch:MODEF 2 "x")
4826    (set (match_operand:SWI48 0 "register_operand")
4827         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4828   "TARGET_AVOID_VECTOR_DECODE
4829    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4830    && optimize_insn_for_speed_p ()"
4831   [(set (match_dup 2) (match_dup 1))
4832    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4834 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4835   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4836         (fix:SWI248x (match_operand 1 "register_operand")))]
4837   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4838    && TARGET_FISTTP
4839    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4840          && (TARGET_64BIT || <MODE>mode != DImode))
4841         && TARGET_SSE_MATH)
4842    && can_create_pseudo_p ()"
4843   "#"
4844   "&& 1"
4845   [(const_int 0)]
4847   if (memory_operand (operands[0], VOIDmode))
4848     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4849   else
4850     {
4851       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4852       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4853                                                             operands[1],
4854                                                             operands[2]));
4855     }
4856   DONE;
4858   [(set_attr "type" "fisttp")
4859    (set_attr "mode" "<MODE>")])
4861 (define_insn "fix_trunc<mode>_i387_fisttp"
4862   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4863         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4864    (clobber (match_scratch:XF 2 "=&1f"))]
4865   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4866    && TARGET_FISTTP
4867    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4868          && (TARGET_64BIT || <MODE>mode != DImode))
4869         && TARGET_SSE_MATH)"
4870   "* return output_fix_trunc (insn, operands, true);"
4871   [(set_attr "type" "fisttp")
4872    (set_attr "mode" "<MODE>")])
4874 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4875   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4876         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4877    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4878    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4879   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4880    && TARGET_FISTTP
4881    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4882         && (TARGET_64BIT || <MODE>mode != DImode))
4883         && TARGET_SSE_MATH)"
4884   "#"
4885   [(set_attr "type" "fisttp")
4886    (set_attr "mode" "<MODE>")])
4888 (define_split
4889   [(set (match_operand:SWI248x 0 "register_operand")
4890         (fix:SWI248x (match_operand 1 "register_operand")))
4891    (clobber (match_operand:SWI248x 2 "memory_operand"))
4892    (clobber (match_scratch 3))]
4893   "reload_completed"
4894   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4895               (clobber (match_dup 3))])
4896    (set (match_dup 0) (match_dup 2))])
4898 (define_split
4899   [(set (match_operand:SWI248x 0 "memory_operand")
4900         (fix:SWI248x (match_operand 1 "register_operand")))
4901    (clobber (match_operand:SWI248x 2 "memory_operand"))
4902    (clobber (match_scratch 3))]
4903   "reload_completed"
4904   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4905               (clobber (match_dup 3))])])
4907 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4908 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4909 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4910 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4911 ;; function in i386.c.
4912 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4913   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4914         (fix:SWI248x (match_operand 1 "register_operand")))
4915    (clobber (reg:CC FLAGS_REG))]
4916   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4917    && !TARGET_FISTTP
4918    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4919          && (TARGET_64BIT || <MODE>mode != DImode))
4920    && can_create_pseudo_p ()"
4921   "#"
4922   "&& 1"
4923   [(const_int 0)]
4925   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4927   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4928   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4929   if (memory_operand (operands[0], VOIDmode))
4930     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4931                                          operands[2], operands[3]));
4932   else
4933     {
4934       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4935       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4936                                                      operands[2], operands[3],
4937                                                      operands[4]));
4938     }
4939   DONE;
4941   [(set_attr "type" "fistp")
4942    (set_attr "i387_cw" "trunc")
4943    (set_attr "mode" "<MODE>")])
4945 (define_insn "fix_truncdi_i387"
4946   [(set (match_operand:DI 0 "memory_operand" "=m")
4947         (fix:DI (match_operand 1 "register_operand" "f")))
4948    (use (match_operand:HI 2 "memory_operand" "m"))
4949    (use (match_operand:HI 3 "memory_operand" "m"))
4950    (clobber (match_scratch:XF 4 "=&1f"))]
4951   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4952    && !TARGET_FISTTP
4953    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4954   "* return output_fix_trunc (insn, operands, false);"
4955   [(set_attr "type" "fistp")
4956    (set_attr "i387_cw" "trunc")
4957    (set_attr "mode" "DI")])
4959 (define_insn "fix_truncdi_i387_with_temp"
4960   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4961         (fix:DI (match_operand 1 "register_operand" "f,f")))
4962    (use (match_operand:HI 2 "memory_operand" "m,m"))
4963    (use (match_operand:HI 3 "memory_operand" "m,m"))
4964    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4965    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4966   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4967    && !TARGET_FISTTP
4968    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4969   "#"
4970   [(set_attr "type" "fistp")
4971    (set_attr "i387_cw" "trunc")
4972    (set_attr "mode" "DI")])
4974 (define_split
4975   [(set (match_operand:DI 0 "register_operand")
4976         (fix:DI (match_operand 1 "register_operand")))
4977    (use (match_operand:HI 2 "memory_operand"))
4978    (use (match_operand:HI 3 "memory_operand"))
4979    (clobber (match_operand:DI 4 "memory_operand"))
4980    (clobber (match_scratch 5))]
4981   "reload_completed"
4982   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4983               (use (match_dup 2))
4984               (use (match_dup 3))
4985               (clobber (match_dup 5))])
4986    (set (match_dup 0) (match_dup 4))])
4988 (define_split
4989   [(set (match_operand:DI 0 "memory_operand")
4990         (fix:DI (match_operand 1 "register_operand")))
4991    (use (match_operand:HI 2 "memory_operand"))
4992    (use (match_operand:HI 3 "memory_operand"))
4993    (clobber (match_operand:DI 4 "memory_operand"))
4994    (clobber (match_scratch 5))]
4995   "reload_completed"
4996   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4997               (use (match_dup 2))
4998               (use (match_dup 3))
4999               (clobber (match_dup 5))])])
5001 (define_insn "fix_trunc<mode>_i387"
5002   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5003         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5004    (use (match_operand:HI 2 "memory_operand" "m"))
5005    (use (match_operand:HI 3 "memory_operand" "m"))]
5006   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5007    && !TARGET_FISTTP
5008    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5009   "* return output_fix_trunc (insn, operands, false);"
5010   [(set_attr "type" "fistp")
5011    (set_attr "i387_cw" "trunc")
5012    (set_attr "mode" "<MODE>")])
5014 (define_insn "fix_trunc<mode>_i387_with_temp"
5015   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5016         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5017    (use (match_operand:HI 2 "memory_operand" "m,m"))
5018    (use (match_operand:HI 3 "memory_operand" "m,m"))
5019    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5020   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5021    && !TARGET_FISTTP
5022    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5023   "#"
5024   [(set_attr "type" "fistp")
5025    (set_attr "i387_cw" "trunc")
5026    (set_attr "mode" "<MODE>")])
5028 (define_split
5029   [(set (match_operand:SWI24 0 "register_operand")
5030         (fix:SWI24 (match_operand 1 "register_operand")))
5031    (use (match_operand:HI 2 "memory_operand"))
5032    (use (match_operand:HI 3 "memory_operand"))
5033    (clobber (match_operand:SWI24 4 "memory_operand"))]
5034   "reload_completed"
5035   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5036               (use (match_dup 2))
5037               (use (match_dup 3))])
5038    (set (match_dup 0) (match_dup 4))])
5040 (define_split
5041   [(set (match_operand:SWI24 0 "memory_operand")
5042         (fix:SWI24 (match_operand 1 "register_operand")))
5043    (use (match_operand:HI 2 "memory_operand"))
5044    (use (match_operand:HI 3 "memory_operand"))
5045    (clobber (match_operand:SWI24 4 "memory_operand"))]
5046   "reload_completed"
5047   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5048               (use (match_dup 2))
5049               (use (match_dup 3))])])
5051 (define_insn "x86_fnstcw_1"
5052   [(set (match_operand:HI 0 "memory_operand" "=m")
5053         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5054   "TARGET_80387"
5055   "fnstcw\t%0"
5056   [(set (attr "length")
5057         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5058    (set_attr "mode" "HI")
5059    (set_attr "unit" "i387")
5060    (set_attr "bdver1_decode" "vector")])
5062 (define_insn "x86_fldcw_1"
5063   [(set (reg:HI FPCR_REG)
5064         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5065   "TARGET_80387"
5066   "fldcw\t%0"
5067   [(set (attr "length")
5068         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5069    (set_attr "mode" "HI")
5070    (set_attr "unit" "i387")
5071    (set_attr "athlon_decode" "vector")
5072    (set_attr "amdfam10_decode" "vector")
5073    (set_attr "bdver1_decode" "vector")])
5075 ;; Conversion between fixed point and floating point.
5077 ;; Even though we only accept memory inputs, the backend _really_
5078 ;; wants to be able to do this between registers.  Thankfully, LRA
5079 ;; will fix this up for us during register allocation.
5081 (define_insn "floathi<mode>2"
5082   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5083         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5084   "TARGET_80387
5085    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5086        || TARGET_MIX_SSE_I387)"
5087   "fild%Z1\t%1"
5088   [(set_attr "type" "fmov")
5089    (set_attr "mode" "<MODE>")
5090    (set_attr "znver1_decode" "double")
5091    (set_attr "fp_int_src" "true")])
5093 (define_insn "float<SWI48x:mode>xf2"
5094   [(set (match_operand:XF 0 "register_operand" "=f")
5095         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5096   "TARGET_80387"
5097   "fild%Z1\t%1"
5098   [(set_attr "type" "fmov")
5099    (set_attr "mode" "XF")
5100    (set_attr "znver1_decode" "double")
5101    (set_attr "fp_int_src" "true")])
5103 (define_expand "float<SWI48:mode><MODEF:mode>2"
5104   [(set (match_operand:MODEF 0 "register_operand")
5105         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5106   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5108   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5109       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5110     {
5111       rtx reg = gen_reg_rtx (XFmode);
5112       rtx (*insn)(rtx, rtx);
5114       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5116       if (<MODEF:MODE>mode == SFmode)
5117         insn = gen_truncxfsf2;
5118       else if (<MODEF:MODE>mode == DFmode)
5119         insn = gen_truncxfdf2;
5120       else
5121         gcc_unreachable ();
5123       emit_insn (insn (operands[0], reg));
5124       DONE;
5125     }
5128 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5129   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5130         (float:MODEF
5131           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5132   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5133   "@
5134    fild%Z1\t%1
5135    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5136    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5137   [(set_attr "type" "fmov,sseicvt,sseicvt")
5138    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5139    (set_attr "mode" "<MODEF:MODE>")
5140    (set (attr "prefix_rex")
5141      (if_then_else
5142        (and (eq_attr "prefix" "maybe_vex")
5143             (match_test "<SWI48:MODE>mode == DImode"))
5144        (const_string "1")
5145        (const_string "*")))
5146    (set_attr "unit" "i387,*,*")
5147    (set_attr "athlon_decode" "*,double,direct")
5148    (set_attr "amdfam10_decode" "*,vector,double")
5149    (set_attr "bdver1_decode" "*,double,direct")
5150    (set_attr "znver1_decode" "double,*,*")
5151    (set_attr "fp_int_src" "true")
5152    (set (attr "enabled")
5153      (cond [(eq_attr "alternative" "0")
5154               (symbol_ref "TARGET_MIX_SSE_I387
5155                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5156                                                 <SWI48:MODE>mode)")
5157            ]
5158            (symbol_ref "true")))
5159    (set (attr "preferred_for_speed")
5160      (cond [(eq_attr "alternative" "1")
5161               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5162            (symbol_ref "true")))])
5164 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5165   [(set (match_operand:MODEF 0 "register_operand" "=f")
5166         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5167   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5168   "fild%Z1\t%1"
5169   [(set_attr "type" "fmov")
5170    (set_attr "mode" "<MODEF:MODE>")
5171    (set_attr "znver1_decode" "double")
5172    (set_attr "fp_int_src" "true")])
5174 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5175 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5176 ;; alternative in sse2_loadld.
5177 (define_split
5178   [(set (match_operand:MODEF 0 "sse_reg_operand")
5179         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5180   "TARGET_USE_VECTOR_CONVERTS
5181    && optimize_function_for_speed_p (cfun)
5182    && reload_completed
5183    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5184    && (!EXT_REX_SSE_REG_P (operands[0])
5185        || TARGET_AVX512VL)"
5186   [(const_int 0)]
5188   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5189   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5191   emit_insn (gen_sse2_loadld (operands[4],
5192                               CONST0_RTX (V4SImode), operands[1]));
5194   if (<ssevecmode>mode == V4SFmode)
5195     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5196   else
5197     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5198   DONE;
5201 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5202 ;; late in the pass sequence (after register rename pass), so allocated
5203 ;; registers won't change anymore
5205 (define_split
5206   [(set (match_operand:MODEF 0 "sse_reg_operand")
5207         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5208   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5209    && optimize_function_for_speed_p (cfun)
5210    && epilogue_completed
5211    && (!EXT_REX_SSE_REG_P (operands[0])
5212        || TARGET_AVX512VL)"
5213   [(set (match_dup 0)
5214         (vec_merge:<MODEF:ssevecmode>
5215           (vec_duplicate:<MODEF:ssevecmode>
5216             (float:MODEF
5217               (match_dup 1)))
5218           (match_dup 0)
5219           (const_int 1)))]
5221   const machine_mode vmode = <MODEF:ssevecmode>mode;
5223   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5224   emit_move_insn (operands[0], CONST0_RTX (vmode));
5227 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5228 ;; late in the pass sequence (after register rename pass),
5229 ;; so allocated registers won't change anymore.
5231 (define_split
5232   [(set (match_operand:SF 0 "sse_reg_operand")
5233         (float_truncate:SF
5234           (match_operand:DF 1 "nonimmediate_operand")))]
5235   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5236    && optimize_function_for_speed_p (cfun)
5237    && epilogue_completed
5238    && (!REG_P (operands[1])
5239        || REGNO (operands[0]) != REGNO (operands[1]))
5240    && (!EXT_REX_SSE_REG_P (operands[0])
5241        || TARGET_AVX512VL)"
5242   [(set (match_dup 0)
5243         (vec_merge:V4SF
5244           (vec_duplicate:V4SF
5245             (float_truncate:SF
5246               (match_dup 1)))
5247           (match_dup 0)
5248           (const_int 1)))]
5250   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5251   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5254 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5255 ;; late in the pass sequence (after register rename pass),
5256 ;; so allocated registers won't change anymore.
5258 (define_split
5259   [(set (match_operand:DF 0 "sse_reg_operand")
5260         (float_extend:DF
5261           (match_operand:SF 1 "nonimmediate_operand")))]
5262   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5263    && optimize_function_for_speed_p (cfun)
5264    && epilogue_completed
5265    && (!REG_P (operands[1])
5266        || REGNO (operands[0]) != REGNO (operands[1]))
5267    && (!EXT_REX_SSE_REG_P (operands[0])
5268        || TARGET_AVX512VL)"
5269   [(set (match_dup 0)
5270         (vec_merge:V2DF
5271           (vec_duplicate:V2DF
5272             (float_extend:DF
5273               (match_dup 1)))
5274           (match_dup 0)
5275           (const_int 1)))]
5277   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5278   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers.  */
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5286         (float:X87MODEF
5287           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288    (clobber (match_scratch:V4SI 3 "=X,x"))
5289    (clobber (match_scratch:V4SI 4 "=X,x"))
5290    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5293    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5294   "#"
5295   [(set_attr "type" "multi")
5296    (set_attr "mode" "<X87MODEF:MODE>")
5297    (set_attr "unit" "i387")
5298    (set_attr "fp_int_src" "true")])
5300 (define_split
5301   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5302         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5303    (clobber (match_scratch:V4SI 3))
5304    (clobber (match_scratch:V4SI 4))
5305    (clobber (match_operand:DI 2 "memory_operand"))]
5306   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5308    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309    && reload_completed"
5310   [(set (match_dup 2) (match_dup 3))
5311    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5313   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5314      Assemble the 64-bit DImode value in an xmm register.  */
5315   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5316                               gen_lowpart (SImode, operands[1])));
5317   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5318                               gen_highpart (SImode, operands[1])));
5319   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5320                                          operands[4]));
5322   operands[3] = gen_lowpart (DImode, operands[3]);
5325 (define_split
5326   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5327         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5328    (clobber (match_scratch:V4SI 3))
5329    (clobber (match_scratch:V4SI 4))
5330    (clobber (match_operand:DI 2 "memory_operand"))]
5331   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5333    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5334    && reload_completed"
5335   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5337 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5338   [(set (match_operand:MODEF 0 "register_operand")
5339         (unsigned_float:MODEF
5340           (match_operand:SWI12 1 "nonimmediate_operand")))]
5341   "!TARGET_64BIT
5342    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5344   operands[1] = convert_to_mode (SImode, operands[1], 1);
5345   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5346   DONE;
5349 ;; Avoid store forwarding (partial memory) stall penalty by extending
5350 ;; SImode value to DImode through XMM register instead of pushing two
5351 ;; SImode values to stack. Also note that fild loads from memory only.
5353 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5354   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5355         (unsigned_float:X87MODEF
5356           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5357    (clobber (match_scratch:DI 3 "=x"))
5358    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5359   "!TARGET_64BIT
5360    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5361    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5362   "#"
5363   "&& reload_completed"
5364   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5365    (set (match_dup 2) (match_dup 3))
5366    (set (match_dup 0)
5367         (float:X87MODEF (match_dup 2)))]
5368   ""
5369   [(set_attr "type" "multi")
5370    (set_attr "mode" "<MODE>")])
5372 (define_expand "floatunssi<mode>2"
5373   [(parallel
5374      [(set (match_operand:X87MODEF 0 "register_operand")
5375            (unsigned_float:X87MODEF
5376              (match_operand:SI 1 "nonimmediate_operand")))
5377       (clobber (match_scratch:DI 3))
5378       (clobber (match_dup 2))])]
5379   "!TARGET_64BIT
5380    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5381         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5382        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5384   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5385     {
5386       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5387       DONE;
5388     }
5389   else
5390     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5393 (define_expand "floatunsdisf2"
5394   [(use (match_operand:SF 0 "register_operand"))
5395    (use (match_operand:DI 1 "nonimmediate_operand"))]
5396   "TARGET_64BIT && TARGET_SSE_MATH"
5397   "x86_emit_floatuns (operands); DONE;")
5399 (define_expand "floatunsdidf2"
5400   [(use (match_operand:DF 0 "register_operand"))
5401    (use (match_operand:DI 1 "nonimmediate_operand"))]
5402   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5403    && TARGET_SSE2 && TARGET_SSE_MATH"
5405   if (TARGET_64BIT)
5406     x86_emit_floatuns (operands);
5407   else
5408     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5409   DONE;
5412 ;; Load effective address instructions
5414 (define_insn_and_split "*lea<mode>"
5415   [(set (match_operand:SWI48 0 "register_operand" "=r")
5416         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5417   ""
5419   if (SImode_address_operand (operands[1], VOIDmode))
5420     {
5421       gcc_assert (TARGET_64BIT);
5422       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5423     }
5424   else 
5425     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5427   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5428   [(const_int 0)]
5430   machine_mode mode = <MODE>mode;
5431   rtx pat;
5433   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5434      change operands[] array behind our back.  */
5435   pat = PATTERN (curr_insn);
5437   operands[0] = SET_DEST (pat);
5438   operands[1] = SET_SRC (pat);
5440   /* Emit all operations in SImode for zero-extended addresses.  */
5441   if (SImode_address_operand (operands[1], VOIDmode))
5442     mode = SImode;
5444   ix86_split_lea_for_addr (curr_insn, operands, mode);
5446   /* Zero-extend return register to DImode for zero-extended addresses.  */
5447   if (mode != <MODE>mode)
5448     emit_insn (gen_zero_extendsidi2
5449                (operands[0], gen_lowpart (mode, operands[0])));
5451   DONE;
5453   [(set_attr "type" "lea")
5454    (set (attr "mode")
5455      (if_then_else
5456        (match_operand 1 "SImode_address_operand")
5457        (const_string "SI")
5458        (const_string "<MODE>")))])
5460 ;; Add instructions
5462 (define_expand "add<mode>3"
5463   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5464         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5465                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5466   ""
5467   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5469 (define_insn_and_split "*add<dwi>3_doubleword"
5470   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5471         (plus:<DWI>
5472           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5473           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5474                                                         "ro<di>,r<di>")))
5475    (clobber (reg:CC FLAGS_REG))]
5476   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5477   "#"
5478   "reload_completed"
5479   [(parallel [(set (reg:CCC FLAGS_REG)
5480                    (compare:CCC
5481                      (plus:DWIH (match_dup 1) (match_dup 2))
5482                      (match_dup 1)))
5483               (set (match_dup 0)
5484                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5485    (parallel [(set (match_dup 3)
5486                    (plus:DWIH
5487                      (plus:DWIH
5488                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5489                        (match_dup 4))
5490                      (match_dup 5)))
5491               (clobber (reg:CC FLAGS_REG))])]
5493   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5494   if (operands[2] == const0_rtx)
5495     {
5496       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5497       DONE;
5498     }
5501 (define_insn "*add<mode>_1"
5502   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5503         (plus:SWI48
5504           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5505           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5506    (clobber (reg:CC FLAGS_REG))]
5507   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5509   switch (get_attr_type (insn))
5510     {
5511     case TYPE_LEA:
5512       return "#";
5514     case TYPE_INCDEC:
5515       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5516       if (operands[2] == const1_rtx)
5517         return "inc{<imodesuffix>}\t%0";
5518       else
5519         {
5520           gcc_assert (operands[2] == constm1_rtx);
5521           return "dec{<imodesuffix>}\t%0";
5522         }
5524     default:
5525       /* For most processors, ADD is faster than LEA.  This alternative
5526          was added to use ADD as much as possible.  */
5527       if (which_alternative == 2)
5528         std::swap (operands[1], operands[2]);
5529         
5530       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5532         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5534       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5535     }
5537   [(set (attr "type")
5538      (cond [(eq_attr "alternative" "3")
5539               (const_string "lea")
5540             (match_operand:SWI48 2 "incdec_operand")
5541               (const_string "incdec")
5542            ]
5543            (const_string "alu")))
5544    (set (attr "length_immediate")
5545       (if_then_else
5546         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5547         (const_string "1")
5548         (const_string "*")))
5549    (set_attr "mode" "<MODE>")])
5551 ;; It may seem that nonimmediate operand is proper one for operand 1.
5552 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5553 ;; we take care in ix86_binary_operator_ok to not allow two memory
5554 ;; operands so proper swapping will be done in reload.  This allow
5555 ;; patterns constructed from addsi_1 to match.
5557 (define_insn "addsi_1_zext"
5558   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5559         (zero_extend:DI
5560           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5561                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5562    (clobber (reg:CC FLAGS_REG))]
5563   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5565   switch (get_attr_type (insn))
5566     {
5567     case TYPE_LEA:
5568       return "#";
5570     case TYPE_INCDEC:
5571       if (operands[2] == const1_rtx)
5572         return "inc{l}\t%k0";
5573       else
5574         {
5575           gcc_assert (operands[2] == constm1_rtx);
5576           return "dec{l}\t%k0";
5577         }
5579     default:
5580       /* For most processors, ADD is faster than LEA.  This alternative
5581          was added to use ADD as much as possible.  */
5582       if (which_alternative == 1)
5583         std::swap (operands[1], operands[2]);
5585       if (x86_maybe_negate_const_int (&operands[2], SImode))
5586         return "sub{l}\t{%2, %k0|%k0, %2}";
5588       return "add{l}\t{%2, %k0|%k0, %2}";
5589     }
5591   [(set (attr "type")
5592      (cond [(eq_attr "alternative" "2")
5593               (const_string "lea")
5594             (match_operand:SI 2 "incdec_operand")
5595               (const_string "incdec")
5596            ]
5597            (const_string "alu")))
5598    (set (attr "length_immediate")
5599       (if_then_else
5600         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5601         (const_string "1")
5602         (const_string "*")))
5603    (set_attr "mode" "SI")])
5605 (define_insn "*addhi_1"
5606   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5607         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5608                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5609    (clobber (reg:CC FLAGS_REG))]
5610   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5612   switch (get_attr_type (insn))
5613     {
5614     case TYPE_LEA:
5615       return "#";
5617     case TYPE_INCDEC:
5618       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5619       if (operands[2] == const1_rtx)
5620         return "inc{w}\t%0";
5621       else
5622         {
5623           gcc_assert (operands[2] == constm1_rtx);
5624           return "dec{w}\t%0";
5625         }
5627     default:
5628       /* For most processors, ADD is faster than LEA.  This alternative
5629          was added to use ADD as much as possible.  */
5630       if (which_alternative == 2)
5631         std::swap (operands[1], operands[2]);
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (x86_maybe_negate_const_int (&operands[2], HImode))
5635         return "sub{w}\t{%2, %0|%0, %2}";
5637       return "add{w}\t{%2, %0|%0, %2}";
5638     }
5640   [(set (attr "type")
5641      (cond [(eq_attr "alternative" "3")
5642               (const_string "lea")
5643             (match_operand:HI 2 "incdec_operand")
5644               (const_string "incdec")
5645            ]
5646            (const_string "alu")))
5647    (set (attr "length_immediate")
5648       (if_then_else
5649         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5650         (const_string "1")
5651         (const_string "*")))
5652    (set_attr "mode" "HI,HI,HI,SI")])
5654 (define_insn "*addqi_1"
5655   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5656         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5657                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5658    (clobber (reg:CC FLAGS_REG))]
5659   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5661   bool widen = (get_attr_mode (insn) != MODE_QI);
5663   switch (get_attr_type (insn))
5664     {
5665     case TYPE_LEA:
5666       return "#";
5668     case TYPE_INCDEC:
5669       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670       if (operands[2] == const1_rtx)
5671         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5672       else
5673         {
5674           gcc_assert (operands[2] == constm1_rtx);
5675           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5676         }
5678     default:
5679       /* For most processors, ADD is faster than LEA.  These alternatives
5680          were added to use ADD as much as possible.  */
5681       if (which_alternative == 2 || which_alternative == 4)
5682         std::swap (operands[1], operands[2]);
5684       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685       if (x86_maybe_negate_const_int (&operands[2], QImode))
5686         {
5687           if (widen)
5688             return "sub{l}\t{%2, %k0|%k0, %2}";
5689           else
5690             return "sub{b}\t{%2, %0|%0, %2}";
5691         }
5692       if (widen)
5693         return "add{l}\t{%k2, %k0|%k0, %k2}";
5694       else
5695         return "add{b}\t{%2, %0|%0, %2}";
5696     }
5698   [(set (attr "type")
5699      (cond [(eq_attr "alternative" "5")
5700               (const_string "lea")
5701             (match_operand:QI 2 "incdec_operand")
5702               (const_string "incdec")
5703            ]
5704            (const_string "alu")))
5705    (set (attr "length_immediate")
5706       (if_then_else
5707         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5708         (const_string "1")
5709         (const_string "*")))
5710    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5711    ;; Potential partial reg stall on alternatives 3 and 4.
5712    (set (attr "preferred_for_speed")
5713      (cond [(eq_attr "alternative" "3,4")
5714               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5715            (symbol_ref "true")))])
5717 (define_insn "*addqi_1_slp"
5718   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5719         (plus:QI (match_dup 0)
5720                  (match_operand:QI 1 "general_operand" "qn,qm")))
5721    (clobber (reg:CC FLAGS_REG))]
5722   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5723    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5725   switch (get_attr_type (insn))
5726     {
5727     case TYPE_INCDEC:
5728       if (operands[1] == const1_rtx)
5729         return "inc{b}\t%0";
5730       else
5731         {
5732           gcc_assert (operands[1] == constm1_rtx);
5733           return "dec{b}\t%0";
5734         }
5736     default:
5737       if (x86_maybe_negate_const_int (&operands[1], QImode))
5738         return "sub{b}\t{%1, %0|%0, %1}";
5740       return "add{b}\t{%1, %0|%0, %1}";
5741     }
5743   [(set (attr "type")
5744      (if_then_else (match_operand:QI 1 "incdec_operand")
5745         (const_string "incdec")
5746         (const_string "alu1")))
5747    (set (attr "memory")
5748      (if_then_else (match_operand 1 "memory_operand")
5749         (const_string "load")
5750         (const_string "none")))
5751    (set_attr "mode" "QI")])
5753 ;; Split non destructive adds if we cannot use lea.
5754 (define_split
5755   [(set (match_operand:SWI48 0 "register_operand")
5756         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5757                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5758    (clobber (reg:CC FLAGS_REG))]
5759   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5760   [(set (match_dup 0) (match_dup 1))
5761    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5762               (clobber (reg:CC FLAGS_REG))])])
5764 ;; Split non destructive adds if we cannot use lea.
5765 (define_split
5766   [(set (match_operand:DI 0 "register_operand")
5767         (zero_extend:DI
5768           (plus:SI (match_operand:SI 1 "register_operand")
5769                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5770    (clobber (reg:CC FLAGS_REG))]
5771   "TARGET_64BIT
5772    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5773   [(set (match_dup 3) (match_dup 1))
5774    (parallel [(set (match_dup 0)
5775                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5776               (clobber (reg:CC FLAGS_REG))])]
5777   "operands[3] = gen_lowpart (SImode, operands[0]);")
5779 ;; Convert add to the lea pattern to avoid flags dependency.
5780 (define_split
5781   [(set (match_operand:SWI 0 "register_operand")
5782         (plus:SWI (match_operand:SWI 1 "register_operand")
5783                   (match_operand:SWI 2 "<nonmemory_operand>")))
5784    (clobber (reg:CC FLAGS_REG))]
5785   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5786   [(set (match_dup 0)
5787         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5789   if (<MODE>mode != <LEAMODE>mode)
5790     {
5791       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5792       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5793       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5794     }
5797 ;; Convert add to the lea pattern to avoid flags dependency.
5798 (define_split
5799   [(set (match_operand:DI 0 "register_operand")
5800         (zero_extend:DI
5801           (plus:SI (match_operand:SI 1 "register_operand")
5802                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5803    (clobber (reg:CC FLAGS_REG))]
5804   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5805   [(set (match_dup 0)
5806         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5808 (define_insn "*add<mode>_2"
5809   [(set (reg FLAGS_REG)
5810         (compare
5811           (plus:SWI
5812             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5813             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5814           (const_int 0)))
5815    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5816         (plus:SWI (match_dup 1) (match_dup 2)))]
5817   "ix86_match_ccmode (insn, CCGOCmode)
5818    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{<imodesuffix>}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{<imodesuffix>}\t%0";
5829         }
5831     default:
5832       if (which_alternative == 2)
5833         std::swap (operands[1], operands[2]);
5834         
5835       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5837         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5839       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5840     }
5842   [(set (attr "type")
5843      (if_then_else (match_operand:SWI 2 "incdec_operand")
5844         (const_string "incdec")
5845         (const_string "alu")))
5846    (set (attr "length_immediate")
5847       (if_then_else
5848         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5849         (const_string "1")
5850         (const_string "*")))
5851    (set_attr "mode" "<MODE>")])
5853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5854 (define_insn "*addsi_2_zext"
5855   [(set (reg FLAGS_REG)
5856         (compare
5857           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5858                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5859           (const_int 0)))
5860    (set (match_operand:DI 0 "register_operand" "=r,r")
5861         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5862   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5863    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5865   switch (get_attr_type (insn))
5866     {
5867     case TYPE_INCDEC:
5868       if (operands[2] == const1_rtx)
5869         return "inc{l}\t%k0";
5870       else
5871         {
5872           gcc_assert (operands[2] == constm1_rtx);
5873           return "dec{l}\t%k0";
5874         }
5876     default:
5877       if (which_alternative == 1)
5878         std::swap (operands[1], operands[2]);
5880       if (x86_maybe_negate_const_int (&operands[2], SImode))
5881         return "sub{l}\t{%2, %k0|%k0, %2}";
5883       return "add{l}\t{%2, %k0|%k0, %2}";
5884     }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:SI 2 "incdec_operand")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set (attr "length_immediate")
5891       (if_then_else
5892         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5893         (const_string "1")
5894         (const_string "*")))
5895    (set_attr "mode" "SI")])
5897 (define_insn "*add<mode>_3"
5898   [(set (reg FLAGS_REG)
5899         (compare
5900           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5901           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5902    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5903   "ix86_match_ccmode (insn, CCZmode)
5904    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5906   switch (get_attr_type (insn))
5907     {
5908     case TYPE_INCDEC:
5909       if (operands[2] == const1_rtx)
5910         return "inc{<imodesuffix>}\t%0";
5911       else
5912         {
5913           gcc_assert (operands[2] == constm1_rtx);
5914           return "dec{<imodesuffix>}\t%0";
5915         }
5917     default:
5918       if (which_alternative == 1)
5919         std::swap (operands[1], operands[2]);
5921       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5922       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5923         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5925       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5926     }
5928   [(set (attr "type")
5929      (if_then_else (match_operand:SWI 2 "incdec_operand")
5930         (const_string "incdec")
5931         (const_string "alu")))
5932    (set (attr "length_immediate")
5933       (if_then_else
5934         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5935         (const_string "1")
5936         (const_string "*")))
5937    (set_attr "mode" "<MODE>")])
5939 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5940 (define_insn "*addsi_3_zext"
5941   [(set (reg FLAGS_REG)
5942         (compare
5943           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5944           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5945    (set (match_operand:DI 0 "register_operand" "=r,r")
5946         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5947   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5948    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5950   switch (get_attr_type (insn))
5951     {
5952     case TYPE_INCDEC:
5953       if (operands[2] == const1_rtx)
5954         return "inc{l}\t%k0";
5955       else
5956         {
5957           gcc_assert (operands[2] == constm1_rtx);
5958           return "dec{l}\t%k0";
5959         }
5961     default:
5962       if (which_alternative == 1)
5963         std::swap (operands[1], operands[2]);
5965       if (x86_maybe_negate_const_int (&operands[2], SImode))
5966         return "sub{l}\t{%2, %k0|%k0, %2}";
5968       return "add{l}\t{%2, %k0|%k0, %2}";
5969     }
5971   [(set (attr "type")
5972      (if_then_else (match_operand:SI 2 "incdec_operand")
5973         (const_string "incdec")
5974         (const_string "alu")))
5975    (set (attr "length_immediate")
5976       (if_then_else
5977         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5978         (const_string "1")
5979         (const_string "*")))
5980    (set_attr "mode" "SI")])
5982 ; For comparisons against 1, -1 and 128, we may generate better code
5983 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5984 ; is matched then.  We can't accept general immediate, because for
5985 ; case of overflows,  the result is messed up.
5986 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5987 ; only for comparisons not depending on it.
5989 (define_insn "*adddi_4"
5990   [(set (reg FLAGS_REG)
5991         (compare
5992           (match_operand:DI 1 "nonimmediate_operand" "0")
5993           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5994    (clobber (match_scratch:DI 0 "=rm"))]
5995   "TARGET_64BIT
5996    && ix86_match_ccmode (insn, CCGCmode)"
5998   switch (get_attr_type (insn))
5999     {
6000     case TYPE_INCDEC:
6001       if (operands[2] == constm1_rtx)
6002         return "inc{q}\t%0";
6003       else
6004         {
6005           gcc_assert (operands[2] == const1_rtx);
6006           return "dec{q}\t%0";
6007         }
6009     default:
6010       if (x86_maybe_negate_const_int (&operands[2], DImode))
6011         return "add{q}\t{%2, %0|%0, %2}";
6013       return "sub{q}\t{%2, %0|%0, %2}";
6014     }
6016   [(set (attr "type")
6017      (if_then_else (match_operand:DI 2 "incdec_operand")
6018         (const_string "incdec")
6019         (const_string "alu")))
6020    (set (attr "length_immediate")
6021       (if_then_else
6022         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6023         (const_string "1")
6024         (const_string "*")))
6025    (set_attr "mode" "DI")])
6027 ; For comparisons against 1, -1 and 128, we may generate better code
6028 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6029 ; is matched then.  We can't accept general immediate, because for
6030 ; case of overflows,  the result is messed up.
6031 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6032 ; only for comparisons not depending on it.
6034 (define_insn "*add<mode>_4"
6035   [(set (reg FLAGS_REG)
6036         (compare
6037           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6038           (match_operand:SWI124 2 "const_int_operand" "n")))
6039    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6040   "ix86_match_ccmode (insn, CCGCmode)"
6042   switch (get_attr_type (insn))
6043     {
6044     case TYPE_INCDEC:
6045       if (operands[2] == constm1_rtx)
6046         return "inc{<imodesuffix>}\t%0";
6047       else
6048         {
6049           gcc_assert (operands[2] == const1_rtx);
6050           return "dec{<imodesuffix>}\t%0";
6051         }
6053     default:
6054       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6057       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6058     }
6060   [(set (attr "type")
6061      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6062         (const_string "incdec")
6063         (const_string "alu")))
6064    (set (attr "length_immediate")
6065       (if_then_else
6066         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6067         (const_string "1")
6068         (const_string "*")))
6069    (set_attr "mode" "<MODE>")])
6071 (define_insn "*add<mode>_5"
6072   [(set (reg FLAGS_REG)
6073         (compare
6074           (plus:SWI
6075             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6076             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6077           (const_int 0)))
6078    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6079   "ix86_match_ccmode (insn, CCGOCmode)
6080    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6082   switch (get_attr_type (insn))
6083     {
6084     case TYPE_INCDEC:
6085       if (operands[2] == const1_rtx)
6086         return "inc{<imodesuffix>}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[2] == constm1_rtx);
6090           return "dec{<imodesuffix>}\t%0";
6091         }
6093     default:
6094       if (which_alternative == 1)
6095         std::swap (operands[1], operands[2]);
6097       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6098       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6099         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6101       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6102     }
6104   [(set (attr "type")
6105      (if_then_else (match_operand:SWI 2 "incdec_operand")
6106         (const_string "incdec")
6107         (const_string "alu")))
6108    (set (attr "length_immediate")
6109       (if_then_else
6110         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6111         (const_string "1")
6112         (const_string "*")))
6113    (set_attr "mode" "<MODE>")])
6115 (define_insn "addqi_ext_1"
6116   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6117                          (const_int 8)
6118                          (const_int 8))
6119         (plus:SI
6120           (zero_extract:SI
6121             (match_operand 1 "ext_register_operand" "0,0")
6122             (const_int 8)
6123             (const_int 8))
6124           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6125    (clobber (reg:CC FLAGS_REG))]
6126   ""
6128   switch (get_attr_type (insn))
6129     {
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return "inc{b}\t%h0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return "dec{b}\t%h0";
6137         }
6139     default:
6140       return "add{b}\t{%2, %h0|%h0, %2}";
6141     }
6143   [(set_attr "isa" "*,nox64")
6144    (set (attr "type")
6145      (if_then_else (match_operand:QI 2 "incdec_operand")
6146         (const_string "incdec")
6147         (const_string "alu")))
6148    (set_attr "modrm" "1")
6149    (set_attr "mode" "QI")])
6151 (define_insn "*addqi_ext_2"
6152   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6153                          (const_int 8)
6154                          (const_int 8))
6155         (plus:SI
6156           (zero_extract:SI
6157             (match_operand 1 "ext_register_operand" "%0")
6158             (const_int 8)
6159             (const_int 8))
6160           (zero_extract:SI
6161             (match_operand 2 "ext_register_operand" "Q")
6162             (const_int 8)
6163             (const_int 8))))
6164    (clobber (reg:CC FLAGS_REG))]
6165   ""
6166   "add{b}\t{%h2, %h0|%h0, %h2}"
6167   [(set_attr "type" "alu")
6168    (set_attr "mode" "QI")])
6170 ;; Add with jump on overflow.
6171 (define_expand "addv<mode>4"
6172   [(parallel [(set (reg:CCO FLAGS_REG)
6173                    (eq:CCO (plus:<DWI>
6174                               (sign_extend:<DWI>
6175                                  (match_operand:SWI 1 "nonimmediate_operand"))
6176                               (match_dup 4))
6177                            (sign_extend:<DWI>
6178                               (plus:SWI (match_dup 1)
6179                                         (match_operand:SWI 2
6180                                            "<general_operand>")))))
6181               (set (match_operand:SWI 0 "register_operand")
6182                    (plus:SWI (match_dup 1) (match_dup 2)))])
6183    (set (pc) (if_then_else
6184                (eq (reg:CCO FLAGS_REG) (const_int 0))
6185                (label_ref (match_operand 3))
6186                (pc)))]
6187   ""
6189   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6190   if (CONST_INT_P (operands[2]))
6191     operands[4] = operands[2];
6192   else
6193     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6196 (define_insn "*addv<mode>4"
6197   [(set (reg:CCO FLAGS_REG)
6198         (eq:CCO (plus:<DWI>
6199                    (sign_extend:<DWI>
6200                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6201                    (sign_extend:<DWI>
6202                       (match_operand:SWI 2 "<general_sext_operand>"
6203                                            "<r>mWe,<r>We")))
6204                 (sign_extend:<DWI>
6205                    (plus:SWI (match_dup 1) (match_dup 2)))))
6206    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6207         (plus:SWI (match_dup 1) (match_dup 2)))]
6208   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6209   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6210   [(set_attr "type" "alu")
6211    (set_attr "mode" "<MODE>")])
6213 (define_insn "*addv<mode>4_1"
6214   [(set (reg:CCO FLAGS_REG)
6215         (eq:CCO (plus:<DWI>
6216                    (sign_extend:<DWI>
6217                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6218                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6219                 (sign_extend:<DWI>
6220                    (plus:SWI (match_dup 1)
6221                              (match_operand:SWI 2 "x86_64_immediate_operand"
6222                                                   "<i>")))))
6223    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6224         (plus:SWI (match_dup 1) (match_dup 2)))]
6225   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6226    && CONST_INT_P (operands[2])
6227    && INTVAL (operands[2]) == INTVAL (operands[3])"
6228   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6229   [(set_attr "type" "alu")
6230    (set_attr "mode" "<MODE>")
6231    (set (attr "length_immediate")
6232         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6233                   (const_string "1")
6234                (match_test "<MODE_SIZE> == 8")
6235                   (const_string "4")]
6236               (const_string "<MODE_SIZE>")))])
6238 (define_expand "uaddv<mode>4"
6239   [(parallel [(set (reg:CCC FLAGS_REG)
6240                    (compare:CCC
6241                      (plus:SWI
6242                        (match_operand:SWI 1 "nonimmediate_operand")
6243                        (match_operand:SWI 2 "<general_operand>"))
6244                      (match_dup 1)))
6245               (set (match_operand:SWI 0 "register_operand")
6246                    (plus:SWI (match_dup 1) (match_dup 2)))])
6247    (set (pc) (if_then_else
6248                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6249                (label_ref (match_operand 3))
6250                (pc)))]
6251   ""
6252   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6254 ;; The lea patterns for modes less than 32 bits need to be matched by
6255 ;; several insns converted to real lea by splitters.
6257 (define_insn_and_split "*lea<mode>_general_1"
6258   [(set (match_operand:SWI12 0 "register_operand" "=r")
6259         (plus:SWI12
6260           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6261                       (match_operand:SWI12 2 "register_operand" "r"))
6262           (match_operand:SWI12 3 "immediate_operand" "i")))]
6263   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6264   "#"
6265   "&& reload_completed"
6266   [(set (match_dup 0)
6267         (plus:SI
6268           (plus:SI (match_dup 1) (match_dup 2))
6269           (match_dup 3)))]
6271   operands[0] = gen_lowpart (SImode, operands[0]);
6272   operands[1] = gen_lowpart (SImode, operands[1]);
6273   operands[2] = gen_lowpart (SImode, operands[2]);
6274   operands[3] = gen_lowpart (SImode, operands[3]);
6276   [(set_attr "type" "lea")
6277    (set_attr "mode" "SI")])
6279 (define_insn_and_split "*lea<mode>_general_2"
6280   [(set (match_operand:SWI12 0 "register_operand" "=r")
6281         (plus:SWI12
6282           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6283                       (match_operand 2 "const248_operand" "n"))
6284           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6285   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6286   "#"
6287   "&& reload_completed"
6288   [(set (match_dup 0)
6289         (plus:SI
6290           (mult:SI (match_dup 1) (match_dup 2))
6291           (match_dup 3)))]
6293   operands[0] = gen_lowpart (SImode, operands[0]);
6294   operands[1] = gen_lowpart (SImode, operands[1]);
6295   operands[3] = gen_lowpart (SImode, operands[3]);
6297   [(set_attr "type" "lea")
6298    (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea<mode>_general_3"
6301   [(set (match_operand:SWI12 0 "register_operand" "=r")
6302         (plus:SWI12
6303           (plus:SWI12
6304             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6305                         (match_operand 2 "const248_operand" "n"))
6306             (match_operand:SWI12 3 "register_operand" "r"))
6307           (match_operand:SWI12 4 "immediate_operand" "i")))]
6308   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6309   "#"
6310   "&& reload_completed"
6311   [(set (match_dup 0)
6312         (plus:SI
6313           (plus:SI
6314             (mult:SI (match_dup 1) (match_dup 2))
6315             (match_dup 3))
6316           (match_dup 4)))]
6318   operands[0] = gen_lowpart (SImode, operands[0]);
6319   operands[1] = gen_lowpart (SImode, operands[1]);
6320   operands[3] = gen_lowpart (SImode, operands[3]);
6321   operands[4] = gen_lowpart (SImode, operands[4]);
6323   [(set_attr "type" "lea")
6324    (set_attr "mode" "SI")])
6326 (define_insn_and_split "*lea<mode>_general_4"
6327   [(set (match_operand:SWI12 0 "register_operand" "=r")
6328         (any_or:SWI12
6329           (ashift:SWI12
6330             (match_operand:SWI12 1 "index_register_operand" "l")
6331             (match_operand 2 "const_0_to_3_operand" "n"))
6332           (match_operand 3 "const_int_operand" "n")))]
6333   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6334    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6335        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6336   "#"
6337   "&& reload_completed"
6338   [(set (match_dup 0)
6339         (plus:SI
6340           (mult:SI (match_dup 1) (match_dup 2))
6341           (match_dup 3)))]
6343   operands[0] = gen_lowpart (SImode, operands[0]);
6344   operands[1] = gen_lowpart (SImode, operands[1]);
6345   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6347   [(set_attr "type" "lea")
6348    (set_attr "mode" "SI")])
6350 (define_insn_and_split "*lea<mode>_general_4"
6351   [(set (match_operand:SWI48 0 "register_operand" "=r")
6352         (any_or:SWI48
6353           (ashift:SWI48
6354             (match_operand:SWI48 1 "index_register_operand" "l")
6355             (match_operand 2 "const_0_to_3_operand" "n"))
6356           (match_operand 3 "const_int_operand" "n")))]
6357   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6358    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6359   "#"
6360   "&& reload_completed"
6361   [(set (match_dup 0)
6362         (plus:SWI48
6363           (mult:SWI48 (match_dup 1) (match_dup 2))
6364           (match_dup 3)))]
6365   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6366   [(set_attr "type" "lea")
6367    (set_attr "mode" "<MODE>")])
6369 ;; Subtract instructions
6371 (define_expand "sub<mode>3"
6372   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6373         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6374                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6375   ""
6376   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6378 (define_insn_and_split "*sub<dwi>3_doubleword"
6379   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6380         (minus:<DWI>
6381           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6382           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6383                                                         "ro<di>,r<di>")))
6384    (clobber (reg:CC FLAGS_REG))]
6385   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6386   "#"
6387   "reload_completed"
6388   [(parallel [(set (reg:CC FLAGS_REG)
6389                    (compare:CC (match_dup 1) (match_dup 2)))
6390               (set (match_dup 0)
6391                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6392    (parallel [(set (match_dup 3)
6393                    (minus:DWIH
6394                      (minus:DWIH
6395                        (match_dup 4)
6396                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6397                      (match_dup 5)))
6398               (clobber (reg:CC FLAGS_REG))])]
6400   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6401   if (operands[2] == const0_rtx)
6402     {
6403       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6404       DONE;
6405     }
6408 (define_insn "*sub<mode>_1"
6409   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6410         (minus:SWI
6411           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6412           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6413    (clobber (reg:CC FLAGS_REG))]
6414   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416   [(set_attr "type" "alu")
6417    (set_attr "mode" "<MODE>")])
6419 (define_insn "*subsi_1_zext"
6420   [(set (match_operand:DI 0 "register_operand" "=r")
6421         (zero_extend:DI
6422           (minus:SI (match_operand:SI 1 "register_operand" "0")
6423                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6424    (clobber (reg:CC FLAGS_REG))]
6425   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6426   "sub{l}\t{%2, %k0|%k0, %2}"
6427   [(set_attr "type" "alu")
6428    (set_attr "mode" "SI")])
6430 (define_insn "*subqi_1_slp"
6431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6432         (minus:QI (match_dup 0)
6433                   (match_operand:QI 1 "general_operand" "qn,qm")))
6434    (clobber (reg:CC FLAGS_REG))]
6435   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6436    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6437   "sub{b}\t{%1, %0|%0, %1}"
6438   [(set_attr "type" "alu1")
6439    (set_attr "mode" "QI")])
6441 (define_insn "*sub<mode>_2"
6442   [(set (reg FLAGS_REG)
6443         (compare
6444           (minus:SWI
6445             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6446             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6447           (const_int 0)))
6448    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449         (minus:SWI (match_dup 1) (match_dup 2)))]
6450   "ix86_match_ccmode (insn, CCGOCmode)
6451    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6452   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6453   [(set_attr "type" "alu")
6454    (set_attr "mode" "<MODE>")])
6456 (define_insn "*subsi_2_zext"
6457   [(set (reg FLAGS_REG)
6458         (compare
6459           (minus:SI (match_operand:SI 1 "register_operand" "0")
6460                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6461           (const_int 0)))
6462    (set (match_operand:DI 0 "register_operand" "=r")
6463         (zero_extend:DI
6464           (minus:SI (match_dup 1)
6465                     (match_dup 2))))]
6466   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6467    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6468   "sub{l}\t{%2, %k0|%k0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "SI")])
6472 ;; Subtract with jump on overflow.
6473 (define_expand "subv<mode>4"
6474   [(parallel [(set (reg:CCO FLAGS_REG)
6475                    (eq:CCO (minus:<DWI>
6476                               (sign_extend:<DWI>
6477                                  (match_operand:SWI 1 "nonimmediate_operand"))
6478                               (match_dup 4))
6479                            (sign_extend:<DWI>
6480                               (minus:SWI (match_dup 1)
6481                                          (match_operand:SWI 2
6482                                             "<general_operand>")))))
6483               (set (match_operand:SWI 0 "register_operand")
6484                    (minus:SWI (match_dup 1) (match_dup 2)))])
6485    (set (pc) (if_then_else
6486                (eq (reg:CCO FLAGS_REG) (const_int 0))
6487                (label_ref (match_operand 3))
6488                (pc)))]
6489   ""
6491   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6492   if (CONST_INT_P (operands[2]))
6493     operands[4] = operands[2];
6494   else
6495     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6498 (define_insn "*subv<mode>4"
6499   [(set (reg:CCO FLAGS_REG)
6500         (eq:CCO (minus:<DWI>
6501                    (sign_extend:<DWI>
6502                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6503                    (sign_extend:<DWI>
6504                       (match_operand:SWI 2 "<general_sext_operand>"
6505                                            "<r>We,<r>m")))
6506                 (sign_extend:<DWI>
6507                    (minus:SWI (match_dup 1) (match_dup 2)))))
6508    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6509         (minus:SWI (match_dup 1) (match_dup 2)))]
6510   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6511   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6512   [(set_attr "type" "alu")
6513    (set_attr "mode" "<MODE>")])
6515 (define_insn "*subv<mode>4_1"
6516   [(set (reg:CCO FLAGS_REG)
6517         (eq:CCO (minus:<DWI>
6518                    (sign_extend:<DWI>
6519                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6520                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6521                 (sign_extend:<DWI>
6522                    (minus:SWI (match_dup 1)
6523                               (match_operand:SWI 2 "x86_64_immediate_operand"
6524                                                    "<i>")))))
6525    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6526         (minus:SWI (match_dup 1) (match_dup 2)))]
6527   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6528    && CONST_INT_P (operands[2])
6529    && INTVAL (operands[2]) == INTVAL (operands[3])"
6530   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6531   [(set_attr "type" "alu")
6532    (set_attr "mode" "<MODE>")
6533    (set (attr "length_immediate")
6534         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6535                   (const_string "1")
6536                (match_test "<MODE_SIZE> == 8")
6537                   (const_string "4")]
6538               (const_string "<MODE_SIZE>")))])
6540 (define_expand "usubv<mode>4"
6541   [(parallel [(set (reg:CC FLAGS_REG)
6542                    (compare:CC
6543                      (match_operand:SWI 1 "nonimmediate_operand")
6544                      (match_operand:SWI 2 "<general_operand>")))
6545               (set (match_operand:SWI 0 "register_operand")
6546                    (minus:SWI (match_dup 1) (match_dup 2)))])
6547    (set (pc) (if_then_else
6548                (ltu (reg:CC FLAGS_REG) (const_int 0))
6549                (label_ref (match_operand 3))
6550                (pc)))]
6551   ""
6552   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6554 (define_insn "*sub<mode>_3"
6555   [(set (reg FLAGS_REG)
6556         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6557                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6558    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6559         (minus:SWI (match_dup 1) (match_dup 2)))]
6560   "ix86_match_ccmode (insn, CCmode)
6561    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6562   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "mode" "<MODE>")])
6566 (define_insn "*subsi_3_zext"
6567   [(set (reg FLAGS_REG)
6568         (compare (match_operand:SI 1 "register_operand" "0")
6569                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6570    (set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (minus:SI (match_dup 1)
6573                     (match_dup 2))))]
6574   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6575    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576   "sub{l}\t{%2, %1|%1, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6580 ;; Add with carry and subtract with borrow
6582 (define_insn "add<mode>3_carry"
6583   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6584         (plus:SWI
6585           (plus:SWI
6586             (match_operator:SWI 4 "ix86_carry_flag_operator"
6587              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6588             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6589           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6590    (clobber (reg:CC FLAGS_REG))]
6591   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6592   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6593   [(set_attr "type" "alu")
6594    (set_attr "use_carry" "1")
6595    (set_attr "pent_pair" "pu")
6596    (set_attr "mode" "<MODE>")])
6598 (define_insn "*addsi3_carry_zext"
6599   [(set (match_operand:DI 0 "register_operand" "=r")
6600         (zero_extend:DI
6601           (plus:SI
6602             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6603                       [(reg FLAGS_REG) (const_int 0)])
6604                      (match_operand:SI 1 "register_operand" "%0"))
6605             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6606    (clobber (reg:CC FLAGS_REG))]
6607   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6608   "adc{l}\t{%2, %k0|%k0, %2}"
6609   [(set_attr "type" "alu")
6610    (set_attr "use_carry" "1")
6611    (set_attr "pent_pair" "pu")
6612    (set_attr "mode" "SI")])
6614 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6616 (define_insn "addcarry<mode>"
6617   [(set (reg:CCC FLAGS_REG)
6618         (compare:CCC
6619           (plus:SWI48
6620             (plus:SWI48
6621               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6622                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6623               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6624             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6625           (match_dup 1)))
6626    (set (match_operand:SWI48 0 "register_operand" "=r")
6627         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6628                                  [(match_dup 3) (const_int 0)])
6629                                 (match_dup 1))
6630                     (match_dup 2)))]
6631   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6632   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "use_carry" "1")
6635    (set_attr "pent_pair" "pu")
6636    (set_attr "mode" "<MODE>")])
6638 (define_insn "sub<mode>3_carry"
6639   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6640         (minus:SWI
6641           (minus:SWI
6642             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6643             (match_operator:SWI 4 "ix86_carry_flag_operator"
6644              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6645           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6646    (clobber (reg:CC FLAGS_REG))]
6647   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6648   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6649   [(set_attr "type" "alu")
6650    (set_attr "use_carry" "1")
6651    (set_attr "pent_pair" "pu")
6652    (set_attr "mode" "<MODE>")])
6654 (define_insn "*subsi3_carry_zext"
6655   [(set (match_operand:DI 0 "register_operand" "=r")
6656         (zero_extend:DI
6657           (minus:SI
6658             (minus:SI
6659               (match_operand:SI 1 "register_operand" "0")
6660               (match_operator:SI 3 "ix86_carry_flag_operator"
6661                [(reg FLAGS_REG) (const_int 0)]))
6662             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sbb{l}\t{%2, %k0|%k0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "use_carry" "1")
6668    (set_attr "pent_pair" "pu")
6669    (set_attr "mode" "SI")])
6671 (define_insn "subborrow<mode>"
6672   [(set (reg:CCC FLAGS_REG)
6673         (compare:CCC
6674           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6675           (plus:SWI48
6676             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6677              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6678             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6679    (set (match_operand:SWI48 0 "register_operand" "=r")
6680         (minus:SWI48 (minus:SWI48 (match_dup 1)
6681                                   (match_op_dup 4
6682                                    [(match_dup 3) (const_int 0)]))
6683                      (match_dup 2)))]
6684   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6685   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "use_carry" "1")
6688    (set_attr "pent_pair" "pu")
6689    (set_attr "mode" "<MODE>")])
6691 ;; Overflow setting add instructions
6693 (define_expand "addqi3_cconly_overflow"
6694   [(parallel
6695      [(set (reg:CCC FLAGS_REG)
6696            (compare:CCC
6697              (plus:QI
6698                (match_operand:QI 0 "nonimmediate_operand")
6699                (match_operand:QI 1 "general_operand"))
6700              (match_dup 0)))
6701       (clobber (match_scratch:QI 2))])]
6702   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6704 (define_insn "*add<mode>3_cconly_overflow_1"
6705   [(set (reg:CCC FLAGS_REG)
6706         (compare:CCC
6707           (plus:SWI
6708             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6709             (match_operand:SWI 2 "<general_operand>" "<g>"))
6710           (match_dup 1)))
6711    (clobber (match_scratch:SWI 0 "=<r>"))]
6712   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6714   [(set_attr "type" "alu")
6715    (set_attr "mode" "<MODE>")])
6717 (define_insn "*add<mode>3_cconly_overflow_2"
6718   [(set (reg:CCC FLAGS_REG)
6719         (compare:CCC
6720           (plus:SWI
6721             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6722             (match_operand:SWI 2 "<general_operand>" "<g>"))
6723           (match_dup 2)))
6724    (clobber (match_scratch:SWI 0 "=<r>"))]
6725   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6726   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6727   [(set_attr "type" "alu")
6728    (set_attr "mode" "<MODE>")])
6730 (define_insn "*add<mode>3_cc_overflow_1"
6731   [(set (reg:CCC FLAGS_REG)
6732         (compare:CCC
6733             (plus:SWI
6734                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6735                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6736             (match_dup 1)))
6737    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6738         (plus:SWI (match_dup 1) (match_dup 2)))]
6739   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6740   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6741   [(set_attr "type" "alu")
6742    (set_attr "mode" "<MODE>")])
6744 (define_insn "*add<mode>3_cc_overflow_2"
6745   [(set (reg:CCC FLAGS_REG)
6746         (compare:CCC
6747             (plus:SWI
6748                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6749                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6750             (match_dup 2)))
6751    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6752         (plus:SWI (match_dup 1) (match_dup 2)))]
6753   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6754   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "<MODE>")])
6758 (define_insn "*addsi3_zext_cc_overflow_1"
6759   [(set (reg:CCC FLAGS_REG)
6760         (compare:CCC
6761           (plus:SI
6762             (match_operand:SI 1 "nonimmediate_operand" "%0")
6763             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6764           (match_dup 1)))
6765    (set (match_operand:DI 0 "register_operand" "=r")
6766         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6767   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6768   "add{l}\t{%2, %k0|%k0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "mode" "SI")])
6772 (define_insn "*addsi3_zext_cc_overflow_2"
6773   [(set (reg:CCC FLAGS_REG)
6774         (compare:CCC
6775           (plus:SI
6776             (match_operand:SI 1 "nonimmediate_operand" "%0")
6777             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6778           (match_dup 2)))
6779    (set (match_operand:DI 0 "register_operand" "=r")
6780         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6781   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6782   "add{l}\t{%2, %k0|%k0, %2}"
6783   [(set_attr "type" "alu")
6784    (set_attr "mode" "SI")])
6786 ;; The patterns that match these are at the end of this file.
6788 (define_expand "<plusminus_insn>xf3"
6789   [(set (match_operand:XF 0 "register_operand")
6790         (plusminus:XF
6791           (match_operand:XF 1 "register_operand")
6792           (match_operand:XF 2 "register_operand")))]
6793   "TARGET_80387")
6795 (define_expand "<plusminus_insn><mode>3"
6796   [(set (match_operand:MODEF 0 "register_operand")
6797         (plusminus:MODEF
6798           (match_operand:MODEF 1 "register_operand")
6799           (match_operand:MODEF 2 "nonimmediate_operand")))]
6800   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6801     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6803 ;; Multiply instructions
6805 (define_expand "mul<mode>3"
6806   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6807                    (mult:SWIM248
6808                      (match_operand:SWIM248 1 "register_operand")
6809                      (match_operand:SWIM248 2 "<general_operand>")))
6810               (clobber (reg:CC FLAGS_REG))])])
6812 (define_expand "mulqi3"
6813   [(parallel [(set (match_operand:QI 0 "register_operand")
6814                    (mult:QI
6815                      (match_operand:QI 1 "register_operand")
6816                      (match_operand:QI 2 "nonimmediate_operand")))
6817               (clobber (reg:CC FLAGS_REG))])]
6818   "TARGET_QIMODE_MATH")
6820 ;; On AMDFAM10
6821 ;; IMUL reg32/64, reg32/64, imm8        Direct
6822 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6823 ;; IMUL reg32/64, reg32/64, imm32       Direct
6824 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6825 ;; IMUL reg32/64, reg32/64              Direct
6826 ;; IMUL reg32/64, mem32/64              Direct
6828 ;; On BDVER1, all above IMULs use DirectPath
6830 ;; On AMDFAM10
6831 ;; IMUL reg16, reg16, imm8      VectorPath
6832 ;; IMUL reg16, mem16, imm8      VectorPath
6833 ;; IMUL reg16, reg16, imm16     VectorPath
6834 ;; IMUL reg16, mem16, imm16     VectorPath
6835 ;; IMUL reg16, reg16            Direct
6836 ;; IMUL reg16, mem16            Direct
6838 ;; On BDVER1, all HI MULs use DoublePath
6840 (define_insn "*mul<mode>3_1"
6841   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6842         (mult:SWIM248
6843           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6844           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6845    (clobber (reg:CC FLAGS_REG))]
6846   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6847   "@
6848    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6849    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6850    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6851   [(set_attr "type" "imul")
6852    (set_attr "prefix_0f" "0,0,1")
6853    (set (attr "athlon_decode")
6854         (cond [(eq_attr "cpu" "athlon")
6855                   (const_string "vector")
6856                (eq_attr "alternative" "1")
6857                   (const_string "vector")
6858                (and (eq_attr "alternative" "2")
6859                     (ior (match_test "<MODE>mode == HImode")
6860                          (match_operand 1 "memory_operand")))
6861                   (const_string "vector")]
6862               (const_string "direct")))
6863    (set (attr "amdfam10_decode")
6864         (cond [(and (eq_attr "alternative" "0,1")
6865                     (ior (match_test "<MODE>mode == HImode")
6866                          (match_operand 1 "memory_operand")))
6867                   (const_string "vector")]
6868               (const_string "direct")))
6869    (set (attr "bdver1_decode")
6870         (if_then_else
6871           (match_test "<MODE>mode == HImode")
6872             (const_string "double")
6873             (const_string "direct")))
6874    (set_attr "mode" "<MODE>")])
6876 (define_insn "*mulsi3_1_zext"
6877   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6878         (zero_extend:DI
6879           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6880                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6881    (clobber (reg:CC FLAGS_REG))]
6882   "TARGET_64BIT
6883    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884   "@
6885    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6886    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6887    imul{l}\t{%2, %k0|%k0, %2}"
6888   [(set_attr "type" "imul")
6889    (set_attr "prefix_0f" "0,0,1")
6890    (set (attr "athlon_decode")
6891         (cond [(eq_attr "cpu" "athlon")
6892                   (const_string "vector")
6893                (eq_attr "alternative" "1")
6894                   (const_string "vector")
6895                (and (eq_attr "alternative" "2")
6896                     (match_operand 1 "memory_operand"))
6897                   (const_string "vector")]
6898               (const_string "direct")))
6899    (set (attr "amdfam10_decode")
6900         (cond [(and (eq_attr "alternative" "0,1")
6901                     (match_operand 1 "memory_operand"))
6902                   (const_string "vector")]
6903               (const_string "direct")))
6904    (set_attr "bdver1_decode" "direct")
6905    (set_attr "mode" "SI")])
6907 ;;On AMDFAM10 and BDVER1
6908 ;; MUL reg8     Direct
6909 ;; MUL mem8     Direct
6911 (define_insn "*mulqi3_1"
6912   [(set (match_operand:QI 0 "register_operand" "=a")
6913         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6914                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "TARGET_QIMODE_MATH
6917    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6918   "mul{b}\t%2"
6919   [(set_attr "type" "imul")
6920    (set_attr "length_immediate" "0")
6921    (set (attr "athlon_decode")
6922      (if_then_else (eq_attr "cpu" "athlon")
6923         (const_string "vector")
6924         (const_string "direct")))
6925    (set_attr "amdfam10_decode" "direct")
6926    (set_attr "bdver1_decode" "direct")
6927    (set_attr "mode" "QI")])
6929 ;; Multiply with jump on overflow.
6930 (define_expand "mulv<mode>4"
6931   [(parallel [(set (reg:CCO FLAGS_REG)
6932                    (eq:CCO (mult:<DWI>
6933                               (sign_extend:<DWI>
6934                                  (match_operand:SWI248 1 "register_operand"))
6935                               (match_dup 4))
6936                            (sign_extend:<DWI>
6937                               (mult:SWI248 (match_dup 1)
6938                                            (match_operand:SWI248 2
6939                                               "<general_operand>")))))
6940               (set (match_operand:SWI248 0 "register_operand")
6941                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6942    (set (pc) (if_then_else
6943                (eq (reg:CCO FLAGS_REG) (const_int 0))
6944                (label_ref (match_operand 3))
6945                (pc)))]
6946   ""
6948   if (CONST_INT_P (operands[2]))
6949     operands[4] = operands[2];
6950   else
6951     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6954 (define_insn "*mulv<mode>4"
6955   [(set (reg:CCO FLAGS_REG)
6956         (eq:CCO (mult:<DWI>
6957                    (sign_extend:<DWI>
6958                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6959                    (sign_extend:<DWI>
6960                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6961                 (sign_extend:<DWI>
6962                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6963    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6964         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6965   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966   "@
6967    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6968    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6969   [(set_attr "type" "imul")
6970    (set_attr "prefix_0f" "0,1")
6971    (set (attr "athlon_decode")
6972         (cond [(eq_attr "cpu" "athlon")
6973                   (const_string "vector")
6974                (eq_attr "alternative" "0")
6975                   (const_string "vector")
6976                (and (eq_attr "alternative" "1")
6977                     (match_operand 1 "memory_operand"))
6978                   (const_string "vector")]
6979               (const_string "direct")))
6980    (set (attr "amdfam10_decode")
6981         (cond [(and (eq_attr "alternative" "1")
6982                     (match_operand 1 "memory_operand"))
6983                   (const_string "vector")]
6984               (const_string "direct")))
6985    (set_attr "bdver1_decode" "direct")
6986    (set_attr "mode" "<MODE>")])
6988 (define_insn "*mulvhi4"
6989   [(set (reg:CCO FLAGS_REG)
6990         (eq:CCO (mult:SI
6991                    (sign_extend:SI
6992                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6993                    (sign_extend:SI
6994                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6995                 (sign_extend:SI
6996                    (mult:HI (match_dup 1) (match_dup 2)))))
6997    (set (match_operand:HI 0 "register_operand" "=r")
6998         (mult:HI (match_dup 1) (match_dup 2)))]
6999   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7000   "imul{w}\t{%2, %0|%0, %2}"
7001   [(set_attr "type" "imul")
7002    (set_attr "prefix_0f" "1")
7003    (set_attr "athlon_decode" "vector")
7004    (set_attr "amdfam10_decode" "direct")
7005    (set_attr "bdver1_decode" "double")
7006    (set_attr "mode" "HI")])
7008 (define_insn "*mulv<mode>4_1"
7009   [(set (reg:CCO FLAGS_REG)
7010         (eq:CCO (mult:<DWI>
7011                    (sign_extend:<DWI>
7012                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7013                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7014                 (sign_extend:<DWI>
7015                    (mult:SWI248 (match_dup 1)
7016                                 (match_operand:SWI248 2
7017                                    "<immediate_operand>" "K,<i>")))))
7018    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7019         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7020   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7021    && CONST_INT_P (operands[2])
7022    && INTVAL (operands[2]) == INTVAL (operands[3])"
7023   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7024   [(set_attr "type" "imul")
7025    (set (attr "prefix_0f")
7026         (if_then_else
7027           (match_test "<MODE>mode == HImode")
7028             (const_string "0")
7029             (const_string "*")))
7030    (set (attr "athlon_decode")
7031         (cond [(eq_attr "cpu" "athlon")
7032                   (const_string "vector")
7033                (eq_attr "alternative" "1")
7034                   (const_string "vector")]
7035               (const_string "direct")))
7036    (set (attr "amdfam10_decode")
7037         (cond [(ior (match_test "<MODE>mode == HImode")
7038                     (match_operand 1 "memory_operand"))
7039                   (const_string "vector")]
7040               (const_string "direct")))
7041    (set (attr "bdver1_decode")
7042         (if_then_else
7043           (match_test "<MODE>mode == HImode")
7044             (const_string "double")
7045             (const_string "direct")))
7046    (set_attr "mode" "<MODE>")
7047    (set (attr "length_immediate")
7048         (cond [(eq_attr "alternative" "0")
7049                   (const_string "1")
7050                (match_test "<MODE_SIZE> == 8")
7051                   (const_string "4")]
7052               (const_string "<MODE_SIZE>")))])
7054 (define_expand "umulv<mode>4"
7055   [(parallel [(set (reg:CCO FLAGS_REG)
7056                    (eq:CCO (mult:<DWI>
7057                               (zero_extend:<DWI>
7058                                  (match_operand:SWI248 1
7059                                                       "nonimmediate_operand"))
7060                               (zero_extend:<DWI>
7061                                  (match_operand:SWI248 2
7062                                                       "nonimmediate_operand")))
7063                            (zero_extend:<DWI>
7064                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7065               (set (match_operand:SWI248 0 "register_operand")
7066                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7067               (clobber (match_scratch:SWI248 4))])
7068    (set (pc) (if_then_else
7069                (eq (reg:CCO FLAGS_REG) (const_int 0))
7070                (label_ref (match_operand 3))
7071                (pc)))]
7072   ""
7074   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7075     operands[1] = force_reg (<MODE>mode, operands[1]);
7078 (define_insn "*umulv<mode>4"
7079   [(set (reg:CCO FLAGS_REG)
7080         (eq:CCO (mult:<DWI>
7081                    (zero_extend:<DWI>
7082                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7083                    (zero_extend:<DWI>
7084                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7085                 (zero_extend:<DWI>
7086                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7087    (set (match_operand:SWI248 0 "register_operand" "=a")
7088         (mult:SWI248 (match_dup 1) (match_dup 2)))
7089    (clobber (match_scratch:SWI248 3 "=d"))]
7090   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091   "mul{<imodesuffix>}\t%2"
7092   [(set_attr "type" "imul")
7093    (set_attr "length_immediate" "0")
7094    (set (attr "athlon_decode")
7095      (if_then_else (eq_attr "cpu" "athlon")
7096        (const_string "vector")
7097        (const_string "double")))
7098    (set_attr "amdfam10_decode" "double")
7099    (set_attr "bdver1_decode" "direct")
7100    (set_attr "mode" "<MODE>")])
7102 (define_expand "<u>mulvqi4"
7103   [(parallel [(set (reg:CCO FLAGS_REG)
7104                    (eq:CCO (mult:HI
7105                               (any_extend:HI
7106                                  (match_operand:QI 1 "nonimmediate_operand"))
7107                               (any_extend:HI
7108                                  (match_operand:QI 2 "nonimmediate_operand")))
7109                            (any_extend:HI
7110                               (mult:QI (match_dup 1) (match_dup 2)))))
7111               (set (match_operand:QI 0 "register_operand")
7112                    (mult:QI (match_dup 1) (match_dup 2)))])
7113    (set (pc) (if_then_else
7114                (eq (reg:CCO FLAGS_REG) (const_int 0))
7115                (label_ref (match_operand 3))
7116                (pc)))]
7117   "TARGET_QIMODE_MATH"
7119   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7120     operands[1] = force_reg (QImode, operands[1]);
7123 (define_insn "*<u>mulvqi4"
7124   [(set (reg:CCO FLAGS_REG)
7125         (eq:CCO (mult:HI
7126                    (any_extend:HI
7127                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7128                    (any_extend:HI
7129                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7130                 (any_extend:HI
7131                    (mult:QI (match_dup 1) (match_dup 2)))))
7132    (set (match_operand:QI 0 "register_operand" "=a")
7133         (mult:QI (match_dup 1) (match_dup 2)))]
7134   "TARGET_QIMODE_MATH
7135    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7136   "<sgnprefix>mul{b}\t%2"
7137   [(set_attr "type" "imul")
7138    (set_attr "length_immediate" "0")
7139    (set (attr "athlon_decode")
7140      (if_then_else (eq_attr "cpu" "athlon")
7141         (const_string "vector")
7142         (const_string "direct")))
7143    (set_attr "amdfam10_decode" "direct")
7144    (set_attr "bdver1_decode" "direct")
7145    (set_attr "mode" "QI")])
7147 (define_expand "<u>mul<mode><dwi>3"
7148   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7149                    (mult:<DWI>
7150                      (any_extend:<DWI>
7151                        (match_operand:DWIH 1 "nonimmediate_operand"))
7152                      (any_extend:<DWI>
7153                        (match_operand:DWIH 2 "register_operand"))))
7154               (clobber (reg:CC FLAGS_REG))])])
7156 (define_expand "<u>mulqihi3"
7157   [(parallel [(set (match_operand:HI 0 "register_operand")
7158                    (mult:HI
7159                      (any_extend:HI
7160                        (match_operand:QI 1 "nonimmediate_operand"))
7161                      (any_extend:HI
7162                        (match_operand:QI 2 "register_operand"))))
7163               (clobber (reg:CC FLAGS_REG))])]
7164   "TARGET_QIMODE_MATH")
7166 (define_insn "*bmi2_umul<mode><dwi>3_1"
7167   [(set (match_operand:DWIH 0 "register_operand" "=r")
7168         (mult:DWIH
7169           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7170           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7171    (set (match_operand:DWIH 1 "register_operand" "=r")
7172         (truncate:DWIH
7173           (lshiftrt:<DWI>
7174             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7175                         (zero_extend:<DWI> (match_dup 3)))
7176             (match_operand:QI 4 "const_int_operand" "n"))))]
7177   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7178    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7179   "mulx\t{%3, %0, %1|%1, %0, %3}"
7180   [(set_attr "type" "imulx")
7181    (set_attr "prefix" "vex")
7182    (set_attr "mode" "<MODE>")])
7184 (define_insn "*umul<mode><dwi>3_1"
7185   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7186         (mult:<DWI>
7187           (zero_extend:<DWI>
7188             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7189           (zero_extend:<DWI>
7190             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7191    (clobber (reg:CC FLAGS_REG))]
7192   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7193   "@
7194    #
7195    mul{<imodesuffix>}\t%2"
7196   [(set_attr "isa" "bmi2,*")
7197    (set_attr "type" "imulx,imul")
7198    (set_attr "length_immediate" "*,0")
7199    (set (attr "athlon_decode")
7200         (cond [(eq_attr "alternative" "1")
7201                  (if_then_else (eq_attr "cpu" "athlon")
7202                    (const_string "vector")
7203                    (const_string "double"))]
7204               (const_string "*")))
7205    (set_attr "amdfam10_decode" "*,double")
7206    (set_attr "bdver1_decode" "*,direct")
7207    (set_attr "prefix" "vex,orig")
7208    (set_attr "mode" "<MODE>")])
7210 ;; Convert mul to the mulx pattern to avoid flags dependency.
7211 (define_split
7212  [(set (match_operand:<DWI> 0 "register_operand")
7213        (mult:<DWI>
7214          (zero_extend:<DWI>
7215            (match_operand:DWIH 1 "register_operand"))
7216          (zero_extend:<DWI>
7217            (match_operand:DWIH 2 "nonimmediate_operand"))))
7218   (clobber (reg:CC FLAGS_REG))]
7219  "TARGET_BMI2 && reload_completed
7220   && REGNO (operands[1]) == DX_REG"
7221   [(parallel [(set (match_dup 3)
7222                    (mult:DWIH (match_dup 1) (match_dup 2)))
7223               (set (match_dup 4)
7224                    (truncate:DWIH
7225                      (lshiftrt:<DWI>
7226                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7227                                    (zero_extend:<DWI> (match_dup 2)))
7228                        (match_dup 5))))])]
7230   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7232   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7235 (define_insn "*mul<mode><dwi>3_1"
7236   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7237         (mult:<DWI>
7238           (sign_extend:<DWI>
7239             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7240           (sign_extend:<DWI>
7241             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7242    (clobber (reg:CC FLAGS_REG))]
7243   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7244   "imul{<imodesuffix>}\t%2"
7245   [(set_attr "type" "imul")
7246    (set_attr "length_immediate" "0")
7247    (set (attr "athlon_decode")
7248      (if_then_else (eq_attr "cpu" "athlon")
7249         (const_string "vector")
7250         (const_string "double")))
7251    (set_attr "amdfam10_decode" "double")
7252    (set_attr "bdver1_decode" "direct")
7253    (set_attr "mode" "<MODE>")])
7255 (define_insn "*<u>mulqihi3_1"
7256   [(set (match_operand:HI 0 "register_operand" "=a")
7257         (mult:HI
7258           (any_extend:HI
7259             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7260           (any_extend:HI
7261             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7262    (clobber (reg:CC FLAGS_REG))]
7263   "TARGET_QIMODE_MATH
7264    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7265   "<sgnprefix>mul{b}\t%2"
7266   [(set_attr "type" "imul")
7267    (set_attr "length_immediate" "0")
7268    (set (attr "athlon_decode")
7269      (if_then_else (eq_attr "cpu" "athlon")
7270         (const_string "vector")
7271         (const_string "direct")))
7272    (set_attr "amdfam10_decode" "direct")
7273    (set_attr "bdver1_decode" "direct")
7274    (set_attr "mode" "QI")])
7276 (define_expand "<s>mul<mode>3_highpart"
7277   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7278                    (truncate:SWI48
7279                      (lshiftrt:<DWI>
7280                        (mult:<DWI>
7281                          (any_extend:<DWI>
7282                            (match_operand:SWI48 1 "nonimmediate_operand"))
7283                          (any_extend:<DWI>
7284                            (match_operand:SWI48 2 "register_operand")))
7285                        (match_dup 4))))
7286               (clobber (match_scratch:SWI48 3))
7287               (clobber (reg:CC FLAGS_REG))])]
7288   ""
7289   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7291 (define_insn "*<s>muldi3_highpart_1"
7292   [(set (match_operand:DI 0 "register_operand" "=d")
7293         (truncate:DI
7294           (lshiftrt:TI
7295             (mult:TI
7296               (any_extend:TI
7297                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7298               (any_extend:TI
7299                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7300             (const_int 64))))
7301    (clobber (match_scratch:DI 3 "=1"))
7302    (clobber (reg:CC FLAGS_REG))]
7303   "TARGET_64BIT
7304    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7305   "<sgnprefix>mul{q}\t%2"
7306   [(set_attr "type" "imul")
7307    (set_attr "length_immediate" "0")
7308    (set (attr "athlon_decode")
7309      (if_then_else (eq_attr "cpu" "athlon")
7310         (const_string "vector")
7311         (const_string "double")))
7312    (set_attr "amdfam10_decode" "double")
7313    (set_attr "bdver1_decode" "direct")
7314    (set_attr "mode" "DI")])
7316 (define_insn "*<s>mulsi3_highpart_1"
7317   [(set (match_operand:SI 0 "register_operand" "=d")
7318         (truncate:SI
7319           (lshiftrt:DI
7320             (mult:DI
7321               (any_extend:DI
7322                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7323               (any_extend:DI
7324                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7325             (const_int 32))))
7326    (clobber (match_scratch:SI 3 "=1"))
7327    (clobber (reg:CC FLAGS_REG))]
7328   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7329   "<sgnprefix>mul{l}\t%2"
7330   [(set_attr "type" "imul")
7331    (set_attr "length_immediate" "0")
7332    (set (attr "athlon_decode")
7333      (if_then_else (eq_attr "cpu" "athlon")
7334         (const_string "vector")
7335         (const_string "double")))
7336    (set_attr "amdfam10_decode" "double")
7337    (set_attr "bdver1_decode" "direct")
7338    (set_attr "mode" "SI")])
7340 (define_insn "*<s>mulsi3_highpart_zext"
7341   [(set (match_operand:DI 0 "register_operand" "=d")
7342         (zero_extend:DI (truncate:SI
7343           (lshiftrt:DI
7344             (mult:DI (any_extend:DI
7345                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7346                      (any_extend:DI
7347                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7348             (const_int 32)))))
7349    (clobber (match_scratch:SI 3 "=1"))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "TARGET_64BIT
7352    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353   "<sgnprefix>mul{l}\t%2"
7354   [(set_attr "type" "imul")
7355    (set_attr "length_immediate" "0")
7356    (set (attr "athlon_decode")
7357      (if_then_else (eq_attr "cpu" "athlon")
7358         (const_string "vector")
7359         (const_string "double")))
7360    (set_attr "amdfam10_decode" "double")
7361    (set_attr "bdver1_decode" "direct")
7362    (set_attr "mode" "SI")])
7364 ;; The patterns that match these are at the end of this file.
7366 (define_expand "mulxf3"
7367   [(set (match_operand:XF 0 "register_operand")
7368         (mult:XF (match_operand:XF 1 "register_operand")
7369                  (match_operand:XF 2 "register_operand")))]
7370   "TARGET_80387")
7372 (define_expand "mul<mode>3"
7373   [(set (match_operand:MODEF 0 "register_operand")
7374         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7375                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7376   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7377     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7379 ;; Divide instructions
7381 ;; The patterns that match these are at the end of this file.
7383 (define_expand "divxf3"
7384   [(set (match_operand:XF 0 "register_operand")
7385         (div:XF (match_operand:XF 1 "register_operand")
7386                 (match_operand:XF 2 "register_operand")))]
7387   "TARGET_80387")
7389 (define_expand "divdf3"
7390   [(set (match_operand:DF 0 "register_operand")
7391         (div:DF (match_operand:DF 1 "register_operand")
7392                 (match_operand:DF 2 "nonimmediate_operand")))]
7393    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7394     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7396 (define_expand "divsf3"
7397   [(set (match_operand:SF 0 "register_operand")
7398         (div:SF (match_operand:SF 1 "register_operand")
7399                 (match_operand:SF 2 "nonimmediate_operand")))]
7400   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7401     || TARGET_SSE_MATH"
7403   if (TARGET_SSE_MATH
7404       && TARGET_RECIP_DIV
7405       && optimize_insn_for_speed_p ()
7406       && flag_finite_math_only && !flag_trapping_math
7407       && flag_unsafe_math_optimizations)
7408     {
7409       ix86_emit_swdivsf (operands[0], operands[1],
7410                          operands[2], SFmode);
7411       DONE;
7412     }
7415 ;; Divmod instructions.
7417 (define_expand "divmod<mode>4"
7418   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7419                    (div:SWIM248
7420                      (match_operand:SWIM248 1 "register_operand")
7421                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7422               (set (match_operand:SWIM248 3 "register_operand")
7423                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7424               (clobber (reg:CC FLAGS_REG))])])
7426 ;; Split with 8bit unsigned divide:
7427 ;;      if (dividend an divisor are in [0-255])
7428 ;;         use 8bit unsigned integer divide
7429 ;;       else
7430 ;;         use original integer divide
7431 (define_split
7432   [(set (match_operand:SWI48 0 "register_operand")
7433         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7434                     (match_operand:SWI48 3 "nonimmediate_operand")))
7435    (set (match_operand:SWI48 1 "register_operand")
7436         (mod:SWI48 (match_dup 2) (match_dup 3)))
7437    (clobber (reg:CC FLAGS_REG))]
7438   "TARGET_USE_8BIT_IDIV
7439    && TARGET_QIMODE_MATH
7440    && can_create_pseudo_p ()
7441    && !optimize_insn_for_size_p ()"
7442   [(const_int 0)]
7443   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7445 (define_insn_and_split "divmod<mode>4_1"
7446   [(set (match_operand:SWI48 0 "register_operand" "=a")
7447         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7448                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7449    (set (match_operand:SWI48 1 "register_operand" "=&d")
7450         (mod:SWI48 (match_dup 2) (match_dup 3)))
7451    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7452    (clobber (reg:CC FLAGS_REG))]
7453   ""
7454   "#"
7455   "reload_completed"
7456   [(parallel [(set (match_dup 1)
7457                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7458               (clobber (reg:CC FLAGS_REG))])
7459    (parallel [(set (match_dup 0)
7460                    (div:SWI48 (match_dup 2) (match_dup 3)))
7461               (set (match_dup 1)
7462                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7463               (use (match_dup 1))
7464               (clobber (reg:CC FLAGS_REG))])]
7466   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7468   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7469     operands[4] = operands[2];
7470   else
7471     {
7472       /* Avoid use of cltd in favor of a mov+shift.  */
7473       emit_move_insn (operands[1], operands[2]);
7474       operands[4] = operands[1];
7475     }
7477   [(set_attr "type" "multi")
7478    (set_attr "mode" "<MODE>")])
7480 (define_insn_and_split "*divmod<mode>4"
7481   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7482         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7483                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7484    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7485         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7486    (clobber (reg:CC FLAGS_REG))]
7487   ""
7488   "#"
7489   "reload_completed"
7490   [(parallel [(set (match_dup 1)
7491                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7492               (clobber (reg:CC FLAGS_REG))])
7493    (parallel [(set (match_dup 0)
7494                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7495               (set (match_dup 1)
7496                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7497               (use (match_dup 1))
7498               (clobber (reg:CC FLAGS_REG))])]
7500   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7502   if (<MODE>mode != HImode
7503       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7504     operands[4] = operands[2];
7505   else
7506     {
7507       /* Avoid use of cltd in favor of a mov+shift.  */
7508       emit_move_insn (operands[1], operands[2]);
7509       operands[4] = operands[1];
7510     }
7512   [(set_attr "type" "multi")
7513    (set_attr "mode" "<MODE>")])
7515 (define_insn "*divmod<mode>4_noext"
7516   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7517         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7518                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7519    (set (match_operand:SWIM248 1 "register_operand" "=d")
7520         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7521    (use (match_operand:SWIM248 4 "register_operand" "1"))
7522    (clobber (reg:CC FLAGS_REG))]
7523   ""
7524   "idiv{<imodesuffix>}\t%3"
7525   [(set_attr "type" "idiv")
7526    (set_attr "mode" "<MODE>")])
7528 (define_expand "divmodqi4"
7529   [(parallel [(set (match_operand:QI 0 "register_operand")
7530                    (div:QI
7531                      (match_operand:QI 1 "register_operand")
7532                      (match_operand:QI 2 "nonimmediate_operand")))
7533               (set (match_operand:QI 3 "register_operand")
7534                    (mod:QI (match_dup 1) (match_dup 2)))
7535               (clobber (reg:CC FLAGS_REG))])]
7536   "TARGET_QIMODE_MATH"
7538   rtx div, mod;
7539   rtx tmp0, tmp1;
7540   
7541   tmp0 = gen_reg_rtx (HImode);
7542   tmp1 = gen_reg_rtx (HImode);
7544   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7545      in AX.  */
7546   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7547   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7549   /* Extract remainder from AH.  */
7550   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7551   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7553   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7554   set_unique_reg_note (insn, REG_EQUAL, mod);
7556   /* Extract quotient from AL.  */
7557   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7559   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7560   set_unique_reg_note (insn, REG_EQUAL, div);
7562   DONE;
7565 ;; Divide AX by r/m8, with result stored in
7566 ;; AL <- Quotient
7567 ;; AH <- Remainder
7568 ;; Change div/mod to HImode and extend the second argument to HImode
7569 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7570 ;; combine may fail.
7571 (define_insn "divmodhiqi3"
7572   [(set (match_operand:HI 0 "register_operand" "=a")
7573         (ior:HI
7574           (ashift:HI
7575             (zero_extend:HI
7576               (truncate:QI
7577                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7578                         (sign_extend:HI
7579                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7580             (const_int 8))
7581           (zero_extend:HI
7582             (truncate:QI
7583               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "TARGET_QIMODE_MATH"
7586   "idiv{b}\t%2"
7587   [(set_attr "type" "idiv")
7588    (set_attr "mode" "QI")])
7590 (define_expand "udivmod<mode>4"
7591   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7592                    (udiv:SWIM248
7593                      (match_operand:SWIM248 1 "register_operand")
7594                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7595               (set (match_operand:SWIM248 3 "register_operand")
7596                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7597               (clobber (reg:CC FLAGS_REG))])])
7599 ;; Split with 8bit unsigned divide:
7600 ;;      if (dividend an divisor are in [0-255])
7601 ;;         use 8bit unsigned integer divide
7602 ;;       else
7603 ;;         use original integer divide
7604 (define_split
7605   [(set (match_operand:SWI48 0 "register_operand")
7606         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7607                     (match_operand:SWI48 3 "nonimmediate_operand")))
7608    (set (match_operand:SWI48 1 "register_operand")
7609         (umod:SWI48 (match_dup 2) (match_dup 3)))
7610    (clobber (reg:CC FLAGS_REG))]
7611   "TARGET_USE_8BIT_IDIV
7612    && TARGET_QIMODE_MATH
7613    && can_create_pseudo_p ()
7614    && !optimize_insn_for_size_p ()"
7615   [(const_int 0)]
7616   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7618 (define_insn_and_split "udivmod<mode>4_1"
7619   [(set (match_operand:SWI48 0 "register_operand" "=a")
7620         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7621                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7622    (set (match_operand:SWI48 1 "register_operand" "=&d")
7623         (umod:SWI48 (match_dup 2) (match_dup 3)))
7624    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7625    (clobber (reg:CC FLAGS_REG))]
7626   ""
7627   "#"
7628   "reload_completed"
7629   [(set (match_dup 1) (const_int 0))
7630    (parallel [(set (match_dup 0)
7631                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7632               (set (match_dup 1)
7633                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7634               (use (match_dup 1))
7635               (clobber (reg:CC FLAGS_REG))])]
7636   ""
7637   [(set_attr "type" "multi")
7638    (set_attr "mode" "<MODE>")])
7640 (define_insn_and_split "*udivmod<mode>4"
7641   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7642         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7643                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7644    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7645         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   ""
7648   "#"
7649   "reload_completed"
7650   [(set (match_dup 1) (const_int 0))
7651    (parallel [(set (match_dup 0)
7652                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7653               (set (match_dup 1)
7654                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7655               (use (match_dup 1))
7656               (clobber (reg:CC FLAGS_REG))])]
7657   ""
7658   [(set_attr "type" "multi")
7659    (set_attr "mode" "<MODE>")])
7661 ;; Optimize division or modulo by constant power of 2, if the constant
7662 ;; materializes only after expansion.
7663 (define_insn_and_split "*udivmod<mode>4_pow2"
7664   [(set (match_operand:SWI48 0 "register_operand" "=r")
7665         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7666                     (match_operand:SWI48 3 "const_int_operand" "n")))
7667    (set (match_operand:SWI48 1 "register_operand" "=r")
7668         (umod:SWI48 (match_dup 2) (match_dup 3)))
7669    (clobber (reg:CC FLAGS_REG))]
7670   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7671    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7672   "#"
7673   "&& 1"
7674   [(set (match_dup 1) (match_dup 2))
7675    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7676               (clobber (reg:CC FLAGS_REG))])
7677    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7678               (clobber (reg:CC FLAGS_REG))])]
7680   int v = exact_log2 (UINTVAL (operands[3]));
7681   operands[4] = GEN_INT (v);
7682   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7684   [(set_attr "type" "multi")
7685    (set_attr "mode" "<MODE>")])
7687 (define_insn "*udivmod<mode>4_noext"
7688   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7689         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7690                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7691    (set (match_operand:SWIM248 1 "register_operand" "=d")
7692         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7693    (use (match_operand:SWIM248 4 "register_operand" "1"))
7694    (clobber (reg:CC FLAGS_REG))]
7695   ""
7696   "div{<imodesuffix>}\t%3"
7697   [(set_attr "type" "idiv")
7698    (set_attr "mode" "<MODE>")])
7700 (define_expand "udivmodqi4"
7701   [(parallel [(set (match_operand:QI 0 "register_operand")
7702                    (udiv:QI
7703                      (match_operand:QI 1 "register_operand")
7704                      (match_operand:QI 2 "nonimmediate_operand")))
7705               (set (match_operand:QI 3 "register_operand")
7706                    (umod:QI (match_dup 1) (match_dup 2)))
7707               (clobber (reg:CC FLAGS_REG))])]
7708   "TARGET_QIMODE_MATH"
7710   rtx div, mod;
7711   rtx tmp0, tmp1;
7712   
7713   tmp0 = gen_reg_rtx (HImode);
7714   tmp1 = gen_reg_rtx (HImode);
7716   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
7717   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7718   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7720   /* Extract remainder from AH.  */
7721   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7722   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7723   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7725   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7726   set_unique_reg_note (insn, REG_EQUAL, mod);
7728   /* Extract quotient from AL.  */
7729   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7731   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7732   set_unique_reg_note (insn, REG_EQUAL, div);
7734   DONE;
7737 (define_insn "udivmodhiqi3"
7738   [(set (match_operand:HI 0 "register_operand" "=a")
7739         (ior:HI
7740           (ashift:HI
7741             (zero_extend:HI
7742               (truncate:QI
7743                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7744                         (zero_extend:HI
7745                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7746             (const_int 8))
7747           (zero_extend:HI
7748             (truncate:QI
7749               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7750    (clobber (reg:CC FLAGS_REG))]
7751   "TARGET_QIMODE_MATH"
7752   "div{b}\t%2"
7753   [(set_attr "type" "idiv")
7754    (set_attr "mode" "QI")])
7756 ;; We cannot use div/idiv for double division, because it causes
7757 ;; "division by zero" on the overflow and that's not what we expect
7758 ;; from truncate.  Because true (non truncating) double division is
7759 ;; never generated, we can't create this insn anyway.
7761 ;(define_insn ""
7762 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7763 ;       (truncate:SI
7764 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7765 ;                  (zero_extend:DI
7766 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7767 ;   (set (match_operand:SI 3 "register_operand" "=d")
7768 ;       (truncate:SI
7769 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7770 ;   (clobber (reg:CC FLAGS_REG))]
7771 ;  ""
7772 ;  "div{l}\t{%2, %0|%0, %2}"
7773 ;  [(set_attr "type" "idiv")])
7775 ;;- Logical AND instructions
7777 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7778 ;; Note that this excludes ah.
7780 (define_expand "testsi_ccno_1"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7784                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7785           (const_int 0)))])
7787 (define_expand "testqi_ccz_1"
7788   [(set (reg:CCZ FLAGS_REG)
7789         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7790                              (match_operand:QI 1 "nonmemory_operand"))
7791                  (const_int 0)))])
7793 (define_expand "testdi_ccno_1"
7794   [(set (reg:CCNO FLAGS_REG)
7795         (compare:CCNO
7796           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7797                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7798           (const_int 0)))]
7799   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7801 (define_insn "*testdi_1"
7802   [(set (reg FLAGS_REG)
7803         (compare
7804          (and:DI
7805           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7806           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7807          (const_int 0)))]
7808   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7809    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7810   "@
7811    test{l}\t{%k1, %k0|%k0, %k1}
7812    test{l}\t{%k1, %k0|%k0, %k1}
7813    test{q}\t{%1, %0|%0, %1}
7814    test{q}\t{%1, %0|%0, %1}
7815    test{q}\t{%1, %0|%0, %1}"
7816   [(set_attr "type" "test")
7817    (set_attr "modrm" "0,1,0,1,1")
7818    (set_attr "mode" "SI,SI,DI,DI,DI")])
7820 (define_insn "*testqi_1_maybe_si"
7821   [(set (reg FLAGS_REG)
7822         (compare
7823           (and:QI
7824             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7825             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7826           (const_int 0)))]
7827    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7828     && ix86_match_ccmode (insn,
7829                          CONST_INT_P (operands[1])
7830                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7832   if (which_alternative == 3)
7833     {
7834       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7835         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7836       return "test{l}\t{%1, %k0|%k0, %1}";
7837     }
7838   return "test{b}\t{%1, %0|%0, %1}";
7840   [(set_attr "type" "test")
7841    (set_attr "modrm" "0,1,1,1")
7842    (set_attr "mode" "QI,QI,QI,SI")
7843    (set_attr "pent_pair" "uv,np,uv,np")])
7845 (define_insn "*test<mode>_1"
7846   [(set (reg FLAGS_REG)
7847         (compare
7848          (and:SWI124
7849           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7850           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7851          (const_int 0)))]
7852   "ix86_match_ccmode (insn, CCNOmode)
7853    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7854   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7855   [(set_attr "type" "test")
7856    (set_attr "modrm" "0,1,1")
7857    (set_attr "mode" "<MODE>")
7858    (set_attr "pent_pair" "uv,np,uv")])
7860 (define_expand "testqi_ext_ccno_0"
7861   [(set (reg:CCNO FLAGS_REG)
7862         (compare:CCNO
7863           (and:SI
7864             (zero_extract:SI
7865               (match_operand 0 "ext_register_operand")
7866               (const_int 8)
7867               (const_int 8))
7868             (match_operand 1 "const_int_operand"))
7869           (const_int 0)))])
7871 (define_insn "*testqi_ext_0"
7872   [(set (reg FLAGS_REG)
7873         (compare
7874           (and:SI
7875             (zero_extract:SI
7876               (match_operand 0 "ext_register_operand" "Q")
7877               (const_int 8)
7878               (const_int 8))
7879             (match_operand 1 "const_int_operand" "n"))
7880           (const_int 0)))]
7881   "ix86_match_ccmode (insn, CCNOmode)"
7882   "test{b}\t{%1, %h0|%h0, %1}"
7883   [(set_attr "type" "test")
7884    (set_attr "mode" "QI")
7885    (set_attr "length_immediate" "1")
7886    (set_attr "modrm" "1")
7887    (set_attr "pent_pair" "np")])
7889 (define_insn "*testqi_ext_1"
7890   [(set (reg FLAGS_REG)
7891         (compare
7892           (and:SI
7893             (zero_extract:SI
7894               (match_operand 0 "ext_register_operand" "Q,Q")
7895               (const_int 8)
7896               (const_int 8))
7897             (zero_extend:SI
7898               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7899           (const_int 0)))]
7900   "ix86_match_ccmode (insn, CCNOmode)"
7901   "test{b}\t{%1, %h0|%h0, %1}"
7902   [(set_attr "isa" "*,nox64")
7903    (set_attr "type" "test")
7904    (set_attr "mode" "QI")])
7906 (define_insn "*testqi_ext_2"
7907   [(set (reg FLAGS_REG)
7908         (compare
7909           (and:SI
7910             (zero_extract:SI
7911               (match_operand 0 "ext_register_operand" "Q")
7912               (const_int 8)
7913               (const_int 8))
7914             (zero_extract:SI
7915               (match_operand 1 "ext_register_operand" "Q")
7916               (const_int 8)
7917               (const_int 8)))
7918           (const_int 0)))]
7919   "ix86_match_ccmode (insn, CCNOmode)"
7920   "test{b}\t{%h1, %h0|%h0, %h1}"
7921   [(set_attr "type" "test")
7922    (set_attr "mode" "QI")])
7924 ;; Combine likes to form bit extractions for some tests.  Humor it.
7925 (define_insn "*testqi_ext_3"
7926   [(set (reg FLAGS_REG)
7927         (compare (zero_extract:SWI248
7928                    (match_operand 0 "nonimmediate_operand" "rm")
7929                    (match_operand 1 "const_int_operand" "n")
7930                    (match_operand 2 "const_int_operand" "n"))
7931                  (const_int 0)))]
7932   "ix86_match_ccmode (insn, CCNOmode)
7933    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7934        || GET_MODE (operands[0]) == SImode
7935        || GET_MODE (operands[0]) == HImode
7936        || GET_MODE (operands[0]) == QImode)
7937    /* Ensure that resulting mask is zero or sign extended operand.  */
7938    && INTVAL (operands[2]) >= 0
7939    && ((INTVAL (operands[1]) > 0
7940         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7941        || (<MODE>mode == DImode
7942            && INTVAL (operands[1]) > 32
7943            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7944   "#")
7946 (define_split
7947   [(set (match_operand 0 "flags_reg_operand")
7948         (match_operator 1 "compare_operator"
7949           [(zero_extract
7950              (match_operand 2 "nonimmediate_operand")
7951              (match_operand 3 "const_int_operand")
7952              (match_operand 4 "const_int_operand"))
7953            (const_int 0)]))]
7954   "ix86_match_ccmode (insn, CCNOmode)"
7955   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7957   rtx val = operands[2];
7958   HOST_WIDE_INT len = INTVAL (operands[3]);
7959   HOST_WIDE_INT pos = INTVAL (operands[4]);
7960   HOST_WIDE_INT mask;
7961   machine_mode mode, submode;
7963   mode = GET_MODE (val);
7964   if (MEM_P (val))
7965     {
7966       /* ??? Combine likes to put non-volatile mem extractions in QImode
7967          no matter the size of the test.  So find a mode that works.  */
7968       if (! MEM_VOLATILE_P (val))
7969         {
7970           mode = smallest_mode_for_size (pos + len, MODE_INT);
7971           val = adjust_address (val, mode, 0);
7972         }
7973     }
7974   else if (SUBREG_P (val)
7975            && (submode = GET_MODE (SUBREG_REG (val)),
7976                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7977            && pos + len <= GET_MODE_BITSIZE (submode)
7978            && GET_MODE_CLASS (submode) == MODE_INT)
7979     {
7980       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7981       mode = submode;
7982       val = SUBREG_REG (val);
7983     }
7984   else if (mode == HImode && pos + len <= 8)
7985     {
7986       /* Small HImode tests can be converted to QImode.  */
7987       mode = QImode;
7988       val = gen_lowpart (QImode, val);
7989     }
7991   if (len == HOST_BITS_PER_WIDE_INT)
7992     mask = -1;
7993   else
7994     mask = (HOST_WIDE_INT_1 << len) - 1;
7995   mask <<= pos;
7997   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8000 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8001 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8002 ;; this is relatively important trick.
8003 ;; Do the conversion only post-reload to avoid limiting of the register class
8004 ;; to QI regs.
8005 (define_split
8006   [(set (match_operand 0 "flags_reg_operand")
8007         (match_operator 1 "compare_operator"
8008           [(and (match_operand 2 "QIreg_operand")
8009                 (match_operand 3 "const_int_operand"))
8010            (const_int 0)]))]
8011    "reload_completed
8012     && GET_MODE (operands[2]) != QImode
8013     && ((ix86_match_ccmode (insn, CCZmode)
8014          && !(INTVAL (operands[3]) & ~(255 << 8)))
8015         || (ix86_match_ccmode (insn, CCNOmode)
8016             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8017   [(set (match_dup 0)
8018         (match_op_dup 1
8019           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8020                    (match_dup 3))
8021            (const_int 0)]))]
8023   operands[2] = gen_lowpart (SImode, operands[2]);
8024   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
8027 (define_split
8028   [(set (match_operand 0 "flags_reg_operand")
8029         (match_operator 1 "compare_operator"
8030           [(and (match_operand 2 "nonimmediate_operand")
8031                 (match_operand 3 "const_int_operand"))
8032            (const_int 0)]))]
8033    "reload_completed
8034     && GET_MODE (operands[2]) != QImode
8035     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036     && ((ix86_match_ccmode (insn, CCZmode)
8037          && !(INTVAL (operands[3]) & ~255))
8038         || (ix86_match_ccmode (insn, CCNOmode)
8039             && !(INTVAL (operands[3]) & ~127)))"
8040   [(set (match_dup 0)
8041         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8042                          (const_int 0)]))]
8044   operands[2] = gen_lowpart (QImode, operands[2]);
8045   operands[3] = gen_lowpart (QImode, operands[3]);
8048 (define_split
8049   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8050         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8051                             (match_operand:SWI1248x 2 "mask_reg_operand")))
8052    (clobber (reg:CC FLAGS_REG))]
8053   "TARGET_AVX512F && reload_completed"
8054   [(set (match_dup 0)
8055         (any_logic:SWI1248x (match_dup 1)
8056                             (match_dup 2)))])
8058 (define_mode_iterator SWI1248_AVX512BW
8059   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8061 (define_insn "*k<logic><mode>"
8062   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8063         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8064                                     (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8065   "TARGET_AVX512F"
8066   {
8067     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8068       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8069     else
8070       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8071   }
8072   [(set_attr "mode" "<MODE>")
8073    (set_attr "type" "msklog")
8074    (set_attr "prefix" "vex")])
8076 ;; %%% This used to optimize known byte-wide and operations to memory,
8077 ;; and sometimes to QImode registers.  If this is considered useful,
8078 ;; it should be done with splitters.
8080 (define_expand "and<mode>3"
8081   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8082         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8083                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8084   ""
8086   machine_mode mode = <MODE>mode;
8087   rtx (*insn) (rtx, rtx);
8089   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8090     {
8091       HOST_WIDE_INT ival = INTVAL (operands[2]);
8093       if (ival == (HOST_WIDE_INT) 0xffffffff)
8094         mode = SImode;
8095       else if (ival == 0xffff)
8096         mode = HImode;
8097       else if (ival == 0xff)
8098         mode = QImode;
8099       }
8101   if (mode == <MODE>mode)
8102     {
8103       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8104       DONE;
8105     }
8107   if (<MODE>mode == DImode)
8108     insn = (mode == SImode)
8109            ? gen_zero_extendsidi2
8110            : (mode == HImode)
8111            ? gen_zero_extendhidi2
8112            : gen_zero_extendqidi2;
8113   else if (<MODE>mode == SImode)
8114     insn = (mode == HImode)
8115            ? gen_zero_extendhisi2
8116            : gen_zero_extendqisi2;
8117   else if (<MODE>mode == HImode)
8118     insn = gen_zero_extendqihi2;
8119   else
8120     gcc_unreachable ();
8122   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8123   DONE;
8126 (define_insn "*anddi_1"
8127   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8128         (and:DI
8129          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8130          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8131    (clobber (reg:CC FLAGS_REG))]
8132   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8134   switch (get_attr_type (insn))
8135     {
8136     case TYPE_IMOVX:
8137       return "#";
8139     case TYPE_MSKLOG:
8140       return "kandq\t{%2, %1, %0|%0, %1, %2}";
8142     default:
8143       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8144       if (get_attr_mode (insn) == MODE_SI)
8145         return "and{l}\t{%k2, %k0|%k0, %k2}";
8146       else
8147         return "and{q}\t{%2, %0|%0, %2}";
8148     }
8150   [(set_attr "type" "alu,alu,alu,imovx,msklog")
8151    (set_attr "length_immediate" "*,*,*,0,0")
8152    (set (attr "prefix_rex")
8153      (if_then_else
8154        (and (eq_attr "type" "imovx")
8155             (and (match_test "INTVAL (operands[2]) == 0xff")
8156                  (match_operand 1 "ext_QIreg_operand")))
8157        (const_string "1")
8158        (const_string "*")))
8159    (set_attr "mode" "SI,DI,DI,SI,DI")])
8161 (define_insn_and_split "*anddi3_doubleword"
8162   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8163         (and:DI
8164          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8165          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8168    && ix86_binary_operator_ok (AND, DImode, operands)"
8169   "#"
8170   "&& reload_completed"
8171   [(const_int 0)]
8173   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8174   if (operands[2] == const0_rtx)
8175     {
8176       operands[1] = const0_rtx;
8177       ix86_expand_move (SImode, &operands[0]);
8178     }
8179   else if (operands[2] != constm1_rtx)
8180     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8181   else if (operands[5] == constm1_rtx)
8182     emit_note (NOTE_INSN_DELETED);
8183   if (operands[5] == const0_rtx)
8184     {
8185       operands[4] = const0_rtx;
8186       ix86_expand_move (SImode, &operands[3]);
8187     }
8188   else if (operands[5] != constm1_rtx)
8189     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8190   DONE;
8193 (define_insn "*andsi_1"
8194   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8195         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8196                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "ix86_binary_operator_ok (AND, SImode, operands)"
8200   switch (get_attr_type (insn))
8201     {
8202     case TYPE_IMOVX:
8203       return "#";
8205     case TYPE_MSKLOG:
8206       return "kandd\t{%2, %1, %0|%0, %1, %2}";
8208     default:
8209       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8210       return "and{l}\t{%2, %0|%0, %2}";
8211     }
8213   [(set_attr "type" "alu,alu,imovx,msklog")
8214    (set (attr "prefix_rex")
8215      (if_then_else
8216        (and (eq_attr "type" "imovx")
8217             (and (match_test "INTVAL (operands[2]) == 0xff")
8218                  (match_operand 1 "ext_QIreg_operand")))
8219        (const_string "1")
8220        (const_string "*")))
8221    (set_attr "length_immediate" "*,*,0,0")
8222    (set_attr "mode" "SI")])
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_1_zext"
8226   [(set (match_operand:DI 0 "register_operand" "=r")
8227         (zero_extend:DI
8228           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8229                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8232   "and{l}\t{%2, %k0|%k0, %2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "mode" "SI")])
8236 (define_insn "*andhi_1"
8237   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8238         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8239                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "ix86_binary_operator_ok (AND, HImode, operands)"
8243   switch (get_attr_type (insn))
8244     {
8245     case TYPE_IMOVX:
8246       return "#";
8248     case TYPE_MSKLOG:
8249       return "kandw\t{%2, %1, %0|%0, %1, %2}";
8251     default:
8252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8253       return "and{w}\t{%2, %0|%0, %2}";
8254     }
8256   [(set_attr "type" "alu,alu,imovx,msklog")
8257    (set_attr "length_immediate" "*,*,0,*")
8258    (set (attr "prefix_rex")
8259      (if_then_else
8260        (and (eq_attr "type" "imovx")
8261             (match_operand 1 "ext_QIreg_operand"))
8262        (const_string "1")
8263        (const_string "*")))
8264    (set_attr "mode" "HI,HI,SI,HI")])
8266 (define_insn "*andqi_1"
8267   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8268         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8269                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "ix86_binary_operator_ok (AND, QImode, operands)"
8273   switch (which_alternative)
8274     {
8275     case 0:
8276     case 1:
8277       return "and{b}\t{%2, %0|%0, %2}";
8278     case 2:
8279       return "and{l}\t{%k2, %k0|%k0, %k2}";
8280     case 3:
8281       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8282                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
8283     default:
8284       gcc_unreachable ();
8285     }
8287   [(set_attr "type" "alu,alu,alu,msklog")
8288    (set_attr "mode" "QI,QI,SI,HI")
8289    ;; Potential partial reg stall on alternative 2.
8290    (set (attr "preferred_for_speed")
8291      (cond [(eq_attr "alternative" "2")
8292               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8293            (symbol_ref "true")))])
8295 (define_insn "*andqi_1_slp"
8296   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8297         (and:QI (match_dup 0)
8298                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8299    (clobber (reg:CC FLAGS_REG))]
8300   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8301    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8302   "and{b}\t{%1, %0|%0, %1}"
8303   [(set_attr "type" "alu1")
8304    (set_attr "mode" "QI")])
8306 (define_insn "kandn<mode>"
8307   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8308         (and:SWI12
8309           (not:SWI12
8310             (match_operand:SWI12 1 "register_operand" "r,0,k"))
8311           (match_operand:SWI12 2 "register_operand" "r,r,k")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "TARGET_AVX512F"
8315   switch (which_alternative)
8316     {
8317     case 0:
8318       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8319     case 1:
8320       return "#";
8321     case 2:
8322       if (TARGET_AVX512DQ && <MODE>mode == QImode)
8323         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8324       else
8325         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8326     default:
8327       gcc_unreachable ();
8328     }
8330   [(set_attr "isa" "bmi,*,avx512f")
8331    (set_attr "type" "bitmanip,*,msklog")
8332    (set_attr "prefix" "*,*,vex")
8333    (set_attr "btver2_decode" "direct,*,*")
8334    (set_attr "mode" "<MODE>")])
8336 (define_split
8337   [(set (match_operand:SWI12 0 "general_reg_operand")
8338         (and:SWI12
8339           (not:SWI12
8340             (match_dup 0))
8341           (match_operand:SWI12 1 "general_reg_operand")))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8344   [(set (match_dup 0)
8345         (not:SWI12 (match_dup 0)))
8346    (parallel [(set (match_dup 0)
8347                    (and:SWI12 (match_dup 0)
8348                               (match_dup 1)))
8349               (clobber (reg:CC FLAGS_REG))])])
8351 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8352 (define_split
8353   [(set (match_operand:DI 0 "register_operand")
8354         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8355                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "TARGET_64BIT"
8358   [(parallel [(set (match_dup 0)
8359                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8360               (clobber (reg:CC FLAGS_REG))])]
8361   "operands[2] = gen_lowpart (SImode, operands[2]);")
8363 (define_split
8364   [(set (match_operand:SWI248 0 "register_operand")
8365         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8366                     (match_operand:SWI248 2 "const_int_operand")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "reload_completed
8369    && (!REG_P (operands[1])
8370        || REGNO (operands[0]) != REGNO (operands[1]))"
8371   [(const_int 0)]
8373   HOST_WIDE_INT ival = INTVAL (operands[2]);
8374   machine_mode mode;
8375   rtx (*insn) (rtx, rtx);
8377   if (ival == (HOST_WIDE_INT) 0xffffffff)
8378     mode = SImode;
8379   else if (ival == 0xffff)
8380     mode = HImode;
8381   else
8382     {
8383       gcc_assert (ival == 0xff);
8384       mode = QImode;
8385     }
8387   if (<MODE>mode == DImode)
8388     insn = (mode == SImode)
8389            ? gen_zero_extendsidi2
8390            : (mode == HImode)
8391            ? gen_zero_extendhidi2
8392            : gen_zero_extendqidi2;
8393   else
8394     {
8395       if (<MODE>mode != SImode)
8396         /* Zero extend to SImode to avoid partial register stalls.  */
8397         operands[0] = gen_lowpart (SImode, operands[0]);
8399       insn = (mode == HImode)
8400              ? gen_zero_extendhisi2
8401              : gen_zero_extendqisi2;
8402     }
8403   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8404   DONE;
8407 (define_split
8408   [(set (match_operand:SWI48 0 "register_operand")
8409         (and:SWI48 (match_dup 0)
8410                    (const_int -65536)))
8411    (clobber (reg:CC FLAGS_REG))]
8412   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8413     || optimize_function_for_size_p (cfun)"
8414   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8415   "operands[1] = gen_lowpart (HImode, operands[0]);")
8417 (define_split
8418   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8419         (and:SWI248 (match_dup 0)
8420                     (const_int -256)))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8423    && reload_completed"
8424   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8425   "operands[1] = gen_lowpart (QImode, operands[0]);")
8427 (define_split
8428   [(set (match_operand:SWI248 0 "QIreg_operand")
8429         (and:SWI248 (match_dup 0)
8430                     (const_int -65281)))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8433    && reload_completed"
8434   [(parallel [(set (zero_extract:SI (match_dup 0)
8435                                     (const_int 8)
8436                                     (const_int 8))
8437                    (xor:SI
8438                      (zero_extract:SI (match_dup 0)
8439                                       (const_int 8)
8440                                       (const_int 8))
8441                      (zero_extract:SI (match_dup 0)
8442                                       (const_int 8)
8443                                       (const_int 8))))
8444               (clobber (reg:CC FLAGS_REG))])]
8445   "operands[0] = gen_lowpart (SImode, operands[0]);")
8447 (define_insn "*anddi_2"
8448   [(set (reg FLAGS_REG)
8449         (compare
8450          (and:DI
8451           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8452           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8453          (const_int 0)))
8454    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8455         (and:DI (match_dup 1) (match_dup 2)))]
8456   "TARGET_64BIT
8457    && ix86_match_ccmode
8458         (insn,
8459          /* If we are going to emit andl instead of andq, and the operands[2]
8460             constant might have the SImode sign bit set, make sure the sign
8461             flag isn't tested, because the instruction will set the sign flag
8462             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8463             conservatively assume it might have bit 31 set.  */
8464          (satisfies_constraint_Z (operands[2])
8465           && (!CONST_INT_P (operands[2])
8466               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8467          ? CCZmode : CCNOmode)
8468    && ix86_binary_operator_ok (AND, DImode, operands)"
8469   "@
8470    and{l}\t{%k2, %k0|%k0, %k2}
8471    and{q}\t{%2, %0|%0, %2}
8472    and{q}\t{%2, %0|%0, %2}"
8473   [(set_attr "type" "alu")
8474    (set_attr "mode" "SI,DI,DI")])
8476 (define_insn "*andqi_2_maybe_si"
8477   [(set (reg FLAGS_REG)
8478         (compare (and:QI
8479                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8480                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8481                  (const_int 0)))
8482    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8483         (and:QI (match_dup 1) (match_dup 2)))]
8484   "ix86_binary_operator_ok (AND, QImode, operands)
8485    && ix86_match_ccmode (insn,
8486                          CONST_INT_P (operands[2])
8487                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8489   if (which_alternative == 2)
8490     {
8491       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8492         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8493       return "and{l}\t{%2, %k0|%k0, %2}";
8494     }
8495   return "and{b}\t{%2, %0|%0, %2}";
8497   [(set_attr "type" "alu")
8498    (set_attr "mode" "QI,QI,SI")])
8500 (define_insn "*and<mode>_2"
8501   [(set (reg FLAGS_REG)
8502         (compare (and:SWI124
8503                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8504                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8505                  (const_int 0)))
8506    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8507         (and:SWI124 (match_dup 1) (match_dup 2)))]
8508   "ix86_match_ccmode (insn, CCNOmode)
8509    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8510   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8511   [(set_attr "type" "alu")
8512    (set_attr "mode" "<MODE>")])
8514 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8515 (define_insn "*andsi_2_zext"
8516   [(set (reg FLAGS_REG)
8517         (compare (and:SI
8518                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8519                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8520                  (const_int 0)))
8521    (set (match_operand:DI 0 "register_operand" "=r")
8522         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8523   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8524    && ix86_binary_operator_ok (AND, SImode, operands)"
8525   "and{l}\t{%2, %k0|%k0, %2}"
8526   [(set_attr "type" "alu")
8527    (set_attr "mode" "SI")])
8529 (define_insn "*andqi_2_slp"
8530   [(set (reg FLAGS_REG)
8531         (compare (and:QI
8532                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8533                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8534                  (const_int 0)))
8535    (set (strict_low_part (match_dup 0))
8536         (and:QI (match_dup 0) (match_dup 1)))]
8537   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8538    && ix86_match_ccmode (insn, CCNOmode)
8539    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8540   "and{b}\t{%1, %0|%0, %1}"
8541   [(set_attr "type" "alu1")
8542    (set_attr "mode" "QI")])
8544 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8545 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8546 ;; for a QImode operand, which of course failed.
8547 (define_insn "andqi_ext_0"
8548   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8549                          (const_int 8)
8550                          (const_int 8))
8551         (and:SI
8552           (zero_extract:SI
8553             (match_operand 1 "ext_register_operand" "0")
8554             (const_int 8)
8555             (const_int 8))
8556           (match_operand 2 "const_int_operand" "n")))
8557    (clobber (reg:CC FLAGS_REG))]
8558   ""
8559   "and{b}\t{%2, %h0|%h0, %2}"
8560   [(set_attr "type" "alu")
8561    (set_attr "length_immediate" "1")
8562    (set_attr "modrm" "1")
8563    (set_attr "mode" "QI")])
8565 ;; Generated by peephole translating test to and.  This shows up
8566 ;; often in fp comparisons.
8567 (define_insn "*andqi_ext_0_cc"
8568   [(set (reg FLAGS_REG)
8569         (compare
8570           (and:SI
8571             (zero_extract:SI
8572               (match_operand 1 "ext_register_operand" "0")
8573               (const_int 8)
8574               (const_int 8))
8575             (match_operand 2 "const_int_operand" "n"))
8576           (const_int 0)))
8577    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8578                          (const_int 8)
8579                          (const_int 8))
8580         (and:SI
8581           (zero_extract:SI
8582             (match_dup 1)
8583             (const_int 8)
8584             (const_int 8))
8585           (match_dup 2)))]
8586   "ix86_match_ccmode (insn, CCNOmode)"
8587   "and{b}\t{%2, %h0|%h0, %2}"
8588   [(set_attr "type" "alu")
8589    (set_attr "length_immediate" "1")
8590    (set_attr "modrm" "1")
8591    (set_attr "mode" "QI")])
8593 (define_insn "*andqi_ext_1"
8594   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8595                          (const_int 8)
8596                          (const_int 8))
8597         (and:SI
8598           (zero_extract:SI
8599             (match_operand 1 "ext_register_operand" "0,0")
8600             (const_int 8)
8601             (const_int 8))
8602           (zero_extend:SI
8603             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8604    (clobber (reg:CC FLAGS_REG))]
8605   ""
8606   "and{b}\t{%2, %h0|%h0, %2}"
8607   [(set_attr "isa" "*,nox64")
8608    (set_attr "type" "alu")
8609    (set_attr "length_immediate" "0")
8610    (set_attr "mode" "QI")])
8612 (define_insn "*andqi_ext_2"
8613   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8614                          (const_int 8)
8615                          (const_int 8))
8616         (and:SI
8617           (zero_extract:SI
8618             (match_operand 1 "ext_register_operand" "%0")
8619             (const_int 8)
8620             (const_int 8))
8621           (zero_extract:SI
8622             (match_operand 2 "ext_register_operand" "Q")
8623             (const_int 8)
8624             (const_int 8))))
8625    (clobber (reg:CC FLAGS_REG))]
8626   ""
8627   "and{b}\t{%h2, %h0|%h0, %h2}"
8628   [(set_attr "type" "alu")
8629    (set_attr "length_immediate" "0")
8630    (set_attr "mode" "QI")])
8632 ;; Convert wide AND instructions with immediate operand to shorter QImode
8633 ;; equivalents when possible.
8634 ;; Don't do the splitting with memory operands, since it introduces risk
8635 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8636 ;; for size, but that can (should?) be handled by generic code instead.
8637 (define_split
8638   [(set (match_operand 0 "QIreg_operand")
8639         (and (match_operand 1 "register_operand")
8640              (match_operand 2 "const_int_operand")))
8641    (clobber (reg:CC FLAGS_REG))]
8642    "reload_completed
8643     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8644     && !(~INTVAL (operands[2]) & ~(255 << 8))
8645     && GET_MODE (operands[0]) != QImode"
8646   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8647                    (and:SI (zero_extract:SI (match_dup 1)
8648                                             (const_int 8) (const_int 8))
8649                            (match_dup 2)))
8650               (clobber (reg:CC FLAGS_REG))])]
8652   operands[0] = gen_lowpart (SImode, operands[0]);
8653   operands[1] = gen_lowpart (SImode, operands[1]);
8654   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8657 ;; Since AND can be encoded with sign extended immediate, this is only
8658 ;; profitable when 7th bit is not set.
8659 (define_split
8660   [(set (match_operand 0 "any_QIreg_operand")
8661         (and (match_operand 1 "general_operand")
8662              (match_operand 2 "const_int_operand")))
8663    (clobber (reg:CC FLAGS_REG))]
8664    "reload_completed
8665     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8666     && !(~INTVAL (operands[2]) & ~255)
8667     && !(INTVAL (operands[2]) & 128)
8668     && GET_MODE (operands[0]) != QImode"
8669   [(parallel [(set (strict_low_part (match_dup 0))
8670                    (and:QI (match_dup 1)
8671                            (match_dup 2)))
8672               (clobber (reg:CC FLAGS_REG))])]
8674   operands[0] = gen_lowpart (QImode, operands[0]);
8675   operands[1] = gen_lowpart (QImode, operands[1]);
8676   operands[2] = gen_lowpart (QImode, operands[2]);
8679 ;; Logical inclusive and exclusive OR instructions
8681 ;; %%% This used to optimize known byte-wide and operations to memory.
8682 ;; If this is considered useful, it should be done with splitters.
8684 (define_expand "<code><mode>3"
8685   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8686         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8687                              (match_operand:SWIM1248x 2 "<general_operand>")))]
8688   ""
8689   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8691 (define_insn "*<code><mode>_1"
8692   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8693         (any_or:SWI48
8694          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8695          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8696    (clobber (reg:CC FLAGS_REG))]
8697   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8698   "@
8699    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8700    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8701    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8702   [(set_attr "type" "alu,alu,msklog")
8703    (set_attr "mode" "<MODE>")])
8705 (define_insn_and_split "*<code>di3_doubleword"
8706   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8707         (any_or:DI
8708          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8709          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8710    (clobber (reg:CC FLAGS_REG))]
8711   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8712    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8713   "#"
8714   "&& reload_completed"
8715   [(const_int 0)]
8717   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8718   if (operands[2] == constm1_rtx)
8719     {
8720       if (<CODE> == IOR)
8721         {
8722           operands[1] = constm1_rtx;
8723           ix86_expand_move (SImode, &operands[0]);
8724         }
8725       else
8726         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8727     }
8728   else if (operands[2] != const0_rtx)
8729     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8730   else if (operands[5] == const0_rtx)
8731     emit_note (NOTE_INSN_DELETED);
8732   if (operands[5] == constm1_rtx)
8733     {
8734       if (<CODE> == IOR)
8735         {
8736           operands[4] = constm1_rtx;
8737           ix86_expand_move (SImode, &operands[3]);
8738         }
8739       else
8740         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8741     }
8742   else if (operands[5] != const0_rtx)
8743     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8744   DONE;
8747 (define_insn_and_split "*andndi3_doubleword"
8748   [(set (match_operand:DI 0 "register_operand" "=r")
8749         (and:DI
8750           (not:DI (match_operand:DI 1 "register_operand" "r"))
8751           (match_operand:DI 2 "nonimmediate_operand" "rm")))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8754   "#"
8755   "&& reload_completed"
8756   [(parallel [(set (match_dup 0)
8757                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8758               (clobber (reg:CC FLAGS_REG))])
8759    (parallel [(set (match_dup 3)
8760                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8761               (clobber (reg:CC FLAGS_REG))])]
8762   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8764 (define_insn "*<code>hi_1"
8765   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8766         (any_or:HI
8767          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8768          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8771   "@
8772   <logic>{w}\t{%2, %0|%0, %2}
8773   <logic>{w}\t{%2, %0|%0, %2}
8774   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8775   [(set_attr "type" "alu,alu,msklog")
8776    (set_attr "mode" "HI")])
8778 (define_insn "*<code>qi_1"
8779   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8780         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8781                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8782    (clobber (reg:CC FLAGS_REG))]
8783   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8784   "@
8785    <logic>{b}\t{%2, %0|%0, %2}
8786    <logic>{b}\t{%2, %0|%0, %2}
8787    <logic>{l}\t{%k2, %k0|%k0, %k2}
8788    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8789   [(set_attr "type" "alu,alu,alu,msklog")
8790    (set_attr "mode" "QI,QI,SI,HI")
8791    ;; Potential partial reg stall on alternative 2.
8792    (set (attr "preferred_for_speed")
8793      (cond [(eq_attr "alternative" "2")
8794               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8795            (symbol_ref "true")))])
8797 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8798 (define_insn "*<code>si_1_zext"
8799   [(set (match_operand:DI 0 "register_operand" "=r")
8800         (zero_extend:DI
8801          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8802                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8803    (clobber (reg:CC FLAGS_REG))]
8804   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8805   "<logic>{l}\t{%2, %k0|%k0, %2}"
8806   [(set_attr "type" "alu")
8807    (set_attr "mode" "SI")])
8809 (define_insn "*<code>si_1_zext_imm"
8810   [(set (match_operand:DI 0 "register_operand" "=r")
8811         (any_or:DI
8812          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8813          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8814    (clobber (reg:CC FLAGS_REG))]
8815   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8816   "<logic>{l}\t{%2, %k0|%k0, %2}"
8817   [(set_attr "type" "alu")
8818    (set_attr "mode" "SI")])
8820 (define_insn "*<code>qi_1_slp"
8821   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8822         (any_or:QI (match_dup 0)
8823                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8826    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8827   "<logic>{b}\t{%1, %0|%0, %1}"
8828   [(set_attr "type" "alu1")
8829    (set_attr "mode" "QI")])
8831 (define_insn "*<code><mode>_2"
8832   [(set (reg FLAGS_REG)
8833         (compare (any_or:SWI
8834                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8835                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8836                  (const_int 0)))
8837    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8838         (any_or:SWI (match_dup 1) (match_dup 2)))]
8839   "ix86_match_ccmode (insn, CCNOmode)
8840    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8841   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8842   [(set_attr "type" "alu")
8843    (set_attr "mode" "<MODE>")])
8845 (define_insn "kxnor<mode>"
8846   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8847         (not:SWI12
8848           (xor:SWI12
8849             (match_operand:SWI12 1 "register_operand" "0,k")
8850             (match_operand:SWI12 2 "register_operand" "r,k"))))
8851    (clobber (reg:CC FLAGS_REG))]
8852   "TARGET_AVX512F"
8854   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8855     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8856   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8858   [(set_attr "type" "*,msklog")
8859    (set_attr "prefix" "*,vex")
8860    (set_attr "mode" "<MODE>")])
8862 (define_insn "kxnor<mode>"
8863   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8864         (not:SWI48x
8865           (xor:SWI48x
8866             (match_operand:SWI48x 1 "register_operand" "0,k")
8867             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8868    (clobber (reg:CC FLAGS_REG))]
8869   "TARGET_AVX512BW"
8870   "@
8871    #
8872    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8873   [(set_attr "type" "*,msklog")
8874    (set_attr "prefix" "*,vex")
8875    (set_attr "mode" "<MODE>")])
8877 (define_split
8878   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8879         (not:SWI1248x
8880           (xor:SWI1248x
8881             (match_dup 0)
8882             (match_operand:SWI1248x 1 "general_reg_operand"))))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "TARGET_AVX512F && reload_completed"
8885    [(parallel [(set (match_dup 0)
8886                     (xor:SWI1248x (match_dup 0)
8887                                   (match_dup 1)))
8888                (clobber (reg:CC FLAGS_REG))])
8889     (set (match_dup 0)
8890          (not:SWI1248x (match_dup 0)))])
8892 ;;There are kortrest[bdq] but no intrinsics for them.
8893 ;;We probably don't need to implement them.
8894 (define_insn "kortestzhi"
8895   [(set (reg:CCZ FLAGS_REG)
8896         (compare:CCZ
8897           (ior:HI
8898             (match_operand:HI 0 "register_operand" "k")
8899             (match_operand:HI 1 "register_operand" "k"))
8900           (const_int 0)))]
8901   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8902   "kortestw\t{%1, %0|%0, %1}"
8903   [(set_attr "mode" "HI")
8904    (set_attr "type" "msklog")
8905    (set_attr "prefix" "vex")])
8907 (define_insn "kortestchi"
8908   [(set (reg:CCC FLAGS_REG)
8909         (compare:CCC
8910           (ior:HI
8911             (match_operand:HI 0 "register_operand" "k")
8912             (match_operand:HI 1 "register_operand" "k"))
8913           (const_int -1)))]
8914   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8915   "kortestw\t{%1, %0|%0, %1}"
8916   [(set_attr "mode" "HI")
8917    (set_attr "type" "msklog")
8918    (set_attr "prefix" "vex")])
8920 (define_insn "kunpckhi"
8921   [(set (match_operand:HI 0 "register_operand" "=k")
8922         (ior:HI
8923           (ashift:HI
8924             (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8925             (const_int 8))
8926           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8927   "TARGET_AVX512F"
8928   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8929   [(set_attr "mode" "HI")
8930    (set_attr "type" "msklog")
8931    (set_attr "prefix" "vex")])
8933 (define_insn "kunpcksi"
8934   [(set (match_operand:SI 0 "register_operand" "=k")
8935         (ior:SI
8936           (ashift:SI
8937             (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8938             (const_int 16))
8939           (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8940   "TARGET_AVX512BW"
8941   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8942   [(set_attr "mode" "SI")])
8944 (define_insn "kunpckdi"
8945   [(set (match_operand:DI 0 "register_operand" "=k")
8946         (ior:DI
8947           (ashift:DI
8948             (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8949             (const_int 32))
8950           (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8951   "TARGET_AVX512BW"
8952   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8953   [(set_attr "mode" "DI")])
8955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8956 ;; ??? Special case for immediate operand is missing - it is tricky.
8957 (define_insn "*<code>si_2_zext"
8958   [(set (reg FLAGS_REG)
8959         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8960                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8961                  (const_int 0)))
8962    (set (match_operand:DI 0 "register_operand" "=r")
8963         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8964   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8966   "<logic>{l}\t{%2, %k0|%k0, %2}"
8967   [(set_attr "type" "alu")
8968    (set_attr "mode" "SI")])
8970 (define_insn "*<code>si_2_zext_imm"
8971   [(set (reg FLAGS_REG)
8972         (compare (any_or:SI
8973                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8974                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8975                  (const_int 0)))
8976    (set (match_operand:DI 0 "register_operand" "=r")
8977         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8978   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8979    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8980   "<logic>{l}\t{%2, %k0|%k0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8984 (define_insn "*<code>qi_2_slp"
8985   [(set (reg FLAGS_REG)
8986         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8987                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8988                  (const_int 0)))
8989    (set (strict_low_part (match_dup 0))
8990         (any_or:QI (match_dup 0) (match_dup 1)))]
8991   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992    && ix86_match_ccmode (insn, CCNOmode)
8993    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8994   "<logic>{b}\t{%1, %0|%0, %1}"
8995   [(set_attr "type" "alu1")
8996    (set_attr "mode" "QI")])
8998 (define_insn "*<code><mode>_3"
8999   [(set (reg FLAGS_REG)
9000         (compare (any_or:SWI
9001                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9002                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9003                  (const_int 0)))
9004    (clobber (match_scratch:SWI 0 "=<r>"))]
9005   "ix86_match_ccmode (insn, CCNOmode)
9006    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9007   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9008   [(set_attr "type" "alu")
9009    (set_attr "mode" "<MODE>")])
9011 (define_insn "*<code>qi_ext_0"
9012   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9013                          (const_int 8)
9014                          (const_int 8))
9015         (any_or:SI
9016           (zero_extract:SI
9017             (match_operand 1 "ext_register_operand" "0")
9018             (const_int 8)
9019             (const_int 8))
9020           (match_operand 2 "const_int_operand" "n")))
9021    (clobber (reg:CC FLAGS_REG))]
9022   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9023   "<logic>{b}\t{%2, %h0|%h0, %2}"
9024   [(set_attr "type" "alu")
9025    (set_attr "length_immediate" "1")
9026    (set_attr "modrm" "1")
9027    (set_attr "mode" "QI")])
9029 (define_insn "*<code>qi_ext_1"
9030   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9031                          (const_int 8)
9032                          (const_int 8))
9033         (any_or:SI
9034           (zero_extract:SI
9035             (match_operand 1 "ext_register_operand" "0,0")
9036             (const_int 8)
9037             (const_int 8))
9038           (zero_extend:SI
9039             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9042   "<logic>{b}\t{%2, %h0|%h0, %2}"
9043   [(set_attr "isa" "*,nox64")
9044    (set_attr "type" "alu")
9045    (set_attr "length_immediate" "0")
9046    (set_attr "mode" "QI")])
9048 (define_insn "*<code>qi_ext_2"
9049   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9050                          (const_int 8)
9051                          (const_int 8))
9052         (any_or:SI
9053           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9054                            (const_int 8)
9055                            (const_int 8))
9056           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9057                            (const_int 8)
9058                            (const_int 8))))
9059    (clobber (reg:CC FLAGS_REG))]
9060   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9061   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9062   [(set_attr "type" "alu")
9063    (set_attr "length_immediate" "0")
9064    (set_attr "mode" "QI")])
9066 (define_split
9067   [(set (match_operand 0 "QIreg_operand")
9068         (any_or (match_operand 1 "register_operand")
9069                 (match_operand 2 "const_int_operand")))
9070    (clobber (reg:CC FLAGS_REG))]
9071    "reload_completed
9072     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9073     && !(INTVAL (operands[2]) & ~(255 << 8))
9074     && GET_MODE (operands[0]) != QImode"
9075   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9076                    (any_or:SI (zero_extract:SI (match_dup 1)
9077                                                (const_int 8) (const_int 8))
9078                               (match_dup 2)))
9079               (clobber (reg:CC FLAGS_REG))])]
9081   operands[0] = gen_lowpart (SImode, operands[0]);
9082   operands[1] = gen_lowpart (SImode, operands[1]);
9083   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
9086 ;; Since OR can be encoded with sign extended immediate, this is only
9087 ;; profitable when 7th bit is set.
9088 (define_split
9089   [(set (match_operand 0 "any_QIreg_operand")
9090         (any_or (match_operand 1 "general_operand")
9091                 (match_operand 2 "const_int_operand")))
9092    (clobber (reg:CC FLAGS_REG))]
9093    "reload_completed
9094     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9095     && !(INTVAL (operands[2]) & ~255)
9096     && (INTVAL (operands[2]) & 128)
9097     && GET_MODE (operands[0]) != QImode"
9098   [(parallel [(set (strict_low_part (match_dup 0))
9099                    (any_or:QI (match_dup 1)
9100                               (match_dup 2)))
9101               (clobber (reg:CC FLAGS_REG))])]
9103   operands[0] = gen_lowpart (QImode, operands[0]);
9104   operands[1] = gen_lowpart (QImode, operands[1]);
9105   operands[2] = gen_lowpart (QImode, operands[2]);
9108 (define_expand "xorqi_cc_ext_1"
9109   [(parallel [
9110      (set (reg:CCNO FLAGS_REG)
9111           (compare:CCNO
9112             (xor:SI
9113               (zero_extract:SI
9114                 (match_operand 1 "ext_register_operand")
9115                 (const_int 8)
9116                 (const_int 8))
9117               (match_operand:QI 2 "const_int_operand"))
9118             (const_int 0)))
9119      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9120                            (const_int 8)
9121                            (const_int 8))
9122           (xor:SI
9123             (zero_extract:SI
9124              (match_dup 1)
9125              (const_int 8)
9126              (const_int 8))
9127             (match_dup 2)))])])
9129 (define_insn "*xorqi_cc_ext_1"
9130   [(set (reg FLAGS_REG)
9131         (compare
9132           (xor:SI
9133             (zero_extract:SI
9134               (match_operand 1 "ext_register_operand" "0,0")
9135               (const_int 8)
9136               (const_int 8))
9137             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9138           (const_int 0)))
9139    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9140                          (const_int 8)
9141                          (const_int 8))
9142         (xor:SI
9143           (zero_extract:SI
9144            (match_dup 1)
9145            (const_int 8)
9146            (const_int 8))
9147           (match_dup 2)))]
9148   "ix86_match_ccmode (insn, CCNOmode)"
9149   "xor{b}\t{%2, %h0|%h0, %2}"
9150   [(set_attr "isa" "*,nox64")
9151    (set_attr "type" "alu")
9152    (set_attr "modrm" "1")
9153    (set_attr "mode" "QI")])
9155 ;; Negation instructions
9157 (define_expand "neg<mode>2"
9158   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9159         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9160   ""
9161   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9163 (define_insn_and_split "*neg<dwi>2_doubleword"
9164   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9165         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9166    (clobber (reg:CC FLAGS_REG))]
9167   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9168   "#"
9169   "reload_completed"
9170   [(parallel
9171     [(set (reg:CCZ FLAGS_REG)
9172           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9173      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9174    (parallel
9175     [(set (match_dup 2)
9176           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9177                                 (match_dup 3))
9178                      (const_int 0)))
9179      (clobber (reg:CC FLAGS_REG))])
9180    (parallel
9181     [(set (match_dup 2)
9182           (neg:DWIH (match_dup 2)))
9183      (clobber (reg:CC FLAGS_REG))])]
9184   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9186 (define_insn "*neg<mode>2_1"
9187   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9188         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9189    (clobber (reg:CC FLAGS_REG))]
9190   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9191   "neg{<imodesuffix>}\t%0"
9192   [(set_attr "type" "negnot")
9193    (set_attr "mode" "<MODE>")])
9195 ;; Combine is quite creative about this pattern.
9196 (define_insn "*negsi2_1_zext"
9197   [(set (match_operand:DI 0 "register_operand" "=r")
9198         (lshiftrt:DI
9199           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9200                              (const_int 32)))
9201         (const_int 32)))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9204   "neg{l}\t%k0"
9205   [(set_attr "type" "negnot")
9206    (set_attr "mode" "SI")])
9208 ;; The problem with neg is that it does not perform (compare x 0),
9209 ;; it really performs (compare 0 x), which leaves us with the zero
9210 ;; flag being the only useful item.
9212 (define_insn "*neg<mode>2_cmpz"
9213   [(set (reg:CCZ FLAGS_REG)
9214         (compare:CCZ
9215           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9216                    (const_int 0)))
9217    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9218         (neg:SWI (match_dup 1)))]
9219   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9220   "neg{<imodesuffix>}\t%0"
9221   [(set_attr "type" "negnot")
9222    (set_attr "mode" "<MODE>")])
9224 (define_insn "*negsi2_cmpz_zext"
9225   [(set (reg:CCZ FLAGS_REG)
9226         (compare:CCZ
9227           (lshiftrt:DI
9228             (neg:DI (ashift:DI
9229                       (match_operand:DI 1 "register_operand" "0")
9230                       (const_int 32)))
9231             (const_int 32))
9232           (const_int 0)))
9233    (set (match_operand:DI 0 "register_operand" "=r")
9234         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9235                                         (const_int 32)))
9236                      (const_int 32)))]
9237   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9238   "neg{l}\t%k0"
9239   [(set_attr "type" "negnot")
9240    (set_attr "mode" "SI")])
9242 ;; Negate with jump on overflow.
9243 (define_expand "negv<mode>3"
9244   [(parallel [(set (reg:CCO FLAGS_REG)
9245                    (ne:CCO (match_operand:SWI 1 "register_operand")
9246                            (match_dup 3)))
9247               (set (match_operand:SWI 0 "register_operand")
9248                    (neg:SWI (match_dup 1)))])
9249    (set (pc) (if_then_else
9250                (eq (reg:CCO FLAGS_REG) (const_int 0))
9251                (label_ref (match_operand 2))
9252                (pc)))]
9253   ""
9255   operands[3]
9256     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9257                     <MODE>mode);
9260 (define_insn "*negv<mode>3"
9261   [(set (reg:CCO FLAGS_REG)
9262         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9263                 (match_operand:SWI 2 "const_int_operand")))
9264    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9265         (neg:SWI (match_dup 1)))]
9266   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9267    && mode_signbit_p (<MODE>mode, operands[2])"
9268   "neg{<imodesuffix>}\t%0"
9269   [(set_attr "type" "negnot")
9270    (set_attr "mode" "<MODE>")])
9272 ;; Changing of sign for FP values is doable using integer unit too.
9274 (define_expand "<code><mode>2"
9275   [(set (match_operand:X87MODEF 0 "register_operand")
9276         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9277   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9278   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9280 (define_insn "*absneg<mode>2"
9281   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9282         (match_operator:MODEF 3 "absneg_operator"
9283           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9284    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9285    (clobber (reg:CC FLAGS_REG))]
9286   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9287   "#"
9288   [(set (attr "enabled")
9289      (if_then_else
9290        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9291        (if_then_else
9292          (eq_attr "alternative" "2")
9293          (symbol_ref "TARGET_MIX_SSE_I387")
9294          (symbol_ref "true"))
9295        (if_then_else
9296          (eq_attr "alternative" "2,3")
9297          (symbol_ref "true")
9298          (symbol_ref "false"))))])
9300 (define_insn "*absnegxf2_i387"
9301   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9302         (match_operator:XF 3 "absneg_operator"
9303           [(match_operand:XF 1 "register_operand" "0,0")]))
9304    (use (match_operand 2))
9305    (clobber (reg:CC FLAGS_REG))]
9306   "TARGET_80387"
9307   "#")
9309 (define_expand "<code>tf2"
9310   [(set (match_operand:TF 0 "register_operand")
9311         (absneg:TF (match_operand:TF 1 "register_operand")))]
9312   "TARGET_SSE"
9313   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9315 (define_insn "*absnegtf2_sse"
9316   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9317         (match_operator:TF 3 "absneg_operator"
9318           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9319    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9320    (clobber (reg:CC FLAGS_REG))]
9321   "TARGET_SSE"
9322   "#")
9324 ;; Splitters for fp abs and neg.
9326 (define_split
9327   [(set (match_operand 0 "fp_register_operand")
9328         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9329    (use (match_operand 2))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "reload_completed"
9332   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9334 (define_split
9335   [(set (match_operand 0 "sse_reg_operand")
9336         (match_operator 3 "absneg_operator"
9337           [(match_operand 1 "register_operand")]))
9338    (use (match_operand 2 "nonimmediate_operand"))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "reload_completed"
9341   [(set (match_dup 0) (match_dup 3))]
9343   machine_mode mode = GET_MODE (operands[0]);
9344   machine_mode vmode = GET_MODE (operands[2]);
9345   rtx tmp;
9347   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9348   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9349   if (operands_match_p (operands[0], operands[2]))
9350     std::swap (operands[1], operands[2]);
9351   if (GET_CODE (operands[3]) == ABS)
9352     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9353   else
9354     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9355   operands[3] = tmp;
9358 (define_split
9359   [(set (match_operand:SF 0 "general_reg_operand")
9360         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9361    (use (match_operand:V4SF 2))
9362    (clobber (reg:CC FLAGS_REG))]
9363   "reload_completed"
9364   [(parallel [(set (match_dup 0) (match_dup 1))
9365               (clobber (reg:CC FLAGS_REG))])]
9367   rtx tmp;
9368   operands[0] = gen_lowpart (SImode, operands[0]);
9369   if (GET_CODE (operands[1]) == ABS)
9370     {
9371       tmp = gen_int_mode (0x7fffffff, SImode);
9372       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9373     }
9374   else
9375     {
9376       tmp = gen_int_mode (0x80000000, SImode);
9377       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9378     }
9379   operands[1] = tmp;
9382 (define_split
9383   [(set (match_operand:DF 0 "general_reg_operand")
9384         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9385    (use (match_operand 2))
9386    (clobber (reg:CC FLAGS_REG))]
9387   "reload_completed"
9388   [(parallel [(set (match_dup 0) (match_dup 1))
9389               (clobber (reg:CC FLAGS_REG))])]
9391   rtx tmp;
9392   if (TARGET_64BIT)
9393     {
9394       tmp = gen_lowpart (DImode, operands[0]);
9395       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9396       operands[0] = tmp;
9398       if (GET_CODE (operands[1]) == ABS)
9399         tmp = const0_rtx;
9400       else
9401         tmp = gen_rtx_NOT (DImode, tmp);
9402     }
9403   else
9404     {
9405       operands[0] = gen_highpart (SImode, operands[0]);
9406       if (GET_CODE (operands[1]) == ABS)
9407         {
9408           tmp = gen_int_mode (0x7fffffff, SImode);
9409           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9410         }
9411       else
9412         {
9413           tmp = gen_int_mode (0x80000000, SImode);
9414           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9415         }
9416     }
9417   operands[1] = tmp;
9420 (define_split
9421   [(set (match_operand:XF 0 "general_reg_operand")
9422         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9423    (use (match_operand 2))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "reload_completed"
9426   [(parallel [(set (match_dup 0) (match_dup 1))
9427               (clobber (reg:CC FLAGS_REG))])]
9429   rtx tmp;
9430   operands[0] = gen_rtx_REG (SImode,
9431                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9432   if (GET_CODE (operands[1]) == ABS)
9433     {
9434       tmp = GEN_INT (0x7fff);
9435       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9436     }
9437   else
9438     {
9439       tmp = GEN_INT (0x8000);
9440       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9441     }
9442   operands[1] = tmp;
9445 ;; Conditionalize these after reload. If they match before reload, we
9446 ;; lose the clobber and ability to use integer instructions.
9448 (define_insn "*<code><mode>2_1"
9449   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9450         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9451   "TARGET_80387
9452    && (reload_completed
9453        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9454   "f<absneg_mnemonic>"
9455   [(set_attr "type" "fsgn")
9456    (set_attr "mode" "<MODE>")])
9458 (define_insn "*<code>extendsfdf2"
9459   [(set (match_operand:DF 0 "register_operand" "=f")
9460         (absneg:DF (float_extend:DF
9461                      (match_operand:SF 1 "register_operand" "0"))))]
9462   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9463   "f<absneg_mnemonic>"
9464   [(set_attr "type" "fsgn")
9465    (set_attr "mode" "DF")])
9467 (define_insn "*<code>extendsfxf2"
9468   [(set (match_operand:XF 0 "register_operand" "=f")
9469         (absneg:XF (float_extend:XF
9470                      (match_operand:SF 1 "register_operand" "0"))))]
9471   "TARGET_80387"
9472   "f<absneg_mnemonic>"
9473   [(set_attr "type" "fsgn")
9474    (set_attr "mode" "XF")])
9476 (define_insn "*<code>extenddfxf2"
9477   [(set (match_operand:XF 0 "register_operand" "=f")
9478         (absneg:XF (float_extend:XF
9479                      (match_operand:DF 1 "register_operand" "0"))))]
9480   "TARGET_80387"
9481   "f<absneg_mnemonic>"
9482   [(set_attr "type" "fsgn")
9483    (set_attr "mode" "XF")])
9485 ;; Copysign instructions
9487 (define_mode_iterator CSGNMODE [SF DF TF])
9488 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9490 (define_expand "copysign<mode>3"
9491   [(match_operand:CSGNMODE 0 "register_operand")
9492    (match_operand:CSGNMODE 1 "nonmemory_operand")
9493    (match_operand:CSGNMODE 2 "register_operand")]
9494   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9495    || (TARGET_SSE && (<MODE>mode == TFmode))"
9496   "ix86_expand_copysign (operands); DONE;")
9498 (define_insn_and_split "copysign<mode>3_const"
9499   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9500         (unspec:CSGNMODE
9501           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9502            (match_operand:CSGNMODE 2 "register_operand" "0")
9503            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9504           UNSPEC_COPYSIGN))]
9505   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9506    || (TARGET_SSE && (<MODE>mode == TFmode))"
9507   "#"
9508   "&& reload_completed"
9509   [(const_int 0)]
9510   "ix86_split_copysign_const (operands); DONE;")
9512 (define_insn "copysign<mode>3_var"
9513   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9514         (unspec:CSGNMODE
9515           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9516            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9517            (match_operand:<CSGNVMODE> 4
9518              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9519            (match_operand:<CSGNVMODE> 5
9520              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9521           UNSPEC_COPYSIGN))
9522    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9523   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9524    || (TARGET_SSE && (<MODE>mode == TFmode))"
9525   "#")
9527 (define_split
9528   [(set (match_operand:CSGNMODE 0 "register_operand")
9529         (unspec:CSGNMODE
9530           [(match_operand:CSGNMODE 2 "register_operand")
9531            (match_operand:CSGNMODE 3 "register_operand")
9532            (match_operand:<CSGNVMODE> 4)
9533            (match_operand:<CSGNVMODE> 5)]
9534           UNSPEC_COPYSIGN))
9535    (clobber (match_scratch:<CSGNVMODE> 1))]
9536   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9537     || (TARGET_SSE && (<MODE>mode == TFmode)))
9538    && reload_completed"
9539   [(const_int 0)]
9540   "ix86_split_copysign_var (operands); DONE;")
9542 ;; One complement instructions
9544 (define_expand "one_cmpl<mode>2"
9545   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9546         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9547   ""
9548   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9550 (define_insn "*one_cmpl<mode>2_1"
9551   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9552         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9553   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9554   "@
9555    not{<imodesuffix>}\t%0
9556    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9557   [(set_attr "isa" "*,avx512bw")
9558    (set_attr "type" "negnot,msklog")
9559    (set_attr "prefix" "*,vex")
9560    (set_attr "mode" "<MODE>")])
9562 (define_insn "*one_cmplhi2_1"
9563   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9564         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9565   "ix86_unary_operator_ok (NOT, HImode, operands)"
9566   "@
9567    not{w}\t%0
9568    knotw\t{%1, %0|%0, %1}"
9569   [(set_attr "isa" "*,avx512f")
9570    (set_attr "type" "negnot,msklog")
9571    (set_attr "prefix" "*,vex")
9572    (set_attr "mode" "HI")])
9574 (define_insn "*one_cmplqi2_1"
9575   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9576         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9577   "ix86_unary_operator_ok (NOT, QImode, operands)"
9579   switch (which_alternative)
9580     {
9581     case 0:
9582       return "not{b}\t%0";
9583     case 1:
9584       return "not{l}\t%k0";
9585     case 2:
9586       if (TARGET_AVX512DQ)
9587         return "knotb\t{%1, %0|%0, %1}";
9588       return "knotw\t{%1, %0|%0, %1}";
9589     default:
9590       gcc_unreachable ();
9591     }
9593   [(set_attr "isa" "*,*,avx512f")
9594    (set_attr "type" "negnot,negnot,msklog")
9595    (set_attr "prefix" "*,*,vex")
9596    (set_attr "mode" "QI,SI,QI")
9597    ;; Potential partial reg stall on alternative 1.
9598    (set (attr "preferred_for_speed")
9599      (cond [(eq_attr "alternative" "1")
9600               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9601            (symbol_ref "true")))])
9603 ;; ??? Currently never generated - xor is used instead.
9604 (define_insn "*one_cmplsi2_1_zext"
9605   [(set (match_operand:DI 0 "register_operand" "=r")
9606         (zero_extend:DI
9607           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9608   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9609   "not{l}\t%k0"
9610   [(set_attr "type" "negnot")
9611    (set_attr "mode" "SI")])
9613 (define_insn "*one_cmpl<mode>2_2"
9614   [(set (reg FLAGS_REG)
9615         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9616                  (const_int 0)))
9617    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9618         (not:SWI (match_dup 1)))]
9619   "ix86_match_ccmode (insn, CCNOmode)
9620    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9621   "#"
9622   [(set_attr "type" "alu1")
9623    (set_attr "mode" "<MODE>")])
9625 (define_split
9626   [(set (match_operand 0 "flags_reg_operand")
9627         (match_operator 2 "compare_operator"
9628           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9629            (const_int 0)]))
9630    (set (match_operand:SWI 1 "nonimmediate_operand")
9631         (not:SWI (match_dup 3)))]
9632   "ix86_match_ccmode (insn, CCNOmode)"
9633   [(parallel [(set (match_dup 0)
9634                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9635                                     (const_int 0)]))
9636               (set (match_dup 1)
9637                    (xor:SWI (match_dup 3) (const_int -1)))])])
9639 ;; ??? Currently never generated - xor is used instead.
9640 (define_insn "*one_cmplsi2_2_zext"
9641   [(set (reg FLAGS_REG)
9642         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9643                  (const_int 0)))
9644    (set (match_operand:DI 0 "register_operand" "=r")
9645         (zero_extend:DI (not:SI (match_dup 1))))]
9646   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9647    && ix86_unary_operator_ok (NOT, SImode, operands)"
9648   "#"
9649   [(set_attr "type" "alu1")
9650    (set_attr "mode" "SI")])
9652 (define_split
9653   [(set (match_operand 0 "flags_reg_operand")
9654         (match_operator 2 "compare_operator"
9655           [(not:SI (match_operand:SI 3 "register_operand"))
9656            (const_int 0)]))
9657    (set (match_operand:DI 1 "register_operand")
9658         (zero_extend:DI (not:SI (match_dup 3))))]
9659   "ix86_match_ccmode (insn, CCNOmode)"
9660   [(parallel [(set (match_dup 0)
9661                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9662                                     (const_int 0)]))
9663               (set (match_dup 1)
9664                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9666 ;; Shift instructions
9668 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9669 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9670 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9671 ;; from the assembler input.
9673 ;; This instruction shifts the target reg/mem as usual, but instead of
9674 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9675 ;; is a left shift double, bits are taken from the high order bits of
9676 ;; reg, else if the insn is a shift right double, bits are taken from the
9677 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9678 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9680 ;; Since sh[lr]d does not change the `reg' operand, that is done
9681 ;; separately, making all shifts emit pairs of shift double and normal
9682 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9683 ;; support a 63 bit shift, each shift where the count is in a reg expands
9684 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9686 ;; If the shift count is a constant, we need never emit more than one
9687 ;; shift pair, instead using moves and sign extension for counts greater
9688 ;; than 31.
9690 (define_insn "*<mshift><mode>3"
9691   [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9692         (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9693                                        (match_operand:QI 2 "immediate_operand" "i")))]
9694   "TARGET_AVX512F"
9695   "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9696   [(set_attr "type" "msklog")
9697    (set_attr "prefix" "vex")])
9699 (define_expand "ashl<mode>3"
9700   [(set (match_operand:SDWIM 0 "<shift_operand>")
9701         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9702                       (match_operand:QI 2 "nonmemory_operand")))]
9703   ""
9704   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9706 (define_insn "*ashl<mode>3_doubleword"
9707   [(set (match_operand:DWI 0 "register_operand" "=&r")
9708         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9709                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   ""
9712   "#"
9713   [(set_attr "type" "multi")])
9715 (define_split
9716   [(set (match_operand:DWI 0 "register_operand")
9717         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9718                     (match_operand:QI 2 "nonmemory_operand")))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9721   [(const_int 0)]
9722   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9724 ;; By default we don't ask for a scratch register, because when DWImode
9725 ;; values are manipulated, registers are already at a premium.  But if
9726 ;; we have one handy, we won't turn it away.
9728 (define_peephole2
9729   [(match_scratch:DWIH 3 "r")
9730    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9731                    (ashift:<DWI>
9732                      (match_operand:<DWI> 1 "nonmemory_operand")
9733                      (match_operand:QI 2 "nonmemory_operand")))
9734               (clobber (reg:CC FLAGS_REG))])
9735    (match_dup 3)]
9736   "TARGET_CMOVE"
9737   [(const_int 0)]
9738   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9740 (define_insn "x86_64_shld"
9741   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9742         (ior:DI (ashift:DI (match_dup 0)
9743                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9744                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9745                   (minus:QI (const_int 64) (match_dup 2)))))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "TARGET_64BIT"
9748   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9749   [(set_attr "type" "ishift")
9750    (set_attr "prefix_0f" "1")
9751    (set_attr "mode" "DI")
9752    (set_attr "athlon_decode" "vector")
9753    (set_attr "amdfam10_decode" "vector")
9754    (set_attr "bdver1_decode" "vector")])
9756 (define_insn "x86_shld"
9757   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9758         (ior:SI (ashift:SI (match_dup 0)
9759                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9760                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9761                   (minus:QI (const_int 32) (match_dup 2)))))
9762    (clobber (reg:CC FLAGS_REG))]
9763   ""
9764   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9765   [(set_attr "type" "ishift")
9766    (set_attr "prefix_0f" "1")
9767    (set_attr "mode" "SI")
9768    (set_attr "pent_pair" "np")
9769    (set_attr "athlon_decode" "vector")
9770    (set_attr "amdfam10_decode" "vector")
9771    (set_attr "bdver1_decode" "vector")])
9773 (define_expand "x86_shift<mode>_adj_1"
9774   [(set (reg:CCZ FLAGS_REG)
9775         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9776                              (match_dup 4))
9777                      (const_int 0)))
9778    (set (match_operand:SWI48 0 "register_operand")
9779         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9780                             (match_operand:SWI48 1 "register_operand")
9781                             (match_dup 0)))
9782    (set (match_dup 1)
9783         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9784                             (match_operand:SWI48 3 "register_operand")
9785                             (match_dup 1)))]
9786   "TARGET_CMOVE"
9787   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9789 (define_expand "x86_shift<mode>_adj_2"
9790   [(use (match_operand:SWI48 0 "register_operand"))
9791    (use (match_operand:SWI48 1 "register_operand"))
9792    (use (match_operand:QI 2 "register_operand"))]
9793   ""
9795   rtx_code_label *label = gen_label_rtx ();
9796   rtx tmp;
9798   emit_insn (gen_testqi_ccz_1 (operands[2],
9799                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9801   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9802   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9803   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9804                               gen_rtx_LABEL_REF (VOIDmode, label),
9805                               pc_rtx);
9806   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9807   JUMP_LABEL (tmp) = label;
9809   emit_move_insn (operands[0], operands[1]);
9810   ix86_expand_clear (operands[1]);
9812   emit_label (label);
9813   LABEL_NUSES (label) = 1;
9815   DONE;
9818 ;; Avoid useless masking of count operand.
9819 (define_insn_and_split "*ashl<mode>3_mask"
9820   [(set (match_operand:SWI48 0 "nonimmediate_operand")
9821         (ashift:SWI48
9822           (match_operand:SWI48 1 "nonimmediate_operand")
9823           (subreg:QI
9824             (and:SI
9825               (match_operand:SI 2 "register_operand")
9826               (match_operand:SI 3 "const_int_operand")) 0)))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9829    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9830       == GET_MODE_BITSIZE (<MODE>mode)-1
9831    && can_create_pseudo_p ()"
9832   "#"
9833   "&& 1"
9834   [(parallel
9835      [(set (match_dup 0)
9836            (ashift:SWI48 (match_dup 1)
9837                          (match_dup 2)))
9838       (clobber (reg:CC FLAGS_REG))])]
9839   "operands[2] = gen_lowpart (QImode, operands[2]);")
9841 (define_insn "*bmi2_ashl<mode>3_1"
9842   [(set (match_operand:SWI48 0 "register_operand" "=r")
9843         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9844                       (match_operand:SWI48 2 "register_operand" "r")))]
9845   "TARGET_BMI2"
9846   "shlx\t{%2, %1, %0|%0, %1, %2}"
9847   [(set_attr "type" "ishiftx")
9848    (set_attr "mode" "<MODE>")])
9850 (define_insn "*ashl<mode>3_1"
9851   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9852         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9853                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9854    (clobber (reg:CC FLAGS_REG))]
9855   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9857   switch (get_attr_type (insn))
9858     {
9859     case TYPE_LEA:
9860     case TYPE_ISHIFTX:
9861       return "#";
9863     case TYPE_ALU:
9864       gcc_assert (operands[2] == const1_rtx);
9865       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9866       return "add{<imodesuffix>}\t%0, %0";
9868     default:
9869       if (operands[2] == const1_rtx
9870           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9871         return "sal{<imodesuffix>}\t%0";
9872       else
9873         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9874     }
9876   [(set_attr "isa" "*,*,bmi2")
9877    (set (attr "type")
9878      (cond [(eq_attr "alternative" "1")
9879               (const_string "lea")
9880             (eq_attr "alternative" "2")
9881               (const_string "ishiftx")
9882             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9883                       (match_operand 0 "register_operand"))
9884                  (match_operand 2 "const1_operand"))
9885               (const_string "alu")
9886            ]
9887            (const_string "ishift")))
9888    (set (attr "length_immediate")
9889      (if_then_else
9890        (ior (eq_attr "type" "alu")
9891             (and (eq_attr "type" "ishift")
9892                  (and (match_operand 2 "const1_operand")
9893                       (ior (match_test "TARGET_SHIFT1")
9894                            (match_test "optimize_function_for_size_p (cfun)")))))
9895        (const_string "0")
9896        (const_string "*")))
9897    (set_attr "mode" "<MODE>")])
9899 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9900 (define_split
9901   [(set (match_operand:SWI48 0 "register_operand")
9902         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9903                       (match_operand:QI 2 "register_operand")))
9904    (clobber (reg:CC FLAGS_REG))]
9905   "TARGET_BMI2 && reload_completed"
9906   [(set (match_dup 0)
9907         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9908   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9910 (define_insn "*bmi2_ashlsi3_1_zext"
9911   [(set (match_operand:DI 0 "register_operand" "=r")
9912         (zero_extend:DI
9913           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9914                      (match_operand:SI 2 "register_operand" "r"))))]
9915   "TARGET_64BIT && TARGET_BMI2"
9916   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9917   [(set_attr "type" "ishiftx")
9918    (set_attr "mode" "SI")])
9920 (define_insn "*ashlsi3_1_zext"
9921   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9922         (zero_extend:DI
9923           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9924                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9925    (clobber (reg:CC FLAGS_REG))]
9926   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9928   switch (get_attr_type (insn))
9929     {
9930     case TYPE_LEA:
9931     case TYPE_ISHIFTX:
9932       return "#";
9934     case TYPE_ALU:
9935       gcc_assert (operands[2] == const1_rtx);
9936       return "add{l}\t%k0, %k0";
9938     default:
9939       if (operands[2] == const1_rtx
9940           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9941         return "sal{l}\t%k0";
9942       else
9943         return "sal{l}\t{%2, %k0|%k0, %2}";
9944     }
9946   [(set_attr "isa" "*,*,bmi2")
9947    (set (attr "type")
9948      (cond [(eq_attr "alternative" "1")
9949               (const_string "lea")
9950             (eq_attr "alternative" "2")
9951               (const_string "ishiftx")
9952             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9953                  (match_operand 2 "const1_operand"))
9954               (const_string "alu")
9955            ]
9956            (const_string "ishift")))
9957    (set (attr "length_immediate")
9958      (if_then_else
9959        (ior (eq_attr "type" "alu")
9960             (and (eq_attr "type" "ishift")
9961                  (and (match_operand 2 "const1_operand")
9962                       (ior (match_test "TARGET_SHIFT1")
9963                            (match_test "optimize_function_for_size_p (cfun)")))))
9964        (const_string "0")
9965        (const_string "*")))
9966    (set_attr "mode" "SI")])
9968 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9969 (define_split
9970   [(set (match_operand:DI 0 "register_operand")
9971         (zero_extend:DI
9972           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9973                      (match_operand:QI 2 "register_operand"))))
9974    (clobber (reg:CC FLAGS_REG))]
9975   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9976   [(set (match_dup 0)
9977         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9978   "operands[2] = gen_lowpart (SImode, operands[2]);")
9980 (define_insn "*ashlhi3_1"
9981   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9982         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9983                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9984    (clobber (reg:CC FLAGS_REG))]
9985   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9987   switch (get_attr_type (insn))
9988     {
9989     case TYPE_LEA:
9990       return "#";
9992     case TYPE_ALU:
9993       gcc_assert (operands[2] == const1_rtx);
9994       return "add{w}\t%0, %0";
9996     default:
9997       if (operands[2] == const1_rtx
9998           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9999         return "sal{w}\t%0";
10000       else
10001         return "sal{w}\t{%2, %0|%0, %2}";
10002     }
10004   [(set (attr "type")
10005      (cond [(eq_attr "alternative" "1")
10006               (const_string "lea")
10007             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10008                       (match_operand 0 "register_operand"))
10009                  (match_operand 2 "const1_operand"))
10010               (const_string "alu")
10011            ]
10012            (const_string "ishift")))
10013    (set (attr "length_immediate")
10014      (if_then_else
10015        (ior (eq_attr "type" "alu")
10016             (and (eq_attr "type" "ishift")
10017                  (and (match_operand 2 "const1_operand")
10018                       (ior (match_test "TARGET_SHIFT1")
10019                            (match_test "optimize_function_for_size_p (cfun)")))))
10020        (const_string "0")
10021        (const_string "*")))
10022    (set_attr "mode" "HI,SI")])
10024 (define_insn "*ashlqi3_1"
10025   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10026         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10027                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10028    (clobber (reg:CC FLAGS_REG))]
10029   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10031   switch (get_attr_type (insn))
10032     {
10033     case TYPE_LEA:
10034       return "#";
10036     case TYPE_ALU:
10037       gcc_assert (operands[2] == const1_rtx);
10038       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10039         return "add{l}\t%k0, %k0";
10040       else
10041         return "add{b}\t%0, %0";
10043     default:
10044       if (operands[2] == const1_rtx
10045           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10046         {
10047           if (get_attr_mode (insn) == MODE_SI)
10048             return "sal{l}\t%k0";
10049           else
10050             return "sal{b}\t%0";
10051         }
10052       else
10053         {
10054           if (get_attr_mode (insn) == MODE_SI)
10055             return "sal{l}\t{%2, %k0|%k0, %2}";
10056           else
10057             return "sal{b}\t{%2, %0|%0, %2}";
10058         }
10059     }
10061   [(set (attr "type")
10062      (cond [(eq_attr "alternative" "2")
10063               (const_string "lea")
10064             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10065                       (match_operand 0 "register_operand"))
10066                  (match_operand 2 "const1_operand"))
10067               (const_string "alu")
10068            ]
10069            (const_string "ishift")))
10070    (set (attr "length_immediate")
10071      (if_then_else
10072        (ior (eq_attr "type" "alu")
10073             (and (eq_attr "type" "ishift")
10074                  (and (match_operand 2 "const1_operand")
10075                       (ior (match_test "TARGET_SHIFT1")
10076                            (match_test "optimize_function_for_size_p (cfun)")))))
10077        (const_string "0")
10078        (const_string "*")))
10079    (set_attr "mode" "QI,SI,SI")
10080    ;; Potential partial reg stall on alternative 1.
10081    (set (attr "preferred_for_speed")
10082      (cond [(eq_attr "alternative" "1")
10083               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10084            (symbol_ref "true")))])
10086 (define_insn "*ashlqi3_1_slp"
10087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10088         (ashift:QI (match_dup 0)
10089                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10090    (clobber (reg:CC FLAGS_REG))]
10091   "(optimize_function_for_size_p (cfun)
10092     || !TARGET_PARTIAL_FLAG_REG_STALL
10093     || (operands[1] == const1_rtx
10094         && (TARGET_SHIFT1
10095             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10097   switch (get_attr_type (insn))
10098     {
10099     case TYPE_ALU:
10100       gcc_assert (operands[1] == const1_rtx);
10101       return "add{b}\t%0, %0";
10103     default:
10104       if (operands[1] == const1_rtx
10105           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10106         return "sal{b}\t%0";
10107       else
10108         return "sal{b}\t{%1, %0|%0, %1}";
10109     }
10111   [(set (attr "type")
10112      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10113                       (match_operand 0 "register_operand"))
10114                  (match_operand 1 "const1_operand"))
10115               (const_string "alu")
10116            ]
10117            (const_string "ishift1")))
10118    (set (attr "length_immediate")
10119      (if_then_else
10120        (ior (eq_attr "type" "alu")
10121             (and (eq_attr "type" "ishift1")
10122                  (and (match_operand 1 "const1_operand")
10123                       (ior (match_test "TARGET_SHIFT1")
10124                            (match_test "optimize_function_for_size_p (cfun)")))))
10125        (const_string "0")
10126        (const_string "*")))
10127    (set_attr "mode" "QI")])
10129 ;; Convert ashift to the lea pattern to avoid flags dependency.
10130 (define_split
10131   [(set (match_operand:SWI 0 "register_operand")
10132         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10133                     (match_operand 2 "const_0_to_3_operand")))
10134    (clobber (reg:CC FLAGS_REG))]
10135   "reload_completed
10136    && REGNO (operands[0]) != REGNO (operands[1])"
10137   [(set (match_dup 0)
10138         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10140   if (<MODE>mode != <LEAMODE>mode)
10141     {
10142       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10143       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10144     }
10145   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10148 ;; Convert ashift to the lea pattern to avoid flags dependency.
10149 (define_split
10150   [(set (match_operand:DI 0 "register_operand")
10151         (zero_extend:DI
10152           (ashift:SI (match_operand:SI 1 "index_register_operand")
10153                      (match_operand 2 "const_0_to_3_operand"))))
10154    (clobber (reg:CC FLAGS_REG))]
10155   "TARGET_64BIT && reload_completed
10156    && REGNO (operands[0]) != REGNO (operands[1])"
10157   [(set (match_dup 0)
10158         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10160   operands[1] = gen_lowpart (SImode, operands[1]);
10161   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10164 ;; This pattern can't accept a variable shift count, since shifts by
10165 ;; zero don't affect the flags.  We assume that shifts by constant
10166 ;; zero are optimized away.
10167 (define_insn "*ashl<mode>3_cmp"
10168   [(set (reg FLAGS_REG)
10169         (compare
10170           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10171                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10172           (const_int 0)))
10173    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10174         (ashift:SWI (match_dup 1) (match_dup 2)))]
10175   "(optimize_function_for_size_p (cfun)
10176     || !TARGET_PARTIAL_FLAG_REG_STALL
10177     || (operands[2] == const1_rtx
10178         && (TARGET_SHIFT1
10179             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10180    && ix86_match_ccmode (insn, CCGOCmode)
10181    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10183   switch (get_attr_type (insn))
10184     {
10185     case TYPE_ALU:
10186       gcc_assert (operands[2] == const1_rtx);
10187       return "add{<imodesuffix>}\t%0, %0";
10189     default:
10190       if (operands[2] == const1_rtx
10191           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10192         return "sal{<imodesuffix>}\t%0";
10193       else
10194         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10195     }
10197   [(set (attr "type")
10198      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10199                       (match_operand 0 "register_operand"))
10200                  (match_operand 2 "const1_operand"))
10201               (const_string "alu")
10202            ]
10203            (const_string "ishift")))
10204    (set (attr "length_immediate")
10205      (if_then_else
10206        (ior (eq_attr "type" "alu")
10207             (and (eq_attr "type" "ishift")
10208                  (and (match_operand 2 "const1_operand")
10209                       (ior (match_test "TARGET_SHIFT1")
10210                            (match_test "optimize_function_for_size_p (cfun)")))))
10211        (const_string "0")
10212        (const_string "*")))
10213    (set_attr "mode" "<MODE>")])
10215 (define_insn "*ashlsi3_cmp_zext"
10216   [(set (reg FLAGS_REG)
10217         (compare
10218           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10219                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10220           (const_int 0)))
10221    (set (match_operand:DI 0 "register_operand" "=r")
10222         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10223   "TARGET_64BIT
10224    && (optimize_function_for_size_p (cfun)
10225        || !TARGET_PARTIAL_FLAG_REG_STALL
10226        || (operands[2] == const1_rtx
10227            && (TARGET_SHIFT1
10228                || TARGET_DOUBLE_WITH_ADD)))
10229    && ix86_match_ccmode (insn, CCGOCmode)
10230    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10232   switch (get_attr_type (insn))
10233     {
10234     case TYPE_ALU:
10235       gcc_assert (operands[2] == const1_rtx);
10236       return "add{l}\t%k0, %k0";
10238     default:
10239       if (operands[2] == const1_rtx
10240           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241         return "sal{l}\t%k0";
10242       else
10243         return "sal{l}\t{%2, %k0|%k0, %2}";
10244     }
10246   [(set (attr "type")
10247      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10248                  (match_operand 2 "const1_operand"))
10249               (const_string "alu")
10250            ]
10251            (const_string "ishift")))
10252    (set (attr "length_immediate")
10253      (if_then_else
10254        (ior (eq_attr "type" "alu")
10255             (and (eq_attr "type" "ishift")
10256                  (and (match_operand 2 "const1_operand")
10257                       (ior (match_test "TARGET_SHIFT1")
10258                            (match_test "optimize_function_for_size_p (cfun)")))))
10259        (const_string "0")
10260        (const_string "*")))
10261    (set_attr "mode" "SI")])
10263 (define_insn "*ashl<mode>3_cconly"
10264   [(set (reg FLAGS_REG)
10265         (compare
10266           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10267                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10268           (const_int 0)))
10269    (clobber (match_scratch:SWI 0 "=<r>"))]
10270   "(optimize_function_for_size_p (cfun)
10271     || !TARGET_PARTIAL_FLAG_REG_STALL
10272     || (operands[2] == const1_rtx
10273         && (TARGET_SHIFT1
10274             || TARGET_DOUBLE_WITH_ADD)))
10275    && ix86_match_ccmode (insn, CCGOCmode)"
10277   switch (get_attr_type (insn))
10278     {
10279     case TYPE_ALU:
10280       gcc_assert (operands[2] == const1_rtx);
10281       return "add{<imodesuffix>}\t%0, %0";
10283     default:
10284       if (operands[2] == const1_rtx
10285           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286         return "sal{<imodesuffix>}\t%0";
10287       else
10288         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10289     }
10291   [(set (attr "type")
10292      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10293                       (match_operand 0 "register_operand"))
10294                  (match_operand 2 "const1_operand"))
10295               (const_string "alu")
10296            ]
10297            (const_string "ishift")))
10298    (set (attr "length_immediate")
10299      (if_then_else
10300        (ior (eq_attr "type" "alu")
10301             (and (eq_attr "type" "ishift")
10302                  (and (match_operand 2 "const1_operand")
10303                       (ior (match_test "TARGET_SHIFT1")
10304                            (match_test "optimize_function_for_size_p (cfun)")))))
10305        (const_string "0")
10306        (const_string "*")))
10307    (set_attr "mode" "<MODE>")])
10309 ;; See comment above `ashl<mode>3' about how this works.
10311 (define_expand "<shift_insn><mode>3"
10312   [(set (match_operand:SDWIM 0 "<shift_operand>")
10313         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10314                            (match_operand:QI 2 "nonmemory_operand")))]
10315   ""
10316   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10318 ;; Avoid useless masking of count operand.
10319 (define_insn_and_split "*<shift_insn><mode>3_mask"
10320   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10321         (any_shiftrt:SWI48
10322           (match_operand:SWI48 1 "nonimmediate_operand")
10323           (subreg:QI
10324             (and:SI
10325               (match_operand:SI 2 "register_operand")
10326               (match_operand:SI 3 "const_int_operand")) 0)))
10327    (clobber (reg:CC FLAGS_REG))]
10328   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10329    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10330       == GET_MODE_BITSIZE (<MODE>mode)-1
10331    && can_create_pseudo_p ()"
10332   "#"
10333   "&& 1"
10334   [(parallel
10335      [(set (match_dup 0)
10336            (any_shiftrt:SWI48 (match_dup 1)
10337                               (match_dup 2)))
10338       (clobber (reg:CC FLAGS_REG))])]
10339   "operands[2] = gen_lowpart (QImode, operands[2]);")
10341 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10342   [(set (match_operand:DWI 0 "register_operand" "=&r")
10343         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10344                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   ""
10347   "#"
10348   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10349   [(const_int 0)]
10350   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10351   [(set_attr "type" "multi")])
10353 ;; By default we don't ask for a scratch register, because when DWImode
10354 ;; values are manipulated, registers are already at a premium.  But if
10355 ;; we have one handy, we won't turn it away.
10357 (define_peephole2
10358   [(match_scratch:DWIH 3 "r")
10359    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10360                    (any_shiftrt:<DWI>
10361                      (match_operand:<DWI> 1 "register_operand")
10362                      (match_operand:QI 2 "nonmemory_operand")))
10363               (clobber (reg:CC FLAGS_REG))])
10364    (match_dup 3)]
10365   "TARGET_CMOVE"
10366   [(const_int 0)]
10367   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10369 (define_insn "x86_64_shrd"
10370   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10371         (ior:DI (lshiftrt:DI (match_dup 0)
10372                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10373                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10374                   (minus:QI (const_int 64) (match_dup 2)))))
10375    (clobber (reg:CC FLAGS_REG))]
10376   "TARGET_64BIT"
10377   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10378   [(set_attr "type" "ishift")
10379    (set_attr "prefix_0f" "1")
10380    (set_attr "mode" "DI")
10381    (set_attr "athlon_decode" "vector")
10382    (set_attr "amdfam10_decode" "vector")
10383    (set_attr "bdver1_decode" "vector")])
10385 (define_insn "x86_shrd"
10386   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10387         (ior:SI (lshiftrt:SI (match_dup 0)
10388                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10389                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10390                   (minus:QI (const_int 32) (match_dup 2)))))
10391    (clobber (reg:CC FLAGS_REG))]
10392   ""
10393   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10394   [(set_attr "type" "ishift")
10395    (set_attr "prefix_0f" "1")
10396    (set_attr "mode" "SI")
10397    (set_attr "pent_pair" "np")
10398    (set_attr "athlon_decode" "vector")
10399    (set_attr "amdfam10_decode" "vector")
10400    (set_attr "bdver1_decode" "vector")])
10402 (define_insn "ashrdi3_cvt"
10403   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10404         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10405                      (match_operand:QI 2 "const_int_operand")))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "TARGET_64BIT && INTVAL (operands[2]) == 63
10408    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10409    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10410   "@
10411    {cqto|cqo}
10412    sar{q}\t{%2, %0|%0, %2}"
10413   [(set_attr "type" "imovx,ishift")
10414    (set_attr "prefix_0f" "0,*")
10415    (set_attr "length_immediate" "0,*")
10416    (set_attr "modrm" "0,1")
10417    (set_attr "mode" "DI")])
10419 (define_insn "ashrsi3_cvt"
10420   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10421         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10422                      (match_operand:QI 2 "const_int_operand")))
10423    (clobber (reg:CC FLAGS_REG))]
10424   "INTVAL (operands[2]) == 31
10425    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10426    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10427   "@
10428    {cltd|cdq}
10429    sar{l}\t{%2, %0|%0, %2}"
10430   [(set_attr "type" "imovx,ishift")
10431    (set_attr "prefix_0f" "0,*")
10432    (set_attr "length_immediate" "0,*")
10433    (set_attr "modrm" "0,1")
10434    (set_attr "mode" "SI")])
10436 (define_insn "*ashrsi3_cvt_zext"
10437   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10438         (zero_extend:DI
10439           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10440                        (match_operand:QI 2 "const_int_operand"))))
10441    (clobber (reg:CC FLAGS_REG))]
10442   "TARGET_64BIT && INTVAL (operands[2]) == 31
10443    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10444    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10445   "@
10446    {cltd|cdq}
10447    sar{l}\t{%2, %k0|%k0, %2}"
10448   [(set_attr "type" "imovx,ishift")
10449    (set_attr "prefix_0f" "0,*")
10450    (set_attr "length_immediate" "0,*")
10451    (set_attr "modrm" "0,1")
10452    (set_attr "mode" "SI")])
10454 (define_expand "x86_shift<mode>_adj_3"
10455   [(use (match_operand:SWI48 0 "register_operand"))
10456    (use (match_operand:SWI48 1 "register_operand"))
10457    (use (match_operand:QI 2 "register_operand"))]
10458   ""
10460   rtx_code_label *label = gen_label_rtx ();
10461   rtx tmp;
10463   emit_insn (gen_testqi_ccz_1 (operands[2],
10464                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10466   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10467   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10468   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10469                               gen_rtx_LABEL_REF (VOIDmode, label),
10470                               pc_rtx);
10471   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10472   JUMP_LABEL (tmp) = label;
10474   emit_move_insn (operands[0], operands[1]);
10475   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10476                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10477   emit_label (label);
10478   LABEL_NUSES (label) = 1;
10480   DONE;
10483 (define_insn "*bmi2_<shift_insn><mode>3_1"
10484   [(set (match_operand:SWI48 0 "register_operand" "=r")
10485         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10486                            (match_operand:SWI48 2 "register_operand" "r")))]
10487   "TARGET_BMI2"
10488   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10489   [(set_attr "type" "ishiftx")
10490    (set_attr "mode" "<MODE>")])
10492 (define_insn "*<shift_insn><mode>3_1"
10493   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10494         (any_shiftrt:SWI48
10495           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10496           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10500   switch (get_attr_type (insn))
10501     {
10502     case TYPE_ISHIFTX:
10503       return "#";
10505     default:
10506       if (operands[2] == const1_rtx
10507           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10508         return "<shift>{<imodesuffix>}\t%0";
10509       else
10510         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10511     }
10513   [(set_attr "isa" "*,bmi2")
10514    (set_attr "type" "ishift,ishiftx")
10515    (set (attr "length_immediate")
10516      (if_then_else
10517        (and (match_operand 2 "const1_operand")
10518             (ior (match_test "TARGET_SHIFT1")
10519                  (match_test "optimize_function_for_size_p (cfun)")))
10520        (const_string "0")
10521        (const_string "*")))
10522    (set_attr "mode" "<MODE>")])
10524 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10525 (define_split
10526   [(set (match_operand:SWI48 0 "register_operand")
10527         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10528                            (match_operand:QI 2 "register_operand")))
10529    (clobber (reg:CC FLAGS_REG))]
10530   "TARGET_BMI2 && reload_completed"
10531   [(set (match_dup 0)
10532         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10533   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10535 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10536   [(set (match_operand:DI 0 "register_operand" "=r")
10537         (zero_extend:DI
10538           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10539                           (match_operand:SI 2 "register_operand" "r"))))]
10540   "TARGET_64BIT && TARGET_BMI2"
10541   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10542   [(set_attr "type" "ishiftx")
10543    (set_attr "mode" "SI")])
10545 (define_insn "*<shift_insn>si3_1_zext"
10546   [(set (match_operand:DI 0 "register_operand" "=r,r")
10547         (zero_extend:DI
10548           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10549                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10550    (clobber (reg:CC FLAGS_REG))]
10551   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10553   switch (get_attr_type (insn))
10554     {
10555     case TYPE_ISHIFTX:
10556       return "#";
10558     default:
10559       if (operands[2] == const1_rtx
10560           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10561         return "<shift>{l}\t%k0";
10562       else
10563         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10564     }
10566   [(set_attr "isa" "*,bmi2")
10567    (set_attr "type" "ishift,ishiftx")
10568    (set (attr "length_immediate")
10569      (if_then_else
10570        (and (match_operand 2 "const1_operand")
10571             (ior (match_test "TARGET_SHIFT1")
10572                  (match_test "optimize_function_for_size_p (cfun)")))
10573        (const_string "0")
10574        (const_string "*")))
10575    (set_attr "mode" "SI")])
10577 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10578 (define_split
10579   [(set (match_operand:DI 0 "register_operand")
10580         (zero_extend:DI
10581           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10582                           (match_operand:QI 2 "register_operand"))))
10583    (clobber (reg:CC FLAGS_REG))]
10584   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10585   [(set (match_dup 0)
10586         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10587   "operands[2] = gen_lowpart (SImode, operands[2]);")
10589 (define_insn "*<shift_insn><mode>3_1"
10590   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10591         (any_shiftrt:SWI12
10592           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10593           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10594    (clobber (reg:CC FLAGS_REG))]
10595   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10597   if (operands[2] == const1_rtx
10598       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10599     return "<shift>{<imodesuffix>}\t%0";
10600   else
10601     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10603   [(set_attr "type" "ishift")
10604    (set (attr "length_immediate")
10605      (if_then_else
10606        (and (match_operand 2 "const1_operand")
10607             (ior (match_test "TARGET_SHIFT1")
10608                  (match_test "optimize_function_for_size_p (cfun)")))
10609        (const_string "0")
10610        (const_string "*")))
10611    (set_attr "mode" "<MODE>")])
10613 (define_insn "*<shift_insn>qi3_1_slp"
10614   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10615         (any_shiftrt:QI (match_dup 0)
10616                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "(optimize_function_for_size_p (cfun)
10619     || !TARGET_PARTIAL_REG_STALL
10620     || (operands[1] == const1_rtx
10621         && TARGET_SHIFT1))"
10623   if (operands[1] == const1_rtx
10624       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10625     return "<shift>{b}\t%0";
10626   else
10627     return "<shift>{b}\t{%1, %0|%0, %1}";
10629   [(set_attr "type" "ishift1")
10630    (set (attr "length_immediate")
10631      (if_then_else
10632        (and (match_operand 1 "const1_operand")
10633             (ior (match_test "TARGET_SHIFT1")
10634                  (match_test "optimize_function_for_size_p (cfun)")))
10635        (const_string "0")
10636        (const_string "*")))
10637    (set_attr "mode" "QI")])
10639 ;; This pattern can't accept a variable shift count, since shifts by
10640 ;; zero don't affect the flags.  We assume that shifts by constant
10641 ;; zero are optimized away.
10642 (define_insn "*<shift_insn><mode>3_cmp"
10643   [(set (reg FLAGS_REG)
10644         (compare
10645           (any_shiftrt:SWI
10646             (match_operand:SWI 1 "nonimmediate_operand" "0")
10647             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10648           (const_int 0)))
10649    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10650         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10651   "(optimize_function_for_size_p (cfun)
10652     || !TARGET_PARTIAL_FLAG_REG_STALL
10653     || (operands[2] == const1_rtx
10654         && TARGET_SHIFT1))
10655    && ix86_match_ccmode (insn, CCGOCmode)
10656    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10658   if (operands[2] == const1_rtx
10659       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10660     return "<shift>{<imodesuffix>}\t%0";
10661   else
10662     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10664   [(set_attr "type" "ishift")
10665    (set (attr "length_immediate")
10666      (if_then_else
10667        (and (match_operand 2 "const1_operand")
10668             (ior (match_test "TARGET_SHIFT1")
10669                  (match_test "optimize_function_for_size_p (cfun)")))
10670        (const_string "0")
10671        (const_string "*")))
10672    (set_attr "mode" "<MODE>")])
10674 (define_insn "*<shift_insn>si3_cmp_zext"
10675   [(set (reg FLAGS_REG)
10676         (compare
10677           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10678                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10679           (const_int 0)))
10680    (set (match_operand:DI 0 "register_operand" "=r")
10681         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10682   "TARGET_64BIT
10683    && (optimize_function_for_size_p (cfun)
10684        || !TARGET_PARTIAL_FLAG_REG_STALL
10685        || (operands[2] == const1_rtx
10686            && TARGET_SHIFT1))
10687    && ix86_match_ccmode (insn, CCGOCmode)
10688    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10690   if (operands[2] == const1_rtx
10691       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10692     return "<shift>{l}\t%k0";
10693   else
10694     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10696   [(set_attr "type" "ishift")
10697    (set (attr "length_immediate")
10698      (if_then_else
10699        (and (match_operand 2 "const1_operand")
10700             (ior (match_test "TARGET_SHIFT1")
10701                  (match_test "optimize_function_for_size_p (cfun)")))
10702        (const_string "0")
10703        (const_string "*")))
10704    (set_attr "mode" "SI")])
10706 (define_insn "*<shift_insn><mode>3_cconly"
10707   [(set (reg FLAGS_REG)
10708         (compare
10709           (any_shiftrt:SWI
10710             (match_operand:SWI 1 "register_operand" "0")
10711             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10712           (const_int 0)))
10713    (clobber (match_scratch:SWI 0 "=<r>"))]
10714   "(optimize_function_for_size_p (cfun)
10715     || !TARGET_PARTIAL_FLAG_REG_STALL
10716     || (operands[2] == const1_rtx
10717         && TARGET_SHIFT1))
10718    && ix86_match_ccmode (insn, CCGOCmode)"
10720   if (operands[2] == const1_rtx
10721       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10722     return "<shift>{<imodesuffix>}\t%0";
10723   else
10724     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10726   [(set_attr "type" "ishift")
10727    (set (attr "length_immediate")
10728      (if_then_else
10729        (and (match_operand 2 "const1_operand")
10730             (ior (match_test "TARGET_SHIFT1")
10731                  (match_test "optimize_function_for_size_p (cfun)")))
10732        (const_string "0")
10733        (const_string "*")))
10734    (set_attr "mode" "<MODE>")])
10736 ;; Rotate instructions
10738 (define_expand "<rotate_insn>ti3"
10739   [(set (match_operand:TI 0 "register_operand")
10740         (any_rotate:TI (match_operand:TI 1 "register_operand")
10741                        (match_operand:QI 2 "nonmemory_operand")))]
10742   "TARGET_64BIT"
10744   if (const_1_to_63_operand (operands[2], VOIDmode))
10745     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10746                 (operands[0], operands[1], operands[2]));
10747   else
10748     FAIL;
10750   DONE;
10753 (define_expand "<rotate_insn>di3"
10754   [(set (match_operand:DI 0 "shiftdi_operand")
10755         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10756                        (match_operand:QI 2 "nonmemory_operand")))]
10757  ""
10759   if (TARGET_64BIT)
10760     ix86_expand_binary_operator (<CODE>, DImode, operands);
10761   else if (const_1_to_31_operand (operands[2], VOIDmode))
10762     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10763                 (operands[0], operands[1], operands[2]));
10764   else
10765     FAIL;
10767   DONE;
10770 (define_expand "<rotate_insn><mode>3"
10771   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10772         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10773                             (match_operand:QI 2 "nonmemory_operand")))]
10774   ""
10775   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10777 ;; Avoid useless masking of count operand.
10778 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10779   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10780         (any_rotate:SWI48
10781           (match_operand:SWI48 1 "nonimmediate_operand")
10782           (subreg:QI
10783             (and:SI
10784               (match_operand:SI 2 "register_operand")
10785               (match_operand:SI 3 "const_int_operand")) 0)))
10786    (clobber (reg:CC FLAGS_REG))]
10787   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10788    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10789       == GET_MODE_BITSIZE (<MODE>mode)-1
10790    && can_create_pseudo_p ()"
10791   "#"
10792   "&& 1"
10793   [(parallel
10794      [(set (match_dup 0)
10795            (any_rotate:SWI48 (match_dup 1)
10796                              (match_dup 2)))
10797       (clobber (reg:CC FLAGS_REG))])]
10798   "operands[2] = gen_lowpart (QImode, operands[2]);")
10800 ;; Implement rotation using two double-precision
10801 ;; shift instructions and a scratch register.
10803 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10804  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10805        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10806                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10807   (clobber (reg:CC FLAGS_REG))
10808   (clobber (match_scratch:DWIH 3 "=&r"))]
10809  ""
10810  "#"
10811  "reload_completed"
10812  [(set (match_dup 3) (match_dup 4))
10813   (parallel
10814    [(set (match_dup 4)
10815          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10816                    (lshiftrt:DWIH (match_dup 5)
10817                                   (minus:QI (match_dup 6) (match_dup 2)))))
10818     (clobber (reg:CC FLAGS_REG))])
10819   (parallel
10820    [(set (match_dup 5)
10821          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10822                    (lshiftrt:DWIH (match_dup 3)
10823                                   (minus:QI (match_dup 6) (match_dup 2)))))
10824     (clobber (reg:CC FLAGS_REG))])]
10826   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10828   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10831 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10832  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10833        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10834                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10835   (clobber (reg:CC FLAGS_REG))
10836   (clobber (match_scratch:DWIH 3 "=&r"))]
10837  ""
10838  "#"
10839  "reload_completed"
10840  [(set (match_dup 3) (match_dup 4))
10841   (parallel
10842    [(set (match_dup 4)
10843          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10844                    (ashift:DWIH (match_dup 5)
10845                                 (minus:QI (match_dup 6) (match_dup 2)))))
10846     (clobber (reg:CC FLAGS_REG))])
10847   (parallel
10848    [(set (match_dup 5)
10849          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10850                    (ashift:DWIH (match_dup 3)
10851                                 (minus:QI (match_dup 6) (match_dup 2)))))
10852     (clobber (reg:CC FLAGS_REG))])]
10854   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10856   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10859 (define_insn "*bmi2_rorx<mode>3_1"
10860   [(set (match_operand:SWI48 0 "register_operand" "=r")
10861         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10862                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10863   "TARGET_BMI2"
10864   "rorx\t{%2, %1, %0|%0, %1, %2}"
10865   [(set_attr "type" "rotatex")
10866    (set_attr "mode" "<MODE>")])
10868 (define_insn "*<rotate_insn><mode>3_1"
10869   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10870         (any_rotate:SWI48
10871           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10872           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10876   switch (get_attr_type (insn))
10877     {
10878     case TYPE_ROTATEX:
10879       return "#";
10881     default:
10882       if (operands[2] == const1_rtx
10883           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10884         return "<rotate>{<imodesuffix>}\t%0";
10885       else
10886         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10887     }
10889   [(set_attr "isa" "*,bmi2")
10890    (set_attr "type" "rotate,rotatex")
10891    (set (attr "length_immediate")
10892      (if_then_else
10893        (and (eq_attr "type" "rotate")
10894             (and (match_operand 2 "const1_operand")
10895                  (ior (match_test "TARGET_SHIFT1")
10896                       (match_test "optimize_function_for_size_p (cfun)"))))
10897        (const_string "0")
10898        (const_string "*")))
10899    (set_attr "mode" "<MODE>")])
10901 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10902 (define_split
10903   [(set (match_operand:SWI48 0 "register_operand")
10904         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10905                       (match_operand:QI 2 "immediate_operand")))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "TARGET_BMI2 && reload_completed"
10908   [(set (match_dup 0)
10909         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10911   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10913   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10916 (define_split
10917   [(set (match_operand:SWI48 0 "register_operand")
10918         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10919                         (match_operand:QI 2 "immediate_operand")))
10920    (clobber (reg:CC FLAGS_REG))]
10921   "TARGET_BMI2 && reload_completed"
10922   [(set (match_dup 0)
10923         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10925 (define_insn "*bmi2_rorxsi3_1_zext"
10926   [(set (match_operand:DI 0 "register_operand" "=r")
10927         (zero_extend:DI
10928           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10929                        (match_operand:QI 2 "immediate_operand" "I"))))]
10930   "TARGET_64BIT && TARGET_BMI2"
10931   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10932   [(set_attr "type" "rotatex")
10933    (set_attr "mode" "SI")])
10935 (define_insn "*<rotate_insn>si3_1_zext"
10936   [(set (match_operand:DI 0 "register_operand" "=r,r")
10937         (zero_extend:DI
10938           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10939                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10940    (clobber (reg:CC FLAGS_REG))]
10941   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10943   switch (get_attr_type (insn))
10944     {
10945     case TYPE_ROTATEX:
10946       return "#";
10948     default:
10949       if (operands[2] == const1_rtx
10950           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10951         return "<rotate>{l}\t%k0";
10952       else
10953         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10954     }
10956   [(set_attr "isa" "*,bmi2")
10957    (set_attr "type" "rotate,rotatex")
10958    (set (attr "length_immediate")
10959      (if_then_else
10960        (and (eq_attr "type" "rotate")
10961             (and (match_operand 2 "const1_operand")
10962                  (ior (match_test "TARGET_SHIFT1")
10963                       (match_test "optimize_function_for_size_p (cfun)"))))
10964        (const_string "0")
10965        (const_string "*")))
10966    (set_attr "mode" "SI")])
10968 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10969 (define_split
10970   [(set (match_operand:DI 0 "register_operand")
10971         (zero_extend:DI
10972           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10973                      (match_operand:QI 2 "immediate_operand"))))
10974    (clobber (reg:CC FLAGS_REG))]
10975   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10976   [(set (match_dup 0)
10977         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10979   int bitsize = GET_MODE_BITSIZE (SImode);
10981   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10984 (define_split
10985   [(set (match_operand:DI 0 "register_operand")
10986         (zero_extend:DI
10987           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10988                        (match_operand:QI 2 "immediate_operand"))))
10989    (clobber (reg:CC FLAGS_REG))]
10990   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10991   [(set (match_dup 0)
10992         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10994 (define_insn "*<rotate_insn><mode>3_1"
10995   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10996         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10997                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11001   if (operands[2] == const1_rtx
11002       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11003     return "<rotate>{<imodesuffix>}\t%0";
11004   else
11005     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11007   [(set_attr "type" "rotate")
11008    (set (attr "length_immediate")
11009      (if_then_else
11010        (and (match_operand 2 "const1_operand")
11011             (ior (match_test "TARGET_SHIFT1")
11012                  (match_test "optimize_function_for_size_p (cfun)")))
11013        (const_string "0")
11014        (const_string "*")))
11015    (set_attr "mode" "<MODE>")])
11017 (define_insn "*<rotate_insn>qi3_1_slp"
11018   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11019         (any_rotate:QI (match_dup 0)
11020                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "(optimize_function_for_size_p (cfun)
11023     || !TARGET_PARTIAL_REG_STALL
11024     || (operands[1] == const1_rtx
11025         && TARGET_SHIFT1))"
11027   if (operands[1] == const1_rtx
11028       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11029     return "<rotate>{b}\t%0";
11030   else
11031     return "<rotate>{b}\t{%1, %0|%0, %1}";
11033   [(set_attr "type" "rotate1")
11034    (set (attr "length_immediate")
11035      (if_then_else
11036        (and (match_operand 1 "const1_operand")
11037             (ior (match_test "TARGET_SHIFT1")
11038                  (match_test "optimize_function_for_size_p (cfun)")))
11039        (const_string "0")
11040        (const_string "*")))
11041    (set_attr "mode" "QI")])
11043 (define_split
11044  [(set (match_operand:HI 0 "register_operand")
11045        (any_rotate:HI (match_dup 0) (const_int 8)))
11046   (clobber (reg:CC FLAGS_REG))]
11047  "reload_completed
11048   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11049  [(parallel [(set (strict_low_part (match_dup 0))
11050                   (bswap:HI (match_dup 0)))
11051              (clobber (reg:CC FLAGS_REG))])])
11053 ;; Bit set / bit test instructions
11055 ;; %%% bts, btr, btc, bt.
11056 ;; In general these instructions are *slow* when applied to memory,
11057 ;; since they enforce atomic operation.  When applied to registers,
11058 ;; it depends on the cpu implementation.  They're never faster than
11059 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11060 ;; no point.  But in 64-bit, we can't hold the relevant immediates
11061 ;; within the instruction itself, so operating on bits in the high
11062 ;; 32-bits of a register becomes easier.
11064 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11065 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11066 ;; negdf respectively, so they can never be disabled entirely.
11068 (define_insn "*btsq"
11069   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11070                          (const_int 1)
11071                          (match_operand 1 "const_0_to_63_operand" "J"))
11072         (const_int 1))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11075   "bts{q}\t{%1, %0|%0, %1}"
11076   [(set_attr "type" "alu1")
11077    (set_attr "prefix_0f" "1")
11078    (set_attr "znver1_decode" "double")
11079    (set_attr "mode" "DI")])
11081 (define_insn "*btrq"
11082   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11083                          (const_int 1)
11084                          (match_operand 1 "const_0_to_63_operand" "J"))
11085         (const_int 0))
11086    (clobber (reg:CC FLAGS_REG))]
11087   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11088   "btr{q}\t{%1, %0|%0, %1}"
11089   [(set_attr "type" "alu1")
11090    (set_attr "prefix_0f" "1")
11091    (set_attr "znver1_decode" "double")
11092    (set_attr "mode" "DI")])
11094 (define_insn "*btcq"
11095   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11096                          (const_int 1)
11097                          (match_operand 1 "const_0_to_63_operand" "J"))
11098         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11099    (clobber (reg:CC FLAGS_REG))]
11100   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11101   "btc{q}\t{%1, %0|%0, %1}"
11102   [(set_attr "type" "alu1")
11103    (set_attr "prefix_0f" "1")
11104    (set_attr "znver1_decode" "double")
11105    (set_attr "mode" "DI")])
11107 ;; Allow Nocona to avoid these instructions if a register is available.
11109 (define_peephole2
11110   [(match_scratch:DI 2 "r")
11111    (parallel [(set (zero_extract:DI
11112                      (match_operand:DI 0 "register_operand")
11113                      (const_int 1)
11114                      (match_operand 1 "const_0_to_63_operand"))
11115                    (const_int 1))
11116               (clobber (reg:CC FLAGS_REG))])]
11117   "TARGET_64BIT && !TARGET_USE_BT"
11118   [(parallel [(set (match_dup 0)
11119                    (ior:DI (match_dup 0) (match_dup 3)))
11120               (clobber (reg:CC FLAGS_REG))])]
11122   int i = INTVAL (operands[1]);
11124   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11126   if (!x86_64_immediate_operand (operands[3], DImode))
11127     {
11128       emit_move_insn (operands[2], operands[3]);
11129       operands[3] = operands[2];
11130     }
11133 (define_peephole2
11134   [(match_scratch:DI 2 "r")
11135    (parallel [(set (zero_extract:DI
11136                      (match_operand:DI 0 "register_operand")
11137                      (const_int 1)
11138                      (match_operand 1 "const_0_to_63_operand"))
11139                    (const_int 0))
11140               (clobber (reg:CC FLAGS_REG))])]
11141   "TARGET_64BIT && !TARGET_USE_BT"
11142   [(parallel [(set (match_dup 0)
11143                    (and:DI (match_dup 0) (match_dup 3)))
11144               (clobber (reg:CC FLAGS_REG))])]
11146   int i = INTVAL (operands[1]);
11148   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11150   if (!x86_64_immediate_operand (operands[3], DImode))
11151     {
11152       emit_move_insn (operands[2], operands[3]);
11153       operands[3] = operands[2];
11154     }
11157 (define_peephole2
11158   [(match_scratch:DI 2 "r")
11159    (parallel [(set (zero_extract:DI
11160                      (match_operand:DI 0 "register_operand")
11161                      (const_int 1)
11162                      (match_operand 1 "const_0_to_63_operand"))
11163               (not:DI (zero_extract:DI
11164                         (match_dup 0) (const_int 1) (match_dup 1))))
11165               (clobber (reg:CC FLAGS_REG))])]
11166   "TARGET_64BIT && !TARGET_USE_BT"
11167   [(parallel [(set (match_dup 0)
11168                    (xor:DI (match_dup 0) (match_dup 3)))
11169               (clobber (reg:CC FLAGS_REG))])]
11171   int i = INTVAL (operands[1]);
11173   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11175   if (!x86_64_immediate_operand (operands[3], DImode))
11176     {
11177       emit_move_insn (operands[2], operands[3]);
11178       operands[3] = operands[2];
11179     }
11182 (define_insn "*bt<mode>"
11183   [(set (reg:CCC FLAGS_REG)
11184         (compare:CCC
11185           (zero_extract:SWI48
11186             (match_operand:SWI48 0 "register_operand" "r")
11187             (const_int 1)
11188             (match_operand:SI 1 "nonmemory_operand" "rN"))
11189           (const_int 0)))]
11190   ""
11192   switch (get_attr_mode (insn))
11193     {
11194     case MODE_SI:
11195       return "bt{l}\t{%1, %k0|%k0, %1}";
11197     case MODE_DI:
11198       return "bt{q}\t{%q1, %0|%0, %q1}";
11200     default:
11201       gcc_unreachable ();
11202     }
11204   [(set_attr "type" "alu1")
11205    (set_attr "prefix_0f" "1")
11206    (set (attr "mode")
11207         (if_then_else
11208           (and (match_test "CONST_INT_P (operands[1])")
11209                (match_test "INTVAL (operands[1]) < 32"))
11210           (const_string "SI")
11211           (const_string "<MODE>")))])
11213 (define_insn_and_split "*jcc_bt<mode>"
11214   [(set (pc)
11215         (if_then_else (match_operator 0 "bt_comparison_operator"
11216                         [(zero_extract:SWI48
11217                            (match_operand:SWI48 1 "register_operand")
11218                            (const_int 1)
11219                            (match_operand:SI 2 "nonmemory_operand"))
11220                          (const_int 0)])
11221                       (label_ref (match_operand 3))
11222                       (pc)))
11223    (clobber (reg:CC FLAGS_REG))]
11224   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225    && (CONST_INT_P (operands[2])
11226        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11227           && INTVAL (operands[2])
11228                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11229        : register_operand (operands[2], SImode))
11230    && can_create_pseudo_p ()"
11231   "#"
11232   "&& 1"
11233   [(set (reg:CCC FLAGS_REG)
11234         (compare:CCC
11235           (zero_extract:SWI48
11236             (match_dup 1)
11237             (const_int 1)
11238             (match_dup 2))
11239           (const_int 0)))
11240    (set (pc)
11241         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11242                       (label_ref (match_dup 3))
11243                       (pc)))]
11245   operands[0] = shallow_copy_rtx (operands[0]);
11246   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11249 (define_insn_and_split "*jcc_bt<mode>_1"
11250   [(set (pc)
11251         (if_then_else (match_operator 0 "bt_comparison_operator"
11252                         [(zero_extract:SWI48
11253                            (match_operand:SWI48 1 "register_operand")
11254                            (const_int 1)
11255                            (zero_extend:SI
11256                              (match_operand:QI 2 "register_operand")))
11257                          (const_int 0)])
11258                       (label_ref (match_operand 3))
11259                       (pc)))
11260    (clobber (reg:CC FLAGS_REG))]
11261   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11262    && can_create_pseudo_p ()"
11263   "#"
11264   "&& 1"
11265   [(set (reg:CCC FLAGS_REG)
11266         (compare:CCC
11267           (zero_extract:SWI48
11268             (match_dup 1)
11269             (const_int 1)
11270             (match_dup 2))
11271           (const_int 0)))
11272    (set (pc)
11273         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11274                       (label_ref (match_dup 3))
11275                       (pc)))]
11277   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11278   operands[0] = shallow_copy_rtx (operands[0]);
11279   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11282 ;; Avoid useless masking of bit offset operand.
11283 (define_insn_and_split "*jcc_bt<mode>_mask"
11284   [(set (pc)
11285         (if_then_else (match_operator 0 "bt_comparison_operator"
11286                         [(zero_extract:SWI48
11287                            (match_operand:SWI48 1 "register_operand")
11288                            (const_int 1)
11289                            (and:SI
11290                              (match_operand:SI 2 "register_operand")
11291                              (match_operand 3 "const_int_operand")))])
11292                       (label_ref (match_operand 4))
11293                       (pc)))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11297       == GET_MODE_BITSIZE (<MODE>mode)-1
11298    && can_create_pseudo_p ()"
11299   "#"
11300   "&& 1"
11301   [(set (reg:CCC FLAGS_REG)
11302         (compare:CCC
11303           (zero_extract:SWI48
11304             (match_dup 1)
11305             (const_int 1)
11306             (match_dup 2))
11307           (const_int 0)))
11308    (set (pc)
11309         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11310                       (label_ref (match_dup 4))
11311                       (pc)))]
11313   operands[0] = shallow_copy_rtx (operands[0]);
11314   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11317 ;; Store-flag instructions.
11319 ;; For all sCOND expanders, also expand the compare or test insn that
11320 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11322 (define_insn_and_split "*setcc_di_1"
11323   [(set (match_operand:DI 0 "register_operand" "=q")
11324         (match_operator:DI 1 "ix86_comparison_operator"
11325           [(reg FLAGS_REG) (const_int 0)]))]
11326   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11327   "#"
11328   "&& reload_completed"
11329   [(set (match_dup 2) (match_dup 1))
11330    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11332   operands[1] = shallow_copy_rtx (operands[1]);
11333   PUT_MODE (operands[1], QImode);
11334   operands[2] = gen_lowpart (QImode, operands[0]);
11337 (define_insn_and_split "*setcc_si_1_and"
11338   [(set (match_operand:SI 0 "register_operand" "=q")
11339         (match_operator:SI 1 "ix86_comparison_operator"
11340           [(reg FLAGS_REG) (const_int 0)]))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "!TARGET_PARTIAL_REG_STALL
11343    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11344   "#"
11345   "&& reload_completed"
11346   [(set (match_dup 2) (match_dup 1))
11347    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11348               (clobber (reg:CC FLAGS_REG))])]
11350   operands[1] = shallow_copy_rtx (operands[1]);
11351   PUT_MODE (operands[1], QImode);
11352   operands[2] = gen_lowpart (QImode, operands[0]);
11355 (define_insn_and_split "*setcc_si_1_movzbl"
11356   [(set (match_operand:SI 0 "register_operand" "=q")
11357         (match_operator:SI 1 "ix86_comparison_operator"
11358           [(reg FLAGS_REG) (const_int 0)]))]
11359   "!TARGET_PARTIAL_REG_STALL
11360    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11361   "#"
11362   "&& reload_completed"
11363   [(set (match_dup 2) (match_dup 1))
11364    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11366   operands[1] = shallow_copy_rtx (operands[1]);
11367   PUT_MODE (operands[1], QImode);
11368   operands[2] = gen_lowpart (QImode, operands[0]);
11371 (define_insn "*setcc_qi"
11372   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11373         (match_operator:QI 1 "ix86_comparison_operator"
11374           [(reg FLAGS_REG) (const_int 0)]))]
11375   ""
11376   "set%C1\t%0"
11377   [(set_attr "type" "setcc")
11378    (set_attr "mode" "QI")])
11380 (define_insn "*setcc_qi_slp"
11381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11382         (match_operator:QI 1 "ix86_comparison_operator"
11383           [(reg FLAGS_REG) (const_int 0)]))]
11384   ""
11385   "set%C1\t%0"
11386   [(set_attr "type" "setcc")
11387    (set_attr "mode" "QI")])
11389 ;; In general it is not safe to assume too much about CCmode registers,
11390 ;; so simplify-rtx stops when it sees a second one.  Under certain
11391 ;; conditions this is safe on x86, so help combine not create
11393 ;;      seta    %al
11394 ;;      testb   %al, %al
11395 ;;      sete    %al
11397 (define_split
11398   [(set (match_operand:QI 0 "nonimmediate_operand")
11399         (ne: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);
11409 (define_split
11410   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11411         (ne:QI (match_operator 1 "ix86_comparison_operator"
11412                  [(reg FLAGS_REG) (const_int 0)])
11413             (const_int 0)))]
11414   ""
11415   [(set (match_dup 0) (match_dup 1))]
11417   operands[1] = shallow_copy_rtx (operands[1]);
11418   PUT_MODE (operands[1], QImode);
11421 (define_split
11422   [(set (match_operand:QI 0 "nonimmediate_operand")
11423         (eq:QI (match_operator 1 "ix86_comparison_operator"
11424                  [(reg FLAGS_REG) (const_int 0)])
11425             (const_int 0)))]
11426   ""
11427   [(set (match_dup 0) (match_dup 1))]
11429   operands[1] = shallow_copy_rtx (operands[1]);
11430   PUT_MODE (operands[1], QImode);
11431   PUT_CODE (operands[1],
11432             ix86_reverse_condition (GET_CODE (operands[1]),
11433                                     GET_MODE (XEXP (operands[1], 0))));
11435   /* Make sure that (a) the CCmode we have for the flags is strong
11436      enough for the reversed compare or (b) we have a valid FP compare.  */
11437   if (! ix86_comparison_operator (operands[1], VOIDmode))
11438     FAIL;
11441 (define_split
11442   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11443         (eq:QI (match_operator 1 "ix86_comparison_operator"
11444                  [(reg FLAGS_REG) (const_int 0)])
11445             (const_int 0)))]
11446   ""
11447   [(set (match_dup 0) (match_dup 1))]
11449   operands[1] = shallow_copy_rtx (operands[1]);
11450   PUT_MODE (operands[1], QImode);
11451   PUT_CODE (operands[1],
11452             ix86_reverse_condition (GET_CODE (operands[1]),
11453                                     GET_MODE (XEXP (operands[1], 0))));
11455   /* Make sure that (a) the CCmode we have for the flags is strong
11456      enough for the reversed compare or (b) we have a valid FP compare.  */
11457   if (! ix86_comparison_operator (operands[1], VOIDmode))
11458     FAIL;
11461 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11462 ;; subsequent logical operations are used to imitate conditional moves.
11463 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11464 ;; it directly.
11466 (define_insn "setcc_<mode>_sse"
11467   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11468         (match_operator:MODEF 3 "sse_comparison_operator"
11469           [(match_operand:MODEF 1 "register_operand" "0,x")
11470            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11471   "SSE_FLOAT_MODE_P (<MODE>mode)"
11472   "@
11473    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11474    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11475   [(set_attr "isa" "noavx,avx")
11476    (set_attr "type" "ssecmp")
11477    (set_attr "length_immediate" "1")
11478    (set_attr "prefix" "orig,vex")
11479    (set_attr "mode" "<MODE>")])
11481 ;; Basic conditional jump instructions.
11482 ;; We ignore the overflow flag for signed branch instructions.
11484 (define_insn "*jcc_1"
11485   [(set (pc)
11486         (if_then_else (match_operator 1 "ix86_comparison_operator"
11487                                       [(reg FLAGS_REG) (const_int 0)])
11488                       (label_ref (match_operand 0))
11489                       (pc)))]
11490   ""
11491   "%!%+j%C1\t%l0"
11492   [(set_attr "type" "ibr")
11493    (set_attr "modrm" "0")
11494    (set (attr "length")
11495         (if_then_else
11496           (and (ge (minus (match_dup 0) (pc))
11497                    (const_int -126))
11498                (lt (minus (match_dup 0) (pc))
11499                    (const_int 128)))
11500           (const_int 2)
11501           (const_int 6)))
11502    (set_attr "maybe_prefix_bnd" "1")])
11504 (define_insn "*jcc_2"
11505   [(set (pc)
11506         (if_then_else (match_operator 1 "ix86_comparison_operator"
11507                                       [(reg FLAGS_REG) (const_int 0)])
11508                       (pc)
11509                       (label_ref (match_operand 0))))]
11510   ""
11511   "%!%+j%c1\t%l0"
11512   [(set_attr "type" "ibr")
11513    (set_attr "modrm" "0")
11514    (set (attr "length")
11515         (if_then_else
11516           (and (ge (minus (match_dup 0) (pc))
11517                    (const_int -126))
11518                (lt (minus (match_dup 0) (pc))
11519                    (const_int 128)))
11520           (const_int 2)
11521           (const_int 6)))
11522    (set_attr "maybe_prefix_bnd" "1")])
11524 ;; In general it is not safe to assume too much about CCmode registers,
11525 ;; so simplify-rtx stops when it sees a second one.  Under certain
11526 ;; conditions this is safe on x86, so help combine not create
11528 ;;      seta    %al
11529 ;;      testb   %al, %al
11530 ;;      je      Lfoo
11532 (define_split
11533   [(set (pc)
11534         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11535                                       [(reg FLAGS_REG) (const_int 0)])
11536                           (const_int 0))
11537                       (label_ref (match_operand 1))
11538                       (pc)))]
11539   ""
11540   [(set (pc)
11541         (if_then_else (match_dup 0)
11542                       (label_ref (match_dup 1))
11543                       (pc)))]
11545   operands[0] = shallow_copy_rtx (operands[0]);
11546   PUT_MODE (operands[0], VOIDmode);
11549 (define_split
11550   [(set (pc)
11551         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11552                                       [(reg FLAGS_REG) (const_int 0)])
11553                           (const_int 0))
11554                       (label_ref (match_operand 1))
11555                       (pc)))]
11556   ""
11557   [(set (pc)
11558         (if_then_else (match_dup 0)
11559                       (label_ref (match_dup 1))
11560                       (pc)))]
11562   operands[0] = shallow_copy_rtx (operands[0]);
11563   PUT_MODE (operands[0], VOIDmode);
11564   PUT_CODE (operands[0],
11565             ix86_reverse_condition (GET_CODE (operands[0]),
11566                                     GET_MODE (XEXP (operands[0], 0))));
11568   /* Make sure that (a) the CCmode we have for the flags is strong
11569      enough for the reversed compare or (b) we have a valid FP compare.  */
11570   if (! ix86_comparison_operator (operands[0], VOIDmode))
11571     FAIL;
11574 ;; Define combination compare-and-branch fp compare instructions to help
11575 ;; combine.
11577 (define_insn "*jcc<mode>_0_i387"
11578   [(set (pc)
11579         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11580                         [(match_operand:X87MODEF 1 "register_operand" "f")
11581                          (match_operand:X87MODEF 2 "const0_operand")])
11582           (label_ref (match_operand 3))
11583           (pc)))
11584    (clobber (reg:CCFP FPSR_REG))
11585    (clobber (reg:CCFP FLAGS_REG))
11586    (clobber (match_scratch:HI 4 "=a"))]
11587   "TARGET_80387 && !TARGET_CMOVE"
11588   "#")
11590 (define_insn "*jcc<mode>_0_r_i387"
11591   [(set (pc)
11592         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11593                         [(match_operand:X87MODEF 1 "register_operand" "f")
11594                          (match_operand:X87MODEF 2 "const0_operand")])
11595           (pc)
11596           (label_ref (match_operand 3))))
11597    (clobber (reg:CCFP FPSR_REG))
11598    (clobber (reg:CCFP FLAGS_REG))
11599    (clobber (match_scratch:HI 4 "=a"))]
11600   "TARGET_80387 && !TARGET_CMOVE"
11601   "#")
11603 (define_insn "*jccxf_i387"
11604   [(set (pc)
11605         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11606                         [(match_operand:XF 1 "register_operand" "f")
11607                          (match_operand:XF 2 "register_operand" "f")])
11608           (label_ref (match_operand 3))
11609           (pc)))
11610    (clobber (reg:CCFP FPSR_REG))
11611    (clobber (reg:CCFP FLAGS_REG))
11612    (clobber (match_scratch:HI 4 "=a"))]
11613   "TARGET_80387 && !TARGET_CMOVE"
11614   "#")
11616 (define_insn "*jccxf_r_i387"
11617   [(set (pc)
11618         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11619                         [(match_operand:XF 1 "register_operand" "f")
11620                          (match_operand:XF 2 "register_operand" "f")])
11621           (pc)
11622           (label_ref (match_operand 3))))
11623    (clobber (reg:CCFP FPSR_REG))
11624    (clobber (reg:CCFP FLAGS_REG))
11625    (clobber (match_scratch:HI 4 "=a"))]
11626   "TARGET_80387 && !TARGET_CMOVE"
11627   "#")
11629 (define_insn "*jcc<mode>_i387"
11630   [(set (pc)
11631         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11632                         [(match_operand:MODEF 1 "register_operand" "f")
11633                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11634           (label_ref (match_operand 3))
11635           (pc)))
11636    (clobber (reg:CCFP FPSR_REG))
11637    (clobber (reg:CCFP FLAGS_REG))
11638    (clobber (match_scratch:HI 4 "=a"))]
11639   "TARGET_80387 && !TARGET_CMOVE"
11640   "#")
11642 (define_insn "*jcc<mode>_r_i387"
11643   [(set (pc)
11644         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11645                         [(match_operand:MODEF 1 "register_operand" "f")
11646                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11647           (pc)
11648           (label_ref (match_operand 3))))
11649    (clobber (reg:CCFP FPSR_REG))
11650    (clobber (reg:CCFP FLAGS_REG))
11651    (clobber (match_scratch:HI 4 "=a"))]
11652   "TARGET_80387 && !TARGET_CMOVE"
11653   "#")
11655 (define_insn "*jccu<mode>_i387"
11656   [(set (pc)
11657         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11658                         [(match_operand:X87MODEF 1 "register_operand" "f")
11659                          (match_operand:X87MODEF 2 "register_operand" "f")])
11660           (label_ref (match_operand 3))
11661           (pc)))
11662    (clobber (reg:CCFP FPSR_REG))
11663    (clobber (reg:CCFP FLAGS_REG))
11664    (clobber (match_scratch:HI 4 "=a"))]
11665   "TARGET_80387 && !TARGET_CMOVE"
11666   "#")
11668 (define_insn "*jccu<mode>_r_i387"
11669   [(set (pc)
11670         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11671                         [(match_operand:X87MODEF 1 "register_operand" "f")
11672                          (match_operand:X87MODEF 2 "register_operand" "f")])
11673           (pc)
11674           (label_ref (match_operand 3))))
11675    (clobber (reg:CCFP FPSR_REG))
11676    (clobber (reg:CCFP FLAGS_REG))
11677    (clobber (match_scratch:HI 4 "=a"))]
11678   "TARGET_80387 && !TARGET_CMOVE"
11679   "#")
11681 (define_split
11682   [(set (pc)
11683         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11684                         [(match_operand:X87MODEF 1 "register_operand")
11685                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11686           (match_operand 3)
11687           (match_operand 4)))
11688    (clobber (reg:CCFP FPSR_REG))
11689    (clobber (reg:CCFP FLAGS_REG))]
11690   "TARGET_80387 && !TARGET_CMOVE
11691    && reload_completed"
11692   [(const_int 0)]
11694   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11695                         operands[3], operands[4], NULL_RTX);
11696   DONE;
11699 (define_split
11700   [(set (pc)
11701         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11702                         [(match_operand:X87MODEF 1 "register_operand")
11703                          (match_operand:X87MODEF 2 "general_operand")])
11704           (match_operand 3)
11705           (match_operand 4)))
11706    (clobber (reg:CCFP FPSR_REG))
11707    (clobber (reg:CCFP FLAGS_REG))
11708    (clobber (match_scratch:HI 5))]
11709   "TARGET_80387 && !TARGET_CMOVE
11710    && reload_completed"
11711   [(const_int 0)]
11713   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11714                         operands[3], operands[4], operands[5]);
11715   DONE;
11718 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11719 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11720 ;; with a precedence over other operators and is always put in the first
11721 ;; place. Swap condition and operands to match ficom instruction.
11723 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11724   [(set (pc)
11725         (if_then_else
11726           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11727             [(match_operator:X87MODEF 1 "float_operator"
11728               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11729              (match_operand:X87MODEF 3 "register_operand" "f")])
11730           (label_ref (match_operand 4))
11731           (pc)))
11732    (clobber (reg:CCFP FPSR_REG))
11733    (clobber (reg:CCFP FLAGS_REG))
11734    (clobber (match_scratch:HI 5 "=a"))]
11735   "TARGET_80387 && !TARGET_CMOVE
11736    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11737        || optimize_function_for_size_p (cfun))"
11738   "#")
11740 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11741   [(set (pc)
11742         (if_then_else
11743           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11744             [(match_operator:X87MODEF 1 "float_operator"
11745               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11746              (match_operand:X87MODEF 3 "register_operand" "f")])
11747           (pc)
11748           (label_ref (match_operand 4))))
11749    (clobber (reg:CCFP FPSR_REG))
11750    (clobber (reg:CCFP FLAGS_REG))
11751    (clobber (match_scratch:HI 5 "=a"))]
11752   "TARGET_80387 && !TARGET_CMOVE
11753    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11754        || optimize_function_for_size_p (cfun))"
11755   "#")
11757 (define_split
11758   [(set (pc)
11759         (if_then_else
11760           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11761             [(match_operator:X87MODEF 1 "float_operator"
11762               [(match_operand:SWI24 2 "memory_operand")])
11763              (match_operand:X87MODEF 3 "register_operand")])
11764           (match_operand 4)
11765           (match_operand 5)))
11766    (clobber (reg:CCFP FPSR_REG))
11767    (clobber (reg:CCFP FLAGS_REG))
11768    (clobber (match_scratch:HI 6))]
11769   "TARGET_80387 && !TARGET_CMOVE
11770    && reload_completed"
11771   [(const_int 0)]
11773   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11774                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11775                         operands[4], operands[5], operands[6]);
11776   DONE;
11779 ;; Unconditional and other jump instructions
11781 (define_insn "jump"
11782   [(set (pc)
11783         (label_ref (match_operand 0)))]
11784   ""
11785   "%!jmp\t%l0"
11786   [(set_attr "type" "ibr")
11787    (set_attr "modrm" "0")
11788    (set (attr "length")
11789         (if_then_else
11790           (and (ge (minus (match_dup 0) (pc))
11791                    (const_int -126))
11792                (lt (minus (match_dup 0) (pc))
11793                    (const_int 128)))
11794           (const_int 2)
11795           (const_int 5)))
11796    (set_attr "maybe_prefix_bnd" "1")])
11798 (define_expand "indirect_jump"
11799   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11800   ""
11802   if (TARGET_X32)
11803     operands[0] = convert_memory_address (word_mode, operands[0]);
11806 (define_insn "*indirect_jump"
11807   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11808   ""
11809   "%!jmp\t%A0"
11810   [(set_attr "type" "ibr")
11811    (set_attr "length_immediate" "0")
11812    (set_attr "maybe_prefix_bnd" "1")])
11814 (define_expand "tablejump"
11815   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11816               (use (label_ref (match_operand 1)))])]
11817   ""
11819   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11820      relative.  Convert the relative address to an absolute address.  */
11821   if (flag_pic)
11822     {
11823       rtx op0, op1;
11824       enum rtx_code code;
11826       /* We can't use @GOTOFF for text labels on VxWorks;
11827          see gotoff_operand.  */
11828       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11829         {
11830           code = PLUS;
11831           op0 = operands[0];
11832           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11833         }
11834       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11835         {
11836           code = PLUS;
11837           op0 = operands[0];
11838           op1 = pic_offset_table_rtx;
11839         }
11840       else
11841         {
11842           code = MINUS;
11843           op0 = pic_offset_table_rtx;
11844           op1 = operands[0];
11845         }
11847       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11848                                          OPTAB_DIRECT);
11849     }
11851   if (TARGET_X32)
11852     operands[0] = convert_memory_address (word_mode, operands[0]);
11855 (define_insn "*tablejump_1"
11856   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11857    (use (label_ref (match_operand 1)))]
11858   ""
11859   "%!jmp\t%A0"
11860   [(set_attr "type" "ibr")
11861    (set_attr "length_immediate" "0")
11862    (set_attr "maybe_prefix_bnd" "1")])
11864 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
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    (set (match_operand 3 "any_QIreg_operand")
11872         (zero_extend (match_dup 1)))]
11873   "(peep2_reg_dead_p (3, operands[1])
11874     || operands_match_p (operands[1], 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    (set (match_operand 3 "any_QIreg_operand")
11892         (zero_extend (match_dup 1)))]
11893   "(peep2_reg_dead_p (3, operands[1])
11894     || operands_match_p (operands[1], operands[3]))
11895    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11896    && ! reg_set_p (operands[3], operands[4])"
11897   [(parallel [(set (match_dup 5) (match_dup 0))
11898               (match_dup 4)])
11899    (set (strict_low_part (match_dup 6))
11900         (match_dup 2))]
11902   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11903   operands[6] = gen_lowpart (QImode, operands[3]);
11904   ix86_expand_clear (operands[3]);
11907 ;; Similar, but match zero extend with andsi3.
11909 (define_peephole2
11910   [(set (reg FLAGS_REG) (match_operand 0))
11911    (set (match_operand:QI 1 "register_operand")
11912         (match_operator:QI 2 "ix86_comparison_operator"
11913           [(reg FLAGS_REG) (const_int 0)]))
11914    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11915                    (and:SI (match_dup 3) (const_int 255)))
11916               (clobber (reg:CC FLAGS_REG))])]
11917   "REGNO (operands[1]) == REGNO (operands[3])
11918    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11919   [(set (match_dup 4) (match_dup 0))
11920    (set (strict_low_part (match_dup 5))
11921         (match_dup 2))]
11923   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11924   operands[5] = gen_lowpart (QImode, operands[3]);
11925   ix86_expand_clear (operands[3]);
11928 (define_peephole2
11929   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11930               (match_operand 4)])
11931    (set (match_operand:QI 1 "register_operand")
11932         (match_operator:QI 2 "ix86_comparison_operator"
11933           [(reg FLAGS_REG) (const_int 0)]))
11934    (parallel [(set (match_operand 3 "any_QIreg_operand")
11935                    (zero_extend (match_dup 1)))
11936               (clobber (reg:CC FLAGS_REG))])]
11937   "(peep2_reg_dead_p (3, operands[1])
11938     || operands_match_p (operands[1], operands[3]))
11939    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11940    && ! reg_set_p (operands[3], operands[4])"
11941   [(parallel [(set (match_dup 5) (match_dup 0))
11942               (match_dup 4)])
11943    (set (strict_low_part (match_dup 6))
11944         (match_dup 2))]
11946   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11947   operands[6] = gen_lowpart (QImode, operands[3]);
11948   ix86_expand_clear (operands[3]);
11951 ;; Call instructions.
11953 ;; The predicates normally associated with named expanders are not properly
11954 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11955 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11957 ;; P6 processors will jump to the address after the decrement when %esp
11958 ;; is used as a call operand, so they will execute return address as a code.
11959 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11961 ;; Register constraint for call instruction.
11962 (define_mode_attr c [(SI "l") (DI "r")])
11964 ;; Call subroutine returning no value.
11966 (define_expand "call"
11967   [(call (match_operand:QI 0)
11968          (match_operand 1))
11969    (use (match_operand 2))]
11970   ""
11972   ix86_expand_call (NULL, operands[0], operands[1],
11973                     operands[2], NULL, false);
11974   DONE;
11977 (define_expand "sibcall"
11978   [(call (match_operand:QI 0)
11979          (match_operand 1))
11980    (use (match_operand 2))]
11981   ""
11983   ix86_expand_call (NULL, operands[0], operands[1],
11984                     operands[2], NULL, true);
11985   DONE;
11988 (define_insn "*call"
11989   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11990          (match_operand 1))]
11991   "!SIBLING_CALL_P (insn)"
11992   "* return ix86_output_call_insn (insn, operands[0]);"
11993   [(set_attr "type" "call")])
11995 ;; This covers both call and sibcall since only GOT slot is allowed.
11996 (define_insn "*call_got_x32"
11997   [(call (mem:QI (zero_extend:DI
11998                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11999          (match_operand 1))]
12000   "TARGET_X32"
12002   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12003   return ix86_output_call_insn (insn, fnaddr);
12005   [(set_attr "type" "call")])
12007 ;; Since sibcall never returns, we can only use call-clobbered register
12008 ;; as GOT base.
12009 (define_insn "*sibcall_GOT_32"
12010   [(call (mem:QI
12011            (mem:SI (plus:SI
12012                      (match_operand:SI 0 "register_no_elim_operand" "U")
12013                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12014          (match_operand 2))]
12015   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12017   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12018   fnaddr = gen_const_mem (SImode, fnaddr);
12019   return ix86_output_call_insn (insn, fnaddr);
12021   [(set_attr "type" "call")])
12023 (define_insn "*sibcall"
12024   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12025          (match_operand 1))]
12026   "SIBLING_CALL_P (insn)"
12027   "* return ix86_output_call_insn (insn, operands[0]);"
12028   [(set_attr "type" "call")])
12030 (define_insn "*sibcall_memory"
12031   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12032          (match_operand 1))
12033    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12034   "!TARGET_X32"
12035   "* return ix86_output_call_insn (insn, operands[0]);"
12036   [(set_attr "type" "call")])
12038 (define_peephole2
12039   [(set (match_operand:W 0 "register_operand")
12040         (match_operand:W 1 "memory_operand"))
12041    (call (mem:QI (match_dup 0))
12042          (match_operand 3))]
12043   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12044    && !reg_mentioned_p (operands[0],
12045                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12046   [(parallel [(call (mem:QI (match_dup 1))
12047                     (match_dup 3))
12048               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12050 (define_peephole2
12051   [(set (match_operand:W 0 "register_operand")
12052         (match_operand:W 1 "memory_operand"))
12053    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12054    (call (mem:QI (match_dup 0))
12055          (match_operand 3))]
12056   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12057    && !reg_mentioned_p (operands[0],
12058                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12059   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12060    (parallel [(call (mem:QI (match_dup 1))
12061                     (match_dup 3))
12062               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12064 (define_expand "call_pop"
12065   [(parallel [(call (match_operand:QI 0)
12066                     (match_operand:SI 1))
12067               (set (reg:SI SP_REG)
12068                    (plus:SI (reg:SI SP_REG)
12069                             (match_operand:SI 3)))])]
12070   "!TARGET_64BIT"
12072   ix86_expand_call (NULL, operands[0], operands[1],
12073                     operands[2], operands[3], false);
12074   DONE;
12077 (define_insn "*call_pop"
12078   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12079          (match_operand 1))
12080    (set (reg:SI SP_REG)
12081         (plus:SI (reg:SI SP_REG)
12082                  (match_operand:SI 2 "immediate_operand" "i")))]
12083   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12084   "* return ix86_output_call_insn (insn, operands[0]);"
12085   [(set_attr "type" "call")])
12087 (define_insn "*sibcall_pop"
12088   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12089          (match_operand 1))
12090    (set (reg:SI SP_REG)
12091         (plus:SI (reg:SI SP_REG)
12092                  (match_operand:SI 2 "immediate_operand" "i")))]
12093   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12094   "* return ix86_output_call_insn (insn, operands[0]);"
12095   [(set_attr "type" "call")])
12097 (define_insn "*sibcall_pop_memory"
12098   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12099          (match_operand 1))
12100    (set (reg:SI SP_REG)
12101         (plus:SI (reg:SI SP_REG)
12102                  (match_operand:SI 2 "immediate_operand" "i")))
12103    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12104   "!TARGET_64BIT"
12105   "* return ix86_output_call_insn (insn, operands[0]);"
12106   [(set_attr "type" "call")])
12108 (define_peephole2
12109   [(set (match_operand:SI 0 "register_operand")
12110         (match_operand:SI 1 "memory_operand"))
12111    (parallel [(call (mem:QI (match_dup 0))
12112                     (match_operand 3))
12113               (set (reg:SI SP_REG)
12114                    (plus:SI (reg:SI SP_REG)
12115                             (match_operand:SI 4 "immediate_operand")))])]
12116   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12117    && !reg_mentioned_p (operands[0],
12118                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12119   [(parallel [(call (mem:QI (match_dup 1))
12120                     (match_dup 3))
12121               (set (reg:SI SP_REG)
12122                    (plus:SI (reg:SI SP_REG)
12123                             (match_dup 4)))
12124               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12126 (define_peephole2
12127   [(set (match_operand:SI 0 "register_operand")
12128         (match_operand:SI 1 "memory_operand"))
12129    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12130    (parallel [(call (mem:QI (match_dup 0))
12131                     (match_operand 3))
12132               (set (reg:SI SP_REG)
12133                    (plus:SI (reg:SI SP_REG)
12134                             (match_operand:SI 4 "immediate_operand")))])]
12135   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12136    && !reg_mentioned_p (operands[0],
12137                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12138   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12139    (parallel [(call (mem:QI (match_dup 1))
12140                     (match_dup 3))
12141               (set (reg:SI SP_REG)
12142                    (plus:SI (reg:SI SP_REG)
12143                             (match_dup 4)))
12144               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12146 ;; Combining simple memory jump instruction
12148 (define_peephole2
12149   [(set (match_operand:W 0 "register_operand")
12150         (match_operand:W 1 "memory_operand"))
12151    (set (pc) (match_dup 0))]
12152   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12153   [(set (pc) (match_dup 1))])
12155 ;; Call subroutine, returning value in operand 0
12157 (define_expand "call_value"
12158   [(set (match_operand 0)
12159         (call (match_operand:QI 1)
12160               (match_operand 2)))
12161    (use (match_operand 3))]
12162   ""
12164   ix86_expand_call (operands[0], operands[1], operands[2],
12165                     operands[3], NULL, false);
12166   DONE;
12169 (define_expand "sibcall_value"
12170   [(set (match_operand 0)
12171         (call (match_operand:QI 1)
12172               (match_operand 2)))
12173    (use (match_operand 3))]
12174   ""
12176   ix86_expand_call (operands[0], operands[1], operands[2],
12177                     operands[3], NULL, true);
12178   DONE;
12181 (define_insn "*call_value"
12182   [(set (match_operand 0)
12183         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12184               (match_operand 2)))]
12185   "!SIBLING_CALL_P (insn)"
12186   "* return ix86_output_call_insn (insn, operands[1]);"
12187   [(set_attr "type" "callv")])
12189 ;; This covers both call and sibcall since only GOT slot is allowed.
12190 (define_insn "*call_value_got_x32"
12191   [(set (match_operand 0)
12192         (call (mem:QI
12193                 (zero_extend:DI
12194                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12195               (match_operand 2)))]
12196   "TARGET_X32"
12198   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12199   return ix86_output_call_insn (insn, fnaddr);
12201   [(set_attr "type" "callv")])
12203 ;; Since sibcall never returns, we can only use call-clobbered register
12204 ;; as GOT base.
12205 (define_insn "*sibcall_value_GOT_32"
12206   [(set (match_operand 0)
12207         (call (mem:QI
12208                 (mem:SI (plus:SI
12209                           (match_operand:SI 1 "register_no_elim_operand" "U")
12210                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12211          (match_operand 3)))]
12212   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12214   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12215   fnaddr = gen_const_mem (SImode, fnaddr);
12216   return ix86_output_call_insn (insn, fnaddr);
12218   [(set_attr "type" "callv")])
12220 (define_insn "*sibcall_value"
12221   [(set (match_operand 0)
12222         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12223               (match_operand 2)))]
12224   "SIBLING_CALL_P (insn)"
12225   "* return ix86_output_call_insn (insn, operands[1]);"
12226   [(set_attr "type" "callv")])
12228 (define_insn "*sibcall_value_memory"
12229   [(set (match_operand 0)
12230         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12231               (match_operand 2)))
12232    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12233   "!TARGET_X32"
12234   "* return ix86_output_call_insn (insn, operands[1]);"
12235   [(set_attr "type" "callv")])
12237 (define_peephole2
12238   [(set (match_operand:W 0 "register_operand")
12239         (match_operand:W 1 "memory_operand"))
12240    (set (match_operand 2)
12241    (call (mem:QI (match_dup 0))
12242                  (match_operand 3)))]
12243   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12244    && !reg_mentioned_p (operands[0],
12245                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12246   [(parallel [(set (match_dup 2)
12247                    (call (mem:QI (match_dup 1))
12248                          (match_dup 3)))
12249               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12251 (define_peephole2
12252   [(set (match_operand:W 0 "register_operand")
12253         (match_operand:W 1 "memory_operand"))
12254    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12255    (set (match_operand 2)
12256         (call (mem:QI (match_dup 0))
12257               (match_operand 3)))]
12258   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12259    && !reg_mentioned_p (operands[0],
12260                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12261   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12262    (parallel [(set (match_dup 2)
12263                    (call (mem:QI (match_dup 1))
12264                          (match_dup 3)))
12265               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12267 (define_expand "call_value_pop"
12268   [(parallel [(set (match_operand 0)
12269                    (call (match_operand:QI 1)
12270                          (match_operand:SI 2)))
12271               (set (reg:SI SP_REG)
12272                    (plus:SI (reg:SI SP_REG)
12273                             (match_operand:SI 4)))])]
12274   "!TARGET_64BIT"
12276   ix86_expand_call (operands[0], operands[1], operands[2],
12277                     operands[3], operands[4], false);
12278   DONE;
12281 (define_insn "*call_value_pop"
12282   [(set (match_operand 0)
12283         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12284               (match_operand 2)))
12285    (set (reg:SI SP_REG)
12286         (plus:SI (reg:SI SP_REG)
12287                  (match_operand:SI 3 "immediate_operand" "i")))]
12288   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12289   "* return ix86_output_call_insn (insn, operands[1]);"
12290   [(set_attr "type" "callv")])
12292 (define_insn "*sibcall_value_pop"
12293   [(set (match_operand 0)
12294         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12295               (match_operand 2)))
12296    (set (reg:SI SP_REG)
12297         (plus:SI (reg:SI SP_REG)
12298                  (match_operand:SI 3 "immediate_operand" "i")))]
12299   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12300   "* return ix86_output_call_insn (insn, operands[1]);"
12301   [(set_attr "type" "callv")])
12303 (define_insn "*sibcall_value_pop_memory"
12304   [(set (match_operand 0)
12305         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12306               (match_operand 2)))
12307    (set (reg:SI SP_REG)
12308         (plus:SI (reg:SI SP_REG)
12309                  (match_operand:SI 3 "immediate_operand" "i")))
12310    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12311   "!TARGET_64BIT"
12312   "* return ix86_output_call_insn (insn, operands[1]);"
12313   [(set_attr "type" "callv")])
12315 (define_peephole2
12316   [(set (match_operand:SI 0 "register_operand")
12317         (match_operand:SI 1 "memory_operand"))
12318    (parallel [(set (match_operand 2)
12319                    (call (mem:QI (match_dup 0))
12320                          (match_operand 3)))
12321               (set (reg:SI SP_REG)
12322                    (plus:SI (reg:SI SP_REG)
12323                             (match_operand:SI 4 "immediate_operand")))])]
12324   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12325    && !reg_mentioned_p (operands[0],
12326                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12327   [(parallel [(set (match_dup 2)
12328                    (call (mem:QI (match_dup 1))
12329                          (match_dup 3)))
12330               (set (reg:SI SP_REG)
12331                    (plus:SI (reg:SI SP_REG)
12332                             (match_dup 4)))
12333               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12335 (define_peephole2
12336   [(set (match_operand:SI 0 "register_operand")
12337         (match_operand:SI 1 "memory_operand"))
12338    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12339    (parallel [(set (match_operand 2)
12340                    (call (mem:QI (match_dup 0))
12341                          (match_operand 3)))
12342               (set (reg:SI SP_REG)
12343                    (plus:SI (reg:SI SP_REG)
12344                             (match_operand:SI 4 "immediate_operand")))])]
12345   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12346    && !reg_mentioned_p (operands[0],
12347                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12348   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12349    (parallel [(set (match_dup 2)
12350                    (call (mem:QI (match_dup 1))
12351                          (match_dup 3)))
12352               (set (reg:SI SP_REG)
12353                    (plus:SI (reg:SI SP_REG)
12354                             (match_dup 4)))
12355               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12357 ;; Call subroutine returning any type.
12359 (define_expand "untyped_call"
12360   [(parallel [(call (match_operand 0)
12361                     (const_int 0))
12362               (match_operand 1)
12363               (match_operand 2)])]
12364   ""
12366   int i;
12368   /* In order to give reg-stack an easier job in validating two
12369      coprocessor registers as containing a possible return value,
12370      simply pretend the untyped call returns a complex long double
12371      value. 
12373      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12374      and should have the default ABI.  */
12376   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12377                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12378                     operands[0], const0_rtx,
12379                     GEN_INT ((TARGET_64BIT
12380                               ? (ix86_abi == SYSV_ABI
12381                                  ? X86_64_SSE_REGPARM_MAX
12382                                  : X86_64_MS_SSE_REGPARM_MAX)
12383                               : X86_32_SSE_REGPARM_MAX)
12384                              - 1),
12385                     NULL, false);
12387   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12388     {
12389       rtx set = XVECEXP (operands[2], 0, i);
12390       emit_move_insn (SET_DEST (set), SET_SRC (set));
12391     }
12393   /* The optimizer does not know that the call sets the function value
12394      registers we stored in the result block.  We avoid problems by
12395      claiming that all hard registers are used and clobbered at this
12396      point.  */
12397   emit_insn (gen_blockage ());
12399   DONE;
12402 ;; Prologue and epilogue instructions
12404 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12405 ;; all of memory.  This blocks insns from being moved across this point.
12407 (define_insn "blockage"
12408   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12409   ""
12410   ""
12411   [(set_attr "length" "0")])
12413 ;; Do not schedule instructions accessing memory across this point.
12415 (define_expand "memory_blockage"
12416   [(set (match_dup 0)
12417         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12418   ""
12420   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12421   MEM_VOLATILE_P (operands[0]) = 1;
12424 (define_insn "*memory_blockage"
12425   [(set (match_operand:BLK 0)
12426         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12427   ""
12428   ""
12429   [(set_attr "length" "0")])
12431 ;; As USE insns aren't meaningful after reload, this is used instead
12432 ;; to prevent deleting instructions setting registers for PIC code
12433 (define_insn "prologue_use"
12434   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12435   ""
12436   ""
12437   [(set_attr "length" "0")])
12439 ;; Insn emitted into the body of a function to return from a function.
12440 ;; This is only done if the function's epilogue is known to be simple.
12441 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12443 (define_expand "return"
12444   [(simple_return)]
12445   "ix86_can_use_return_insn_p ()"
12447   if (crtl->args.pops_args)
12448     {
12449       rtx popc = GEN_INT (crtl->args.pops_args);
12450       emit_jump_insn (gen_simple_return_pop_internal (popc));
12451       DONE;
12452     }
12455 ;; We need to disable this for TARGET_SEH, as otherwise
12456 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12457 ;; the maximum size of prologue in unwind information.
12458 ;; Also disallow shrink-wrapping if using stack slot to pass the
12459 ;; static chain pointer - the first instruction has to be pushl %esi
12460 ;; and it can't be moved around, as we use alternate entry points
12461 ;; in that case.
12463 (define_expand "simple_return"
12464   [(simple_return)]
12465   "!TARGET_SEH && !ix86_static_chain_on_stack"
12467   if (crtl->args.pops_args)
12468     {
12469       rtx popc = GEN_INT (crtl->args.pops_args);
12470       emit_jump_insn (gen_simple_return_pop_internal (popc));
12471       DONE;
12472     }
12475 (define_insn "simple_return_internal"
12476   [(simple_return)]
12477   "reload_completed"
12478   "%!ret"
12479   [(set_attr "length" "1")
12480    (set_attr "atom_unit" "jeu")
12481    (set_attr "length_immediate" "0")
12482    (set_attr "modrm" "0")
12483    (set_attr "maybe_prefix_bnd" "1")])
12485 (define_insn "interrupt_return"
12486   [(simple_return)
12487    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12488   "reload_completed"
12490   return TARGET_64BIT ? "iretq" : "iret";
12493 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12494 ;; instruction Athlon and K8 have.
12496 (define_insn "simple_return_internal_long"
12497   [(simple_return)
12498    (unspec [(const_int 0)] UNSPEC_REP)]
12499   "reload_completed"
12501   if (ix86_bnd_prefixed_insn_p (insn))
12502     return "%!ret";
12504   return "rep%; ret";
12506   [(set_attr "length" "2")
12507    (set_attr "atom_unit" "jeu")
12508    (set_attr "length_immediate" "0")
12509    (set_attr "prefix_rep" "1")
12510    (set_attr "modrm" "0")])
12512 (define_insn "simple_return_pop_internal"
12513   [(simple_return)
12514    (use (match_operand:SI 0 "const_int_operand"))]
12515   "reload_completed"
12516   "%!ret\t%0"
12517   [(set_attr "length" "3")
12518    (set_attr "atom_unit" "jeu")
12519    (set_attr "length_immediate" "2")
12520    (set_attr "modrm" "0")
12521    (set_attr "maybe_prefix_bnd" "1")])
12523 (define_insn "simple_return_indirect_internal"
12524   [(simple_return)
12525    (use (match_operand:SI 0 "register_operand" "r"))]
12526   "reload_completed"
12527   "%!jmp\t%A0"
12528   [(set_attr "type" "ibr")
12529    (set_attr "length_immediate" "0")
12530    (set_attr "maybe_prefix_bnd" "1")])
12532 (define_insn "nop"
12533   [(const_int 0)]
12534   ""
12535   "nop"
12536   [(set_attr "length" "1")
12537    (set_attr "length_immediate" "0")
12538    (set_attr "modrm" "0")])
12540 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12541 (define_insn "nops"
12542   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12543                     UNSPECV_NOPS)]
12544   "reload_completed"
12546   int num = INTVAL (operands[0]);
12548   gcc_assert (IN_RANGE (num, 1, 8));
12550   while (num--)
12551     fputs ("\tnop\n", asm_out_file);
12553   return "";
12555   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12556    (set_attr "length_immediate" "0")
12557    (set_attr "modrm" "0")])
12559 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12560 ;; branch prediction penalty for the third jump in a 16-byte
12561 ;; block on K8.
12563 (define_insn "pad"
12564   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12565   ""
12567 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12568   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12569 #else
12570   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12571      The align insn is used to avoid 3 jump instructions in the row to improve
12572      branch prediction and the benefits hardly outweigh the cost of extra 8
12573      nops on the average inserted by full alignment pseudo operation.  */
12574 #endif
12575   return "";
12577   [(set_attr "length" "16")])
12579 (define_expand "prologue"
12580   [(const_int 0)]
12581   ""
12582   "ix86_expand_prologue (); DONE;")
12584 (define_expand "set_got"
12585   [(parallel
12586      [(set (match_operand:SI 0 "register_operand")
12587            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12588       (clobber (reg:CC FLAGS_REG))])]
12589   "!TARGET_64BIT"
12591   if (flag_pic && !TARGET_VXWORKS_RTP)
12592     ix86_pc_thunk_call_expanded = true;
12595 (define_insn "*set_got"
12596   [(set (match_operand:SI 0 "register_operand" "=r")
12597         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "!TARGET_64BIT"
12600   "* return output_set_got (operands[0], NULL_RTX);"
12601   [(set_attr "type" "multi")
12602    (set_attr "length" "12")])
12604 (define_expand "set_got_labelled"
12605   [(parallel
12606      [(set (match_operand:SI 0 "register_operand")
12607            (unspec:SI [(label_ref (match_operand 1))]
12608                       UNSPEC_SET_GOT))
12609       (clobber (reg:CC FLAGS_REG))])]
12610   "!TARGET_64BIT"
12612   if (flag_pic && !TARGET_VXWORKS_RTP)
12613     ix86_pc_thunk_call_expanded = true;
12616 (define_insn "*set_got_labelled"
12617   [(set (match_operand:SI 0 "register_operand" "=r")
12618         (unspec:SI [(label_ref (match_operand 1))]
12619          UNSPEC_SET_GOT))
12620    (clobber (reg:CC FLAGS_REG))]
12621   "!TARGET_64BIT"
12622   "* return output_set_got (operands[0], operands[1]);"
12623   [(set_attr "type" "multi")
12624    (set_attr "length" "12")])
12626 (define_insn "set_got_rex64"
12627   [(set (match_operand:DI 0 "register_operand" "=r")
12628         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12629   "TARGET_64BIT"
12630   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12631   [(set_attr "type" "lea")
12632    (set_attr "length_address" "4")
12633    (set_attr "modrm_class" "unknown")
12634    (set_attr "mode" "DI")])
12636 (define_insn "set_rip_rex64"
12637   [(set (match_operand:DI 0 "register_operand" "=r")
12638         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12639   "TARGET_64BIT"
12640   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12641   [(set_attr "type" "lea")
12642    (set_attr "length_address" "4")
12643    (set_attr "mode" "DI")])
12645 (define_insn "set_got_offset_rex64"
12646   [(set (match_operand:DI 0 "register_operand" "=r")
12647         (unspec:DI
12648           [(label_ref (match_operand 1))]
12649           UNSPEC_SET_GOT_OFFSET))]
12650   "TARGET_LP64"
12651   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12652   [(set_attr "type" "imov")
12653    (set_attr "length_immediate" "0")
12654    (set_attr "length_address" "8")
12655    (set_attr "mode" "DI")])
12657 (define_expand "epilogue"
12658   [(const_int 0)]
12659   ""
12660   "ix86_expand_epilogue (1); DONE;")
12662 (define_expand "sibcall_epilogue"
12663   [(const_int 0)]
12664   ""
12665   "ix86_expand_epilogue (0); DONE;")
12667 (define_expand "eh_return"
12668   [(use (match_operand 0 "register_operand"))]
12669   ""
12671   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12673   /* Tricky bit: we write the address of the handler to which we will
12674      be returning into someone else's stack frame, one word below the
12675      stack address we wish to restore.  */
12676   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12677   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12678   tmp = gen_rtx_MEM (Pmode, tmp);
12679   emit_move_insn (tmp, ra);
12681   emit_jump_insn (gen_eh_return_internal ());
12682   emit_barrier ();
12683   DONE;
12686 (define_insn_and_split "eh_return_internal"
12687   [(eh_return)]
12688   ""
12689   "#"
12690   "epilogue_completed"
12691   [(const_int 0)]
12692   "ix86_expand_epilogue (2); DONE;")
12694 (define_insn "leave"
12695   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12696    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12697    (clobber (mem:BLK (scratch)))]
12698   "!TARGET_64BIT"
12699   "leave"
12700   [(set_attr "type" "leave")])
12702 (define_insn "leave_rex64"
12703   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12704    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12705    (clobber (mem:BLK (scratch)))]
12706   "TARGET_64BIT"
12707   "leave"
12708   [(set_attr "type" "leave")])
12710 ;; Handle -fsplit-stack.
12712 (define_expand "split_stack_prologue"
12713   [(const_int 0)]
12714   ""
12716   ix86_expand_split_stack_prologue ();
12717   DONE;
12720 ;; In order to support the call/return predictor, we use a return
12721 ;; instruction which the middle-end doesn't see.
12722 (define_insn "split_stack_return"
12723   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12724                      UNSPECV_SPLIT_STACK_RETURN)]
12725   ""
12727   if (operands[0] == const0_rtx)
12728     return "ret";
12729   else
12730     return "ret\t%0";
12732   [(set_attr "atom_unit" "jeu")
12733    (set_attr "modrm" "0")
12734    (set (attr "length")
12735         (if_then_else (match_operand:SI 0 "const0_operand")
12736                       (const_int 1)
12737                       (const_int 3)))
12738    (set (attr "length_immediate")
12739         (if_then_else (match_operand:SI 0 "const0_operand")
12740                       (const_int 0)
12741                       (const_int 2)))])
12743 ;; If there are operand 0 bytes available on the stack, jump to
12744 ;; operand 1.
12746 (define_expand "split_stack_space_check"
12747   [(set (pc) (if_then_else
12748               (ltu (minus (reg SP_REG)
12749                           (match_operand 0 "register_operand"))
12750                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12751               (label_ref (match_operand 1))
12752               (pc)))]
12753   ""
12755   rtx reg, size, limit;
12757   reg = gen_reg_rtx (Pmode);
12758   size = force_reg (Pmode, operands[0]);
12759   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12760   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12761                           UNSPEC_STACK_CHECK);
12762   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12763   ix86_expand_branch (GEU, reg, limit, operands[1]);
12765   DONE;
12768 ;; Bit manipulation instructions.
12770 (define_expand "ffs<mode>2"
12771   [(set (match_dup 2) (const_int -1))
12772    (parallel [(set (match_dup 3) (match_dup 4))
12773               (set (match_operand:SWI48 0 "register_operand")
12774                    (ctz:SWI48
12775                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12776    (set (match_dup 0) (if_then_else:SWI48
12777                         (eq (match_dup 3) (const_int 0))
12778                         (match_dup 2)
12779                         (match_dup 0)))
12780    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12781               (clobber (reg:CC FLAGS_REG))])]
12782   ""
12784   machine_mode flags_mode;
12786   if (<MODE>mode == SImode && !TARGET_CMOVE)
12787     {
12788       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12789       DONE;
12790     }
12792   flags_mode
12793     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12795   operands[2] = gen_reg_rtx (<MODE>mode);
12796   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12797   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12800 (define_insn_and_split "ffssi2_no_cmove"
12801   [(set (match_operand:SI 0 "register_operand" "=r")
12802         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12803    (clobber (match_scratch:SI 2 "=&q"))
12804    (clobber (reg:CC FLAGS_REG))]
12805   "!TARGET_CMOVE"
12806   "#"
12807   "&& reload_completed"
12808   [(parallel [(set (match_dup 4) (match_dup 5))
12809               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12810    (set (strict_low_part (match_dup 3))
12811         (eq:QI (match_dup 4) (const_int 0)))
12812    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12813               (clobber (reg:CC FLAGS_REG))])
12814    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12815               (clobber (reg:CC FLAGS_REG))])
12816    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12817               (clobber (reg:CC FLAGS_REG))])]
12819   machine_mode flags_mode
12820     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12822   operands[3] = gen_lowpart (QImode, operands[2]);
12823   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12824   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12826   ix86_expand_clear (operands[2]);
12829 (define_insn "*tzcnt<mode>_1"
12830   [(set (reg:CCC FLAGS_REG)
12831         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12832                      (const_int 0)))
12833    (set (match_operand:SWI48 0 "register_operand" "=r")
12834         (ctz:SWI48 (match_dup 1)))]
12835   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12836   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12837   [(set_attr "type" "alu1")
12838    (set_attr "prefix_0f" "1")
12839    (set_attr "prefix_rep" "1")
12840    (set_attr "btver2_decode" "double")
12841    (set_attr "mode" "<MODE>")])
12843 (define_insn "*bsf<mode>_1"
12844   [(set (reg:CCZ FLAGS_REG)
12845         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12846                      (const_int 0)))
12847    (set (match_operand:SWI48 0 "register_operand" "=r")
12848         (ctz:SWI48 (match_dup 1)))]
12849   ""
12850   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12851   [(set_attr "type" "alu1")
12852    (set_attr "prefix_0f" "1")
12853    (set_attr "btver2_decode" "double")
12854    (set_attr "znver1_decode" "vector")
12855    (set_attr "mode" "<MODE>")])
12857 (define_expand "ctz<mode>2"
12858   [(parallel
12859     [(set (match_operand:SWI48 0 "register_operand")
12860           (ctz:SWI48
12861             (match_operand:SWI48 1 "nonimmediate_operand")))
12862      (clobber (reg:CC FLAGS_REG))])])
12864 ; False dependency happens when destination is only updated by tzcnt,
12865 ; lzcnt or popcnt.  There is no false dependency when destination is
12866 ; also used in source.
12867 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12868   [(set (match_operand:SWI48 0 "register_operand" "=r")
12869         (ctz:SWI48
12870           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12871    (clobber (reg:CC FLAGS_REG))]
12872   "(TARGET_BMI || TARGET_GENERIC)
12873    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12874   "#"
12875   "&& reload_completed"
12876   [(parallel
12877     [(set (match_dup 0)
12878           (ctz:SWI48 (match_dup 1)))
12879      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12880      (clobber (reg:CC FLAGS_REG))])]
12882   if (!reg_mentioned_p (operands[0], operands[1]))
12883     ix86_expand_clear (operands[0]);
12886 (define_insn "*ctz<mode>2_falsedep"
12887   [(set (match_operand:SWI48 0 "register_operand" "=r")
12888         (ctz:SWI48
12889           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12890    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12891            UNSPEC_INSN_FALSE_DEP)
12892    (clobber (reg:CC FLAGS_REG))]
12893   ""
12895   if (TARGET_BMI)
12896     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12897   else if (TARGET_GENERIC)
12898     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12899     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12900   else
12901     gcc_unreachable ();
12903   [(set_attr "type" "alu1")
12904    (set_attr "prefix_0f" "1")
12905    (set_attr "prefix_rep" "1")
12906    (set_attr "mode" "<MODE>")])
12908 (define_insn "*ctz<mode>2"
12909   [(set (match_operand:SWI48 0 "register_operand" "=r")
12910         (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12911    (clobber (reg:CC FLAGS_REG))]
12912   ""
12914   if (TARGET_BMI)
12915     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12916   else if (optimize_function_for_size_p (cfun))
12917     ;
12918   else if (TARGET_GENERIC)
12919     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12920     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12922   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12924   [(set_attr "type" "alu1")
12925    (set_attr "prefix_0f" "1")
12926    (set (attr "prefix_rep")
12927      (if_then_else
12928        (ior (match_test "TARGET_BMI")
12929             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12930                  (match_test "TARGET_GENERIC")))
12931        (const_string "1")
12932        (const_string "0")))
12933    (set_attr "mode" "<MODE>")])
12935 ;; Version of tzcnt that is expanded from intrinsics.  This version provides
12936 ;; operand size as output when source operand is zero. 
12938 (define_expand "bmi_tzcnt_<mode>"
12939   [(parallel
12940     [(set (match_operand:SWI248 0 "register_operand")
12941           (unspec:SWI248
12942             [(match_operand:SWI248 1 "nonimmediate_operand")]
12943             UNSPEC_TZCNT))
12944      (clobber (reg:CC FLAGS_REG))])]
12945   "TARGET_BMI")
12947 ; False dependency happens when destination is only updated by tzcnt,
12948 ; lzcnt or popcnt.  There is no false dependency when destination is
12949 ; also used in source.
12950 (define_insn_and_split "*bmi_tzcnt_<mode>_falsedep_1"
12951   [(set (match_operand:SWI48 0 "register_operand" "=r")
12952         (unspec:SWI48
12953           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12954           UNSPEC_TZCNT))
12955    (clobber (reg:CC FLAGS_REG))]
12956   "TARGET_BMI
12957    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12958   "#"
12959   "&& reload_completed"
12960   [(parallel
12961     [(set (match_dup 0)
12962           (unspec:SWI48 [(match_dup 1)] UNSPEC_TZCNT))
12963      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12964      (clobber (reg:CC FLAGS_REG))])]
12966   if (!reg_mentioned_p (operands[0], operands[1]))
12967     ix86_expand_clear (operands[0]);
12970 (define_insn "*bmi_tzcnt_<mode>_falsedep"
12971   [(set (match_operand:SWI48 0 "register_operand" "=r")
12972         (unspec:SWI48
12973           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
12974           UNSPEC_TZCNT))
12975    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12976            UNSPEC_INSN_FALSE_DEP)
12977    (clobber (reg:CC FLAGS_REG))]
12978   "TARGET_BMI"
12979   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12980   [(set_attr "type" "alu1")
12981    (set_attr "prefix_0f" "1")
12982    (set_attr "prefix_rep" "1")
12983    (set_attr "mode" "<MODE>")])
12985 (define_insn "*bmi_tzcnt_<mode>"
12986   [(set (match_operand:SWI248 0 "register_operand" "=r")
12987         (unspec:SWI248
12988           [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
12989           UNSPEC_TZCNT))
12990    (clobber (reg:CC FLAGS_REG))]
12991   "TARGET_BMI"
12992   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12993   [(set_attr "type" "alu1")
12994    (set_attr "prefix_0f" "1")
12995    (set_attr "prefix_rep" "1")
12996    (set_attr "mode" "<MODE>")])
12998 (define_expand "clz<mode>2"
12999   [(parallel
13000      [(set (match_operand:SWI48 0 "register_operand")
13001            (minus:SWI48
13002              (match_dup 2)
13003              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13004       (clobber (reg:CC FLAGS_REG))])
13005    (parallel
13006      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13007       (clobber (reg:CC FLAGS_REG))])]
13008   ""
13010   if (TARGET_LZCNT)
13011     {
13012       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13013       DONE;
13014     }
13015   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13018 (define_expand "clz<mode>2_lzcnt"
13019   [(parallel
13020     [(set (match_operand:SWI48 0 "register_operand")
13021           (clz:SWI48
13022             (match_operand:SWI48 1 "nonimmediate_operand")))
13023      (clobber (reg:CC FLAGS_REG))])]
13024   "TARGET_LZCNT")
13026 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
13027   [(set (match_operand:SWI48 0 "register_operand" "=r")
13028         (clz:SWI48
13029           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13030    (clobber (reg:CC FLAGS_REG))]
13031   "TARGET_LZCNT
13032    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13033   "#"
13034   "&& reload_completed"
13035   [(parallel
13036     [(set (match_dup 0)
13037           (clz:SWI48 (match_dup 1)))
13038      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13039      (clobber (reg:CC FLAGS_REG))])]
13041   if (!reg_mentioned_p (operands[0], operands[1]))
13042     ix86_expand_clear (operands[0]);
13045 (define_insn "*clz<mode>2_lzcnt_falsedep"
13046   [(set (match_operand:SWI48 0 "register_operand" "=r")
13047         (clz:SWI48
13048           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13049    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13050            UNSPEC_INSN_FALSE_DEP)
13051    (clobber (reg:CC FLAGS_REG))]
13052   "TARGET_LZCNT"
13053   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13054   [(set_attr "prefix_rep" "1")
13055    (set_attr "type" "bitmanip")
13056    (set_attr "mode" "<MODE>")])
13058 (define_insn "*clz<mode>2_lzcnt"
13059   [(set (match_operand:SWI48 0 "register_operand" "=r")
13060         (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13061    (clobber (reg:CC FLAGS_REG))]
13062   "TARGET_LZCNT"
13063   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13064   [(set_attr "prefix_rep" "1")
13065    (set_attr "type" "bitmanip")
13066    (set_attr "mode" "<MODE>")])
13068 ;; Version of lzcnt that is expanded from intrinsics.  This version provides
13069 ;; operand size as output when source operand is zero. 
13071 (define_expand "lzcnt_<mode>"
13072   [(parallel
13073     [(set (match_operand:SWI248 0 "register_operand")
13074           (unspec:SWI248
13075             [(match_operand:SWI248 1 "nonimmediate_operand")]
13076             UNSPEC_LZCNT))
13077      (clobber (reg:CC FLAGS_REG))])]
13078   "TARGET_LZCNT")
13080 ; False dependency happens when destination is only updated by tzcnt,
13081 ; lzcnt or popcnt.  There is no false dependency when destination is
13082 ; also used in source.
13083 (define_insn_and_split "*lzcnt_<mode>_falsedep_1"
13084   [(set (match_operand:SWI48 0 "register_operand" "=r")
13085         (unspec:SWI48
13086           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13087           UNSPEC_LZCNT))
13088    (clobber (reg:CC FLAGS_REG))]
13089   "TARGET_LZCNT
13090    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13091   "#"
13092   "&& reload_completed"
13093   [(parallel
13094     [(set (match_dup 0)
13095           (unspec:SWI48 [(match_dup 1)] UNSPEC_LZCNT))
13096      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13097      (clobber (reg:CC FLAGS_REG))])]
13099   if (!reg_mentioned_p (operands[0], operands[1]))
13100     ix86_expand_clear (operands[0]);
13103 (define_insn "*lzcnt_<mode>_falsedep"
13104   [(set (match_operand:SWI48 0 "register_operand" "=r")
13105         (unspec:SWI48
13106           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")]
13107           UNSPEC_LZCNT))
13108    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13109            UNSPEC_INSN_FALSE_DEP)
13110    (clobber (reg:CC FLAGS_REG))]
13111   "TARGET_LZCNT"
13112   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13113   [(set_attr "type" "alu1")
13114    (set_attr "prefix_0f" "1")
13115    (set_attr "prefix_rep" "1")
13116    (set_attr "mode" "<MODE>")])
13118 (define_insn "*lzcnt_<mode>"
13119   [(set (match_operand:SWI248 0 "register_operand" "=r")
13120         (unspec:SWI248
13121           [(match_operand:SWI248 1 "nonimmediate_operand" "rm")]
13122           UNSPEC_LZCNT))
13123    (clobber (reg:CC FLAGS_REG))]
13124   "TARGET_LZCNT"
13125   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13126   [(set_attr "type" "alu1")
13127    (set_attr "prefix_0f" "1")
13128    (set_attr "prefix_rep" "1")
13129    (set_attr "mode" "<MODE>")])
13131 ;; BMI instructions.
13132 (define_insn "*bmi_andn_<mode>"
13133   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13134         (and:SWI48
13135           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13136           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
13137    (clobber (reg:CC FLAGS_REG))]
13138   "TARGET_BMI"
13139   "andn\t{%2, %1, %0|%0, %1, %2}"
13140   [(set_attr "type" "bitmanip")
13141    (set_attr "btver2_decode" "direct, double")
13142    (set_attr "mode" "<MODE>")])
13144 (define_insn "*bmi_andn_<mode>_ccno"
13145   [(set (reg FLAGS_REG)
13146         (compare
13147           (and:SWI48
13148             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
13149             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
13150           (const_int 0)))
13151    (clobber (match_scratch:SWI48 0 "=r,r"))]
13152   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
13153   "andn\t{%2, %1, %0|%0, %1, %2}"
13154   [(set_attr "type" "bitmanip")
13155    (set_attr "btver2_decode" "direct, double")
13156    (set_attr "mode" "<MODE>")])
13158 (define_insn "bmi_bextr_<mode>"
13159   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13160         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13161                        (match_operand:SWI48 2 "register_operand" "r,r")]
13162                       UNSPEC_BEXTR))
13163    (clobber (reg:CC FLAGS_REG))]
13164   "TARGET_BMI"
13165   "bextr\t{%2, %1, %0|%0, %1, %2}"
13166   [(set_attr "type" "bitmanip")
13167    (set_attr "btver2_decode" "direct, double")
13168    (set_attr "mode" "<MODE>")])
13170 (define_insn "*bmi_bextr_<mode>_ccz"
13171   [(set (reg:CCZ FLAGS_REG)
13172         (compare:CCZ
13173           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13174                          (match_operand:SWI48 2 "register_operand" "r,r")]
13175                         UNSPEC_BEXTR)
13176           (const_int 0)))
13177    (clobber (match_scratch:SWI48 0 "=r,r"))]
13178   "TARGET_BMI"
13179   "bextr\t{%2, %1, %0|%0, %1, %2}"
13180   [(set_attr "type" "bitmanip")
13181    (set_attr "btver2_decode" "direct, double")
13182    (set_attr "mode" "<MODE>")])
13184 (define_insn "*bmi_blsi_<mode>"
13185   [(set (match_operand:SWI48 0 "register_operand" "=r")
13186         (and:SWI48
13187           (neg:SWI48
13188             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13189           (match_dup 1)))
13190    (clobber (reg:CC FLAGS_REG))]
13191   "TARGET_BMI"
13192   "blsi\t{%1, %0|%0, %1}"
13193   [(set_attr "type" "bitmanip")
13194    (set_attr "btver2_decode" "double")
13195    (set_attr "mode" "<MODE>")])
13197 (define_insn "*bmi_blsmsk_<mode>"
13198   [(set (match_operand:SWI48 0 "register_operand" "=r")
13199         (xor:SWI48
13200           (plus:SWI48
13201             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13202             (const_int -1))
13203           (match_dup 1)))
13204    (clobber (reg:CC FLAGS_REG))]
13205   "TARGET_BMI"
13206   "blsmsk\t{%1, %0|%0, %1}"
13207   [(set_attr "type" "bitmanip")
13208    (set_attr "btver2_decode" "double")
13209    (set_attr "mode" "<MODE>")])
13211 (define_insn "*bmi_blsr_<mode>"
13212   [(set (match_operand:SWI48 0 "register_operand" "=r")
13213         (and:SWI48
13214           (plus:SWI48
13215             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13216             (const_int -1))
13217           (match_dup 1)))
13218    (clobber (reg:CC FLAGS_REG))]
13219    "TARGET_BMI"
13220    "blsr\t{%1, %0|%0, %1}"
13221   [(set_attr "type" "bitmanip")
13222    (set_attr "btver2_decode" "double")
13223    (set_attr "mode" "<MODE>")])
13225 ;; BMI2 instructions.
13226 (define_expand "bmi2_bzhi_<mode>3"
13227   [(parallel
13228     [(set (match_operand:SWI48 0 "register_operand")
13229           (zero_extract:SWI48
13230             (match_operand:SWI48 1 "nonimmediate_operand")
13231             (umin:SWI48
13232               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13233                          (const_int 255))
13234               (match_dup 3))
13235             (const_int 0)))
13236      (clobber (reg:CC FLAGS_REG))])]
13237   "TARGET_BMI2"
13238   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13240 (define_insn "*bmi2_bzhi_<mode>3"
13241   [(set (match_operand:SWI48 0 "register_operand" "=r")
13242         (zero_extract:SWI48
13243           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13244           (umin:SWI48
13245             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13246                        (const_int 255))
13247             (match_operand:SWI48 3 "const_int_operand" "n"))
13248           (const_int 0)))
13249    (clobber (reg:CC FLAGS_REG))]
13250   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13251   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13252   [(set_attr "type" "bitmanip")
13253    (set_attr "prefix" "vex")
13254    (set_attr "mode" "<MODE>")])
13256 (define_mode_attr k [(SI "k") (DI "q")])
13258 (define_insn "*bmi2_bzhi_<mode>3_1"
13259   [(set (match_operand:SWI48 0 "register_operand" "=r")
13260         (zero_extract:SWI48
13261           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13262           (umin:SWI48
13263             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13264             (match_operand:SWI48 3 "const_int_operand" "n"))
13265           (const_int 0)))
13266    (clobber (reg:CC FLAGS_REG))]
13267   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13268   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13269   [(set_attr "type" "bitmanip")
13270    (set_attr "prefix" "vex")
13271    (set_attr "mode" "<MODE>")])
13273 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13274   [(set (reg:CCZ FLAGS_REG)
13275         (compare:CCZ
13276           (zero_extract:SWI48
13277             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13278             (umin:SWI48
13279               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13280               (match_operand:SWI48 3 "const_int_operand" "n"))
13281             (const_int 0))
13282         (const_int 0)))
13283    (clobber (match_scratch:SWI48 0 "=r"))]
13284   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13285   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13286   [(set_attr "type" "bitmanip")
13287    (set_attr "prefix" "vex")
13288    (set_attr "mode" "<MODE>")])
13290 (define_insn "bmi2_pdep_<mode>3"
13291   [(set (match_operand:SWI48 0 "register_operand" "=r")
13292         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13293                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13294                        UNSPEC_PDEP))]
13295   "TARGET_BMI2"
13296   "pdep\t{%2, %1, %0|%0, %1, %2}"
13297   [(set_attr "type" "bitmanip")
13298    (set_attr "prefix" "vex")
13299    (set_attr "mode" "<MODE>")])
13301 (define_insn "bmi2_pext_<mode>3"
13302   [(set (match_operand:SWI48 0 "register_operand" "=r")
13303         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13304                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13305                        UNSPEC_PEXT))]
13306   "TARGET_BMI2"
13307   "pext\t{%2, %1, %0|%0, %1, %2}"
13308   [(set_attr "type" "bitmanip")
13309    (set_attr "prefix" "vex")
13310    (set_attr "mode" "<MODE>")])
13312 ;; TBM instructions.
13313 (define_insn "tbm_bextri_<mode>"
13314   [(set (match_operand:SWI48 0 "register_operand" "=r")
13315         (zero_extract:SWI48
13316           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13317           (match_operand 2 "const_0_to_255_operand" "N")
13318           (match_operand 3 "const_0_to_255_operand" "N")))
13319    (clobber (reg:CC FLAGS_REG))]
13320    "TARGET_TBM"
13322   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13323   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13325   [(set_attr "type" "bitmanip")
13326    (set_attr "mode" "<MODE>")])
13328 (define_insn "*tbm_blcfill_<mode>"
13329   [(set (match_operand:SWI48 0 "register_operand" "=r")
13330         (and:SWI48
13331           (plus:SWI48
13332             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13333             (const_int 1))
13334           (match_dup 1)))
13335    (clobber (reg:CC FLAGS_REG))]
13336    "TARGET_TBM"
13337    "blcfill\t{%1, %0|%0, %1}"
13338   [(set_attr "type" "bitmanip")
13339    (set_attr "mode" "<MODE>")])
13341 (define_insn "*tbm_blci_<mode>"
13342   [(set (match_operand:SWI48 0 "register_operand" "=r")
13343         (ior:SWI48
13344           (not:SWI48
13345             (plus:SWI48
13346               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13347               (const_int 1)))
13348           (match_dup 1)))
13349    (clobber (reg:CC FLAGS_REG))]
13350    "TARGET_TBM"
13351    "blci\t{%1, %0|%0, %1}"
13352   [(set_attr "type" "bitmanip")
13353    (set_attr "mode" "<MODE>")])
13355 (define_insn "*tbm_blcic_<mode>"
13356   [(set (match_operand:SWI48 0 "register_operand" "=r")
13357         (and:SWI48
13358           (plus:SWI48
13359             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13360             (const_int 1))
13361           (not:SWI48
13362             (match_dup 1))))
13363    (clobber (reg:CC FLAGS_REG))]
13364    "TARGET_TBM"
13365    "blcic\t{%1, %0|%0, %1}"
13366   [(set_attr "type" "bitmanip")
13367    (set_attr "mode" "<MODE>")])
13369 (define_insn "*tbm_blcmsk_<mode>"
13370   [(set (match_operand:SWI48 0 "register_operand" "=r")
13371         (xor:SWI48
13372           (plus:SWI48
13373             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13374             (const_int 1))
13375           (match_dup 1)))
13376    (clobber (reg:CC FLAGS_REG))]
13377    "TARGET_TBM"
13378    "blcmsk\t{%1, %0|%0, %1}"
13379   [(set_attr "type" "bitmanip")
13380    (set_attr "mode" "<MODE>")])
13382 (define_insn "*tbm_blcs_<mode>"
13383   [(set (match_operand:SWI48 0 "register_operand" "=r")
13384         (ior:SWI48
13385           (plus:SWI48
13386             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13387             (const_int 1))
13388           (match_dup 1)))
13389    (clobber (reg:CC FLAGS_REG))]
13390    "TARGET_TBM"
13391    "blcs\t{%1, %0|%0, %1}"
13392   [(set_attr "type" "bitmanip")
13393    (set_attr "mode" "<MODE>")])
13395 (define_insn "*tbm_blsfill_<mode>"
13396   [(set (match_operand:SWI48 0 "register_operand" "=r")
13397         (ior:SWI48
13398           (plus:SWI48
13399             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13400             (const_int -1))
13401           (match_dup 1)))
13402    (clobber (reg:CC FLAGS_REG))]
13403    "TARGET_TBM"
13404    "blsfill\t{%1, %0|%0, %1}"
13405   [(set_attr "type" "bitmanip")
13406    (set_attr "mode" "<MODE>")])
13408 (define_insn "*tbm_blsic_<mode>"
13409   [(set (match_operand:SWI48 0 "register_operand" "=r")
13410         (ior:SWI48
13411           (plus:SWI48
13412             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13413             (const_int -1))
13414           (not:SWI48
13415             (match_dup 1))))
13416    (clobber (reg:CC FLAGS_REG))]
13417    "TARGET_TBM"
13418    "blsic\t{%1, %0|%0, %1}"
13419   [(set_attr "type" "bitmanip")
13420    (set_attr "mode" "<MODE>")])
13422 (define_insn "*tbm_t1mskc_<mode>"
13423   [(set (match_operand:SWI48 0 "register_operand" "=r")
13424         (ior:SWI48
13425           (plus:SWI48
13426             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13427             (const_int 1))
13428           (not:SWI48
13429             (match_dup 1))))
13430    (clobber (reg:CC FLAGS_REG))]
13431    "TARGET_TBM"
13432    "t1mskc\t{%1, %0|%0, %1}"
13433   [(set_attr "type" "bitmanip")
13434    (set_attr "mode" "<MODE>")])
13436 (define_insn "*tbm_tzmsk_<mode>"
13437   [(set (match_operand:SWI48 0 "register_operand" "=r")
13438         (and:SWI48
13439           (plus:SWI48
13440             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13441             (const_int -1))
13442           (not:SWI48
13443             (match_dup 1))))
13444    (clobber (reg:CC FLAGS_REG))]
13445    "TARGET_TBM"
13446    "tzmsk\t{%1, %0|%0, %1}"
13447   [(set_attr "type" "bitmanip")
13448    (set_attr "mode" "<MODE>")])
13450 (define_insn "bsr_rex64"
13451   [(set (match_operand:DI 0 "register_operand" "=r")
13452         (minus:DI (const_int 63)
13453                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "TARGET_64BIT"
13456   "bsr{q}\t{%1, %0|%0, %1}"
13457   [(set_attr "type" "alu1")
13458    (set_attr "prefix_0f" "1")
13459    (set_attr "znver1_decode" "vector")
13460    (set_attr "mode" "DI")])
13462 (define_insn "bsr"
13463   [(set (match_operand:SI 0 "register_operand" "=r")
13464         (minus:SI (const_int 31)
13465                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13466    (clobber (reg:CC FLAGS_REG))]
13467   ""
13468   "bsr{l}\t{%1, %0|%0, %1}"
13469   [(set_attr "type" "alu1")
13470    (set_attr "prefix_0f" "1")
13471    (set_attr "znver1_decode" "vector")
13472    (set_attr "mode" "SI")])
13474 (define_insn "*bsrhi"
13475   [(set (match_operand:HI 0 "register_operand" "=r")
13476         (minus:HI (const_int 15)
13477                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13478    (clobber (reg:CC FLAGS_REG))]
13479   ""
13480   "bsr{w}\t{%1, %0|%0, %1}"
13481   [(set_attr "type" "alu1")
13482    (set_attr "prefix_0f" "1")
13483    (set_attr "znver1_decode" "vector")
13484    (set_attr "mode" "HI")])
13486 (define_expand "popcount<mode>2"
13487   [(parallel
13488     [(set (match_operand:SWI248 0 "register_operand")
13489           (popcount:SWI248
13490             (match_operand:SWI248 1 "nonimmediate_operand")))
13491      (clobber (reg:CC FLAGS_REG))])]
13492   "TARGET_POPCNT")
13494 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13495   [(set (match_operand:SWI48 0 "register_operand" "=r")
13496         (popcount:SWI48
13497           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13498    (clobber (reg:CC FLAGS_REG))]
13499   "TARGET_POPCNT
13500    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13501   "#"
13502   "&& reload_completed"
13503   [(parallel
13504     [(set (match_dup 0)
13505           (popcount:SWI48 (match_dup 1)))
13506      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13507      (clobber (reg:CC FLAGS_REG))])]
13509   if (!reg_mentioned_p (operands[0], operands[1]))
13510     ix86_expand_clear (operands[0]);
13513 (define_insn "*popcount<mode>2_falsedep"
13514   [(set (match_operand:SWI48 0 "register_operand" "=r")
13515         (popcount:SWI48
13516           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13517    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13518            UNSPEC_INSN_FALSE_DEP)
13519    (clobber (reg:CC FLAGS_REG))]
13520   "TARGET_POPCNT"
13522 #if TARGET_MACHO
13523   return "popcnt\t{%1, %0|%0, %1}";
13524 #else
13525   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13526 #endif
13528   [(set_attr "prefix_rep" "1")
13529    (set_attr "type" "bitmanip")
13530    (set_attr "mode" "<MODE>")])
13532 (define_insn "*popcount<mode>2"
13533   [(set (match_operand:SWI248 0 "register_operand" "=r")
13534         (popcount:SWI248
13535           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13536    (clobber (reg:CC FLAGS_REG))]
13537   "TARGET_POPCNT"
13539 #if TARGET_MACHO
13540   return "popcnt\t{%1, %0|%0, %1}";
13541 #else
13542   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13543 #endif
13545   [(set_attr "prefix_rep" "1")
13546    (set_attr "type" "bitmanip")
13547    (set_attr "mode" "<MODE>")])
13549 (define_expand "bswapdi2"
13550   [(set (match_operand:DI 0 "register_operand")
13551         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13552   "TARGET_64BIT"
13554   if (!TARGET_MOVBE)
13555     operands[1] = force_reg (DImode, operands[1]);
13558 (define_expand "bswapsi2"
13559   [(set (match_operand:SI 0 "register_operand")
13560         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13561   ""
13563   if (TARGET_MOVBE)
13564     ;
13565   else if (TARGET_BSWAP)
13566     operands[1] = force_reg (SImode, operands[1]);
13567   else
13568     {
13569       rtx x = operands[0];
13571       emit_move_insn (x, operands[1]);
13572       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13573       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13574       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13575       DONE;
13576     }
13579 (define_insn "*bswap<mode>2_movbe"
13580   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13581         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13582   "TARGET_MOVBE
13583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13584   "@
13585     bswap\t%0
13586     movbe\t{%1, %0|%0, %1}
13587     movbe\t{%1, %0|%0, %1}"
13588   [(set_attr "type" "bitmanip,imov,imov")
13589    (set_attr "modrm" "0,1,1")
13590    (set_attr "prefix_0f" "*,1,1")
13591    (set_attr "prefix_extra" "*,1,1")
13592    (set_attr "mode" "<MODE>")])
13594 (define_insn "*bswap<mode>2"
13595   [(set (match_operand:SWI48 0 "register_operand" "=r")
13596         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13597   "TARGET_BSWAP"
13598   "bswap\t%0"
13599   [(set_attr "type" "bitmanip")
13600    (set_attr "modrm" "0")
13601    (set_attr "mode" "<MODE>")])
13603 (define_insn "*bswaphi_lowpart_1"
13604   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13605         (bswap:HI (match_dup 0)))
13606    (clobber (reg:CC FLAGS_REG))]
13607   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13608   "@
13609     xchg{b}\t{%h0, %b0|%b0, %h0}
13610     rol{w}\t{$8, %0|%0, 8}"
13611   [(set_attr "length" "2,4")
13612    (set_attr "mode" "QI,HI")])
13614 (define_insn "bswaphi_lowpart"
13615   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13616         (bswap:HI (match_dup 0)))
13617    (clobber (reg:CC FLAGS_REG))]
13618   ""
13619   "rol{w}\t{$8, %0|%0, 8}"
13620   [(set_attr "length" "4")
13621    (set_attr "mode" "HI")])
13623 (define_expand "paritydi2"
13624   [(set (match_operand:DI 0 "register_operand")
13625         (parity:DI (match_operand:DI 1 "register_operand")))]
13626   "! TARGET_POPCNT"
13628   rtx scratch = gen_reg_rtx (QImode);
13630   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13631                                 NULL_RTX, operands[1]));
13633   ix86_expand_setcc (scratch, ORDERED,
13634                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13636   if (TARGET_64BIT)
13637     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13638   else
13639     {
13640       rtx tmp = gen_reg_rtx (SImode);
13642       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13643       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13644     }
13645   DONE;
13648 (define_expand "paritysi2"
13649   [(set (match_operand:SI 0 "register_operand")
13650         (parity:SI (match_operand:SI 1 "register_operand")))]
13651   "! TARGET_POPCNT"
13653   rtx scratch = gen_reg_rtx (QImode);
13655   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13657   ix86_expand_setcc (scratch, ORDERED,
13658                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13660   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13661   DONE;
13664 (define_insn_and_split "paritydi2_cmp"
13665   [(set (reg:CC FLAGS_REG)
13666         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13667                    UNSPEC_PARITY))
13668    (clobber (match_scratch:DI 0 "=r"))
13669    (clobber (match_scratch:SI 1 "=&r"))
13670    (clobber (match_scratch:HI 2 "=Q"))]
13671   "! TARGET_POPCNT"
13672   "#"
13673   "&& reload_completed"
13674   [(parallel
13675      [(set (match_dup 1)
13676            (xor:SI (match_dup 1) (match_dup 4)))
13677       (clobber (reg:CC FLAGS_REG))])
13678    (parallel
13679      [(set (reg:CC FLAGS_REG)
13680            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13681       (clobber (match_dup 1))
13682       (clobber (match_dup 2))])]
13684   operands[4] = gen_lowpart (SImode, operands[3]);
13686   if (TARGET_64BIT)
13687     {
13688       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13689       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13690     }
13691   else
13692     operands[1] = gen_highpart (SImode, operands[3]);
13695 (define_insn_and_split "paritysi2_cmp"
13696   [(set (reg:CC FLAGS_REG)
13697         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13698                    UNSPEC_PARITY))
13699    (clobber (match_scratch:SI 0 "=r"))
13700    (clobber (match_scratch:HI 1 "=&Q"))]
13701   "! TARGET_POPCNT"
13702   "#"
13703   "&& reload_completed"
13704   [(parallel
13705      [(set (match_dup 1)
13706            (xor:HI (match_dup 1) (match_dup 3)))
13707       (clobber (reg:CC FLAGS_REG))])
13708    (parallel
13709      [(set (reg:CC FLAGS_REG)
13710            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13711       (clobber (match_dup 1))])]
13713   operands[3] = gen_lowpart (HImode, operands[2]);
13715   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13716   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13719 (define_insn "*parityhi2_cmp"
13720   [(set (reg:CC FLAGS_REG)
13721         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13722                    UNSPEC_PARITY))
13723    (clobber (match_scratch:HI 0 "=Q"))]
13724   "! TARGET_POPCNT"
13725   "xor{b}\t{%h0, %b0|%b0, %h0}"
13726   [(set_attr "length" "2")
13727    (set_attr "mode" "HI")])
13730 ;; Thread-local storage patterns for ELF.
13732 ;; Note that these code sequences must appear exactly as shown
13733 ;; in order to allow linker relaxation.
13735 (define_insn "*tls_global_dynamic_32_gnu"
13736   [(set (match_operand:SI 0 "register_operand" "=a")
13737         (unspec:SI
13738          [(match_operand:SI 1 "register_operand" "Yb")
13739           (match_operand 2 "tls_symbolic_operand")
13740           (match_operand 3 "constant_call_address_operand" "Bz")
13741           (reg:SI SP_REG)]
13742          UNSPEC_TLS_GD))
13743    (clobber (match_scratch:SI 4 "=d"))
13744    (clobber (match_scratch:SI 5 "=c"))
13745    (clobber (reg:CC FLAGS_REG))]
13746   "!TARGET_64BIT && TARGET_GNU_TLS"
13748   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13749     output_asm_insn
13750       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13751   else
13752     output_asm_insn
13753       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13754   if (TARGET_SUN_TLS)
13755 #ifdef HAVE_AS_IX86_TLSGDPLT
13756     return "call\t%a2@tlsgdplt";
13757 #else
13758     return "call\t%p3@plt";
13759 #endif
13760   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13761     return "call\t%P3";
13762   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13764   [(set_attr "type" "multi")
13765    (set_attr "length" "12")])
13767 (define_expand "tls_global_dynamic_32"
13768   [(parallel
13769     [(set (match_operand:SI 0 "register_operand")
13770           (unspec:SI [(match_operand:SI 2 "register_operand")
13771                       (match_operand 1 "tls_symbolic_operand")
13772                       (match_operand 3 "constant_call_address_operand")
13773                       (reg:SI SP_REG)]
13774                      UNSPEC_TLS_GD))
13775      (clobber (match_scratch:SI 4))
13776      (clobber (match_scratch:SI 5))
13777      (clobber (reg:CC FLAGS_REG))])]
13778   ""
13779   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13781 (define_insn "*tls_global_dynamic_64_<mode>"
13782   [(set (match_operand:P 0 "register_operand" "=a")
13783         (call:P
13784          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13785          (match_operand 3)))
13786    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13787               (reg:P SP_REG)]
13788              UNSPEC_TLS_GD)]
13789   "TARGET_64BIT"
13791   if (!TARGET_X32)
13792     fputs (ASM_BYTE "0x66\n", asm_out_file);
13793   output_asm_insn
13794     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13795   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13796     fputs (ASM_SHORT "0x6666\n", asm_out_file);
13797   else
13798     fputs (ASM_BYTE "0x66\n", asm_out_file);
13799   fputs ("\trex64\n", asm_out_file);
13800   if (TARGET_SUN_TLS)
13801     return "call\t%p2@plt";
13802   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13803     return "call\t%P2";
13804   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13806   [(set_attr "type" "multi")
13807    (set (attr "length")
13808         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13810 (define_insn "*tls_global_dynamic_64_largepic"
13811   [(set (match_operand:DI 0 "register_operand" "=a")
13812         (call:DI
13813          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13814                           (match_operand:DI 3 "immediate_operand" "i")))
13815          (match_operand 4)))
13816    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13817                (reg:DI SP_REG)]
13818               UNSPEC_TLS_GD)]
13819   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13820    && GET_CODE (operands[3]) == CONST
13821    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13822    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13824   output_asm_insn
13825     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13826   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13827   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13828   return "call\t{*%%rax|rax}";
13830   [(set_attr "type" "multi")
13831    (set_attr "length" "22")])
13833 (define_expand "tls_global_dynamic_64_<mode>"
13834   [(parallel
13835     [(set (match_operand:P 0 "register_operand")
13836           (call:P
13837            (mem:QI (match_operand 2))
13838            (const_int 0)))
13839      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13840                 (reg:P SP_REG)]
13841                UNSPEC_TLS_GD)])]
13842   "TARGET_64BIT"
13843   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13845 (define_insn "*tls_local_dynamic_base_32_gnu"
13846   [(set (match_operand:SI 0 "register_operand" "=a")
13847         (unspec:SI
13848          [(match_operand:SI 1 "register_operand" "Yb")
13849           (match_operand 2 "constant_call_address_operand" "Bz")
13850           (reg:SI SP_REG)]
13851          UNSPEC_TLS_LD_BASE))
13852    (clobber (match_scratch:SI 3 "=d"))
13853    (clobber (match_scratch:SI 4 "=c"))
13854    (clobber (reg:CC FLAGS_REG))]
13855   "!TARGET_64BIT && TARGET_GNU_TLS"
13857   output_asm_insn
13858     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13859   if (TARGET_SUN_TLS)
13860     {
13861       if (HAVE_AS_IX86_TLSLDMPLT)
13862         return "call\t%&@tlsldmplt";
13863       else
13864         return "call\t%p2@plt";
13865     }
13866   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13867     return "call\t%P2";
13868   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13870   [(set_attr "type" "multi")
13871    (set_attr "length" "11")])
13873 (define_expand "tls_local_dynamic_base_32"
13874   [(parallel
13875      [(set (match_operand:SI 0 "register_operand")
13876            (unspec:SI
13877             [(match_operand:SI 1 "register_operand")
13878              (match_operand 2 "constant_call_address_operand")
13879              (reg:SI SP_REG)]
13880             UNSPEC_TLS_LD_BASE))
13881       (clobber (match_scratch:SI 3))
13882       (clobber (match_scratch:SI 4))
13883       (clobber (reg:CC FLAGS_REG))])]
13884   ""
13885   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13887 (define_insn "*tls_local_dynamic_base_64_<mode>"
13888   [(set (match_operand:P 0 "register_operand" "=a")
13889         (call:P
13890          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13891          (match_operand 2)))
13892    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13893   "TARGET_64BIT"
13895   output_asm_insn
13896     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13897   if (TARGET_SUN_TLS)
13898     return "call\t%p1@plt";
13899   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13900     return "call\t%P1";
13901   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13903   [(set_attr "type" "multi")
13904    (set_attr "length" "12")])
13906 (define_insn "*tls_local_dynamic_base_64_largepic"
13907   [(set (match_operand:DI 0 "register_operand" "=a")
13908         (call:DI
13909          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13910                           (match_operand:DI 2 "immediate_operand" "i")))
13911          (match_operand 3)))
13912    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13913   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13914    && GET_CODE (operands[2]) == CONST
13915    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13916    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13918   output_asm_insn
13919     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13920   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13921   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13922   return "call\t{*%%rax|rax}";
13924   [(set_attr "type" "multi")
13925    (set_attr "length" "22")])
13927 (define_expand "tls_local_dynamic_base_64_<mode>"
13928   [(parallel
13929      [(set (match_operand:P 0 "register_operand")
13930            (call:P
13931             (mem:QI (match_operand 1))
13932             (const_int 0)))
13933       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13934   "TARGET_64BIT"
13935   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13937 ;; Local dynamic of a single variable is a lose.  Show combine how
13938 ;; to convert that back to global dynamic.
13940 (define_insn_and_split "*tls_local_dynamic_32_once"
13941   [(set (match_operand:SI 0 "register_operand" "=a")
13942         (plus:SI
13943          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13944                      (match_operand 2 "constant_call_address_operand" "Bz")
13945                      (reg:SI SP_REG)]
13946                     UNSPEC_TLS_LD_BASE)
13947          (const:SI (unspec:SI
13948                     [(match_operand 3 "tls_symbolic_operand")]
13949                     UNSPEC_DTPOFF))))
13950    (clobber (match_scratch:SI 4 "=d"))
13951    (clobber (match_scratch:SI 5 "=c"))
13952    (clobber (reg:CC FLAGS_REG))]
13953   ""
13954   "#"
13955   ""
13956   [(parallel
13957      [(set (match_dup 0)
13958            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13959                        (reg:SI SP_REG)]
13960                       UNSPEC_TLS_GD))
13961       (clobber (match_dup 4))
13962       (clobber (match_dup 5))
13963       (clobber (reg:CC FLAGS_REG))])])
13965 ;; Segment register for the thread base ptr load
13966 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13968 ;; Load and add the thread base pointer from %<tp_seg>:0.
13969 (define_insn "*load_tp_x32"
13970   [(set (match_operand:SI 0 "register_operand" "=r")
13971         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13972   "TARGET_X32"
13973   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13974   [(set_attr "type" "imov")
13975    (set_attr "modrm" "0")
13976    (set_attr "length" "7")
13977    (set_attr "memory" "load")
13978    (set_attr "imm_disp" "false")])
13980 (define_insn "*load_tp_x32_zext"
13981   [(set (match_operand:DI 0 "register_operand" "=r")
13982         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13983   "TARGET_X32"
13984   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13985   [(set_attr "type" "imov")
13986    (set_attr "modrm" "0")
13987    (set_attr "length" "7")
13988    (set_attr "memory" "load")
13989    (set_attr "imm_disp" "false")])
13991 (define_insn "*load_tp_<mode>"
13992   [(set (match_operand:P 0 "register_operand" "=r")
13993         (unspec:P [(const_int 0)] UNSPEC_TP))]
13994   "!TARGET_X32"
13995   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13996   [(set_attr "type" "imov")
13997    (set_attr "modrm" "0")
13998    (set_attr "length" "7")
13999    (set_attr "memory" "load")
14000    (set_attr "imm_disp" "false")])
14002 (define_insn "*add_tp_x32"
14003   [(set (match_operand:SI 0 "register_operand" "=r")
14004         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14005                  (match_operand:SI 1 "register_operand" "0")))
14006    (clobber (reg:CC FLAGS_REG))]
14007   "TARGET_X32"
14008   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
14009   [(set_attr "type" "alu")
14010    (set_attr "modrm" "0")
14011    (set_attr "length" "7")
14012    (set_attr "memory" "load")
14013    (set_attr "imm_disp" "false")])
14015 (define_insn "*add_tp_x32_zext"
14016   [(set (match_operand:DI 0 "register_operand" "=r")
14017         (zero_extend:DI
14018           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14019                    (match_operand:SI 1 "register_operand" "0"))))
14020    (clobber (reg:CC FLAGS_REG))]
14021   "TARGET_X32"
14022   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
14023   [(set_attr "type" "alu")
14024    (set_attr "modrm" "0")
14025    (set_attr "length" "7")
14026    (set_attr "memory" "load")
14027    (set_attr "imm_disp" "false")])
14029 (define_insn "*add_tp_<mode>"
14030   [(set (match_operand:P 0 "register_operand" "=r")
14031         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
14032                 (match_operand:P 1 "register_operand" "0")))
14033    (clobber (reg:CC FLAGS_REG))]
14034   "!TARGET_X32"
14035   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
14036   [(set_attr "type" "alu")
14037    (set_attr "modrm" "0")
14038    (set_attr "length" "7")
14039    (set_attr "memory" "load")
14040    (set_attr "imm_disp" "false")])
14042 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14043 ;; %rax as destination of the initial executable code sequence.
14044 (define_insn "tls_initial_exec_64_sun"
14045   [(set (match_operand:DI 0 "register_operand" "=a")
14046         (unspec:DI
14047          [(match_operand 1 "tls_symbolic_operand")]
14048          UNSPEC_TLS_IE_SUN))
14049    (clobber (reg:CC FLAGS_REG))]
14050   "TARGET_64BIT && TARGET_SUN_TLS"
14052   output_asm_insn
14053     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14054   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14056   [(set_attr "type" "multi")])
14058 ;; GNU2 TLS patterns can be split.
14060 (define_expand "tls_dynamic_gnu2_32"
14061   [(set (match_dup 3)
14062         (plus:SI (match_operand:SI 2 "register_operand")
14063                  (const:SI
14064                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14065                              UNSPEC_TLSDESC))))
14066    (parallel
14067     [(set (match_operand:SI 0 "register_operand")
14068           (unspec:SI [(match_dup 1) (match_dup 3)
14069                       (match_dup 2) (reg:SI SP_REG)]
14070                       UNSPEC_TLSDESC))
14071      (clobber (reg:CC FLAGS_REG))])]
14072   "!TARGET_64BIT && TARGET_GNU2_TLS"
14074   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14075   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14078 (define_insn "*tls_dynamic_gnu2_lea_32"
14079   [(set (match_operand:SI 0 "register_operand" "=r")
14080         (plus:SI (match_operand:SI 1 "register_operand" "b")
14081                  (const:SI
14082                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14083                               UNSPEC_TLSDESC))))]
14084   "!TARGET_64BIT && TARGET_GNU2_TLS"
14085   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14086   [(set_attr "type" "lea")
14087    (set_attr "mode" "SI")
14088    (set_attr "length" "6")
14089    (set_attr "length_address" "4")])
14091 (define_insn "*tls_dynamic_gnu2_call_32"
14092   [(set (match_operand:SI 0 "register_operand" "=a")
14093         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14094                     (match_operand:SI 2 "register_operand" "0")
14095                     ;; we have to make sure %ebx still points to the GOT
14096                     (match_operand:SI 3 "register_operand" "b")
14097                     (reg:SI SP_REG)]
14098                    UNSPEC_TLSDESC))
14099    (clobber (reg:CC FLAGS_REG))]
14100   "!TARGET_64BIT && TARGET_GNU2_TLS"
14101   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14102   [(set_attr "type" "call")
14103    (set_attr "length" "2")
14104    (set_attr "length_address" "0")])
14106 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14107   [(set (match_operand:SI 0 "register_operand" "=&a")
14108         (plus:SI
14109          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14110                      (match_operand:SI 4)
14111                      (match_operand:SI 2 "register_operand" "b")
14112                      (reg:SI SP_REG)]
14113                     UNSPEC_TLSDESC)
14114          (const:SI (unspec:SI
14115                     [(match_operand 1 "tls_symbolic_operand")]
14116                     UNSPEC_DTPOFF))))
14117    (clobber (reg:CC FLAGS_REG))]
14118   "!TARGET_64BIT && TARGET_GNU2_TLS"
14119   "#"
14120   ""
14121   [(set (match_dup 0) (match_dup 5))]
14123   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14124   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14127 (define_expand "tls_dynamic_gnu2_64"
14128   [(set (match_dup 2)
14129         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14130                    UNSPEC_TLSDESC))
14131    (parallel
14132     [(set (match_operand:DI 0 "register_operand")
14133           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14134                      UNSPEC_TLSDESC))
14135      (clobber (reg:CC FLAGS_REG))])]
14136   "TARGET_64BIT && TARGET_GNU2_TLS"
14138   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14139   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14142 (define_insn "*tls_dynamic_gnu2_lea_64"
14143   [(set (match_operand:DI 0 "register_operand" "=r")
14144         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14145                    UNSPEC_TLSDESC))]
14146   "TARGET_64BIT && TARGET_GNU2_TLS"
14147   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14148   [(set_attr "type" "lea")
14149    (set_attr "mode" "DI")
14150    (set_attr "length" "7")
14151    (set_attr "length_address" "4")])
14153 (define_insn "*tls_dynamic_gnu2_call_64"
14154   [(set (match_operand:DI 0 "register_operand" "=a")
14155         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14156                     (match_operand:DI 2 "register_operand" "0")
14157                     (reg:DI SP_REG)]
14158                    UNSPEC_TLSDESC))
14159    (clobber (reg:CC FLAGS_REG))]
14160   "TARGET_64BIT && TARGET_GNU2_TLS"
14161   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14162   [(set_attr "type" "call")
14163    (set_attr "length" "2")
14164    (set_attr "length_address" "0")])
14166 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14167   [(set (match_operand:DI 0 "register_operand" "=&a")
14168         (plus:DI
14169          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14170                      (match_operand:DI 3)
14171                      (reg:DI SP_REG)]
14172                     UNSPEC_TLSDESC)
14173          (const:DI (unspec:DI
14174                     [(match_operand 1 "tls_symbolic_operand")]
14175                     UNSPEC_DTPOFF))))
14176    (clobber (reg:CC FLAGS_REG))]
14177   "TARGET_64BIT && TARGET_GNU2_TLS"
14178   "#"
14179   ""
14180   [(set (match_dup 0) (match_dup 4))]
14182   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14183   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14186 ;; These patterns match the binary 387 instructions for addM3, subM3,
14187 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14188 ;; SFmode.  The first is the normal insn, the second the same insn but
14189 ;; with one operand a conversion, and the third the same insn but with
14190 ;; the other operand a conversion.  The conversion may be SFmode or
14191 ;; SImode if the target mode DFmode, but only SImode if the target mode
14192 ;; is SFmode.
14194 ;; Gcc is slightly more smart about handling normal two address instructions
14195 ;; so use special patterns for add and mull.
14197 (define_insn "*fop_<mode>_comm"
14198   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14199         (match_operator:MODEF 3 "binary_fp_operator"
14200           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14201            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14202   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14204    && COMMUTATIVE_ARITH_P (operands[3])
14205    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14206   "* return output_387_binary_op (insn, operands);"
14207   [(set (attr "type")
14208         (if_then_else (eq_attr "alternative" "1,2")
14209            (if_then_else (match_operand:MODEF 3 "mult_operator")
14210               (const_string "ssemul")
14211               (const_string "sseadd"))
14212            (if_then_else (match_operand:MODEF 3 "mult_operator")
14213               (const_string "fmul")
14214               (const_string "fop"))))
14215    (set_attr "isa" "*,noavx,avx")
14216    (set_attr "prefix" "orig,orig,vex")
14217    (set_attr "mode" "<MODE>")
14218    (set (attr "enabled")
14219      (if_then_else
14220        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14221        (if_then_else
14222          (eq_attr "alternative" "0")
14223          (symbol_ref "TARGET_MIX_SSE_I387
14224                       && X87_ENABLE_ARITH (<MODE>mode)")
14225          (const_string "*"))
14226        (if_then_else
14227          (eq_attr "alternative" "0")
14228          (symbol_ref "true")
14229          (symbol_ref "false"))))])
14231 (define_insn "*rcpsf2_sse"
14232   [(set (match_operand:SF 0 "register_operand" "=x")
14233         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14234                    UNSPEC_RCP))]
14235   "TARGET_SSE_MATH"
14236   "%vrcpss\t{%1, %d0|%d0, %1}"
14237   [(set_attr "type" "sse")
14238    (set_attr "atom_sse_attr" "rcp")
14239    (set_attr "btver2_sse_attr" "rcp")
14240    (set_attr "prefix" "maybe_vex")
14241    (set_attr "mode" "SF")])
14243 (define_insn "*fop_<mode>_1"
14244   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14245         (match_operator:MODEF 3 "binary_fp_operator"
14246           [(match_operand:MODEF 1
14247              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14248            (match_operand:MODEF 2
14249              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14250   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14251     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14252    && !COMMUTATIVE_ARITH_P (operands[3])
14253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14254   "* return output_387_binary_op (insn, operands);"
14255   [(set (attr "type")
14256         (if_then_else (eq_attr "alternative" "2,3")
14257            (if_then_else (match_operand:MODEF 3 "div_operator")
14258               (const_string "ssediv")
14259               (const_string "sseadd"))
14260            (if_then_else (match_operand:MODEF 3 "div_operator")
14261               (const_string "fdiv")
14262               (const_string "fop"))))
14263    (set_attr "isa" "*,*,noavx,avx")
14264    (set_attr "prefix" "orig,orig,orig,vex")
14265    (set_attr "mode" "<MODE>")
14266    (set (attr "enabled")
14267      (if_then_else
14268        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14269        (if_then_else
14270          (eq_attr "alternative" "0,1")
14271          (symbol_ref "TARGET_MIX_SSE_I387
14272                       && X87_ENABLE_ARITH (<MODE>mode)")
14273          (const_string "*"))
14274        (if_then_else
14275          (eq_attr "alternative" "0,1")
14276          (symbol_ref "true")
14277          (symbol_ref "false"))))])
14279 ;; ??? Add SSE splitters for these!
14280 (define_insn "*fop_<MODEF:mode>_2_i387"
14281   [(set (match_operand:MODEF 0 "register_operand" "=f")
14282         (match_operator:MODEF 3 "binary_fp_operator"
14283           [(float:MODEF
14284              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14285            (match_operand:MODEF 2 "register_operand" "0")]))]
14286   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14287    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14288    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14289        || optimize_function_for_size_p (cfun))"
14290   "* return output_387_binary_op (insn, operands);"
14291   [(set (attr "type")
14292         (cond [(match_operand:MODEF 3 "mult_operator")
14293                  (const_string "fmul")
14294                (match_operand:MODEF 3 "div_operator")
14295                  (const_string "fdiv")
14296               ]
14297               (const_string "fop")))
14298    (set_attr "fp_int_src" "true")
14299    (set_attr "mode" "<SWI24:MODE>")])
14301 (define_insn "*fop_<MODEF:mode>_3_i387"
14302   [(set (match_operand:MODEF 0 "register_operand" "=f")
14303         (match_operator:MODEF 3 "binary_fp_operator"
14304           [(match_operand:MODEF 1 "register_operand" "0")
14305            (float:MODEF
14306              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14307   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14308    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14309    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14310        || optimize_function_for_size_p (cfun))"
14311   "* return output_387_binary_op (insn, operands);"
14312   [(set (attr "type")
14313         (cond [(match_operand:MODEF 3 "mult_operator")
14314                  (const_string "fmul")
14315                (match_operand:MODEF 3 "div_operator")
14316                  (const_string "fdiv")
14317               ]
14318               (const_string "fop")))
14319    (set_attr "fp_int_src" "true")
14320    (set_attr "mode" "<MODE>")])
14322 (define_insn "*fop_df_4_i387"
14323   [(set (match_operand:DF 0 "register_operand" "=f,f")
14324         (match_operator:DF 3 "binary_fp_operator"
14325            [(float_extend:DF
14326              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14327             (match_operand:DF 2 "register_operand" "0,f")]))]
14328   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14329    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14330   "* return output_387_binary_op (insn, operands);"
14331   [(set (attr "type")
14332         (cond [(match_operand:DF 3 "mult_operator")
14333                  (const_string "fmul")
14334                (match_operand:DF 3 "div_operator")
14335                  (const_string "fdiv")
14336               ]
14337               (const_string "fop")))
14338    (set_attr "mode" "SF")])
14340 (define_insn "*fop_df_5_i387"
14341   [(set (match_operand:DF 0 "register_operand" "=f,f")
14342         (match_operator:DF 3 "binary_fp_operator"
14343           [(match_operand:DF 1 "register_operand" "0,f")
14344            (float_extend:DF
14345             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14346   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14347    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14348   "* return output_387_binary_op (insn, operands);"
14349   [(set (attr "type")
14350         (cond [(match_operand:DF 3 "mult_operator")
14351                  (const_string "fmul")
14352                (match_operand:DF 3 "div_operator")
14353                  (const_string "fdiv")
14354               ]
14355               (const_string "fop")))
14356    (set_attr "mode" "SF")])
14358 (define_insn "*fop_df_6_i387"
14359   [(set (match_operand:DF 0 "register_operand" "=f,f")
14360         (match_operator:DF 3 "binary_fp_operator"
14361           [(float_extend:DF
14362             (match_operand:SF 1 "register_operand" "0,f"))
14363            (float_extend:DF
14364             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14365   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14366    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14367   "* return output_387_binary_op (insn, operands);"
14368   [(set (attr "type")
14369         (cond [(match_operand:DF 3 "mult_operator")
14370                  (const_string "fmul")
14371                (match_operand:DF 3 "div_operator")
14372                  (const_string "fdiv")
14373               ]
14374               (const_string "fop")))
14375    (set_attr "mode" "SF")])
14377 (define_insn "*fop_xf_comm_i387"
14378   [(set (match_operand:XF 0 "register_operand" "=f")
14379         (match_operator:XF 3 "binary_fp_operator"
14380                         [(match_operand:XF 1 "register_operand" "%0")
14381                          (match_operand:XF 2 "register_operand" "f")]))]
14382   "TARGET_80387
14383    && COMMUTATIVE_ARITH_P (operands[3])"
14384   "* return output_387_binary_op (insn, operands);"
14385   [(set (attr "type")
14386         (if_then_else (match_operand:XF 3 "mult_operator")
14387            (const_string "fmul")
14388            (const_string "fop")))
14389    (set_attr "mode" "XF")])
14391 (define_insn "*fop_xf_1_i387"
14392   [(set (match_operand:XF 0 "register_operand" "=f,f")
14393         (match_operator:XF 3 "binary_fp_operator"
14394                         [(match_operand:XF 1 "register_operand" "0,f")
14395                          (match_operand:XF 2 "register_operand" "f,0")]))]
14396   "TARGET_80387
14397    && !COMMUTATIVE_ARITH_P (operands[3])"
14398   "* return output_387_binary_op (insn, operands);"
14399   [(set (attr "type")
14400         (if_then_else (match_operand:XF 3 "div_operator")
14401            (const_string "fdiv")
14402            (const_string "fop")))
14403    (set_attr "mode" "XF")])
14405 (define_insn "*fop_xf_2_i387"
14406   [(set (match_operand:XF 0 "register_operand" "=f")
14407         (match_operator:XF 3 "binary_fp_operator"
14408           [(float:XF
14409              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14410            (match_operand:XF 2 "register_operand" "0")]))]
14411   "TARGET_80387
14412    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14413   "* return output_387_binary_op (insn, operands);"
14414   [(set (attr "type")
14415         (cond [(match_operand:XF 3 "mult_operator")
14416                  (const_string "fmul")
14417                (match_operand:XF 3 "div_operator")
14418                  (const_string "fdiv")
14419               ]
14420               (const_string "fop")))
14421    (set_attr "fp_int_src" "true")
14422    (set_attr "mode" "<MODE>")])
14424 (define_insn "*fop_xf_3_i387"
14425   [(set (match_operand:XF 0 "register_operand" "=f")
14426         (match_operator:XF 3 "binary_fp_operator"
14427           [(match_operand:XF 1 "register_operand" "0")
14428            (float:XF
14429              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14430   "TARGET_80387
14431    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14432   "* return output_387_binary_op (insn, operands);"
14433   [(set (attr "type")
14434         (cond [(match_operand:XF 3 "mult_operator")
14435                  (const_string "fmul")
14436                (match_operand:XF 3 "div_operator")
14437                  (const_string "fdiv")
14438               ]
14439               (const_string "fop")))
14440    (set_attr "fp_int_src" "true")
14441    (set_attr "mode" "<MODE>")])
14443 (define_insn "*fop_xf_4_i387"
14444   [(set (match_operand:XF 0 "register_operand" "=f,f")
14445         (match_operator:XF 3 "binary_fp_operator"
14446            [(float_extend:XF
14447               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14448             (match_operand:XF 2 "register_operand" "0,f")]))]
14449   "TARGET_80387"
14450   "* return output_387_binary_op (insn, operands);"
14451   [(set (attr "type")
14452         (cond [(match_operand:XF 3 "mult_operator")
14453                  (const_string "fmul")
14454                (match_operand:XF 3 "div_operator")
14455                  (const_string "fdiv")
14456               ]
14457               (const_string "fop")))
14458    (set_attr "mode" "<MODE>")])
14460 (define_insn "*fop_xf_5_i387"
14461   [(set (match_operand:XF 0 "register_operand" "=f,f")
14462         (match_operator:XF 3 "binary_fp_operator"
14463           [(match_operand:XF 1 "register_operand" "0,f")
14464            (float_extend:XF
14465              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14466   "TARGET_80387"
14467   "* return output_387_binary_op (insn, operands);"
14468   [(set (attr "type")
14469         (cond [(match_operand:XF 3 "mult_operator")
14470                  (const_string "fmul")
14471                (match_operand:XF 3 "div_operator")
14472                  (const_string "fdiv")
14473               ]
14474               (const_string "fop")))
14475    (set_attr "mode" "<MODE>")])
14477 (define_insn "*fop_xf_6_i387"
14478   [(set (match_operand:XF 0 "register_operand" "=f,f")
14479         (match_operator:XF 3 "binary_fp_operator"
14480           [(float_extend:XF
14481              (match_operand:MODEF 1 "register_operand" "0,f"))
14482            (float_extend:XF
14483              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14484   "TARGET_80387"
14485   "* return output_387_binary_op (insn, operands);"
14486   [(set (attr "type")
14487         (cond [(match_operand:XF 3 "mult_operator")
14488                  (const_string "fmul")
14489                (match_operand:XF 3 "div_operator")
14490                  (const_string "fdiv")
14491               ]
14492               (const_string "fop")))
14493    (set_attr "mode" "<MODE>")])
14495 ;; FPU special functions.
14497 ;; This pattern implements a no-op XFmode truncation for
14498 ;; all fancy i386 XFmode math functions.
14500 (define_insn "truncxf<mode>2_i387_noop_unspec"
14501   [(set (match_operand:MODEF 0 "register_operand" "=f")
14502         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14503         UNSPEC_TRUNC_NOOP))]
14504   "TARGET_USE_FANCY_MATH_387"
14505   "* return output_387_reg_move (insn, operands);"
14506   [(set_attr "type" "fmov")
14507    (set_attr "mode" "<MODE>")])
14509 (define_insn "sqrtxf2"
14510   [(set (match_operand:XF 0 "register_operand" "=f")
14511         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14512   "TARGET_USE_FANCY_MATH_387"
14513   "fsqrt"
14514   [(set_attr "type" "fpspc")
14515    (set_attr "mode" "XF")
14516    (set_attr "athlon_decode" "direct")
14517    (set_attr "amdfam10_decode" "direct")
14518    (set_attr "bdver1_decode" "direct")])
14520 (define_insn "sqrt_extend<mode>xf2_i387"
14521   [(set (match_operand:XF 0 "register_operand" "=f")
14522         (sqrt:XF
14523           (float_extend:XF
14524             (match_operand:MODEF 1 "register_operand" "0"))))]
14525   "TARGET_USE_FANCY_MATH_387"
14526   "fsqrt"
14527   [(set_attr "type" "fpspc")
14528    (set_attr "mode" "XF")
14529    (set_attr "athlon_decode" "direct")
14530    (set_attr "amdfam10_decode" "direct")
14531    (set_attr "bdver1_decode" "direct")])
14533 (define_insn "*rsqrtsf2_sse"
14534   [(set (match_operand:SF 0 "register_operand" "=x")
14535         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14536                    UNSPEC_RSQRT))]
14537   "TARGET_SSE_MATH"
14538   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14539   [(set_attr "type" "sse")
14540    (set_attr "atom_sse_attr" "rcp")
14541    (set_attr "btver2_sse_attr" "rcp")
14542    (set_attr "prefix" "maybe_vex")
14543    (set_attr "mode" "SF")])
14545 (define_expand "rsqrtsf2"
14546   [(set (match_operand:SF 0 "register_operand")
14547         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14548                    UNSPEC_RSQRT))]
14549   "TARGET_SSE_MATH"
14551   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14552   DONE;
14555 (define_insn "*sqrt<mode>2_sse"
14556   [(set (match_operand:MODEF 0 "register_operand" "=v")
14557         (sqrt:MODEF
14558           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14559   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14560   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14561   [(set_attr "type" "sse")
14562    (set_attr "atom_sse_attr" "sqrt")
14563    (set_attr "btver2_sse_attr" "sqrt")
14564    (set_attr "prefix" "maybe_vex")
14565    (set_attr "mode" "<MODE>")
14566    (set_attr "athlon_decode" "*")
14567    (set_attr "amdfam10_decode" "*")
14568    (set_attr "bdver1_decode" "*")])
14570 (define_expand "sqrt<mode>2"
14571   [(set (match_operand:MODEF 0 "register_operand")
14572         (sqrt:MODEF
14573           (match_operand:MODEF 1 "nonimmediate_operand")))]
14574   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14575    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14577   if (<MODE>mode == SFmode
14578       && TARGET_SSE_MATH
14579       && TARGET_RECIP_SQRT
14580       && !optimize_function_for_size_p (cfun)
14581       && flag_finite_math_only && !flag_trapping_math
14582       && flag_unsafe_math_optimizations)
14583     {
14584       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14585       DONE;
14586     }
14588   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14589     {
14590       rtx op0 = gen_reg_rtx (XFmode);
14591       rtx op1 = force_reg (<MODE>mode, operands[1]);
14593       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14594       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14595       DONE;
14596    }
14599 (define_insn "fpremxf4_i387"
14600   [(set (match_operand:XF 0 "register_operand" "=f")
14601         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14602                     (match_operand:XF 3 "register_operand" "1")]
14603                    UNSPEC_FPREM_F))
14604    (set (match_operand:XF 1 "register_operand" "=u")
14605         (unspec:XF [(match_dup 2) (match_dup 3)]
14606                    UNSPEC_FPREM_U))
14607    (set (reg:CCFP FPSR_REG)
14608         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14609                      UNSPEC_C2_FLAG))]
14610   "TARGET_USE_FANCY_MATH_387
14611    && flag_finite_math_only"
14612   "fprem"
14613   [(set_attr "type" "fpspc")
14614    (set_attr "znver1_decode" "vector")
14615    (set_attr "mode" "XF")])
14617 (define_expand "fmodxf3"
14618   [(use (match_operand:XF 0 "register_operand"))
14619    (use (match_operand:XF 1 "general_operand"))
14620    (use (match_operand:XF 2 "general_operand"))]
14621   "TARGET_USE_FANCY_MATH_387
14622    && flag_finite_math_only"
14624   rtx_code_label *label = gen_label_rtx ();
14626   rtx op1 = gen_reg_rtx (XFmode);
14627   rtx op2 = gen_reg_rtx (XFmode);
14629   emit_move_insn (op2, operands[2]);
14630   emit_move_insn (op1, operands[1]);
14632   emit_label (label);
14633   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14634   ix86_emit_fp_unordered_jump (label);
14635   LABEL_NUSES (label) = 1;
14637   emit_move_insn (operands[0], op1);
14638   DONE;
14641 (define_expand "fmod<mode>3"
14642   [(use (match_operand:MODEF 0 "register_operand"))
14643    (use (match_operand:MODEF 1 "general_operand"))
14644    (use (match_operand:MODEF 2 "general_operand"))]
14645   "TARGET_USE_FANCY_MATH_387
14646    && flag_finite_math_only"
14648   rtx (*gen_truncxf) (rtx, rtx);
14650   rtx_code_label *label = gen_label_rtx ();
14652   rtx op1 = gen_reg_rtx (XFmode);
14653   rtx op2 = gen_reg_rtx (XFmode);
14655   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14656   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14658   emit_label (label);
14659   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14660   ix86_emit_fp_unordered_jump (label);
14661   LABEL_NUSES (label) = 1;
14663   /* Truncate the result properly for strict SSE math.  */
14664   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14665       && !TARGET_MIX_SSE_I387)
14666     gen_truncxf = gen_truncxf<mode>2;
14667   else
14668     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14670   emit_insn (gen_truncxf (operands[0], op1));
14671   DONE;
14674 (define_insn "fprem1xf4_i387"
14675   [(set (match_operand:XF 0 "register_operand" "=f")
14676         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14677                     (match_operand:XF 3 "register_operand" "1")]
14678                    UNSPEC_FPREM1_F))
14679    (set (match_operand:XF 1 "register_operand" "=u")
14680         (unspec:XF [(match_dup 2) (match_dup 3)]
14681                    UNSPEC_FPREM1_U))
14682    (set (reg:CCFP FPSR_REG)
14683         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14684                      UNSPEC_C2_FLAG))]
14685   "TARGET_USE_FANCY_MATH_387
14686    && flag_finite_math_only"
14687   "fprem1"
14688   [(set_attr "type" "fpspc")
14689    (set_attr "znver1_decode" "vector")
14690    (set_attr "mode" "XF")])
14692 (define_expand "remainderxf3"
14693   [(use (match_operand:XF 0 "register_operand"))
14694    (use (match_operand:XF 1 "general_operand"))
14695    (use (match_operand:XF 2 "general_operand"))]
14696   "TARGET_USE_FANCY_MATH_387
14697    && flag_finite_math_only"
14699   rtx_code_label *label = gen_label_rtx ();
14701   rtx op1 = gen_reg_rtx (XFmode);
14702   rtx op2 = gen_reg_rtx (XFmode);
14704   emit_move_insn (op2, operands[2]);
14705   emit_move_insn (op1, operands[1]);
14707   emit_label (label);
14708   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14709   ix86_emit_fp_unordered_jump (label);
14710   LABEL_NUSES (label) = 1;
14712   emit_move_insn (operands[0], op1);
14713   DONE;
14716 (define_expand "remainder<mode>3"
14717   [(use (match_operand:MODEF 0 "register_operand"))
14718    (use (match_operand:MODEF 1 "general_operand"))
14719    (use (match_operand:MODEF 2 "general_operand"))]
14720   "TARGET_USE_FANCY_MATH_387
14721    && flag_finite_math_only"
14723   rtx (*gen_truncxf) (rtx, rtx);
14725   rtx_code_label *label = gen_label_rtx ();
14727   rtx op1 = gen_reg_rtx (XFmode);
14728   rtx op2 = gen_reg_rtx (XFmode);
14730   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14731   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14733   emit_label (label);
14735   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14736   ix86_emit_fp_unordered_jump (label);
14737   LABEL_NUSES (label) = 1;
14739   /* Truncate the result properly for strict SSE math.  */
14740   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14741       && !TARGET_MIX_SSE_I387)
14742     gen_truncxf = gen_truncxf<mode>2;
14743   else
14744     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14746   emit_insn (gen_truncxf (operands[0], op1));
14747   DONE;
14750 (define_int_iterator SINCOS
14751         [UNSPEC_SIN
14752          UNSPEC_COS])
14754 (define_int_attr sincos
14755         [(UNSPEC_SIN "sin")
14756          (UNSPEC_COS "cos")])
14758 (define_insn "*<sincos>xf2_i387"
14759   [(set (match_operand:XF 0 "register_operand" "=f")
14760         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14761                    SINCOS))]
14762   "TARGET_USE_FANCY_MATH_387
14763    && flag_unsafe_math_optimizations"
14764   "f<sincos>"
14765   [(set_attr "type" "fpspc")
14766    (set_attr "znver1_decode" "vector")
14767    (set_attr "mode" "XF")])
14769 (define_insn "*<sincos>_extend<mode>xf2_i387"
14770   [(set (match_operand:XF 0 "register_operand" "=f")
14771         (unspec:XF [(float_extend:XF
14772                       (match_operand:MODEF 1 "register_operand" "0"))]
14773                    SINCOS))]
14774   "TARGET_USE_FANCY_MATH_387
14775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14776        || TARGET_MIX_SSE_I387)
14777    && flag_unsafe_math_optimizations"
14778   "f<sincos>"
14779   [(set_attr "type" "fpspc")
14780    (set_attr "znver1_decode" "vector")
14781    (set_attr "mode" "XF")])
14783 ;; When sincos pattern is defined, sin and cos builtin functions will be
14784 ;; expanded to sincos pattern with one of its outputs left unused.
14785 ;; CSE pass will figure out if two sincos patterns can be combined,
14786 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14787 ;; depending on the unused output.
14789 (define_insn "sincosxf3"
14790   [(set (match_operand:XF 0 "register_operand" "=f")
14791         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14792                    UNSPEC_SINCOS_COS))
14793    (set (match_operand:XF 1 "register_operand" "=u")
14794         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14795   "TARGET_USE_FANCY_MATH_387
14796    && flag_unsafe_math_optimizations"
14797   "fsincos"
14798   [(set_attr "type" "fpspc")
14799    (set_attr "znver1_decode" "vector")
14800    (set_attr "mode" "XF")])
14802 (define_split
14803   [(set (match_operand:XF 0 "register_operand")
14804         (unspec:XF [(match_operand:XF 2 "register_operand")]
14805                    UNSPEC_SINCOS_COS))
14806    (set (match_operand:XF 1 "register_operand")
14807         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14808   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14809    && can_create_pseudo_p ()"
14810   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14812 (define_split
14813   [(set (match_operand:XF 0 "register_operand")
14814         (unspec:XF [(match_operand:XF 2 "register_operand")]
14815                    UNSPEC_SINCOS_COS))
14816    (set (match_operand:XF 1 "register_operand")
14817         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14818   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14819    && can_create_pseudo_p ()"
14820   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14822 (define_insn "sincos_extend<mode>xf3_i387"
14823   [(set (match_operand:XF 0 "register_operand" "=f")
14824         (unspec:XF [(float_extend:XF
14825                       (match_operand:MODEF 2 "register_operand" "0"))]
14826                    UNSPEC_SINCOS_COS))
14827    (set (match_operand:XF 1 "register_operand" "=u")
14828         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14829   "TARGET_USE_FANCY_MATH_387
14830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831        || TARGET_MIX_SSE_I387)
14832    && flag_unsafe_math_optimizations"
14833   "fsincos"
14834   [(set_attr "type" "fpspc")
14835    (set_attr "znver1_decode" "vector")
14836    (set_attr "mode" "XF")])
14838 (define_split
14839   [(set (match_operand:XF 0 "register_operand")
14840         (unspec:XF [(float_extend:XF
14841                       (match_operand:MODEF 2 "register_operand"))]
14842                    UNSPEC_SINCOS_COS))
14843    (set (match_operand:XF 1 "register_operand")
14844         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14845   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14846    && can_create_pseudo_p ()"
14847   [(set (match_dup 1)
14848         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14850 (define_split
14851   [(set (match_operand:XF 0 "register_operand")
14852         (unspec:XF [(float_extend:XF
14853                       (match_operand:MODEF 2 "register_operand"))]
14854                    UNSPEC_SINCOS_COS))
14855    (set (match_operand:XF 1 "register_operand")
14856         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14857   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14858    && can_create_pseudo_p ()"
14859   [(set (match_dup 0)
14860         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14862 (define_expand "sincos<mode>3"
14863   [(use (match_operand:MODEF 0 "register_operand"))
14864    (use (match_operand:MODEF 1 "register_operand"))
14865    (use (match_operand:MODEF 2 "register_operand"))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14868        || TARGET_MIX_SSE_I387)
14869    && flag_unsafe_math_optimizations"
14871   rtx op0 = gen_reg_rtx (XFmode);
14872   rtx op1 = gen_reg_rtx (XFmode);
14874   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14875   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14876   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14877   DONE;
14880 (define_insn "fptanxf4_i387"
14881   [(set (match_operand:XF 0 "register_operand" "=f")
14882         (match_operand:XF 3 "const_double_operand" "F"))
14883    (set (match_operand:XF 1 "register_operand" "=u")
14884         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14885                    UNSPEC_TAN))]
14886   "TARGET_USE_FANCY_MATH_387
14887    && flag_unsafe_math_optimizations
14888    && standard_80387_constant_p (operands[3]) == 2"
14889   "fptan"
14890   [(set_attr "type" "fpspc")
14891    (set_attr "znver1_decode" "vector")
14892    (set_attr "mode" "XF")])
14894 (define_insn "fptan_extend<mode>xf4_i387"
14895   [(set (match_operand:MODEF 0 "register_operand" "=f")
14896         (match_operand:MODEF 3 "const_double_operand" "F"))
14897    (set (match_operand:XF 1 "register_operand" "=u")
14898         (unspec:XF [(float_extend:XF
14899                       (match_operand:MODEF 2 "register_operand" "0"))]
14900                    UNSPEC_TAN))]
14901   "TARGET_USE_FANCY_MATH_387
14902    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14903        || TARGET_MIX_SSE_I387)
14904    && flag_unsafe_math_optimizations
14905    && standard_80387_constant_p (operands[3]) == 2"
14906   "fptan"
14907   [(set_attr "type" "fpspc")
14908    (set_attr "znver1_decode" "vector")
14909    (set_attr "mode" "XF")])
14911 (define_expand "tanxf2"
14912   [(use (match_operand:XF 0 "register_operand"))
14913    (use (match_operand:XF 1 "register_operand"))]
14914   "TARGET_USE_FANCY_MATH_387
14915    && flag_unsafe_math_optimizations"
14917   rtx one = gen_reg_rtx (XFmode);
14918   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14920   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14921   DONE;
14924 (define_expand "tan<mode>2"
14925   [(use (match_operand:MODEF 0 "register_operand"))
14926    (use (match_operand:MODEF 1 "register_operand"))]
14927   "TARGET_USE_FANCY_MATH_387
14928    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14929        || TARGET_MIX_SSE_I387)
14930    && flag_unsafe_math_optimizations"
14932   rtx op0 = gen_reg_rtx (XFmode);
14934   rtx one = gen_reg_rtx (<MODE>mode);
14935   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14937   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14938                                              operands[1], op2));
14939   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14940   DONE;
14943 (define_insn "*fpatanxf3_i387"
14944   [(set (match_operand:XF 0 "register_operand" "=f")
14945         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14946                     (match_operand:XF 2 "register_operand" "u")]
14947                    UNSPEC_FPATAN))
14948    (clobber (match_scratch:XF 3 "=2"))]
14949   "TARGET_USE_FANCY_MATH_387
14950    && flag_unsafe_math_optimizations"
14951   "fpatan"
14952   [(set_attr "type" "fpspc")
14953    (set_attr "znver1_decode" "vector")
14954    (set_attr "mode" "XF")])
14956 (define_insn "fpatan_extend<mode>xf3_i387"
14957   [(set (match_operand:XF 0 "register_operand" "=f")
14958         (unspec:XF [(float_extend:XF
14959                       (match_operand:MODEF 1 "register_operand" "0"))
14960                     (float_extend:XF
14961                       (match_operand:MODEF 2 "register_operand" "u"))]
14962                    UNSPEC_FPATAN))
14963    (clobber (match_scratch:XF 3 "=2"))]
14964   "TARGET_USE_FANCY_MATH_387
14965    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14966        || TARGET_MIX_SSE_I387)
14967    && flag_unsafe_math_optimizations"
14968   "fpatan"
14969   [(set_attr "type" "fpspc")
14970    (set_attr "znver1_decode" "vector")
14971    (set_attr "mode" "XF")])
14973 (define_expand "atan2xf3"
14974   [(parallel [(set (match_operand:XF 0 "register_operand")
14975                    (unspec:XF [(match_operand:XF 2 "register_operand")
14976                                (match_operand:XF 1 "register_operand")]
14977                               UNSPEC_FPATAN))
14978               (clobber (match_scratch:XF 3))])]
14979   "TARGET_USE_FANCY_MATH_387
14980    && flag_unsafe_math_optimizations")
14982 (define_expand "atan2<mode>3"
14983   [(use (match_operand:MODEF 0 "register_operand"))
14984    (use (match_operand:MODEF 1 "register_operand"))
14985    (use (match_operand:MODEF 2 "register_operand"))]
14986   "TARGET_USE_FANCY_MATH_387
14987    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14988        || TARGET_MIX_SSE_I387)
14989    && flag_unsafe_math_optimizations"
14991   rtx op0 = gen_reg_rtx (XFmode);
14993   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14994   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14995   DONE;
14998 (define_expand "atanxf2"
14999   [(parallel [(set (match_operand:XF 0 "register_operand")
15000                    (unspec:XF [(match_dup 2)
15001                                (match_operand:XF 1 "register_operand")]
15002                               UNSPEC_FPATAN))
15003               (clobber (match_scratch:XF 3))])]
15004   "TARGET_USE_FANCY_MATH_387
15005    && flag_unsafe_math_optimizations"
15007   operands[2] = gen_reg_rtx (XFmode);
15008   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15011 (define_expand "atan<mode>2"
15012   [(use (match_operand:MODEF 0 "register_operand"))
15013    (use (match_operand:MODEF 1 "register_operand"))]
15014   "TARGET_USE_FANCY_MATH_387
15015    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15016        || TARGET_MIX_SSE_I387)
15017    && flag_unsafe_math_optimizations"
15019   rtx op0 = gen_reg_rtx (XFmode);
15021   rtx op2 = gen_reg_rtx (<MODE>mode);
15022   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15024   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15025   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15026   DONE;
15029 (define_expand "asinxf2"
15030   [(set (match_dup 2)
15031         (mult:XF (match_operand:XF 1 "register_operand")
15032                  (match_dup 1)))
15033    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15034    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15035    (parallel [(set (match_operand:XF 0 "register_operand")
15036                    (unspec:XF [(match_dup 5) (match_dup 1)]
15037                               UNSPEC_FPATAN))
15038               (clobber (match_scratch:XF 6))])]
15039   "TARGET_USE_FANCY_MATH_387
15040    && flag_unsafe_math_optimizations"
15042   int i;
15044   for (i = 2; i < 6; i++)
15045     operands[i] = gen_reg_rtx (XFmode);
15047   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15050 (define_expand "asin<mode>2"
15051   [(use (match_operand:MODEF 0 "register_operand"))
15052    (use (match_operand:MODEF 1 "general_operand"))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15055        || TARGET_MIX_SSE_I387)
15056    && flag_unsafe_math_optimizations"
15058   rtx op0 = gen_reg_rtx (XFmode);
15059   rtx op1 = gen_reg_rtx (XFmode);
15061   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15062   emit_insn (gen_asinxf2 (op0, op1));
15063   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15064   DONE;
15067 (define_expand "acosxf2"
15068   [(set (match_dup 2)
15069         (mult:XF (match_operand:XF 1 "register_operand")
15070                  (match_dup 1)))
15071    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15072    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15073    (parallel [(set (match_operand:XF 0 "register_operand")
15074                    (unspec:XF [(match_dup 1) (match_dup 5)]
15075                               UNSPEC_FPATAN))
15076               (clobber (match_scratch:XF 6))])]
15077   "TARGET_USE_FANCY_MATH_387
15078    && flag_unsafe_math_optimizations"
15080   int i;
15082   for (i = 2; i < 6; i++)
15083     operands[i] = gen_reg_rtx (XFmode);
15085   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15088 (define_expand "acos<mode>2"
15089   [(use (match_operand:MODEF 0 "register_operand"))
15090    (use (match_operand:MODEF 1 "general_operand"))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15093        || TARGET_MIX_SSE_I387)
15094    && flag_unsafe_math_optimizations"
15096   rtx op0 = gen_reg_rtx (XFmode);
15097   rtx op1 = gen_reg_rtx (XFmode);
15099   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15100   emit_insn (gen_acosxf2 (op0, op1));
15101   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15102   DONE;
15105 (define_insn "fyl2xxf3_i387"
15106   [(set (match_operand:XF 0 "register_operand" "=f")
15107         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15108                     (match_operand:XF 2 "register_operand" "u")]
15109                    UNSPEC_FYL2X))
15110    (clobber (match_scratch:XF 3 "=2"))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations"
15113   "fyl2x"
15114   [(set_attr "type" "fpspc")
15115    (set_attr "znver1_decode" "vector")
15116    (set_attr "mode" "XF")])
15118 (define_insn "fyl2x_extend<mode>xf3_i387"
15119   [(set (match_operand:XF 0 "register_operand" "=f")
15120         (unspec:XF [(float_extend:XF
15121                       (match_operand:MODEF 1 "register_operand" "0"))
15122                     (match_operand:XF 2 "register_operand" "u")]
15123                    UNSPEC_FYL2X))
15124    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2x"
15130   [(set_attr "type" "fpspc")
15131    (set_attr "znver1_decode" "vector")
15132    (set_attr "mode" "XF")])
15134 (define_expand "logxf2"
15135   [(parallel [(set (match_operand:XF 0 "register_operand")
15136                    (unspec:XF [(match_operand:XF 1 "register_operand")
15137                                (match_dup 2)] UNSPEC_FYL2X))
15138               (clobber (match_scratch:XF 3))])]
15139   "TARGET_USE_FANCY_MATH_387
15140    && flag_unsafe_math_optimizations"
15142   operands[2] = gen_reg_rtx (XFmode);
15143   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15146 (define_expand "log<mode>2"
15147   [(use (match_operand:MODEF 0 "register_operand"))
15148    (use (match_operand:MODEF 1 "register_operand"))]
15149   "TARGET_USE_FANCY_MATH_387
15150    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15151        || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15154   rtx op0 = gen_reg_rtx (XFmode);
15156   rtx op2 = gen_reg_rtx (XFmode);
15157   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15159   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15160   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15161   DONE;
15164 (define_expand "log10xf2"
15165   [(parallel [(set (match_operand:XF 0 "register_operand")
15166                    (unspec:XF [(match_operand:XF 1 "register_operand")
15167                                (match_dup 2)] UNSPEC_FYL2X))
15168               (clobber (match_scratch:XF 3))])]
15169   "TARGET_USE_FANCY_MATH_387
15170    && flag_unsafe_math_optimizations"
15172   operands[2] = gen_reg_rtx (XFmode);
15173   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15176 (define_expand "log10<mode>2"
15177   [(use (match_operand:MODEF 0 "register_operand"))
15178    (use (match_operand:MODEF 1 "register_operand"))]
15179   "TARGET_USE_FANCY_MATH_387
15180    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15181        || TARGET_MIX_SSE_I387)
15182    && flag_unsafe_math_optimizations"
15184   rtx op0 = gen_reg_rtx (XFmode);
15186   rtx op2 = gen_reg_rtx (XFmode);
15187   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15189   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15190   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15191   DONE;
15194 (define_expand "log2xf2"
15195   [(parallel [(set (match_operand:XF 0 "register_operand")
15196                    (unspec:XF [(match_operand:XF 1 "register_operand")
15197                                (match_dup 2)] UNSPEC_FYL2X))
15198               (clobber (match_scratch:XF 3))])]
15199   "TARGET_USE_FANCY_MATH_387
15200    && flag_unsafe_math_optimizations"
15202   operands[2] = gen_reg_rtx (XFmode);
15203   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15206 (define_expand "log2<mode>2"
15207   [(use (match_operand:MODEF 0 "register_operand"))
15208    (use (match_operand:MODEF 1 "register_operand"))]
15209   "TARGET_USE_FANCY_MATH_387
15210    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15211        || TARGET_MIX_SSE_I387)
15212    && flag_unsafe_math_optimizations"
15214   rtx op0 = gen_reg_rtx (XFmode);
15216   rtx op2 = gen_reg_rtx (XFmode);
15217   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15219   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15220   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15221   DONE;
15224 (define_insn "fyl2xp1xf3_i387"
15225   [(set (match_operand:XF 0 "register_operand" "=f")
15226         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15227                     (match_operand:XF 2 "register_operand" "u")]
15228                    UNSPEC_FYL2XP1))
15229    (clobber (match_scratch:XF 3 "=2"))]
15230   "TARGET_USE_FANCY_MATH_387
15231    && flag_unsafe_math_optimizations"
15232   "fyl2xp1"
15233   [(set_attr "type" "fpspc")
15234    (set_attr "znver1_decode" "vector")
15235    (set_attr "mode" "XF")])
15237 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15238   [(set (match_operand:XF 0 "register_operand" "=f")
15239         (unspec:XF [(float_extend:XF
15240                       (match_operand:MODEF 1 "register_operand" "0"))
15241                     (match_operand:XF 2 "register_operand" "u")]
15242                    UNSPEC_FYL2XP1))
15243    (clobber (match_scratch:XF 3 "=2"))]
15244   "TARGET_USE_FANCY_MATH_387
15245    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15246        || TARGET_MIX_SSE_I387)
15247    && flag_unsafe_math_optimizations"
15248   "fyl2xp1"
15249   [(set_attr "type" "fpspc")
15250    (set_attr "znver1_decode" "vector")
15251    (set_attr "mode" "XF")])
15253 (define_expand "log1pxf2"
15254   [(use (match_operand:XF 0 "register_operand"))
15255    (use (match_operand:XF 1 "register_operand"))]
15256   "TARGET_USE_FANCY_MATH_387
15257    && flag_unsafe_math_optimizations"
15259   ix86_emit_i387_log1p (operands[0], operands[1]);
15260   DONE;
15263 (define_expand "log1p<mode>2"
15264   [(use (match_operand:MODEF 0 "register_operand"))
15265    (use (match_operand:MODEF 1 "register_operand"))]
15266   "TARGET_USE_FANCY_MATH_387
15267    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15268        || TARGET_MIX_SSE_I387)
15269    && flag_unsafe_math_optimizations"
15271   rtx op0;
15273   op0 = gen_reg_rtx (XFmode);
15275   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15277   ix86_emit_i387_log1p (op0, operands[1]);
15278   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15279   DONE;
15282 (define_insn "fxtractxf3_i387"
15283   [(set (match_operand:XF 0 "register_operand" "=f")
15284         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15285                    UNSPEC_XTRACT_FRACT))
15286    (set (match_operand:XF 1 "register_operand" "=u")
15287         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && flag_unsafe_math_optimizations"
15290   "fxtract"
15291   [(set_attr "type" "fpspc")
15292    (set_attr "znver1_decode" "vector")
15293    (set_attr "mode" "XF")])
15295 (define_insn "fxtract_extend<mode>xf3_i387"
15296   [(set (match_operand:XF 0 "register_operand" "=f")
15297         (unspec:XF [(float_extend:XF
15298                       (match_operand:MODEF 2 "register_operand" "0"))]
15299                    UNSPEC_XTRACT_FRACT))
15300    (set (match_operand:XF 1 "register_operand" "=u")
15301         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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"
15306   "fxtract"
15307   [(set_attr "type" "fpspc")
15308    (set_attr "znver1_decode" "vector")
15309    (set_attr "mode" "XF")])
15311 (define_expand "logbxf2"
15312   [(parallel [(set (match_dup 2)
15313                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15314                               UNSPEC_XTRACT_FRACT))
15315               (set (match_operand:XF 0 "register_operand")
15316                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15317   "TARGET_USE_FANCY_MATH_387
15318    && flag_unsafe_math_optimizations"
15319   "operands[2] = gen_reg_rtx (XFmode);")
15321 (define_expand "logb<mode>2"
15322   [(use (match_operand:MODEF 0 "register_operand"))
15323    (use (match_operand:MODEF 1 "register_operand"))]
15324   "TARGET_USE_FANCY_MATH_387
15325    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15326        || TARGET_MIX_SSE_I387)
15327    && flag_unsafe_math_optimizations"
15329   rtx op0 = gen_reg_rtx (XFmode);
15330   rtx op1 = gen_reg_rtx (XFmode);
15332   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15333   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15334   DONE;
15337 (define_expand "ilogbxf2"
15338   [(use (match_operand:SI 0 "register_operand"))
15339    (use (match_operand:XF 1 "register_operand"))]
15340   "TARGET_USE_FANCY_MATH_387
15341    && flag_unsafe_math_optimizations"
15343   rtx op0, op1;
15345   if (optimize_insn_for_size_p ())
15346     FAIL;
15348   op0 = gen_reg_rtx (XFmode);
15349   op1 = gen_reg_rtx (XFmode);
15351   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15352   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15353   DONE;
15356 (define_expand "ilogb<mode>2"
15357   [(use (match_operand:SI 0 "register_operand"))
15358    (use (match_operand:MODEF 1 "register_operand"))]
15359   "TARGET_USE_FANCY_MATH_387
15360    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15361        || TARGET_MIX_SSE_I387)
15362    && flag_unsafe_math_optimizations"
15364   rtx op0, op1;
15366   if (optimize_insn_for_size_p ())
15367     FAIL;
15369   op0 = gen_reg_rtx (XFmode);
15370   op1 = gen_reg_rtx (XFmode);
15372   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15373   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15374   DONE;
15377 (define_insn "*f2xm1xf2_i387"
15378   [(set (match_operand:XF 0 "register_operand" "=f")
15379         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15380                    UNSPEC_F2XM1))]
15381   "TARGET_USE_FANCY_MATH_387
15382    && flag_unsafe_math_optimizations"
15383   "f2xm1"
15384   [(set_attr "type" "fpspc")
15385    (set_attr "znver1_decode" "vector")
15386    (set_attr "mode" "XF")])
15388 (define_insn "fscalexf4_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15391                     (match_operand:XF 3 "register_operand" "1")]
15392                    UNSPEC_FSCALE_FRACT))
15393    (set (match_operand:XF 1 "register_operand" "=u")
15394         (unspec:XF [(match_dup 2) (match_dup 3)]
15395                    UNSPEC_FSCALE_EXP))]
15396   "TARGET_USE_FANCY_MATH_387
15397    && flag_unsafe_math_optimizations"
15398   "fscale"
15399   [(set_attr "type" "fpspc")
15400    (set_attr "znver1_decode" "vector")
15401    (set_attr "mode" "XF")])
15403 (define_expand "expNcorexf3"
15404   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15405                                (match_operand:XF 2 "register_operand")))
15406    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15407    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15408    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15409    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15410    (parallel [(set (match_operand:XF 0 "register_operand")
15411                    (unspec:XF [(match_dup 8) (match_dup 4)]
15412                               UNSPEC_FSCALE_FRACT))
15413               (set (match_dup 9)
15414                    (unspec:XF [(match_dup 8) (match_dup 4)]
15415                               UNSPEC_FSCALE_EXP))])]
15416   "TARGET_USE_FANCY_MATH_387
15417    && flag_unsafe_math_optimizations"
15419   int i;
15421   for (i = 3; i < 10; i++)
15422     operands[i] = gen_reg_rtx (XFmode);
15424   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15427 (define_expand "expxf2"
15428   [(use (match_operand:XF 0 "register_operand"))
15429    (use (match_operand:XF 1 "register_operand"))]
15430   "TARGET_USE_FANCY_MATH_387
15431    && flag_unsafe_math_optimizations"
15433   rtx op2;
15435   op2 = gen_reg_rtx (XFmode);
15436   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15438   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15439   DONE;
15442 (define_expand "exp<mode>2"
15443   [(use (match_operand:MODEF 0 "register_operand"))
15444    (use (match_operand:MODEF 1 "general_operand"))]
15445   "TARGET_USE_FANCY_MATH_387
15446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15447        || TARGET_MIX_SSE_I387)
15448    && flag_unsafe_math_optimizations"
15450   rtx op0, op1;
15452   op0 = gen_reg_rtx (XFmode);
15453   op1 = gen_reg_rtx (XFmode);
15455   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15456   emit_insn (gen_expxf2 (op0, op1));
15457   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15458   DONE;
15461 (define_expand "exp10xf2"
15462   [(use (match_operand:XF 0 "register_operand"))
15463    (use (match_operand:XF 1 "register_operand"))]
15464   "TARGET_USE_FANCY_MATH_387
15465    && flag_unsafe_math_optimizations"
15467   rtx op2;
15469   op2 = gen_reg_rtx (XFmode);
15470   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15472   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15473   DONE;
15476 (define_expand "exp10<mode>2"
15477   [(use (match_operand:MODEF 0 "register_operand"))
15478    (use (match_operand:MODEF 1 "general_operand"))]
15479   "TARGET_USE_FANCY_MATH_387
15480    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15481        || TARGET_MIX_SSE_I387)
15482    && flag_unsafe_math_optimizations"
15484   rtx op0, op1;
15486   op0 = gen_reg_rtx (XFmode);
15487   op1 = gen_reg_rtx (XFmode);
15489   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15490   emit_insn (gen_exp10xf2 (op0, op1));
15491   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15492   DONE;
15495 (define_expand "exp2xf2"
15496   [(use (match_operand:XF 0 "register_operand"))
15497    (use (match_operand:XF 1 "register_operand"))]
15498   "TARGET_USE_FANCY_MATH_387
15499    && flag_unsafe_math_optimizations"
15501   rtx op2;
15503   op2 = gen_reg_rtx (XFmode);
15504   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15506   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15507   DONE;
15510 (define_expand "exp2<mode>2"
15511   [(use (match_operand:MODEF 0 "register_operand"))
15512    (use (match_operand:MODEF 1 "general_operand"))]
15513   "TARGET_USE_FANCY_MATH_387
15514    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15515        || TARGET_MIX_SSE_I387)
15516    && flag_unsafe_math_optimizations"
15518   rtx op0, op1;
15520   op0 = gen_reg_rtx (XFmode);
15521   op1 = gen_reg_rtx (XFmode);
15523   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15524   emit_insn (gen_exp2xf2 (op0, op1));
15525   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15526   DONE;
15529 (define_expand "expm1xf2"
15530   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15531                                (match_dup 2)))
15532    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15533    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15534    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15535    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15536    (parallel [(set (match_dup 7)
15537                    (unspec:XF [(match_dup 6) (match_dup 4)]
15538                               UNSPEC_FSCALE_FRACT))
15539               (set (match_dup 8)
15540                    (unspec:XF [(match_dup 6) (match_dup 4)]
15541                               UNSPEC_FSCALE_EXP))])
15542    (parallel [(set (match_dup 10)
15543                    (unspec:XF [(match_dup 9) (match_dup 8)]
15544                               UNSPEC_FSCALE_FRACT))
15545               (set (match_dup 11)
15546                    (unspec:XF [(match_dup 9) (match_dup 8)]
15547                               UNSPEC_FSCALE_EXP))])
15548    (set (match_dup 12) (minus:XF (match_dup 10)
15549                                  (float_extend:XF (match_dup 13))))
15550    (set (match_operand:XF 0 "register_operand")
15551         (plus:XF (match_dup 12) (match_dup 7)))]
15552   "TARGET_USE_FANCY_MATH_387
15553    && flag_unsafe_math_optimizations"
15555   int i;
15557   for (i = 2; i < 13; i++)
15558     operands[i] = gen_reg_rtx (XFmode);
15560   operands[13]
15561     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15563   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15566 (define_expand "expm1<mode>2"
15567   [(use (match_operand:MODEF 0 "register_operand"))
15568    (use (match_operand:MODEF 1 "general_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"
15574   rtx op0, op1;
15576   op0 = gen_reg_rtx (XFmode);
15577   op1 = gen_reg_rtx (XFmode);
15579   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15580   emit_insn (gen_expm1xf2 (op0, op1));
15581   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15582   DONE;
15585 (define_expand "ldexpxf3"
15586   [(match_operand:XF 0 "register_operand")
15587    (match_operand:XF 1 "register_operand")
15588    (match_operand:SI 2 "register_operand")]
15589   "TARGET_USE_FANCY_MATH_387
15590    && flag_unsafe_math_optimizations"
15592   rtx tmp1, tmp2;
15594   tmp1 = gen_reg_rtx (XFmode);
15595   tmp2 = gen_reg_rtx (XFmode);
15597   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15598   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15599                                  operands[1], tmp1));
15600   DONE;
15603 (define_expand "ldexp<mode>3"
15604   [(use (match_operand:MODEF 0 "register_operand"))
15605    (use (match_operand:MODEF 1 "general_operand"))
15606    (use (match_operand:SI 2 "register_operand"))]
15607   "TARGET_USE_FANCY_MATH_387
15608    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15609        || TARGET_MIX_SSE_I387)
15610    && flag_unsafe_math_optimizations"
15612   rtx op0, op1;
15614   op0 = gen_reg_rtx (XFmode);
15615   op1 = gen_reg_rtx (XFmode);
15617   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15618   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15619   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15620   DONE;
15623 (define_expand "scalbxf3"
15624   [(parallel [(set (match_operand:XF 0 " register_operand")
15625                    (unspec:XF [(match_operand:XF 1 "register_operand")
15626                                (match_operand:XF 2 "register_operand")]
15627                               UNSPEC_FSCALE_FRACT))
15628               (set (match_dup 3)
15629                    (unspec:XF [(match_dup 1) (match_dup 2)]
15630                               UNSPEC_FSCALE_EXP))])]
15631   "TARGET_USE_FANCY_MATH_387
15632    && flag_unsafe_math_optimizations"
15634   operands[3] = gen_reg_rtx (XFmode);
15637 (define_expand "scalb<mode>3"
15638   [(use (match_operand:MODEF 0 "register_operand"))
15639    (use (match_operand:MODEF 1 "general_operand"))
15640    (use (match_operand:MODEF 2 "general_operand"))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15643        || TARGET_MIX_SSE_I387)
15644    && flag_unsafe_math_optimizations"
15646   rtx op0, op1, op2;
15648   op0 = gen_reg_rtx (XFmode);
15649   op1 = gen_reg_rtx (XFmode);
15650   op2 = gen_reg_rtx (XFmode);
15652   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15653   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654   emit_insn (gen_scalbxf3 (op0, op1, op2));
15655   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15656   DONE;
15659 (define_expand "significandxf2"
15660   [(parallel [(set (match_operand:XF 0 "register_operand")
15661                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15662                               UNSPEC_XTRACT_FRACT))
15663               (set (match_dup 2)
15664                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15665   "TARGET_USE_FANCY_MATH_387
15666    && flag_unsafe_math_optimizations"
15667   "operands[2] = gen_reg_rtx (XFmode);")
15669 (define_expand "significand<mode>2"
15670   [(use (match_operand:MODEF 0 "register_operand"))
15671    (use (match_operand:MODEF 1 "register_operand"))]
15672   "TARGET_USE_FANCY_MATH_387
15673    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15674        || TARGET_MIX_SSE_I387)
15675    && flag_unsafe_math_optimizations"
15677   rtx op0 = gen_reg_rtx (XFmode);
15678   rtx op1 = gen_reg_rtx (XFmode);
15680   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15682   DONE;
15686 (define_insn "sse4_1_round<mode>2"
15687   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15688         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15689                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15690                       UNSPEC_ROUND))]
15691   "TARGET_ROUND"
15692   "@
15693    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15694    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15695   [(set_attr "type" "ssecvt")
15696    (set_attr "prefix_extra" "1,*")
15697    (set_attr "length_immediate" "*,1")
15698    (set_attr "prefix" "maybe_vex,evex")
15699    (set_attr "isa" "noavx512f,avx512f")
15700    (set_attr "mode" "<MODE>")])
15702 (define_insn "rintxf2"
15703   [(set (match_operand:XF 0 "register_operand" "=f")
15704         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15705                    UNSPEC_FRNDINT))]
15706   "TARGET_USE_FANCY_MATH_387"
15707   "frndint"
15708   [(set_attr "type" "fpspc")
15709    (set_attr "znver1_decode" "vector")
15710    (set_attr "mode" "XF")])
15712 (define_insn "rint<mode>2_frndint"
15713   [(set (match_operand:MODEF 0 "register_operand" "=f")
15714         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15715                       UNSPEC_FRNDINT))]
15716   "TARGET_USE_FANCY_MATH_387"
15717   "frndint"
15718   [(set_attr "type" "fpspc")
15719    (set_attr "znver1_decode" "vector")
15720    (set_attr "mode" "<MODE>")])
15722 (define_expand "rint<mode>2"
15723   [(use (match_operand:MODEF 0 "register_operand"))
15724    (use (match_operand:MODEF 1 "register_operand"))]
15725   "(TARGET_USE_FANCY_MATH_387
15726     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15727         || TARGET_MIX_SSE_I387))
15728    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15730   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15731     {
15732       if (TARGET_ROUND)
15733         emit_insn (gen_sse4_1_round<mode>2
15734                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15735       else
15736         ix86_expand_rint (operands[0], operands[1]);
15737     }
15738   else
15739     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15740   DONE;
15743 (define_expand "round<mode>2"
15744   [(match_operand:X87MODEF 0 "register_operand")
15745    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15746   "(TARGET_USE_FANCY_MATH_387
15747     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15748         || TARGET_MIX_SSE_I387)
15749     && flag_unsafe_math_optimizations)
15750    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15751        && !flag_trapping_math && !flag_rounding_math)"
15753   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15754       && !flag_trapping_math && !flag_rounding_math)
15755     {
15756       if (TARGET_ROUND)
15757         {
15758           operands[1] = force_reg (<MODE>mode, operands[1]);
15759           ix86_expand_round_sse4 (operands[0], operands[1]);
15760         }
15761       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15762         ix86_expand_round (operands[0], operands[1]);
15763       else
15764         ix86_expand_rounddf_32 (operands[0], operands[1]);
15765     }
15766   else
15767     {
15768       operands[1] = force_reg (<MODE>mode, operands[1]);
15769       ix86_emit_i387_round (operands[0], operands[1]);
15770     }
15771   DONE;
15774 (define_insn_and_split "*fistdi2_1"
15775   [(set (match_operand:DI 0 "nonimmediate_operand")
15776         (unspec:DI [(match_operand:XF 1 "register_operand")]
15777                    UNSPEC_FIST))]
15778   "TARGET_USE_FANCY_MATH_387
15779    && can_create_pseudo_p ()"
15780   "#"
15781   "&& 1"
15782   [(const_int 0)]
15784   if (memory_operand (operands[0], VOIDmode))
15785     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15786   else
15787     {
15788       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15789       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15790                                          operands[2]));
15791     }
15792   DONE;
15794   [(set_attr "type" "fpspc")
15795    (set_attr "mode" "DI")])
15797 (define_insn "fistdi2"
15798   [(set (match_operand:DI 0 "memory_operand" "=m")
15799         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15800                    UNSPEC_FIST))
15801    (clobber (match_scratch:XF 2 "=&1f"))]
15802   "TARGET_USE_FANCY_MATH_387"
15803   "* return output_fix_trunc (insn, operands, false);"
15804   [(set_attr "type" "fpspc")
15805    (set_attr "mode" "DI")])
15807 (define_insn "fistdi2_with_temp"
15808   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15809         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15810                    UNSPEC_FIST))
15811    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15812    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15813   "TARGET_USE_FANCY_MATH_387"
15814   "#"
15815   [(set_attr "type" "fpspc")
15816    (set_attr "mode" "DI")])
15818 (define_split
15819   [(set (match_operand:DI 0 "register_operand")
15820         (unspec:DI [(match_operand:XF 1 "register_operand")]
15821                    UNSPEC_FIST))
15822    (clobber (match_operand:DI 2 "memory_operand"))
15823    (clobber (match_scratch 3))]
15824   "reload_completed"
15825   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15826               (clobber (match_dup 3))])
15827    (set (match_dup 0) (match_dup 2))])
15829 (define_split
15830   [(set (match_operand:DI 0 "memory_operand")
15831         (unspec:DI [(match_operand:XF 1 "register_operand")]
15832                    UNSPEC_FIST))
15833    (clobber (match_operand:DI 2 "memory_operand"))
15834    (clobber (match_scratch 3))]
15835   "reload_completed"
15836   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15837               (clobber (match_dup 3))])])
15839 (define_insn_and_split "*fist<mode>2_1"
15840   [(set (match_operand:SWI24 0 "register_operand")
15841         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15842                       UNSPEC_FIST))]
15843   "TARGET_USE_FANCY_MATH_387
15844    && can_create_pseudo_p ()"
15845   "#"
15846   "&& 1"
15847   [(const_int 0)]
15849   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15850   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15851                                         operands[2]));
15852   DONE;
15854   [(set_attr "type" "fpspc")
15855    (set_attr "mode" "<MODE>")])
15857 (define_insn "fist<mode>2"
15858   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15859         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15860                       UNSPEC_FIST))]
15861   "TARGET_USE_FANCY_MATH_387"
15862   "* return output_fix_trunc (insn, operands, false);"
15863   [(set_attr "type" "fpspc")
15864    (set_attr "mode" "<MODE>")])
15866 (define_insn "fist<mode>2_with_temp"
15867   [(set (match_operand:SWI24 0 "register_operand" "=r")
15868         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15869                       UNSPEC_FIST))
15870    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15871   "TARGET_USE_FANCY_MATH_387"
15872   "#"
15873   [(set_attr "type" "fpspc")
15874    (set_attr "mode" "<MODE>")])
15876 (define_split
15877   [(set (match_operand:SWI24 0 "register_operand")
15878         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15879                       UNSPEC_FIST))
15880    (clobber (match_operand:SWI24 2 "memory_operand"))]
15881   "reload_completed"
15882   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15883    (set (match_dup 0) (match_dup 2))])
15885 (define_split
15886   [(set (match_operand:SWI24 0 "memory_operand")
15887         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15888                       UNSPEC_FIST))
15889    (clobber (match_operand:SWI24 2 "memory_operand"))]
15890   "reload_completed"
15891   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15893 (define_expand "lrintxf<mode>2"
15894   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15895      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15896                      UNSPEC_FIST))]
15897   "TARGET_USE_FANCY_MATH_387")
15899 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15900   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15901      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15902                    UNSPEC_FIX_NOTRUNC))]
15903   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15905 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15906   [(match_operand:SWI248x 0 "nonimmediate_operand")
15907    (match_operand:X87MODEF 1 "register_operand")]
15908   "(TARGET_USE_FANCY_MATH_387
15909     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15910         || TARGET_MIX_SSE_I387)
15911     && flag_unsafe_math_optimizations)
15912    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15913        && <SWI248x:MODE>mode != HImode 
15914        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15915        && !flag_trapping_math && !flag_rounding_math)"
15917   if (optimize_insn_for_size_p ())
15918     FAIL;
15920   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15921       && <SWI248x:MODE>mode != HImode
15922       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15923       && !flag_trapping_math && !flag_rounding_math)
15924     ix86_expand_lround (operands[0], operands[1]);
15925   else
15926     ix86_emit_i387_round (operands[0], operands[1]);
15927   DONE;
15930 (define_int_iterator FRNDINT_ROUNDING
15931         [UNSPEC_FRNDINT_FLOOR
15932          UNSPEC_FRNDINT_CEIL
15933          UNSPEC_FRNDINT_TRUNC])
15935 (define_int_iterator FIST_ROUNDING
15936         [UNSPEC_FIST_FLOOR
15937          UNSPEC_FIST_CEIL])
15939 ;; Base name for define_insn
15940 (define_int_attr rounding_insn
15941         [(UNSPEC_FRNDINT_FLOOR "floor")
15942          (UNSPEC_FRNDINT_CEIL "ceil")
15943          (UNSPEC_FRNDINT_TRUNC "btrunc")
15944          (UNSPEC_FIST_FLOOR "floor")
15945          (UNSPEC_FIST_CEIL "ceil")])
15947 (define_int_attr rounding
15948         [(UNSPEC_FRNDINT_FLOOR "floor")
15949          (UNSPEC_FRNDINT_CEIL "ceil")
15950          (UNSPEC_FRNDINT_TRUNC "trunc")
15951          (UNSPEC_FIST_FLOOR "floor")
15952          (UNSPEC_FIST_CEIL "ceil")])
15954 (define_int_attr ROUNDING
15955         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15956          (UNSPEC_FRNDINT_CEIL "CEIL")
15957          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15958          (UNSPEC_FIST_FLOOR "FLOOR")
15959          (UNSPEC_FIST_CEIL "CEIL")])
15961 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15962 (define_insn_and_split "frndint<mode>2_<rounding>"
15963   [(set (match_operand:X87MODEF 0 "register_operand")
15964         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15965                    FRNDINT_ROUNDING))
15966    (clobber (reg:CC FLAGS_REG))]
15967   "TARGET_USE_FANCY_MATH_387
15968    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15969    && can_create_pseudo_p ()"
15970   "#"
15971   "&& 1"
15972   [(const_int 0)]
15974   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15976   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15977   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15979   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15980                                                  operands[2], operands[3]));
15981   DONE;
15983   [(set_attr "type" "frndint")
15984    (set_attr "i387_cw" "<rounding>")
15985    (set_attr "mode" "<MODE>")])
15987 (define_insn "frndint<mode>2_<rounding>_i387"
15988   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15989         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15990                          FRNDINT_ROUNDING))
15991    (use (match_operand:HI 2 "memory_operand" "m"))
15992    (use (match_operand:HI 3 "memory_operand" "m"))]
15993   "TARGET_USE_FANCY_MATH_387
15994    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15995   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15996   [(set_attr "type" "frndint")
15997    (set_attr "i387_cw" "<rounding>")
15998    (set_attr "mode" "<MODE>")])
16000 (define_expand "<rounding_insn>xf2"
16001   [(parallel [(set (match_operand:XF 0 "register_operand")
16002                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16003                               FRNDINT_ROUNDING))
16004               (clobber (reg:CC FLAGS_REG))])]
16005   "TARGET_USE_FANCY_MATH_387
16006    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16008 (define_expand "<rounding_insn><mode>2"
16009   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16010                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16011                                  FRNDINT_ROUNDING))
16012               (clobber (reg:CC FLAGS_REG))])]
16013   "(TARGET_USE_FANCY_MATH_387
16014     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16015         || TARGET_MIX_SSE_I387)
16016     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16017    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16018        && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
16020   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16021       && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
16022     {
16023       if (TARGET_ROUND)
16024         emit_insn (gen_sse4_1_round<mode>2
16025                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16026                                                        | ROUND_NO_EXC)));
16027       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16028         {
16029           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16030             ix86_expand_floorceil (operands[0], operands[1], true);
16031           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16032             ix86_expand_floorceil (operands[0], operands[1], false);
16033           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16034             ix86_expand_trunc (operands[0], operands[1]);
16035           else
16036             gcc_unreachable ();
16037         }
16038       else
16039         {
16040           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16041             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16042           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16043             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16044           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16045             ix86_expand_truncdf_32 (operands[0], operands[1]);
16046           else
16047             gcc_unreachable ();
16048         }
16049     }
16050   else
16051     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16052   DONE;
16055 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16056 (define_insn_and_split "frndintxf2_mask_pm"
16057   [(set (match_operand:XF 0 "register_operand")
16058         (unspec:XF [(match_operand:XF 1 "register_operand")]
16059                    UNSPEC_FRNDINT_MASK_PM))
16060    (clobber (reg:CC FLAGS_REG))]
16061   "TARGET_USE_FANCY_MATH_387
16062    && flag_unsafe_math_optimizations
16063    && can_create_pseudo_p ()"
16064   "#"
16065   "&& 1"
16066   [(const_int 0)]
16068   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16070   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16071   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16073   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16074                                           operands[2], operands[3]));
16075   DONE;
16077   [(set_attr "type" "frndint")
16078    (set_attr "i387_cw" "mask_pm")
16079    (set_attr "mode" "XF")])
16081 (define_insn "frndintxf2_mask_pm_i387"
16082   [(set (match_operand:XF 0 "register_operand" "=f")
16083         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16084                    UNSPEC_FRNDINT_MASK_PM))
16085    (use (match_operand:HI 2 "memory_operand" "m"))
16086    (use (match_operand:HI 3 "memory_operand" "m"))]
16087   "TARGET_USE_FANCY_MATH_387
16088    && flag_unsafe_math_optimizations"
16089   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16090   [(set_attr "type" "frndint")
16091    (set_attr "i387_cw" "mask_pm")
16092    (set_attr "mode" "XF")])
16094 (define_expand "nearbyintxf2"
16095   [(parallel [(set (match_operand:XF 0 "register_operand")
16096                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16097                               UNSPEC_FRNDINT_MASK_PM))
16098               (clobber (reg:CC FLAGS_REG))])]
16099   "TARGET_USE_FANCY_MATH_387
16100    && flag_unsafe_math_optimizations")
16102 (define_expand "nearbyint<mode>2"
16103   [(use (match_operand:MODEF 0 "register_operand"))
16104    (use (match_operand:MODEF 1 "register_operand"))]
16105   "TARGET_USE_FANCY_MATH_387
16106    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16107        || TARGET_MIX_SSE_I387)
16108    && flag_unsafe_math_optimizations"
16110   rtx op0 = gen_reg_rtx (XFmode);
16111   rtx op1 = gen_reg_rtx (XFmode);
16113   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16114   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16116   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16117   DONE;
16120 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16121 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16122   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16123         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16124                         FIST_ROUNDING))
16125    (clobber (reg:CC FLAGS_REG))]
16126   "TARGET_USE_FANCY_MATH_387
16127    && flag_unsafe_math_optimizations
16128    && can_create_pseudo_p ()"
16129   "#"
16130   "&& 1"
16131   [(const_int 0)]
16133   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16135   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16136   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16137   if (memory_operand (operands[0], VOIDmode))
16138     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16139                                            operands[2], operands[3]));
16140   else
16141     {
16142       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16143       emit_insn (gen_fist<mode>2_<rounding>_with_temp
16144                   (operands[0], operands[1], operands[2],
16145                    operands[3], operands[4]));
16146     }
16147   DONE;
16149   [(set_attr "type" "fistp")
16150    (set_attr "i387_cw" "<rounding>")
16151    (set_attr "mode" "<MODE>")])
16153 (define_insn "fistdi2_<rounding>"
16154   [(set (match_operand:DI 0 "memory_operand" "=m")
16155         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16156                    FIST_ROUNDING))
16157    (use (match_operand:HI 2 "memory_operand" "m"))
16158    (use (match_operand:HI 3 "memory_operand" "m"))
16159    (clobber (match_scratch:XF 4 "=&1f"))]
16160   "TARGET_USE_FANCY_MATH_387
16161    && flag_unsafe_math_optimizations"
16162   "* return output_fix_trunc (insn, operands, false);"
16163   [(set_attr "type" "fistp")
16164    (set_attr "i387_cw" "<rounding>")
16165    (set_attr "mode" "DI")])
16167 (define_insn "fistdi2_<rounding>_with_temp"
16168   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16169         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16170                    FIST_ROUNDING))
16171    (use (match_operand:HI 2 "memory_operand" "m,m"))
16172    (use (match_operand:HI 3 "memory_operand" "m,m"))
16173    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16174    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16175   "TARGET_USE_FANCY_MATH_387
16176    && flag_unsafe_math_optimizations"
16177   "#"
16178   [(set_attr "type" "fistp")
16179    (set_attr "i387_cw" "<rounding>")
16180    (set_attr "mode" "DI")])
16182 (define_split
16183   [(set (match_operand:DI 0 "register_operand")
16184         (unspec:DI [(match_operand:XF 1 "register_operand")]
16185                    FIST_ROUNDING))
16186    (use (match_operand:HI 2 "memory_operand"))
16187    (use (match_operand:HI 3 "memory_operand"))
16188    (clobber (match_operand:DI 4 "memory_operand"))
16189    (clobber (match_scratch 5))]
16190   "reload_completed"
16191   [(parallel [(set (match_dup 4)
16192                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16193               (use (match_dup 2))
16194               (use (match_dup 3))
16195               (clobber (match_dup 5))])
16196    (set (match_dup 0) (match_dup 4))])
16198 (define_split
16199   [(set (match_operand:DI 0 "memory_operand")
16200         (unspec:DI [(match_operand:XF 1 "register_operand")]
16201                    FIST_ROUNDING))
16202    (use (match_operand:HI 2 "memory_operand"))
16203    (use (match_operand:HI 3 "memory_operand"))
16204    (clobber (match_operand:DI 4 "memory_operand"))
16205    (clobber (match_scratch 5))]
16206   "reload_completed"
16207   [(parallel [(set (match_dup 0)
16208                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16209               (use (match_dup 2))
16210               (use (match_dup 3))
16211               (clobber (match_dup 5))])])
16213 (define_insn "fist<mode>2_<rounding>"
16214   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16215         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16216                       FIST_ROUNDING))
16217    (use (match_operand:HI 2 "memory_operand" "m"))
16218    (use (match_operand:HI 3 "memory_operand" "m"))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221   "* return output_fix_trunc (insn, operands, false);"
16222   [(set_attr "type" "fistp")
16223    (set_attr "i387_cw" "<rounding>")
16224    (set_attr "mode" "<MODE>")])
16226 (define_insn "fist<mode>2_<rounding>_with_temp"
16227   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16228         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16229                       FIST_ROUNDING))
16230    (use (match_operand:HI 2 "memory_operand" "m,m"))
16231    (use (match_operand:HI 3 "memory_operand" "m,m"))
16232    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16233   "TARGET_USE_FANCY_MATH_387
16234    && flag_unsafe_math_optimizations"
16235   "#"
16236   [(set_attr "type" "fistp")
16237    (set_attr "i387_cw" "<rounding>")
16238    (set_attr "mode" "<MODE>")])
16240 (define_split
16241   [(set (match_operand:SWI24 0 "register_operand")
16242         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16243                       FIST_ROUNDING))
16244    (use (match_operand:HI 2 "memory_operand"))
16245    (use (match_operand:HI 3 "memory_operand"))
16246    (clobber (match_operand:SWI24 4 "memory_operand"))]
16247   "reload_completed"
16248   [(parallel [(set (match_dup 4)
16249                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16250               (use (match_dup 2))
16251               (use (match_dup 3))])
16252    (set (match_dup 0) (match_dup 4))])
16254 (define_split
16255   [(set (match_operand:SWI24 0 "memory_operand")
16256         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16257                       FIST_ROUNDING))
16258    (use (match_operand:HI 2 "memory_operand"))
16259    (use (match_operand:HI 3 "memory_operand"))
16260    (clobber (match_operand:SWI24 4 "memory_operand"))]
16261   "reload_completed"
16262   [(parallel [(set (match_dup 0)
16263                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16264               (use (match_dup 2))
16265               (use (match_dup 3))])])
16267 (define_expand "l<rounding_insn>xf<mode>2"
16268   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16269                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16270                                    FIST_ROUNDING))
16271               (clobber (reg:CC FLAGS_REG))])]
16272   "TARGET_USE_FANCY_MATH_387
16273    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16274    && flag_unsafe_math_optimizations")
16276 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16277   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16278                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16279                                  FIST_ROUNDING))
16280               (clobber (reg:CC FLAGS_REG))])]
16281   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16282    && !flag_trapping_math"
16284   if (TARGET_64BIT && optimize_insn_for_size_p ())
16285     FAIL;
16287   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16288     ix86_expand_lfloorceil (operands[0], operands[1], true);
16289   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16290     ix86_expand_lfloorceil (operands[0], operands[1], false);
16291   else
16292     gcc_unreachable ();
16294   DONE;
16297 (define_insn "fxam<mode>2_i387"
16298   [(set (match_operand:HI 0 "register_operand" "=a")
16299         (unspec:HI
16300           [(match_operand:X87MODEF 1 "register_operand" "f")]
16301           UNSPEC_FXAM))]
16302   "TARGET_USE_FANCY_MATH_387"
16303   "fxam\n\tfnstsw\t%0"
16304   [(set_attr "type" "multi")
16305    (set_attr "length" "4")
16306    (set_attr "unit" "i387")
16307    (set_attr "mode" "<MODE>")])
16309 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16310   [(set (match_operand:HI 0 "register_operand")
16311         (unspec:HI
16312           [(match_operand:MODEF 1 "memory_operand")]
16313           UNSPEC_FXAM_MEM))]
16314   "TARGET_USE_FANCY_MATH_387
16315    && can_create_pseudo_p ()"
16316   "#"
16317   "&& 1"
16318   [(set (match_dup 2)(match_dup 1))
16319    (set (match_dup 0)
16320         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16322   operands[2] = gen_reg_rtx (<MODE>mode);
16324   MEM_VOLATILE_P (operands[1]) = 1;
16326   [(set_attr "type" "multi")
16327    (set_attr "unit" "i387")
16328    (set_attr "mode" "<MODE>")])
16330 (define_expand "isinfxf2"
16331   [(use (match_operand:SI 0 "register_operand"))
16332    (use (match_operand:XF 1 "register_operand"))]
16333   "TARGET_USE_FANCY_MATH_387
16334    && ix86_libc_has_function (function_c99_misc)"
16336   rtx mask = GEN_INT (0x45);
16337   rtx val = GEN_INT (0x05);
16339   rtx scratch = gen_reg_rtx (HImode);
16340   rtx res = gen_reg_rtx (QImode);
16342   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16344   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16345   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16346   ix86_expand_setcc (res, EQ,
16347                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16348   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16349   DONE;
16352 (define_expand "isinf<mode>2"
16353   [(use (match_operand:SI 0 "register_operand"))
16354    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16355   "TARGET_USE_FANCY_MATH_387
16356    && ix86_libc_has_function (function_c99_misc)
16357    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16359   rtx mask = GEN_INT (0x45);
16360   rtx val = GEN_INT (0x05);
16362   rtx scratch = gen_reg_rtx (HImode);
16363   rtx res = gen_reg_rtx (QImode);
16365   /* Remove excess precision by forcing value through memory. */
16366   if (memory_operand (operands[1], VOIDmode))
16367     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16368   else
16369     {
16370       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16372       emit_move_insn (temp, operands[1]);
16373       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16374     }
16376   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16377   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16378   ix86_expand_setcc (res, EQ,
16379                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16380   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16381   DONE;
16384 (define_expand "signbittf2"
16385   [(use (match_operand:SI 0 "register_operand"))
16386    (use (match_operand:TF 1 "register_operand"))]
16387   "TARGET_SSE"
16389   if (TARGET_SSE4_1)
16390     {
16391       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16392       rtx scratch = gen_reg_rtx (QImode);
16394       emit_insn (gen_ptesttf2 (operands[1], mask));
16395         ix86_expand_setcc (scratch, NE,
16396                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16398       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16399     }
16400   else
16401     {
16402       emit_insn (gen_sse_movmskps (operands[0],
16403                                    gen_lowpart (V4SFmode, operands[1])));
16404       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16405     }
16406   DONE;
16409 (define_expand "signbitxf2"
16410   [(use (match_operand:SI 0 "register_operand"))
16411    (use (match_operand:XF 1 "register_operand"))]
16412   "TARGET_USE_FANCY_MATH_387"
16414   rtx scratch = gen_reg_rtx (HImode);
16416   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16417   emit_insn (gen_andsi3 (operands[0],
16418              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16419   DONE;
16422 (define_insn "movmsk_df"
16423   [(set (match_operand:SI 0 "register_operand" "=r")
16424         (unspec:SI
16425           [(match_operand:DF 1 "register_operand" "x")]
16426           UNSPEC_MOVMSK))]
16427   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16428   "%vmovmskpd\t{%1, %0|%0, %1}"
16429   [(set_attr "type" "ssemov")
16430    (set_attr "prefix" "maybe_vex")
16431    (set_attr "mode" "DF")])
16433 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16434 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16435 (define_expand "signbitdf2"
16436   [(use (match_operand:SI 0 "register_operand"))
16437    (use (match_operand:DF 1 "register_operand"))]
16438   "TARGET_USE_FANCY_MATH_387
16439    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16441   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16442     {
16443       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16444       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16445     }
16446   else
16447     {
16448       rtx scratch = gen_reg_rtx (HImode);
16450       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16451       emit_insn (gen_andsi3 (operands[0],
16452                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16453     }
16454   DONE;
16457 (define_expand "signbitsf2"
16458   [(use (match_operand:SI 0 "register_operand"))
16459    (use (match_operand:SF 1 "register_operand"))]
16460   "TARGET_USE_FANCY_MATH_387
16461    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16463   rtx scratch = gen_reg_rtx (HImode);
16465   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16466   emit_insn (gen_andsi3 (operands[0],
16467              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16468   DONE;
16471 ;; Block operation instructions
16473 (define_insn "cld"
16474   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16475   ""
16476   "cld"
16477   [(set_attr "length" "1")
16478    (set_attr "length_immediate" "0")
16479    (set_attr "modrm" "0")])
16481 (define_expand "movmem<mode>"
16482   [(use (match_operand:BLK 0 "memory_operand"))
16483    (use (match_operand:BLK 1 "memory_operand"))
16484    (use (match_operand:SWI48 2 "nonmemory_operand"))
16485    (use (match_operand:SWI48 3 "const_int_operand"))
16486    (use (match_operand:SI 4 "const_int_operand"))
16487    (use (match_operand:SI 5 "const_int_operand"))
16488    (use (match_operand:SI 6 ""))
16489    (use (match_operand:SI 7 ""))
16490    (use (match_operand:SI 8 ""))]
16491   ""
16493  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16494                                 operands[2], NULL, operands[3],
16495                                 operands[4], operands[5],
16496                                 operands[6], operands[7],
16497                                 operands[8], false))
16498    DONE;
16499  else
16500    FAIL;
16503 ;; Most CPUs don't like single string operations
16504 ;; Handle this case here to simplify previous expander.
16506 (define_expand "strmov"
16507   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16508    (set (match_operand 1 "memory_operand") (match_dup 4))
16509    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16510               (clobber (reg:CC FLAGS_REG))])
16511    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16512               (clobber (reg:CC FLAGS_REG))])]
16513   ""
16515   /* Can't use this for non-default address spaces.  */
16516   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16517     FAIL;
16519   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16521   /* If .md ever supports :P for Pmode, these can be directly
16522      in the pattern above.  */
16523   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16524   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16526   /* Can't use this if the user has appropriated esi or edi.  */
16527   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16528       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16529     {
16530       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16531                                       operands[2], operands[3],
16532                                       operands[5], operands[6]));
16533       DONE;
16534     }
16536   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16539 (define_expand "strmov_singleop"
16540   [(parallel [(set (match_operand 1 "memory_operand")
16541                    (match_operand 3 "memory_operand"))
16542               (set (match_operand 0 "register_operand")
16543                    (match_operand 4))
16544               (set (match_operand 2 "register_operand")
16545                    (match_operand 5))])]
16546   ""
16548   if (TARGET_CLD)
16549     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16552 (define_insn "*strmovdi_rex_1"
16553   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16554         (mem:DI (match_operand:P 3 "register_operand" "1")))
16555    (set (match_operand:P 0 "register_operand" "=D")
16556         (plus:P (match_dup 2)
16557                 (const_int 8)))
16558    (set (match_operand:P 1 "register_operand" "=S")
16559         (plus:P (match_dup 3)
16560                 (const_int 8)))]
16561   "TARGET_64BIT
16562    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16563    && ix86_check_no_addr_space (insn)"
16564   "%^movsq"
16565   [(set_attr "type" "str")
16566    (set_attr "memory" "both")
16567    (set_attr "mode" "DI")])
16569 (define_insn "*strmovsi_1"
16570   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16571         (mem:SI (match_operand:P 3 "register_operand" "1")))
16572    (set (match_operand:P 0 "register_operand" "=D")
16573         (plus:P (match_dup 2)
16574                 (const_int 4)))
16575    (set (match_operand:P 1 "register_operand" "=S")
16576         (plus:P (match_dup 3)
16577                 (const_int 4)))]
16578   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16579    && ix86_check_no_addr_space (insn)"
16580   "%^movs{l|d}"
16581   [(set_attr "type" "str")
16582    (set_attr "memory" "both")
16583    (set_attr "mode" "SI")])
16585 (define_insn "*strmovhi_1"
16586   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16587         (mem:HI (match_operand:P 3 "register_operand" "1")))
16588    (set (match_operand:P 0 "register_operand" "=D")
16589         (plus:P (match_dup 2)
16590                 (const_int 2)))
16591    (set (match_operand:P 1 "register_operand" "=S")
16592         (plus:P (match_dup 3)
16593                 (const_int 2)))]
16594   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16595    && ix86_check_no_addr_space (insn)"
16596   "%^movsw"
16597   [(set_attr "type" "str")
16598    (set_attr "memory" "both")
16599    (set_attr "mode" "HI")])
16601 (define_insn "*strmovqi_1"
16602   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16603         (mem:QI (match_operand:P 3 "register_operand" "1")))
16604    (set (match_operand:P 0 "register_operand" "=D")
16605         (plus:P (match_dup 2)
16606                 (const_int 1)))
16607    (set (match_operand:P 1 "register_operand" "=S")
16608         (plus:P (match_dup 3)
16609                 (const_int 1)))]
16610   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16611    && ix86_check_no_addr_space (insn)"
16612   "%^movsb"
16613   [(set_attr "type" "str")
16614    (set_attr "memory" "both")
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_mov"
16623   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16624               (set (match_operand 0 "register_operand")
16625                    (match_operand 5))
16626               (set (match_operand 2 "register_operand")
16627                    (match_operand 6))
16628               (set (match_operand 1 "memory_operand")
16629                    (match_operand 3 "memory_operand"))
16630               (use (match_dup 4))])]
16631   ""
16633   if (TARGET_CLD)
16634     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16637 (define_insn "*rep_movdi_rex64"
16638   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16639    (set (match_operand:P 0 "register_operand" "=D")
16640         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16641                           (const_int 3))
16642                 (match_operand:P 3 "register_operand" "0")))
16643    (set (match_operand:P 1 "register_operand" "=S")
16644         (plus:P (ashift:P (match_dup 5) (const_int 3))
16645                 (match_operand:P 4 "register_operand" "1")))
16646    (set (mem:BLK (match_dup 3))
16647         (mem:BLK (match_dup 4)))
16648    (use (match_dup 5))]
16649   "TARGET_64BIT
16650    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16651    && ix86_check_no_addr_space (insn)"
16652   "%^rep{%;} movsq"
16653   [(set_attr "type" "str")
16654    (set_attr "prefix_rep" "1")
16655    (set_attr "memory" "both")
16656    (set_attr "mode" "DI")])
16658 (define_insn "*rep_movsi"
16659   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16660    (set (match_operand:P 0 "register_operand" "=D")
16661         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16662                           (const_int 2))
16663                  (match_operand:P 3 "register_operand" "0")))
16664    (set (match_operand:P 1 "register_operand" "=S")
16665         (plus:P (ashift:P (match_dup 5) (const_int 2))
16666                 (match_operand:P 4 "register_operand" "1")))
16667    (set (mem:BLK (match_dup 3))
16668         (mem:BLK (match_dup 4)))
16669    (use (match_dup 5))]
16670   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16671    && ix86_check_no_addr_space (insn)"
16672   "%^rep{%;} movs{l|d}"
16673   [(set_attr "type" "str")
16674    (set_attr "prefix_rep" "1")
16675    (set_attr "memory" "both")
16676    (set_attr "mode" "SI")])
16678 (define_insn "*rep_movqi"
16679   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16680    (set (match_operand:P 0 "register_operand" "=D")
16681         (plus:P (match_operand:P 3 "register_operand" "0")
16682                 (match_operand:P 5 "register_operand" "2")))
16683    (set (match_operand:P 1 "register_operand" "=S")
16684         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16685    (set (mem:BLK (match_dup 3))
16686         (mem:BLK (match_dup 4)))
16687    (use (match_dup 5))]
16688   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16689    && ix86_check_no_addr_space (insn)"
16690   "%^rep{%;} movsb"
16691   [(set_attr "type" "str")
16692    (set_attr "prefix_rep" "1")
16693    (set_attr "memory" "both")
16694    (set_attr "mode" "QI")])
16696 (define_expand "setmem<mode>"
16697    [(use (match_operand:BLK 0 "memory_operand"))
16698     (use (match_operand:SWI48 1 "nonmemory_operand"))
16699     (use (match_operand:QI 2 "nonmemory_operand"))
16700     (use (match_operand 3 "const_int_operand"))
16701     (use (match_operand:SI 4 "const_int_operand"))
16702     (use (match_operand:SI 5 "const_int_operand"))
16703     (use (match_operand:SI 6 ""))
16704     (use (match_operand:SI 7 ""))
16705     (use (match_operand:SI 8 ""))]
16706   ""
16708  if (ix86_expand_set_or_movmem (operands[0], NULL,
16709                                 operands[1], operands[2],
16710                                 operands[3], operands[4],
16711                                 operands[5], operands[6],
16712                                 operands[7], operands[8], true))
16713    DONE;
16714  else
16715    FAIL;
16718 ;; Most CPUs don't like single string operations
16719 ;; Handle this case here to simplify previous expander.
16721 (define_expand "strset"
16722   [(set (match_operand 1 "memory_operand")
16723         (match_operand 2 "register_operand"))
16724    (parallel [(set (match_operand 0 "register_operand")
16725                    (match_dup 3))
16726               (clobber (reg:CC FLAGS_REG))])]
16727   ""
16729   /* Can't use this for non-default address spaces.  */
16730   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16731     FAIL;
16733   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16734     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16736   /* If .md ever supports :P for Pmode, this can be directly
16737      in the pattern above.  */
16738   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16739                               GEN_INT (GET_MODE_SIZE (GET_MODE
16740                                                       (operands[2]))));
16741   /* Can't use this if the user has appropriated eax or edi.  */
16742   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16743       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16744     {
16745       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16746                                       operands[3]));
16747       DONE;
16748     }
16751 (define_expand "strset_singleop"
16752   [(parallel [(set (match_operand 1 "memory_operand")
16753                    (match_operand 2 "register_operand"))
16754               (set (match_operand 0 "register_operand")
16755                    (match_operand 3))
16756               (unspec [(const_int 0)] UNSPEC_STOS)])]
16757   ""
16759   if (TARGET_CLD)
16760     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16763 (define_insn "*strsetdi_rex_1"
16764   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16765         (match_operand:DI 2 "register_operand" "a"))
16766    (set (match_operand:P 0 "register_operand" "=D")
16767         (plus:P (match_dup 1)
16768                 (const_int 8)))
16769    (unspec [(const_int 0)] UNSPEC_STOS)]
16770   "TARGET_64BIT
16771    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16772    && ix86_check_no_addr_space (insn)"
16773   "%^stosq"
16774   [(set_attr "type" "str")
16775    (set_attr "memory" "store")
16776    (set_attr "mode" "DI")])
16778 (define_insn "*strsetsi_1"
16779   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16780         (match_operand:SI 2 "register_operand" "a"))
16781    (set (match_operand:P 0 "register_operand" "=D")
16782         (plus:P (match_dup 1)
16783                 (const_int 4)))
16784    (unspec [(const_int 0)] UNSPEC_STOS)]
16785   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16786    && ix86_check_no_addr_space (insn)"
16787   "%^stos{l|d}"
16788   [(set_attr "type" "str")
16789    (set_attr "memory" "store")
16790    (set_attr "mode" "SI")])
16792 (define_insn "*strsethi_1"
16793   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16794         (match_operand:HI 2 "register_operand" "a"))
16795    (set (match_operand:P 0 "register_operand" "=D")
16796         (plus:P (match_dup 1)
16797                 (const_int 2)))
16798    (unspec [(const_int 0)] UNSPEC_STOS)]
16799   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16800    && ix86_check_no_addr_space (insn)"
16801   "%^stosw"
16802   [(set_attr "type" "str")
16803    (set_attr "memory" "store")
16804    (set_attr "mode" "HI")])
16806 (define_insn "*strsetqi_1"
16807   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16808         (match_operand:QI 2 "register_operand" "a"))
16809    (set (match_operand:P 0 "register_operand" "=D")
16810         (plus:P (match_dup 1)
16811                 (const_int 1)))
16812    (unspec [(const_int 0)] UNSPEC_STOS)]
16813   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16814    && ix86_check_no_addr_space (insn)"
16815   "%^stosb"
16816   [(set_attr "type" "str")
16817    (set_attr "memory" "store")
16818    (set (attr "prefix_rex")
16819         (if_then_else
16820           (match_test "<P:MODE>mode == DImode")
16821           (const_string "0")
16822           (const_string "*")))
16823    (set_attr "mode" "QI")])
16825 (define_expand "rep_stos"
16826   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16827               (set (match_operand 0 "register_operand")
16828                    (match_operand 4))
16829               (set (match_operand 2 "memory_operand") (const_int 0))
16830               (use (match_operand 3 "register_operand"))
16831               (use (match_dup 1))])]
16832   ""
16834   if (TARGET_CLD)
16835     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16838 (define_insn "*rep_stosdi_rex64"
16839   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16840    (set (match_operand:P 0 "register_operand" "=D")
16841         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16842                           (const_int 3))
16843                  (match_operand:P 3 "register_operand" "0")))
16844    (set (mem:BLK (match_dup 3))
16845         (const_int 0))
16846    (use (match_operand:DI 2 "register_operand" "a"))
16847    (use (match_dup 4))]
16848   "TARGET_64BIT
16849    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16850    && ix86_check_no_addr_space (insn)"
16851   "%^rep{%;} stosq"
16852   [(set_attr "type" "str")
16853    (set_attr "prefix_rep" "1")
16854    (set_attr "memory" "store")
16855    (set_attr "mode" "DI")])
16857 (define_insn "*rep_stossi"
16858   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16859    (set (match_operand:P 0 "register_operand" "=D")
16860         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16861                           (const_int 2))
16862                  (match_operand:P 3 "register_operand" "0")))
16863    (set (mem:BLK (match_dup 3))
16864         (const_int 0))
16865    (use (match_operand:SI 2 "register_operand" "a"))
16866    (use (match_dup 4))]
16867   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16868    && ix86_check_no_addr_space (insn)"
16869   "%^rep{%;} stos{l|d}"
16870   [(set_attr "type" "str")
16871    (set_attr "prefix_rep" "1")
16872    (set_attr "memory" "store")
16873    (set_attr "mode" "SI")])
16875 (define_insn "*rep_stosqi"
16876   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16877    (set (match_operand:P 0 "register_operand" "=D")
16878         (plus:P (match_operand:P 3 "register_operand" "0")
16879                 (match_operand:P 4 "register_operand" "1")))
16880    (set (mem:BLK (match_dup 3))
16881         (const_int 0))
16882    (use (match_operand:QI 2 "register_operand" "a"))
16883    (use (match_dup 4))]
16884   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16885    && ix86_check_no_addr_space (insn)"
16886   "%^rep{%;} stosb"
16887   [(set_attr "type" "str")
16888    (set_attr "prefix_rep" "1")
16889    (set_attr "memory" "store")
16890    (set (attr "prefix_rex")
16891         (if_then_else
16892           (match_test "<P:MODE>mode == DImode")
16893           (const_string "0")
16894           (const_string "*")))
16895    (set_attr "mode" "QI")])
16897 (define_expand "cmpstrnsi"
16898   [(set (match_operand:SI 0 "register_operand")
16899         (compare:SI (match_operand:BLK 1 "general_operand")
16900                     (match_operand:BLK 2 "general_operand")))
16901    (use (match_operand 3 "general_operand"))
16902    (use (match_operand 4 "immediate_operand"))]
16903   ""
16905   rtx addr1, addr2, out, outlow, count, countreg, align;
16907   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16908     FAIL;
16910   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16911   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16912     FAIL;
16914   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
16915      will have rewritten the length arg to be the minimum of the const string
16916      length and the actual length arg.  If both strings are the same and
16917      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16918      will incorrectly base the results on chars past the 0 byte.  */
16919   tree t1 = MEM_EXPR (operands[1]);
16920   tree t2 = MEM_EXPR (operands[2]);
16921   if (!((t1 && TREE_CODE (t1) == MEM_REF
16922          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16923          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16924       || (t2 && TREE_CODE (t2) == MEM_REF
16925           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16926           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16927     FAIL;
16929   out = operands[0];
16930   if (!REG_P (out))
16931     out = gen_reg_rtx (SImode);
16933   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16934   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16935   if (addr1 != XEXP (operands[1], 0))
16936     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16937   if (addr2 != XEXP (operands[2], 0))
16938     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16940   count = operands[3];
16941   countreg = ix86_zero_extend_to_Pmode (count);
16943   /* %%% Iff we are testing strict equality, we can use known alignment
16944      to good advantage.  This may be possible with combine, particularly
16945      once cc0 is dead.  */
16946   align = operands[4];
16948   if (CONST_INT_P (count))
16949     {
16950       if (INTVAL (count) == 0)
16951         {
16952           emit_move_insn (operands[0], const0_rtx);
16953           DONE;
16954         }
16955       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16956                                      operands[1], operands[2]));
16957     }
16958   else
16959     {
16960       rtx (*gen_cmp) (rtx, rtx);
16962       gen_cmp = (TARGET_64BIT
16963                  ? gen_cmpdi_1 : gen_cmpsi_1);
16965       emit_insn (gen_cmp (countreg, countreg));
16966       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16967                                   operands[1], operands[2]));
16968     }
16970   outlow = gen_lowpart (QImode, out);
16971   emit_insn (gen_cmpintqi (outlow));
16972   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16974   if (operands[0] != out)
16975     emit_move_insn (operands[0], out);
16977   DONE;
16980 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16982 (define_expand "cmpintqi"
16983   [(set (match_dup 1)
16984         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16985    (set (match_dup 2)
16986         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16987    (parallel [(set (match_operand:QI 0 "register_operand")
16988                    (minus:QI (match_dup 1)
16989                              (match_dup 2)))
16990               (clobber (reg:CC FLAGS_REG))])]
16991   ""
16993   operands[1] = gen_reg_rtx (QImode);
16994   operands[2] = gen_reg_rtx (QImode);
16997 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16998 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17000 (define_expand "cmpstrnqi_nz_1"
17001   [(parallel [(set (reg:CC FLAGS_REG)
17002                    (compare:CC (match_operand 4 "memory_operand")
17003                                (match_operand 5 "memory_operand")))
17004               (use (match_operand 2 "register_operand"))
17005               (use (match_operand:SI 3 "immediate_operand"))
17006               (clobber (match_operand 0 "register_operand"))
17007               (clobber (match_operand 1 "register_operand"))
17008               (clobber (match_dup 2))])]
17009   ""
17011   if (TARGET_CLD)
17012     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17015 (define_insn "*cmpstrnqi_nz_1"
17016   [(set (reg:CC FLAGS_REG)
17017         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17018                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17019    (use (match_operand:P 6 "register_operand" "2"))
17020    (use (match_operand:SI 3 "immediate_operand" "i"))
17021    (clobber (match_operand:P 0 "register_operand" "=S"))
17022    (clobber (match_operand:P 1 "register_operand" "=D"))
17023    (clobber (match_operand:P 2 "register_operand" "=c"))]
17024   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17025    && ix86_check_no_addr_space (insn)"
17026   "%^repz{%;} cmpsb"
17027   [(set_attr "type" "str")
17028    (set_attr "mode" "QI")
17029    (set (attr "prefix_rex")
17030         (if_then_else
17031           (match_test "<P:MODE>mode == DImode")
17032           (const_string "0")
17033           (const_string "*")))
17034    (set_attr "prefix_rep" "1")])
17036 ;; The same, but the count is not known to not be zero.
17038 (define_expand "cmpstrnqi_1"
17039   [(parallel [(set (reg:CC FLAGS_REG)
17040                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17041                                      (const_int 0))
17042                   (compare:CC (match_operand 4 "memory_operand")
17043                               (match_operand 5 "memory_operand"))
17044                   (const_int 0)))
17045               (use (match_operand:SI 3 "immediate_operand"))
17046               (use (reg:CC FLAGS_REG))
17047               (clobber (match_operand 0 "register_operand"))
17048               (clobber (match_operand 1 "register_operand"))
17049               (clobber (match_dup 2))])]
17050   ""
17052   if (TARGET_CLD)
17053     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17056 (define_insn "*cmpstrnqi_1"
17057   [(set (reg:CC FLAGS_REG)
17058         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17059                              (const_int 0))
17060           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17061                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17062           (const_int 0)))
17063    (use (match_operand:SI 3 "immediate_operand" "i"))
17064    (use (reg:CC FLAGS_REG))
17065    (clobber (match_operand:P 0 "register_operand" "=S"))
17066    (clobber (match_operand:P 1 "register_operand" "=D"))
17067    (clobber (match_operand:P 2 "register_operand" "=c"))]
17068   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17069    && ix86_check_no_addr_space (insn)"
17070   "%^repz{%;} cmpsb"
17071   [(set_attr "type" "str")
17072    (set_attr "mode" "QI")
17073    (set (attr "prefix_rex")
17074         (if_then_else
17075           (match_test "<P:MODE>mode == DImode")
17076           (const_string "0")
17077           (const_string "*")))
17078    (set_attr "prefix_rep" "1")])
17080 (define_expand "strlen<mode>"
17081   [(set (match_operand:P 0 "register_operand")
17082         (unspec:P [(match_operand:BLK 1 "general_operand")
17083                    (match_operand:QI 2 "immediate_operand")
17084                    (match_operand 3 "immediate_operand")]
17085                   UNSPEC_SCAS))]
17086   ""
17088  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17089    DONE;
17090  else
17091    FAIL;
17094 (define_expand "strlenqi_1"
17095   [(parallel [(set (match_operand 0 "register_operand")
17096                    (match_operand 2))
17097               (clobber (match_operand 1 "register_operand"))
17098               (clobber (reg:CC FLAGS_REG))])]
17099   ""
17101   if (TARGET_CLD)
17102     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17105 (define_insn "*strlenqi_1"
17106   [(set (match_operand:P 0 "register_operand" "=&c")
17107         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17108                    (match_operand:QI 2 "register_operand" "a")
17109                    (match_operand:P 3 "immediate_operand" "i")
17110                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17111    (clobber (match_operand:P 1 "register_operand" "=D"))
17112    (clobber (reg:CC FLAGS_REG))]
17113   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17114    && ix86_check_no_addr_space (insn)"
17115   "%^repnz{%;} scasb"
17116   [(set_attr "type" "str")
17117    (set_attr "mode" "QI")
17118    (set (attr "prefix_rex")
17119         (if_then_else
17120           (match_test "<P:MODE>mode == DImode")
17121           (const_string "0")
17122           (const_string "*")))
17123    (set_attr "prefix_rep" "1")])
17125 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17126 ;; handled in combine, but it is not currently up to the task.
17127 ;; When used for their truth value, the cmpstrn* expanders generate
17128 ;; code like this:
17130 ;;   repz cmpsb
17131 ;;   seta       %al
17132 ;;   setb       %dl
17133 ;;   cmpb       %al, %dl
17134 ;;   jcc        label
17136 ;; The intermediate three instructions are unnecessary.
17138 ;; This one handles cmpstrn*_nz_1...
17139 (define_peephole2
17140   [(parallel[
17141      (set (reg:CC FLAGS_REG)
17142           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17143                       (mem:BLK (match_operand 5 "register_operand"))))
17144      (use (match_operand 6 "register_operand"))
17145      (use (match_operand:SI 3 "immediate_operand"))
17146      (clobber (match_operand 0 "register_operand"))
17147      (clobber (match_operand 1 "register_operand"))
17148      (clobber (match_operand 2 "register_operand"))])
17149    (set (match_operand:QI 7 "register_operand")
17150         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17151    (set (match_operand:QI 8 "register_operand")
17152         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17153    (set (reg FLAGS_REG)
17154         (compare (match_dup 7) (match_dup 8)))
17155   ]
17156   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17157   [(parallel[
17158      (set (reg:CC FLAGS_REG)
17159           (compare:CC (mem:BLK (match_dup 4))
17160                       (mem:BLK (match_dup 5))))
17161      (use (match_dup 6))
17162      (use (match_dup 3))
17163      (clobber (match_dup 0))
17164      (clobber (match_dup 1))
17165      (clobber (match_dup 2))])])
17167 ;; ...and this one handles cmpstrn*_1.
17168 (define_peephole2
17169   [(parallel[
17170      (set (reg:CC FLAGS_REG)
17171           (if_then_else:CC (ne (match_operand 6 "register_operand")
17172                                (const_int 0))
17173             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17174                         (mem:BLK (match_operand 5 "register_operand")))
17175             (const_int 0)))
17176      (use (match_operand:SI 3 "immediate_operand"))
17177      (use (reg:CC FLAGS_REG))
17178      (clobber (match_operand 0 "register_operand"))
17179      (clobber (match_operand 1 "register_operand"))
17180      (clobber (match_operand 2 "register_operand"))])
17181    (set (match_operand:QI 7 "register_operand")
17182         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17183    (set (match_operand:QI 8 "register_operand")
17184         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17185    (set (reg FLAGS_REG)
17186         (compare (match_dup 7) (match_dup 8)))
17187   ]
17188   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17189   [(parallel[
17190      (set (reg:CC FLAGS_REG)
17191           (if_then_else:CC (ne (match_dup 6)
17192                                (const_int 0))
17193             (compare:CC (mem:BLK (match_dup 4))
17194                         (mem:BLK (match_dup 5)))
17195             (const_int 0)))
17196      (use (match_dup 3))
17197      (use (reg:CC FLAGS_REG))
17198      (clobber (match_dup 0))
17199      (clobber (match_dup 1))
17200      (clobber (match_dup 2))])])
17202 ;; Conditional move instructions.
17204 (define_expand "mov<mode>cc"
17205   [(set (match_operand:SWIM 0 "register_operand")
17206         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17207                            (match_operand:SWIM 2 "<general_operand>")
17208                            (match_operand:SWIM 3 "<general_operand>")))]
17209   ""
17210   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17212 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17213 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17214 ;; So just document what we're doing explicitly.
17216 (define_expand "x86_mov<mode>cc_0_m1"
17217   [(parallel
17218     [(set (match_operand:SWI48 0 "register_operand")
17219           (if_then_else:SWI48
17220             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17221              [(match_operand 1 "flags_reg_operand")
17222               (const_int 0)])
17223             (const_int -1)
17224             (const_int 0)))
17225      (clobber (reg:CC FLAGS_REG))])])
17227 (define_insn "*x86_mov<mode>cc_0_m1"
17228   [(set (match_operand:SWI48 0 "register_operand" "=r")
17229         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17230                              [(reg FLAGS_REG) (const_int 0)])
17231           (const_int -1)
17232           (const_int 0)))
17233    (clobber (reg:CC FLAGS_REG))]
17234   ""
17235   "sbb{<imodesuffix>}\t%0, %0"
17236   ; Since we don't have the proper number of operands for an alu insn,
17237   ; fill in all the blanks.
17238   [(set_attr "type" "alu")
17239    (set_attr "modrm_class" "op0")
17240    (set_attr "use_carry" "1")
17241    (set_attr "pent_pair" "pu")
17242    (set_attr "memory" "none")
17243    (set_attr "imm_disp" "false")
17244    (set_attr "mode" "<MODE>")
17245    (set_attr "length_immediate" "0")])
17247 (define_insn "*x86_mov<mode>cc_0_m1_se"
17248   [(set (match_operand:SWI48 0 "register_operand" "=r")
17249         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17250                              [(reg FLAGS_REG) (const_int 0)])
17251                             (const_int 1)
17252                             (const_int 0)))
17253    (clobber (reg:CC FLAGS_REG))]
17254   ""
17255   "sbb{<imodesuffix>}\t%0, %0"
17256   [(set_attr "type" "alu")
17257    (set_attr "modrm_class" "op0")
17258    (set_attr "use_carry" "1")
17259    (set_attr "pent_pair" "pu")
17260    (set_attr "memory" "none")
17261    (set_attr "imm_disp" "false")
17262    (set_attr "mode" "<MODE>")
17263    (set_attr "length_immediate" "0")])
17265 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17266   [(set (match_operand:SWI48 0 "register_operand" "=r")
17267         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17268                     [(reg FLAGS_REG) (const_int 0)])))
17269    (clobber (reg:CC FLAGS_REG))]
17270   ""
17271   "sbb{<imodesuffix>}\t%0, %0"
17272   [(set_attr "type" "alu")
17273    (set_attr "modrm_class" "op0")
17274    (set_attr "use_carry" "1")
17275    (set_attr "pent_pair" "pu")
17276    (set_attr "memory" "none")
17277    (set_attr "imm_disp" "false")
17278    (set_attr "mode" "<MODE>")
17279    (set_attr "length_immediate" "0")])
17281 (define_insn "*mov<mode>cc_noc"
17282   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17283         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17284                                [(reg FLAGS_REG) (const_int 0)])
17285           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17286           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17287   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17288   "@
17289    cmov%O2%C1\t{%2, %0|%0, %2}
17290    cmov%O2%c1\t{%3, %0|%0, %3}"
17291   [(set_attr "type" "icmov")
17292    (set_attr "mode" "<MODE>")])
17294 (define_insn "*movsicc_noc_zext"
17295   [(set (match_operand:DI 0 "register_operand" "=r,r")
17296         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17297                            [(reg FLAGS_REG) (const_int 0)])
17298           (zero_extend:DI
17299             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17300           (zero_extend:DI
17301             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17302   "TARGET_64BIT
17303    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17304   "@
17305    cmov%O2%C1\t{%2, %k0|%k0, %2}
17306    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17307   [(set_attr "type" "icmov")
17308    (set_attr "mode" "SI")])
17310 ;; Don't do conditional moves with memory inputs.  This splitter helps
17311 ;; register starved x86_32 by forcing inputs into registers before reload.
17312 (define_split
17313   [(set (match_operand:SWI248 0 "register_operand")
17314         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17315                                [(reg FLAGS_REG) (const_int 0)])
17316           (match_operand:SWI248 2 "nonimmediate_operand")
17317           (match_operand:SWI248 3 "nonimmediate_operand")))]
17318   "!TARGET_64BIT && TARGET_CMOVE
17319    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17320    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17321    && can_create_pseudo_p ()
17322    && optimize_insn_for_speed_p ()"
17323   [(set (match_dup 0)
17324         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17326   if (MEM_P (operands[2]))
17327     operands[2] = force_reg (<MODE>mode, operands[2]);
17328   if (MEM_P (operands[3]))
17329     operands[3] = force_reg (<MODE>mode, operands[3]);
17332 (define_insn "*movqicc_noc"
17333   [(set (match_operand:QI 0 "register_operand" "=r,r")
17334         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17335                            [(reg FLAGS_REG) (const_int 0)])
17336                       (match_operand:QI 2 "register_operand" "r,0")
17337                       (match_operand:QI 3 "register_operand" "0,r")))]
17338   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17339   "#"
17340   [(set_attr "type" "icmov")
17341    (set_attr "mode" "QI")])
17343 (define_split
17344   [(set (match_operand:SWI12 0 "register_operand")
17345         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17346                               [(reg FLAGS_REG) (const_int 0)])
17347                       (match_operand:SWI12 2 "register_operand")
17348                       (match_operand:SWI12 3 "register_operand")))]
17349   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17350    && reload_completed"
17351   [(set (match_dup 0)
17352         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17354   operands[0] = gen_lowpart (SImode, operands[0]);
17355   operands[2] = gen_lowpart (SImode, operands[2]);
17356   operands[3] = gen_lowpart (SImode, operands[3]);
17359 ;; Don't do conditional moves with memory inputs
17360 (define_peephole2
17361   [(match_scratch:SWI248 4 "r")
17362    (set (match_operand:SWI248 0 "register_operand")
17363         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17364                                [(reg FLAGS_REG) (const_int 0)])
17365           (match_operand:SWI248 2 "nonimmediate_operand")
17366           (match_operand:SWI248 3 "nonimmediate_operand")))]
17367   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17368    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17369    && optimize_insn_for_speed_p ()"
17370   [(set (match_dup 4) (match_dup 5))
17371    (set (match_dup 0)
17372         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17374   if (MEM_P (operands[2]))
17375     {
17376       operands[5] = operands[2];
17377       operands[2] = operands[4];
17378     }
17379   else if (MEM_P (operands[3]))
17380     {
17381       operands[5] = operands[3];
17382       operands[3] = operands[4];
17383     }
17384   else
17385     gcc_unreachable ();
17388 (define_peephole2
17389   [(match_scratch:SI 4 "r")
17390    (set (match_operand:DI 0 "register_operand")
17391         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17392                            [(reg FLAGS_REG) (const_int 0)])
17393           (zero_extend:DI
17394             (match_operand:SI 2 "nonimmediate_operand"))
17395           (zero_extend:DI
17396             (match_operand:SI 3 "nonimmediate_operand"))))]
17397   "TARGET_64BIT
17398    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17399    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17400    && optimize_insn_for_speed_p ()"
17401   [(set (match_dup 4) (match_dup 5))
17402    (set (match_dup 0)
17403         (if_then_else:DI (match_dup 1)
17404           (zero_extend:DI (match_dup 2))
17405           (zero_extend:DI (match_dup 3))))]
17407   if (MEM_P (operands[2]))
17408     {
17409       operands[5] = operands[2];
17410       operands[2] = operands[4];
17411     }
17412   else if (MEM_P (operands[3]))
17413     {
17414       operands[5] = operands[3];
17415       operands[3] = operands[4];
17416     }
17417   else
17418     gcc_unreachable ();
17421 (define_expand "mov<mode>cc"
17422   [(set (match_operand:X87MODEF 0 "register_operand")
17423         (if_then_else:X87MODEF
17424           (match_operand 1 "comparison_operator")
17425           (match_operand:X87MODEF 2 "register_operand")
17426           (match_operand:X87MODEF 3 "register_operand")))]
17427   "(TARGET_80387 && TARGET_CMOVE)
17428    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17429   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17431 (define_insn "*movxfcc_1"
17432   [(set (match_operand:XF 0 "register_operand" "=f,f")
17433         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17434                                 [(reg FLAGS_REG) (const_int 0)])
17435                       (match_operand:XF 2 "register_operand" "f,0")
17436                       (match_operand:XF 3 "register_operand" "0,f")))]
17437   "TARGET_80387 && TARGET_CMOVE"
17438   "@
17439    fcmov%F1\t{%2, %0|%0, %2}
17440    fcmov%f1\t{%3, %0|%0, %3}"
17441   [(set_attr "type" "fcmov")
17442    (set_attr "mode" "XF")])
17444 (define_insn "*movdfcc_1"
17445   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17446         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17447                                 [(reg FLAGS_REG) (const_int 0)])
17448                       (match_operand:DF 2 "nonimmediate_operand"
17449                                                "f ,0,rm,0 ,rm,0")
17450                       (match_operand:DF 3 "nonimmediate_operand"
17451                                                "0 ,f,0 ,rm,0, rm")))]
17452   "TARGET_80387 && TARGET_CMOVE
17453    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17454   "@
17455    fcmov%F1\t{%2, %0|%0, %2}
17456    fcmov%f1\t{%3, %0|%0, %3}
17457    #
17458    #
17459    cmov%O2%C1\t{%2, %0|%0, %2}
17460    cmov%O2%c1\t{%3, %0|%0, %3}"
17461   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17462    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17463    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17465 (define_split
17466   [(set (match_operand:DF 0 "general_reg_operand")
17467         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17468                                 [(reg FLAGS_REG) (const_int 0)])
17469                       (match_operand:DF 2 "nonimmediate_operand")
17470                       (match_operand:DF 3 "nonimmediate_operand")))]
17471   "!TARGET_64BIT && reload_completed"
17472   [(set (match_dup 2)
17473         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17474    (set (match_dup 3)
17475         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17477   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17478   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17481 (define_insn "*movsfcc_1_387"
17482   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17483         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17484                                 [(reg FLAGS_REG) (const_int 0)])
17485                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17486                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17487   "TARGET_80387 && TARGET_CMOVE
17488    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17489   "@
17490    fcmov%F1\t{%2, %0|%0, %2}
17491    fcmov%f1\t{%3, %0|%0, %3}
17492    cmov%O2%C1\t{%2, %0|%0, %2}
17493    cmov%O2%c1\t{%3, %0|%0, %3}"
17494   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17495    (set_attr "mode" "SF,SF,SI,SI")])
17497 ;; Don't do conditional moves with memory inputs.  This splitter helps
17498 ;; register starved x86_32 by forcing inputs into registers before reload.
17499 (define_split
17500   [(set (match_operand:MODEF 0 "register_operand")
17501         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17502                               [(reg FLAGS_REG) (const_int 0)])
17503           (match_operand:MODEF 2 "nonimmediate_operand")
17504           (match_operand:MODEF 3 "nonimmediate_operand")))]
17505   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17506    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17507    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17508    && can_create_pseudo_p ()
17509    && optimize_insn_for_speed_p ()"
17510   [(set (match_dup 0)
17511         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17513   if (MEM_P (operands[2]))
17514     operands[2] = force_reg (<MODE>mode, operands[2]);
17515   if (MEM_P (operands[3]))
17516     operands[3] = force_reg (<MODE>mode, operands[3]);
17519 ;; Don't do conditional moves with memory inputs
17520 (define_peephole2
17521   [(match_scratch:MODEF 4 "r")
17522    (set (match_operand:MODEF 0 "general_reg_operand")
17523         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17524                               [(reg FLAGS_REG) (const_int 0)])
17525           (match_operand:MODEF 2 "nonimmediate_operand")
17526           (match_operand:MODEF 3 "nonimmediate_operand")))]
17527   "(<MODE>mode != DFmode || TARGET_64BIT)
17528    && TARGET_80387 && TARGET_CMOVE
17529    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17530    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17531    && optimize_insn_for_speed_p ()"
17532   [(set (match_dup 4) (match_dup 5))
17533    (set (match_dup 0)
17534         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17536   if (MEM_P (operands[2]))
17537     {
17538       operands[5] = operands[2];
17539       operands[2] = operands[4];
17540     }
17541   else if (MEM_P (operands[3]))
17542     {
17543       operands[5] = operands[3];
17544       operands[3] = operands[4];
17545     }
17546   else
17547     gcc_unreachable ();
17550 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17551 ;; the scalar versions to have only XMM registers as operands.
17553 ;; XOP conditional move
17554 (define_insn "*xop_pcmov_<mode>"
17555   [(set (match_operand:MODEF 0 "register_operand" "=x")
17556         (if_then_else:MODEF
17557           (match_operand:MODEF 1 "register_operand" "x")
17558           (match_operand:MODEF 2 "register_operand" "x")
17559           (match_operand:MODEF 3 "register_operand" "x")))]
17560   "TARGET_XOP"
17561   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17562   [(set_attr "type" "sse4arg")])
17564 ;; These versions of the min/max patterns are intentionally ignorant of
17565 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17566 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17567 ;; are undefined in this condition, we're certain this is correct.
17569 (define_insn "<code><mode>3"
17570   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17571         (smaxmin:MODEF
17572           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17573           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17574   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17575   "@
17576    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17577    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17578   [(set_attr "isa" "noavx,avx")
17579    (set_attr "prefix" "orig,vex")
17580    (set_attr "type" "sseadd")
17581    (set_attr "mode" "<MODE>")])
17583 ;; These versions of the min/max patterns implement exactly the operations
17584 ;;   min = (op1 < op2 ? op1 : op2)
17585 ;;   max = (!(op1 < op2) ? op1 : op2)
17586 ;; Their operands are not commutative, and thus they may be used in the
17587 ;; presence of -0.0 and NaN.
17589 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17590   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17591         (unspec:MODEF
17592           [(match_operand:MODEF 1 "register_operand" "0,v")
17593            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17594           IEEE_MAXMIN))]
17595   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17596   "@
17597    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17598    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17599   [(set_attr "isa" "noavx,avx")
17600    (set_attr "prefix" "orig,maybe_evex")
17601    (set_attr "type" "sseadd")
17602    (set_attr "mode" "<MODE>")])
17604 ;; Make two stack loads independent:
17605 ;;   fld aa              fld aa
17606 ;;   fld %st(0)     ->   fld bb
17607 ;;   fmul bb             fmul %st(1), %st
17609 ;; Actually we only match the last two instructions for simplicity.
17611 (define_peephole2
17612   [(set (match_operand 0 "fp_register_operand")
17613         (match_operand 1 "fp_register_operand"))
17614    (set (match_dup 0)
17615         (match_operator 2 "binary_fp_operator"
17616            [(match_dup 0)
17617             (match_operand 3 "memory_operand")]))]
17618   "REGNO (operands[0]) != REGNO (operands[1])"
17619   [(set (match_dup 0) (match_dup 3))
17620    (set (match_dup 0)
17621         (match_op_dup 2
17622           [(match_dup 5) (match_dup 4)]))]
17624   operands[4] = operands[0];
17625   operands[5] = operands[1];
17627   /* The % modifier is not operational anymore in peephole2's, so we have to
17628      swap the operands manually in the case of addition and multiplication. */
17629   if (COMMUTATIVE_ARITH_P (operands[2]))
17630     std::swap (operands[4], operands[5]);
17633 (define_peephole2
17634   [(set (match_operand 0 "fp_register_operand")
17635         (match_operand 1 "fp_register_operand"))
17636    (set (match_dup 0)
17637         (match_operator 2 "binary_fp_operator"
17638            [(match_operand 3 "memory_operand")
17639             (match_dup 0)]))]
17640   "REGNO (operands[0]) != REGNO (operands[1])"
17641   [(set (match_dup 0) (match_dup 3))
17642    (set (match_dup 0)
17643         (match_op_dup 2
17644           [(match_dup 4) (match_dup 5)]))]
17646   operands[4] = operands[0];
17647   operands[5] = operands[1];
17649   /* The % modifier is not operational anymore in peephole2's, so we have to
17650      swap the operands manually in the case of addition and multiplication. */
17651   if (COMMUTATIVE_ARITH_P (operands[2]))
17652     std::swap (operands[4], operands[5]);
17655 ;; Conditional addition patterns
17656 (define_expand "add<mode>cc"
17657   [(match_operand:SWI 0 "register_operand")
17658    (match_operand 1 "ordered_comparison_operator")
17659    (match_operand:SWI 2 "register_operand")
17660    (match_operand:SWI 3 "const_int_operand")]
17661   ""
17662   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17664 ;; Misc patterns (?)
17666 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17667 ;; Otherwise there will be nothing to keep
17669 ;; [(set (reg ebp) (reg esp))]
17670 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17671 ;;  (clobber (eflags)]
17672 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17674 ;; in proper program order.
17676 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17677   [(set (match_operand:P 0 "register_operand" "=r,r")
17678         (plus:P (match_operand:P 1 "register_operand" "0,r")
17679                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17680    (clobber (reg:CC FLAGS_REG))
17681    (clobber (mem:BLK (scratch)))]
17682   ""
17684   switch (get_attr_type (insn))
17685     {
17686     case TYPE_IMOV:
17687       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17689     case TYPE_ALU:
17690       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17691       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17692         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17694       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17696     default:
17697       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17698       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17699     }
17701   [(set (attr "type")
17702         (cond [(and (eq_attr "alternative" "0")
17703                     (not (match_test "TARGET_OPT_AGU")))
17704                  (const_string "alu")
17705                (match_operand:<MODE> 2 "const0_operand")
17706                  (const_string "imov")
17707               ]
17708               (const_string "lea")))
17709    (set (attr "length_immediate")
17710         (cond [(eq_attr "type" "imov")
17711                  (const_string "0")
17712                (and (eq_attr "type" "alu")
17713                     (match_operand 2 "const128_operand"))
17714                  (const_string "1")
17715               ]
17716               (const_string "*")))
17717    (set_attr "mode" "<MODE>")])
17719 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17720   [(set (match_operand:P 0 "register_operand" "=r")
17721         (minus:P (match_operand:P 1 "register_operand" "0")
17722                  (match_operand:P 2 "register_operand" "r")))
17723    (clobber (reg:CC FLAGS_REG))
17724    (clobber (mem:BLK (scratch)))]
17725   ""
17726   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17727   [(set_attr "type" "alu")
17728    (set_attr "mode" "<MODE>")])
17730 (define_insn "allocate_stack_worker_probe_<mode>"
17731   [(set (match_operand:P 0 "register_operand" "=a")
17732         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17733                             UNSPECV_STACK_PROBE))
17734    (clobber (reg:CC FLAGS_REG))]
17735   "ix86_target_stack_probe ()"
17736   "call\t___chkstk_ms"
17737   [(set_attr "type" "multi")
17738    (set_attr "length" "5")])
17740 (define_expand "allocate_stack"
17741   [(match_operand 0 "register_operand")
17742    (match_operand 1 "general_operand")]
17743   "ix86_target_stack_probe ()"
17745   rtx x;
17747 #ifndef CHECK_STACK_LIMIT
17748 #define CHECK_STACK_LIMIT 0
17749 #endif
17751   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17752       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17753     x = operands[1];
17754   else
17755     {
17756       rtx (*insn) (rtx, rtx);
17758       x = copy_to_mode_reg (Pmode, operands[1]);
17760       insn = (TARGET_64BIT
17761               ? gen_allocate_stack_worker_probe_di
17762               : gen_allocate_stack_worker_probe_si);
17764       emit_insn (insn (x, x));
17765     }
17767   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17768                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17770   if (x != stack_pointer_rtx)
17771     emit_move_insn (stack_pointer_rtx, x);
17773   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17774   DONE;
17777 (define_expand "probe_stack"
17778   [(match_operand 0 "memory_operand")]
17779   ""
17781   rtx (*insn) (rtx, rtx)
17782     = (GET_MODE (operands[0]) == DImode
17783        ? gen_probe_stack_di : gen_probe_stack_si);
17785   emit_insn (insn (operands[0], const0_rtx));
17786   DONE;
17789 ;; Use OR for stack probes, this is shorter.
17790 (define_insn "probe_stack_<mode>"
17791   [(set (match_operand:W 0 "memory_operand" "=m")
17792         (unspec:W [(match_operand:W 1 "const0_operand")]
17793                   UNSPEC_PROBE_STACK))
17794    (clobber (reg:CC FLAGS_REG))]
17795   ""
17796   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17797   [(set_attr "type" "alu1")
17798    (set_attr "mode" "<MODE>")
17799    (set_attr "length_immediate" "1")])
17800   
17801 (define_insn "adjust_stack_and_probe<mode>"
17802   [(set (match_operand:P 0 "register_operand" "=r")
17803         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17804                             UNSPECV_PROBE_STACK_RANGE))
17805    (set (reg:P SP_REG)
17806         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17807    (clobber (reg:CC FLAGS_REG))
17808    (clobber (mem:BLK (scratch)))]
17809   ""
17810   "* return output_adjust_stack_and_probe (operands[0]);"
17811   [(set_attr "type" "multi")])
17813 (define_insn "probe_stack_range<mode>"
17814   [(set (match_operand:P 0 "register_operand" "=r")
17815         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17816                             (match_operand:P 2 "const_int_operand" "n")]
17817                             UNSPECV_PROBE_STACK_RANGE))
17818    (clobber (reg:CC FLAGS_REG))]
17819   ""
17820   "* return output_probe_stack_range (operands[0], operands[2]);"
17821   [(set_attr "type" "multi")])
17823 (define_expand "builtin_setjmp_receiver"
17824   [(label_ref (match_operand 0))]
17825   "!TARGET_64BIT && flag_pic"
17827 #if TARGET_MACHO
17828   if (TARGET_MACHO)
17829     {
17830       rtx xops[3];
17831       rtx_code_label *label_rtx = gen_label_rtx ();
17832       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17833       xops[0] = xops[1] = pic_offset_table_rtx;
17834       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17835       ix86_expand_binary_operator (MINUS, SImode, xops);
17836     }
17837   else
17838 #endif
17839     emit_insn (gen_set_got (pic_offset_table_rtx));
17840   DONE;
17843 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17844 ;; Do not split instructions with mask registers.
17845 (define_split
17846   [(set (match_operand 0 "general_reg_operand")
17847         (match_operator 3 "promotable_binary_operator"
17848            [(match_operand 1 "general_reg_operand")
17849             (match_operand 2 "aligned_operand")]))
17850    (clobber (reg:CC FLAGS_REG))]
17851   "! TARGET_PARTIAL_REG_STALL && reload_completed
17852    && ((GET_MODE (operands[0]) == HImode
17853         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17854             /* ??? next two lines just !satisfies_constraint_K (...) */
17855             || !CONST_INT_P (operands[2])
17856             || satisfies_constraint_K (operands[2])))
17857        || (GET_MODE (operands[0]) == QImode
17858            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17859   [(parallel [(set (match_dup 0)
17860                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17861               (clobber (reg:CC FLAGS_REG))])]
17863   operands[0] = gen_lowpart (SImode, operands[0]);
17864   operands[1] = gen_lowpart (SImode, operands[1]);
17865   if (GET_CODE (operands[3]) != ASHIFT)
17866     operands[2] = gen_lowpart (SImode, operands[2]);
17867   operands[3] = shallow_copy_rtx (operands[3]);
17868   PUT_MODE (operands[3], SImode);
17871 ; Promote the QImode tests, as i386 has encoding of the AND
17872 ; instruction with 32-bit sign-extended immediate and thus the
17873 ; instruction size is unchanged, except in the %eax case for
17874 ; which it is increased by one byte, hence the ! optimize_size.
17875 (define_split
17876   [(set (match_operand 0 "flags_reg_operand")
17877         (match_operator 2 "compare_operator"
17878           [(and (match_operand 3 "aligned_operand")
17879                 (match_operand 4 "const_int_operand"))
17880            (const_int 0)]))
17881    (set (match_operand 1 "register_operand")
17882         (and (match_dup 3) (match_dup 4)))]
17883   "! TARGET_PARTIAL_REG_STALL && reload_completed
17884    && optimize_insn_for_speed_p ()
17885    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17886        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17887    /* Ensure that the operand will remain sign-extended immediate.  */
17888    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17889   [(parallel [(set (match_dup 0)
17890                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17891                                     (const_int 0)]))
17892               (set (match_dup 1)
17893                    (and:SI (match_dup 3) (match_dup 4)))])]
17895   operands[4]
17896     = gen_int_mode (INTVAL (operands[4])
17897                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17898   operands[1] = gen_lowpart (SImode, operands[1]);
17899   operands[3] = gen_lowpart (SImode, operands[3]);
17902 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17903 ; the TEST instruction with 32-bit sign-extended immediate and thus
17904 ; the instruction size would at least double, which is not what we
17905 ; want even with ! optimize_size.
17906 (define_split
17907   [(set (match_operand 0 "flags_reg_operand")
17908         (match_operator 1 "compare_operator"
17909           [(and (match_operand:HI 2 "aligned_operand")
17910                 (match_operand:HI 3 "const_int_operand"))
17911            (const_int 0)]))]
17912   "! TARGET_PARTIAL_REG_STALL && reload_completed
17913    && ! TARGET_FAST_PREFIX
17914    && optimize_insn_for_speed_p ()
17915    /* Ensure that the operand will remain sign-extended immediate.  */
17916    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17917   [(set (match_dup 0)
17918         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17919                          (const_int 0)]))]
17921   operands[3]
17922     = gen_int_mode (INTVAL (operands[3])
17923                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17924   operands[2] = gen_lowpart (SImode, operands[2]);
17927 (define_split
17928   [(set (match_operand 0 "register_operand")
17929         (neg (match_operand 1 "register_operand")))
17930    (clobber (reg:CC FLAGS_REG))]
17931   "! TARGET_PARTIAL_REG_STALL && reload_completed
17932    && (GET_MODE (operands[0]) == HImode
17933        || (GET_MODE (operands[0]) == QImode
17934            && (TARGET_PROMOTE_QImode
17935                || optimize_insn_for_size_p ())))"
17936   [(parallel [(set (match_dup 0)
17937                    (neg:SI (match_dup 1)))
17938               (clobber (reg:CC FLAGS_REG))])]
17940   operands[0] = gen_lowpart (SImode, operands[0]);
17941   operands[1] = gen_lowpart (SImode, operands[1]);
17944 ;; Do not split instructions with mask regs.
17945 (define_split
17946   [(set (match_operand 0 "general_reg_operand")
17947         (not (match_operand 1 "general_reg_operand")))]
17948   "! TARGET_PARTIAL_REG_STALL && reload_completed
17949    && (GET_MODE (operands[0]) == HImode
17950        || (GET_MODE (operands[0]) == QImode
17951            && (TARGET_PROMOTE_QImode
17952                || optimize_insn_for_size_p ())))"
17953   [(set (match_dup 0)
17954         (not:SI (match_dup 1)))]
17956   operands[0] = gen_lowpart (SImode, operands[0]);
17957   operands[1] = gen_lowpart (SImode, operands[1]);
17960 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17961 ;; transform a complex memory operation into two memory to register operations.
17963 ;; Don't push memory operands
17964 (define_peephole2
17965   [(set (match_operand:SWI 0 "push_operand")
17966         (match_operand:SWI 1 "memory_operand"))
17967    (match_scratch:SWI 2 "<r>")]
17968   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17969    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17970   [(set (match_dup 2) (match_dup 1))
17971    (set (match_dup 0) (match_dup 2))])
17973 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17974 ;; SImode pushes.
17975 (define_peephole2
17976   [(set (match_operand:SF 0 "push_operand")
17977         (match_operand:SF 1 "memory_operand"))
17978    (match_scratch:SF 2 "r")]
17979   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17980    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17981   [(set (match_dup 2) (match_dup 1))
17982    (set (match_dup 0) (match_dup 2))])
17984 ;; Don't move an immediate directly to memory when the instruction
17985 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17986 (define_peephole2
17987   [(match_scratch:SWI124 1 "<r>")
17988    (set (match_operand:SWI124 0 "memory_operand")
17989         (const_int 0))]
17990   "optimize_insn_for_speed_p ()
17991    && ((<MODE>mode == HImode
17992        && TARGET_LCP_STALL)
17993        || (!TARGET_USE_MOV0
17994           && TARGET_SPLIT_LONG_MOVES
17995           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17996    && peep2_regno_dead_p (0, FLAGS_REG)"
17997   [(parallel [(set (match_dup 2) (const_int 0))
17998               (clobber (reg:CC FLAGS_REG))])
17999    (set (match_dup 0) (match_dup 1))]
18000   "operands[2] = gen_lowpart (SImode, operands[1]);")
18002 (define_peephole2
18003   [(match_scratch:SWI124 2 "<r>")
18004    (set (match_operand:SWI124 0 "memory_operand")
18005         (match_operand:SWI124 1 "immediate_operand"))]
18006   "optimize_insn_for_speed_p ()
18007    && ((<MODE>mode == HImode
18008        && TARGET_LCP_STALL)
18009        || (TARGET_SPLIT_LONG_MOVES
18010           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18011   [(set (match_dup 2) (match_dup 1))
18012    (set (match_dup 0) (match_dup 2))])
18014 ;; Don't compare memory with zero, load and use a test instead.
18015 (define_peephole2
18016   [(set (match_operand 0 "flags_reg_operand")
18017         (match_operator 1 "compare_operator"
18018           [(match_operand:SI 2 "memory_operand")
18019            (const_int 0)]))
18020    (match_scratch:SI 3 "r")]
18021   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18022   [(set (match_dup 3) (match_dup 2))
18023    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18025 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18026 ;; Don't split NOTs with a displacement operand, because resulting XOR
18027 ;; will not be pairable anyway.
18029 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18030 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18031 ;; so this split helps here as well.
18033 ;; Note: Can't do this as a regular split because we can't get proper
18034 ;; lifetime information then.
18036 (define_peephole2
18037   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18038         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18039   "optimize_insn_for_speed_p ()
18040    && ((TARGET_NOT_UNPAIRABLE
18041         && (!MEM_P (operands[0])
18042             || !memory_displacement_operand (operands[0], <MODE>mode)))
18043        || (TARGET_NOT_VECTORMODE
18044            && long_memory_operand (operands[0], <MODE>mode)))
18045    && peep2_regno_dead_p (0, FLAGS_REG)"
18046   [(parallel [(set (match_dup 0)
18047                    (xor:SWI124 (match_dup 1) (const_int -1)))
18048               (clobber (reg:CC FLAGS_REG))])])
18050 ;; Non pairable "test imm, reg" instructions can be translated to
18051 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18052 ;; byte opcode instead of two, have a short form for byte operands),
18053 ;; so do it for other CPUs as well.  Given that the value was dead,
18054 ;; this should not create any new dependencies.  Pass on the sub-word
18055 ;; versions if we're concerned about partial register stalls.
18057 (define_peephole2
18058   [(set (match_operand 0 "flags_reg_operand")
18059         (match_operator 1 "compare_operator"
18060           [(and:SI (match_operand:SI 2 "register_operand")
18061                    (match_operand:SI 3 "immediate_operand"))
18062            (const_int 0)]))]
18063   "ix86_match_ccmode (insn, CCNOmode)
18064    && (REGNO (operands[2]) != AX_REG
18065        || satisfies_constraint_K (operands[3]))
18066    && peep2_reg_dead_p (1, operands[2])"
18067   [(parallel
18068      [(set (match_dup 0)
18069            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18070                             (const_int 0)]))
18071       (set (match_dup 2)
18072            (and:SI (match_dup 2) (match_dup 3)))])])
18074 ;; We don't need to handle HImode case, because it will be promoted to SImode
18075 ;; on ! TARGET_PARTIAL_REG_STALL
18077 (define_peephole2
18078   [(set (match_operand 0 "flags_reg_operand")
18079         (match_operator 1 "compare_operator"
18080           [(and:QI (match_operand:QI 2 "register_operand")
18081                    (match_operand:QI 3 "immediate_operand"))
18082            (const_int 0)]))]
18083   "! TARGET_PARTIAL_REG_STALL
18084    && ix86_match_ccmode (insn, CCNOmode)
18085    && REGNO (operands[2]) != AX_REG
18086    && peep2_reg_dead_p (1, operands[2])"
18087   [(parallel
18088      [(set (match_dup 0)
18089            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18090                             (const_int 0)]))
18091       (set (match_dup 2)
18092            (and:QI (match_dup 2) (match_dup 3)))])])
18094 (define_peephole2
18095   [(set (match_operand 0 "flags_reg_operand")
18096         (match_operator 1 "compare_operator"
18097           [(and:SI
18098              (zero_extract:SI
18099                (match_operand 2 "QIreg_operand")
18100                (const_int 8)
18101                (const_int 8))
18102              (match_operand 3 "const_int_operand"))
18103            (const_int 0)]))]
18104   "! TARGET_PARTIAL_REG_STALL
18105    && ix86_match_ccmode (insn, CCNOmode)
18106    && REGNO (operands[2]) != AX_REG
18107    && peep2_reg_dead_p (1, operands[2])"
18108   [(parallel [(set (match_dup 0)
18109                    (match_op_dup 1
18110                      [(and:SI
18111                         (zero_extract:SI
18112                           (match_dup 2)
18113                           (const_int 8)
18114                           (const_int 8))
18115                         (match_dup 3))
18116                       (const_int 0)]))
18117               (set (zero_extract:SI (match_dup 2)
18118                                     (const_int 8)
18119                                     (const_int 8))
18120                    (and:SI
18121                      (zero_extract:SI
18122                        (match_dup 2)
18123                        (const_int 8)
18124                        (const_int 8))
18125                      (match_dup 3)))])])
18127 ;; Don't do logical operations with memory inputs.
18128 (define_peephole2
18129   [(match_scratch:SWI 2 "<r>")
18130    (parallel [(set (match_operand:SWI 0 "register_operand")
18131                    (match_operator:SWI 3 "arith_or_logical_operator"
18132                      [(match_dup 0)
18133                       (match_operand:SWI 1 "memory_operand")]))
18134               (clobber (reg:CC FLAGS_REG))])]
18135   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18136   [(set (match_dup 2) (match_dup 1))
18137    (parallel [(set (match_dup 0)
18138                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18139               (clobber (reg:CC FLAGS_REG))])])
18141 (define_peephole2
18142   [(match_scratch:SWI 2 "<r>")
18143    (parallel [(set (match_operand:SWI 0 "register_operand")
18144                    (match_operator:SWI 3 "arith_or_logical_operator"
18145                      [(match_operand:SWI 1 "memory_operand")
18146                       (match_dup 0)]))
18147               (clobber (reg:CC FLAGS_REG))])]
18148   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18149   [(set (match_dup 2) (match_dup 1))
18150    (parallel [(set (match_dup 0)
18151                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18152               (clobber (reg:CC FLAGS_REG))])])
18154 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18155 ;; the memory address refers to the destination of the load!
18157 (define_peephole2
18158   [(set (match_operand:SWI 0 "general_reg_operand")
18159         (match_operand:SWI 1 "general_reg_operand"))
18160    (parallel [(set (match_dup 0)
18161                    (match_operator:SWI 3 "commutative_operator"
18162                      [(match_dup 0)
18163                       (match_operand:SWI 2 "memory_operand")]))
18164               (clobber (reg:CC FLAGS_REG))])]
18165   "REGNO (operands[0]) != REGNO (operands[1])
18166    && (<MODE>mode != QImode
18167        || any_QIreg_operand (operands[1], QImode))"
18168   [(set (match_dup 0) (match_dup 4))
18169    (parallel [(set (match_dup 0)
18170                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18171               (clobber (reg:CC FLAGS_REG))])]
18172   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18174 (define_peephole2
18175   [(set (match_operand 0 "mmx_reg_operand")
18176         (match_operand 1 "mmx_reg_operand"))
18177    (set (match_dup 0)
18178         (match_operator 3 "commutative_operator"
18179           [(match_dup 0)
18180            (match_operand 2 "memory_operand")]))]
18181   "REGNO (operands[0]) != REGNO (operands[1])"
18182   [(set (match_dup 0) (match_dup 2))
18183    (set (match_dup 0)
18184         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18186 (define_peephole2
18187   [(set (match_operand 0 "sse_reg_operand")
18188         (match_operand 1 "sse_reg_operand"))
18189    (set (match_dup 0)
18190         (match_operator 3 "commutative_operator"
18191           [(match_dup 0)
18192            (match_operand 2 "memory_operand")]))]
18193   "REGNO (operands[0]) != REGNO (operands[1])"
18194   [(set (match_dup 0) (match_dup 2))
18195    (set (match_dup 0)
18196         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18198 ; Don't do logical operations with memory outputs
18200 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18201 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18202 ; the same decoder scheduling characteristics as the original.
18204 (define_peephole2
18205   [(match_scratch:SWI 2 "<r>")
18206    (parallel [(set (match_operand:SWI 0 "memory_operand")
18207                    (match_operator:SWI 3 "arith_or_logical_operator"
18208                      [(match_dup 0)
18209                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18210               (clobber (reg:CC FLAGS_REG))])]
18211   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18212   [(set (match_dup 2) (match_dup 0))
18213    (parallel [(set (match_dup 2)
18214                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18215               (clobber (reg:CC FLAGS_REG))])
18216    (set (match_dup 0) (match_dup 2))])
18218 (define_peephole2
18219   [(match_scratch:SWI 2 "<r>")
18220    (parallel [(set (match_operand:SWI 0 "memory_operand")
18221                    (match_operator:SWI 3 "arith_or_logical_operator"
18222                      [(match_operand:SWI 1 "<nonmemory_operand>")
18223                       (match_dup 0)]))
18224               (clobber (reg:CC FLAGS_REG))])]
18225   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18226   [(set (match_dup 2) (match_dup 0))
18227    (parallel [(set (match_dup 2)
18228                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18229               (clobber (reg:CC FLAGS_REG))])
18230    (set (match_dup 0) (match_dup 2))])
18232 ;; Attempt to use arith or logical operations with memory outputs with
18233 ;; setting of flags.
18234 (define_peephole2
18235   [(set (match_operand:SWI 0 "register_operand")
18236         (match_operand:SWI 1 "memory_operand"))
18237    (parallel [(set (match_dup 0)
18238                    (match_operator:SWI 3 "plusminuslogic_operator"
18239                      [(match_dup 0)
18240                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18241               (clobber (reg:CC FLAGS_REG))])
18242    (set (match_dup 1) (match_dup 0))
18243    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18244   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18245    && peep2_reg_dead_p (4, operands[0])
18246    && !reg_overlap_mentioned_p (operands[0], operands[1])
18247    && !reg_overlap_mentioned_p (operands[0], operands[2])
18248    && (<MODE>mode != QImode
18249        || immediate_operand (operands[2], QImode)
18250        || any_QIreg_operand (operands[2], QImode))
18251    && ix86_match_ccmode (peep2_next_insn (3),
18252                          (GET_CODE (operands[3]) == PLUS
18253                           || GET_CODE (operands[3]) == MINUS)
18254                          ? CCGOCmode : CCNOmode)"
18255   [(parallel [(set (match_dup 4) (match_dup 6))
18256               (set (match_dup 1) (match_dup 5))])]
18258   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18259   operands[5]
18260     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18261                       copy_rtx (operands[1]),
18262                       operands[2]);
18263   operands[6]
18264     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18265                        copy_rtx (operands[5]),
18266                        const0_rtx);
18269 ;; Likewise for instances where we have a lea pattern.
18270 (define_peephole2
18271   [(set (match_operand:SWI 0 "register_operand")
18272         (match_operand:SWI 1 "memory_operand"))
18273    (set (match_operand:SWI 3 "register_operand")
18274         (plus:SWI (match_dup 0)
18275                   (match_operand:SWI 2 "<nonmemory_operand>")))
18276    (set (match_dup 1) (match_dup 3))
18277    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18278   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18279    && peep2_reg_dead_p (4, operands[3])
18280    && (rtx_equal_p (operands[0], operands[3])
18281        || peep2_reg_dead_p (2, operands[0]))
18282    && !reg_overlap_mentioned_p (operands[0], operands[1])
18283    && !reg_overlap_mentioned_p (operands[3], operands[1])
18284    && !reg_overlap_mentioned_p (operands[0], operands[2])
18285    && (<MODE>mode != QImode
18286        || immediate_operand (operands[2], QImode)
18287        || any_QIreg_operand (operands[2], QImode))
18288    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18289   [(parallel [(set (match_dup 4) (match_dup 6))
18290               (set (match_dup 1) (match_dup 5))])]
18292   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18293   operands[5]
18294     = gen_rtx_PLUS (<MODE>mode,
18295                     copy_rtx (operands[1]),
18296                     operands[2]);
18297   operands[6]
18298     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18299                        copy_rtx (operands[5]),
18300                        const0_rtx);
18303 (define_peephole2
18304   [(parallel [(set (match_operand:SWI 0 "register_operand")
18305                    (match_operator:SWI 2 "plusminuslogic_operator"
18306                      [(match_dup 0)
18307                       (match_operand:SWI 1 "memory_operand")]))
18308               (clobber (reg:CC FLAGS_REG))])
18309    (set (match_dup 1) (match_dup 0))
18310    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18311   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18312    && GET_CODE (operands[2]) != MINUS
18313    && peep2_reg_dead_p (3, operands[0])
18314    && !reg_overlap_mentioned_p (operands[0], operands[1])
18315    && ix86_match_ccmode (peep2_next_insn (2),
18316                          GET_CODE (operands[2]) == PLUS
18317                          ? CCGOCmode : CCNOmode)"
18318   [(parallel [(set (match_dup 3) (match_dup 5))
18319               (set (match_dup 1) (match_dup 4))])]
18321   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18322   operands[4]
18323     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18324                       copy_rtx (operands[1]),
18325                       operands[0]);
18326   operands[5]
18327     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18328                        copy_rtx (operands[4]),
18329                        const0_rtx);
18332 (define_peephole2
18333   [(set (match_operand:SWI12 0 "register_operand")
18334         (match_operand:SWI12 1 "memory_operand"))
18335    (parallel [(set (match_operand:SI 4 "register_operand")
18336                    (match_operator:SI 3 "plusminuslogic_operator"
18337                      [(match_dup 4)
18338                       (match_operand:SI 2 "nonmemory_operand")]))
18339               (clobber (reg:CC FLAGS_REG))])
18340    (set (match_dup 1) (match_dup 0))
18341    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18342   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18343    && REGNO (operands[0]) == REGNO (operands[4])
18344    && peep2_reg_dead_p (4, operands[0])
18345    && (<MODE>mode != QImode
18346        || immediate_operand (operands[2], SImode)
18347        || any_QIreg_operand (operands[2], SImode))
18348    && !reg_overlap_mentioned_p (operands[0], operands[1])
18349    && !reg_overlap_mentioned_p (operands[0], operands[2])
18350    && ix86_match_ccmode (peep2_next_insn (3),
18351                          (GET_CODE (operands[3]) == PLUS
18352                           || GET_CODE (operands[3]) == MINUS)
18353                          ? CCGOCmode : CCNOmode)"
18354   [(parallel [(set (match_dup 4) (match_dup 6))
18355               (set (match_dup 1) (match_dup 5))])]
18357   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18358   operands[5]
18359     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18360                       copy_rtx (operands[1]),
18361                       gen_lowpart (<MODE>mode, operands[2]));
18362   operands[6]
18363     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18364                        copy_rtx (operands[5]),
18365                        const0_rtx);
18368 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18369 (define_peephole2
18370   [(set (match_operand 0 "general_reg_operand")
18371         (match_operand 1 "const0_operand"))]
18372   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18373    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18374    && peep2_regno_dead_p (0, FLAGS_REG)"
18375   [(parallel [(set (match_dup 0) (const_int 0))
18376               (clobber (reg:CC FLAGS_REG))])]
18377   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18379 (define_peephole2
18380   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18381         (const_int 0))]
18382   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18383    && peep2_regno_dead_p (0, FLAGS_REG)"
18384   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18385               (clobber (reg:CC FLAGS_REG))])])
18387 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18388 (define_peephole2
18389   [(set (match_operand:SWI248 0 "general_reg_operand")
18390         (const_int -1))]
18391   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18392    && peep2_regno_dead_p (0, FLAGS_REG)"
18393   [(parallel [(set (match_dup 0) (const_int -1))
18394               (clobber (reg:CC FLAGS_REG))])]
18396   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18397     operands[0] = gen_lowpart (SImode, operands[0]);
18400 ;; Attempt to convert simple lea to add/shift.
18401 ;; These can be created by move expanders.
18402 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18403 ;; relevant lea instructions were already split.
18405 (define_peephole2
18406   [(set (match_operand:SWI48 0 "register_operand")
18407         (plus:SWI48 (match_dup 0)
18408                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18409   "!TARGET_OPT_AGU
18410    && peep2_regno_dead_p (0, FLAGS_REG)"
18411   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18412               (clobber (reg:CC FLAGS_REG))])])
18414 (define_peephole2
18415   [(set (match_operand:SWI48 0 "register_operand")
18416         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18417                     (match_dup 0)))]
18418   "!TARGET_OPT_AGU
18419    && peep2_regno_dead_p (0, FLAGS_REG)"
18420   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18421               (clobber (reg:CC FLAGS_REG))])])
18423 (define_peephole2
18424   [(set (match_operand:DI 0 "register_operand")
18425         (zero_extend:DI
18426           (plus:SI (match_operand:SI 1 "register_operand")
18427                    (match_operand:SI 2 "nonmemory_operand"))))]
18428   "TARGET_64BIT && !TARGET_OPT_AGU
18429    && REGNO (operands[0]) == REGNO (operands[1])
18430    && peep2_regno_dead_p (0, FLAGS_REG)"
18431   [(parallel [(set (match_dup 0)
18432                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18433               (clobber (reg:CC FLAGS_REG))])])
18435 (define_peephole2
18436   [(set (match_operand:DI 0 "register_operand")
18437         (zero_extend:DI
18438           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18439                    (match_operand:SI 2 "register_operand"))))]
18440   "TARGET_64BIT && !TARGET_OPT_AGU
18441    && REGNO (operands[0]) == REGNO (operands[2])
18442    && peep2_regno_dead_p (0, FLAGS_REG)"
18443   [(parallel [(set (match_dup 0)
18444                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18445               (clobber (reg:CC FLAGS_REG))])])
18447 (define_peephole2
18448   [(set (match_operand:SWI48 0 "register_operand")
18449         (mult:SWI48 (match_dup 0)
18450                     (match_operand:SWI48 1 "const_int_operand")))]
18451   "pow2p_hwi (INTVAL (operands[1]))
18452    && peep2_regno_dead_p (0, FLAGS_REG)"
18453   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18454               (clobber (reg:CC FLAGS_REG))])]
18455   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18457 (define_peephole2
18458   [(set (match_operand:DI 0 "register_operand")
18459         (zero_extend:DI
18460           (mult:SI (match_operand:SI 1 "register_operand")
18461                    (match_operand:SI 2 "const_int_operand"))))]
18462   "TARGET_64BIT
18463    && pow2p_hwi (INTVAL (operands[2]))
18464    && REGNO (operands[0]) == REGNO (operands[1])
18465    && peep2_regno_dead_p (0, FLAGS_REG)"
18466   [(parallel [(set (match_dup 0)
18467                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18468               (clobber (reg:CC FLAGS_REG))])]
18469   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18471 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18472 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18473 ;; On many CPUs it is also faster, since special hardware to avoid esp
18474 ;; dependencies is present.
18476 ;; While some of these conversions may be done using splitters, we use
18477 ;; peepholes in order to allow combine_stack_adjustments pass to see
18478 ;; nonobfuscated RTL.
18480 ;; Convert prologue esp subtractions to push.
18481 ;; We need register to push.  In order to keep verify_flow_info happy we have
18482 ;; two choices
18483 ;; - use scratch and clobber it in order to avoid dependencies
18484 ;; - use already live register
18485 ;; We can't use the second way right now, since there is no reliable way how to
18486 ;; verify that given register is live.  First choice will also most likely in
18487 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18488 ;; call clobbered registers are dead.  We may want to use base pointer as an
18489 ;; alternative when no register is available later.
18491 (define_peephole2
18492   [(match_scratch:W 1 "r")
18493    (parallel [(set (reg:P SP_REG)
18494                    (plus:P (reg:P SP_REG)
18495                            (match_operand:P 0 "const_int_operand")))
18496               (clobber (reg:CC FLAGS_REG))
18497               (clobber (mem:BLK (scratch)))])]
18498   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18499    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18500    && !ix86_using_red_zone ()"
18501   [(clobber (match_dup 1))
18502    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18503               (clobber (mem:BLK (scratch)))])])
18505 (define_peephole2
18506   [(match_scratch:W 1 "r")
18507    (parallel [(set (reg:P SP_REG)
18508                    (plus:P (reg:P SP_REG)
18509                            (match_operand:P 0 "const_int_operand")))
18510               (clobber (reg:CC FLAGS_REG))
18511               (clobber (mem:BLK (scratch)))])]
18512   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18513    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18514    && !ix86_using_red_zone ()"
18515   [(clobber (match_dup 1))
18516    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18517    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18518               (clobber (mem:BLK (scratch)))])])
18520 ;; Convert esp subtractions to push.
18521 (define_peephole2
18522   [(match_scratch:W 1 "r")
18523    (parallel [(set (reg:P SP_REG)
18524                    (plus:P (reg:P SP_REG)
18525                            (match_operand:P 0 "const_int_operand")))
18526               (clobber (reg:CC FLAGS_REG))])]
18527   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18528    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18529    && !ix86_using_red_zone ()"
18530   [(clobber (match_dup 1))
18531    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18533 (define_peephole2
18534   [(match_scratch:W 1 "r")
18535    (parallel [(set (reg:P SP_REG)
18536                    (plus:P (reg:P SP_REG)
18537                            (match_operand:P 0 "const_int_operand")))
18538               (clobber (reg:CC FLAGS_REG))])]
18539   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18540    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18541    && !ix86_using_red_zone ()"
18542   [(clobber (match_dup 1))
18543    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18544    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18546 ;; Convert epilogue deallocator to pop.
18547 (define_peephole2
18548   [(match_scratch:W 1 "r")
18549    (parallel [(set (reg:P SP_REG)
18550                    (plus:P (reg:P SP_REG)
18551                            (match_operand:P 0 "const_int_operand")))
18552               (clobber (reg:CC FLAGS_REG))
18553               (clobber (mem:BLK (scratch)))])]
18554   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18555    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18556   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18557               (clobber (mem:BLK (scratch)))])])
18559 ;; Two pops case is tricky, since pop causes dependency
18560 ;; on destination register.  We use two registers if available.
18561 (define_peephole2
18562   [(match_scratch:W 1 "r")
18563    (match_scratch:W 2 "r")
18564    (parallel [(set (reg:P SP_REG)
18565                    (plus:P (reg:P SP_REG)
18566                            (match_operand:P 0 "const_int_operand")))
18567               (clobber (reg:CC FLAGS_REG))
18568               (clobber (mem:BLK (scratch)))])]
18569   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18570    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18571   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18572               (clobber (mem:BLK (scratch)))])
18573    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18575 (define_peephole2
18576   [(match_scratch:W 1 "r")
18577    (parallel [(set (reg:P SP_REG)
18578                    (plus:P (reg:P SP_REG)
18579                            (match_operand:P 0 "const_int_operand")))
18580               (clobber (reg:CC FLAGS_REG))
18581               (clobber (mem:BLK (scratch)))])]
18582   "optimize_insn_for_size_p ()
18583    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18584   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18585               (clobber (mem:BLK (scratch)))])
18586    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18588 ;; Convert esp additions to pop.
18589 (define_peephole2
18590   [(match_scratch:W 1 "r")
18591    (parallel [(set (reg:P SP_REG)
18592                    (plus:P (reg:P SP_REG)
18593                            (match_operand:P 0 "const_int_operand")))
18594               (clobber (reg:CC FLAGS_REG))])]
18595   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18596   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18598 ;; Two pops case is tricky, since pop causes dependency
18599 ;; on destination register.  We use two registers if available.
18600 (define_peephole2
18601   [(match_scratch:W 1 "r")
18602    (match_scratch:W 2 "r")
18603    (parallel [(set (reg:P SP_REG)
18604                    (plus:P (reg:P SP_REG)
18605                            (match_operand:P 0 "const_int_operand")))
18606               (clobber (reg:CC FLAGS_REG))])]
18607   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18608   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18609    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18611 (define_peephole2
18612   [(match_scratch:W 1 "r")
18613    (parallel [(set (reg:P SP_REG)
18614                    (plus:P (reg:P SP_REG)
18615                            (match_operand:P 0 "const_int_operand")))
18616               (clobber (reg:CC FLAGS_REG))])]
18617   "optimize_insn_for_size_p ()
18618    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18619   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18620    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18622 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18623 ;; required and register dies.  Similarly for 128 to -128.
18624 (define_peephole2
18625   [(set (match_operand 0 "flags_reg_operand")
18626         (match_operator 1 "compare_operator"
18627           [(match_operand 2 "register_operand")
18628            (match_operand 3 "const_int_operand")]))]
18629   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18630      && incdec_operand (operands[3], GET_MODE (operands[3])))
18631     || (!TARGET_FUSE_CMP_AND_BRANCH
18632         && INTVAL (operands[3]) == 128))
18633    && ix86_match_ccmode (insn, CCGCmode)
18634    && peep2_reg_dead_p (1, operands[2])"
18635   [(parallel [(set (match_dup 0)
18636                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18637               (clobber (match_dup 2))])])
18639 ;; Convert imul by three, five and nine into lea
18640 (define_peephole2
18641   [(parallel
18642     [(set (match_operand:SWI48 0 "register_operand")
18643           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18644                       (match_operand:SWI48 2 "const359_operand")))
18645      (clobber (reg:CC FLAGS_REG))])]
18646   "!TARGET_PARTIAL_REG_STALL
18647    || <MODE>mode == SImode
18648    || optimize_function_for_size_p (cfun)"
18649   [(set (match_dup 0)
18650         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18651                     (match_dup 1)))]
18652   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18654 (define_peephole2
18655   [(parallel
18656     [(set (match_operand:SWI48 0 "register_operand")
18657           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18658                       (match_operand:SWI48 2 "const359_operand")))
18659      (clobber (reg:CC FLAGS_REG))])]
18660   "optimize_insn_for_speed_p ()
18661    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18662   [(set (match_dup 0) (match_dup 1))
18663    (set (match_dup 0)
18664         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18665                     (match_dup 0)))]
18666   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18668 ;; imul $32bit_imm, mem, reg is vector decoded, while
18669 ;; imul $32bit_imm, reg, reg is direct decoded.
18670 (define_peephole2
18671   [(match_scratch:SWI48 3 "r")
18672    (parallel [(set (match_operand:SWI48 0 "register_operand")
18673                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18674                                (match_operand:SWI48 2 "immediate_operand")))
18675               (clobber (reg:CC FLAGS_REG))])]
18676   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18677    && !satisfies_constraint_K (operands[2])"
18678   [(set (match_dup 3) (match_dup 1))
18679    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18680               (clobber (reg:CC FLAGS_REG))])])
18682 (define_peephole2
18683   [(match_scratch:SI 3 "r")
18684    (parallel [(set (match_operand:DI 0 "register_operand")
18685                    (zero_extend:DI
18686                      (mult:SI (match_operand:SI 1 "memory_operand")
18687                               (match_operand:SI 2 "immediate_operand"))))
18688               (clobber (reg:CC FLAGS_REG))])]
18689   "TARGET_64BIT
18690    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18691    && !satisfies_constraint_K (operands[2])"
18692   [(set (match_dup 3) (match_dup 1))
18693    (parallel [(set (match_dup 0)
18694                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18695               (clobber (reg:CC FLAGS_REG))])])
18697 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18698 ;; Convert it into imul reg, reg
18699 ;; It would be better to force assembler to encode instruction using long
18700 ;; immediate, but there is apparently no way to do so.
18701 (define_peephole2
18702   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18703                    (mult:SWI248
18704                     (match_operand:SWI248 1 "nonimmediate_operand")
18705                     (match_operand:SWI248 2 "const_int_operand")))
18706               (clobber (reg:CC FLAGS_REG))])
18707    (match_scratch:SWI248 3 "r")]
18708   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18709    && satisfies_constraint_K (operands[2])"
18710   [(set (match_dup 3) (match_dup 2))
18711    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18712               (clobber (reg:CC FLAGS_REG))])]
18714   if (!rtx_equal_p (operands[0], operands[1]))
18715     emit_move_insn (operands[0], operands[1]);
18718 ;; After splitting up read-modify operations, array accesses with memory
18719 ;; operands might end up in form:
18720 ;;  sall    $2, %eax
18721 ;;  movl    4(%esp), %edx
18722 ;;  addl    %edx, %eax
18723 ;; instead of pre-splitting:
18724 ;;  sall    $2, %eax
18725 ;;  addl    4(%esp), %eax
18726 ;; Turn it into:
18727 ;;  movl    4(%esp), %edx
18728 ;;  leal    (%edx,%eax,4), %eax
18730 (define_peephole2
18731   [(match_scratch:W 5 "r")
18732    (parallel [(set (match_operand 0 "register_operand")
18733                    (ashift (match_operand 1 "register_operand")
18734                            (match_operand 2 "const_int_operand")))
18735                (clobber (reg:CC FLAGS_REG))])
18736    (parallel [(set (match_operand 3 "register_operand")
18737                    (plus (match_dup 0)
18738                          (match_operand 4 "x86_64_general_operand")))
18739                    (clobber (reg:CC FLAGS_REG))])]
18740   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18741    /* Validate MODE for lea.  */
18742    && ((!TARGET_PARTIAL_REG_STALL
18743         && (GET_MODE (operands[0]) == QImode
18744             || GET_MODE (operands[0]) == HImode))
18745        || GET_MODE (operands[0]) == SImode
18746        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18747    && (rtx_equal_p (operands[0], operands[3])
18748        || peep2_reg_dead_p (2, operands[0]))
18749    /* We reorder load and the shift.  */
18750    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18751   [(set (match_dup 5) (match_dup 4))
18752    (set (match_dup 0) (match_dup 1))]
18754   machine_mode op1mode = GET_MODE (operands[1]);
18755   machine_mode mode = op1mode == DImode ? DImode : SImode;
18756   int scale = 1 << INTVAL (operands[2]);
18757   rtx index = gen_lowpart (word_mode, operands[1]);
18758   rtx base = gen_lowpart (word_mode, operands[5]);
18759   rtx dest = gen_lowpart (mode, operands[3]);
18761   operands[1] = gen_rtx_PLUS (word_mode, base,
18762                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18763   if (mode != word_mode)
18764     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18766   operands[5] = base;
18767   if (op1mode != word_mode)
18768     operands[5] = gen_lowpart (op1mode, operands[5]);
18770   operands[0] = dest;
18773 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18774 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18775 ;; caught for use by garbage collectors and the like.  Using an insn that
18776 ;; maps to SIGILL makes it more likely the program will rightfully die.
18777 ;; Keeping with tradition, "6" is in honor of #UD.
18778 (define_insn "trap"
18779   [(trap_if (const_int 1) (const_int 6))]
18780   ""
18782 #ifdef HAVE_AS_IX86_UD2
18783   return "ud2";
18784 #else
18785   return ASM_SHORT "0x0b0f";
18786 #endif
18788   [(set_attr "length" "2")])
18790 (define_expand "prefetch"
18791   [(prefetch (match_operand 0 "address_operand")
18792              (match_operand:SI 1 "const_int_operand")
18793              (match_operand:SI 2 "const_int_operand"))]
18794   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18796   bool write = INTVAL (operands[1]) != 0;
18797   int locality = INTVAL (operands[2]);
18799   gcc_assert (IN_RANGE (locality, 0, 3));
18801   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18802      supported by SSE counterpart (non-SSE2 athlon machines) or the
18803      SSE prefetch is not available (K6 machines).  Otherwise use SSE
18804      prefetch as it allows specifying of locality.  */
18806   if (write)
18807     {
18808       if (TARGET_PREFETCHWT1)
18809         operands[2] = GEN_INT (MAX (locality, 2)); 
18810       else if (TARGET_PRFCHW)
18811         operands[2] = GEN_INT (3);
18812       else if (TARGET_3DNOW && !TARGET_SSE2)
18813         operands[2] = GEN_INT (3);
18814       else if (TARGET_PREFETCH_SSE)
18815         operands[1] = const0_rtx;
18816       else
18817         {
18818           gcc_assert (TARGET_3DNOW);
18819           operands[2] = GEN_INT (3);
18820         }
18821     }
18822   else
18823     {
18824       if (TARGET_PREFETCH_SSE)
18825         ;
18826       else
18827         {
18828           gcc_assert (TARGET_3DNOW);
18829           operands[2] = GEN_INT (3);
18830         }
18831     }
18834 (define_insn "*prefetch_sse"
18835   [(prefetch (match_operand 0 "address_operand" "p")
18836              (const_int 0)
18837              (match_operand:SI 1 "const_int_operand"))]
18838   "TARGET_PREFETCH_SSE"
18840   static const char * const patterns[4] = {
18841    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18842   };
18844   int locality = INTVAL (operands[1]);
18845   gcc_assert (IN_RANGE (locality, 0, 3));
18847   return patterns[locality];
18849   [(set_attr "type" "sse")
18850    (set_attr "atom_sse_attr" "prefetch")
18851    (set (attr "length_address")
18852         (symbol_ref "memory_address_length (operands[0], false)"))
18853    (set_attr "memory" "none")])
18855 (define_insn "*prefetch_3dnow"
18856   [(prefetch (match_operand 0 "address_operand" "p")
18857              (match_operand:SI 1 "const_int_operand" "n")
18858              (const_int 3))]
18859   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18861   if (INTVAL (operands[1]) == 0)
18862     return "prefetch\t%a0";
18863   else
18864     return "prefetchw\t%a0";
18866   [(set_attr "type" "mmx")
18867    (set (attr "length_address")
18868         (symbol_ref "memory_address_length (operands[0], false)"))
18869    (set_attr "memory" "none")])
18871 (define_insn "*prefetch_prefetchwt1"
18872   [(prefetch (match_operand 0 "address_operand" "p")
18873              (const_int 1)
18874              (const_int 2))]
18875   "TARGET_PREFETCHWT1"
18876   "prefetchwt1\t%a0";
18877   [(set_attr "type" "sse")
18878    (set (attr "length_address")
18879         (symbol_ref "memory_address_length (operands[0], false)"))
18880    (set_attr "memory" "none")])
18882 (define_expand "stack_protect_set"
18883   [(match_operand 0 "memory_operand")
18884    (match_operand 1 "memory_operand")]
18885   "TARGET_SSP_TLS_GUARD"
18887   rtx (*insn)(rtx, rtx);
18889 #ifdef TARGET_THREAD_SSP_OFFSET
18890   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18891   insn = (TARGET_LP64
18892           ? gen_stack_tls_protect_set_di
18893           : gen_stack_tls_protect_set_si);
18894 #else
18895   insn = (TARGET_LP64
18896           ? gen_stack_protect_set_di
18897           : gen_stack_protect_set_si);
18898 #endif
18900   emit_insn (insn (operands[0], operands[1]));
18901   DONE;
18904 (define_insn "stack_protect_set_<mode>"
18905   [(set (match_operand:PTR 0 "memory_operand" "=m")
18906         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18907                     UNSPEC_SP_SET))
18908    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18909    (clobber (reg:CC FLAGS_REG))]
18910   "TARGET_SSP_TLS_GUARD"
18911   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18912   [(set_attr "type" "multi")])
18914 (define_insn "stack_tls_protect_set_<mode>"
18915   [(set (match_operand:PTR 0 "memory_operand" "=m")
18916         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18917                     UNSPEC_SP_TLS_SET))
18918    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18919    (clobber (reg:CC FLAGS_REG))]
18920   ""
18921   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18922   [(set_attr "type" "multi")])
18924 (define_expand "stack_protect_test"
18925   [(match_operand 0 "memory_operand")
18926    (match_operand 1 "memory_operand")
18927    (match_operand 2)]
18928   "TARGET_SSP_TLS_GUARD"
18930   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18932   rtx (*insn)(rtx, rtx, rtx);
18934 #ifdef TARGET_THREAD_SSP_OFFSET
18935   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18936   insn = (TARGET_LP64
18937           ? gen_stack_tls_protect_test_di
18938           : gen_stack_tls_protect_test_si);
18939 #else
18940   insn = (TARGET_LP64
18941           ? gen_stack_protect_test_di
18942           : gen_stack_protect_test_si);
18943 #endif
18945   emit_insn (insn (flags, operands[0], operands[1]));
18947   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18948                                   flags, const0_rtx, operands[2]));
18949   DONE;
18952 (define_insn "stack_protect_test_<mode>"
18953   [(set (match_operand:CCZ 0 "flags_reg_operand")
18954         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18955                      (match_operand:PTR 2 "memory_operand" "m")]
18956                     UNSPEC_SP_TEST))
18957    (clobber (match_scratch:PTR 3 "=&r"))]
18958   "TARGET_SSP_TLS_GUARD"
18959   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18960   [(set_attr "type" "multi")])
18962 (define_insn "stack_tls_protect_test_<mode>"
18963   [(set (match_operand:CCZ 0 "flags_reg_operand")
18964         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18965                      (match_operand:PTR 2 "const_int_operand" "i")]
18966                     UNSPEC_SP_TLS_TEST))
18967    (clobber (match_scratch:PTR 3 "=r"))]
18968   ""
18969   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18970   [(set_attr "type" "multi")])
18972 (define_insn "sse4_2_crc32<mode>"
18973   [(set (match_operand:SI 0 "register_operand" "=r")
18974         (unspec:SI
18975           [(match_operand:SI 1 "register_operand" "0")
18976            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18977           UNSPEC_CRC32))]
18978   "TARGET_SSE4_2 || TARGET_CRC32"
18979   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18980   [(set_attr "type" "sselog1")
18981    (set_attr "prefix_rep" "1")
18982    (set_attr "prefix_extra" "1")
18983    (set (attr "prefix_data16")
18984      (if_then_else (match_operand:HI 2)
18985        (const_string "1")
18986        (const_string "*")))
18987    (set (attr "prefix_rex")
18988      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18989        (const_string "1")
18990        (const_string "*")))
18991    (set_attr "mode" "SI")])
18993 (define_insn "sse4_2_crc32di"
18994   [(set (match_operand:DI 0 "register_operand" "=r")
18995         (unspec:DI
18996           [(match_operand:DI 1 "register_operand" "0")
18997            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18998           UNSPEC_CRC32))]
18999   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19000   "crc32{q}\t{%2, %0|%0, %2}"
19001   [(set_attr "type" "sselog1")
19002    (set_attr "prefix_rep" "1")
19003    (set_attr "prefix_extra" "1")
19004    (set_attr "mode" "DI")])
19006 (define_insn "rdpmc"
19007   [(set (match_operand:DI 0 "register_operand" "=A")
19008         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19009                             UNSPECV_RDPMC))]
19010   "!TARGET_64BIT"
19011   "rdpmc"
19012   [(set_attr "type" "other")
19013    (set_attr "length" "2")])
19015 (define_insn "rdpmc_rex64"
19016   [(set (match_operand:DI 0 "register_operand" "=a")
19017         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19018                             UNSPECV_RDPMC))
19019    (set (match_operand:DI 1 "register_operand" "=d")
19020         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19021   "TARGET_64BIT"
19022   "rdpmc"
19023   [(set_attr "type" "other")
19024    (set_attr "length" "2")])
19026 (define_insn "rdtsc"
19027   [(set (match_operand:DI 0 "register_operand" "=A")
19028         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19029   "!TARGET_64BIT"
19030   "rdtsc"
19031   [(set_attr "type" "other")
19032    (set_attr "length" "2")])
19034 (define_insn "rdtsc_rex64"
19035   [(set (match_operand:DI 0 "register_operand" "=a")
19036         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19037    (set (match_operand:DI 1 "register_operand" "=d")
19038         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19039   "TARGET_64BIT"
19040   "rdtsc"
19041   [(set_attr "type" "other")
19042    (set_attr "length" "2")])
19044 (define_insn "rdtscp"
19045   [(set (match_operand:DI 0 "register_operand" "=A")
19046         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19047    (set (match_operand:SI 1 "register_operand" "=c")
19048         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19049   "!TARGET_64BIT"
19050   "rdtscp"
19051   [(set_attr "type" "other")
19052    (set_attr "length" "3")])
19054 (define_insn "rdtscp_rex64"
19055   [(set (match_operand:DI 0 "register_operand" "=a")
19056         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19057    (set (match_operand:DI 1 "register_operand" "=d")
19058         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19059    (set (match_operand:SI 2 "register_operand" "=c")
19060         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19061   "TARGET_64BIT"
19062   "rdtscp"
19063   [(set_attr "type" "other")
19064    (set_attr "length" "3")])
19066 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19068 ;; FXSR, XSAVE and XSAVEOPT instructions
19070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19072 (define_insn "fxsave"
19073   [(set (match_operand:BLK 0 "memory_operand" "=m")
19074         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19075   "TARGET_FXSR"
19076   "fxsave\t%0"
19077   [(set_attr "type" "other")
19078    (set_attr "memory" "store")
19079    (set (attr "length")
19080         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19082 (define_insn "fxsave64"
19083   [(set (match_operand:BLK 0 "memory_operand" "=m")
19084         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19085   "TARGET_64BIT && TARGET_FXSR"
19086   "fxsave64\t%0"
19087   [(set_attr "type" "other")
19088    (set_attr "memory" "store")
19089    (set (attr "length")
19090         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19092 (define_insn "fxrstor"
19093   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19094                     UNSPECV_FXRSTOR)]
19095   "TARGET_FXSR"
19096   "fxrstor\t%0"
19097   [(set_attr "type" "other")
19098    (set_attr "memory" "load")
19099    (set (attr "length")
19100         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19102 (define_insn "fxrstor64"
19103   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19104                     UNSPECV_FXRSTOR64)]
19105   "TARGET_64BIT && TARGET_FXSR"
19106   "fxrstor64\t%0"
19107   [(set_attr "type" "other")
19108    (set_attr "memory" "load")
19109    (set (attr "length")
19110         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19112 (define_int_iterator ANY_XSAVE
19113         [UNSPECV_XSAVE
19114          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19115          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19116          (UNSPECV_XSAVES "TARGET_XSAVES")])
19118 (define_int_iterator ANY_XSAVE64
19119         [UNSPECV_XSAVE64
19120          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19121          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19122          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19124 (define_int_attr xsave
19125         [(UNSPECV_XSAVE "xsave")
19126          (UNSPECV_XSAVE64 "xsave64")
19127          (UNSPECV_XSAVEOPT "xsaveopt")
19128          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19129          (UNSPECV_XSAVEC "xsavec")
19130          (UNSPECV_XSAVEC64 "xsavec64")
19131          (UNSPECV_XSAVES "xsaves")
19132          (UNSPECV_XSAVES64 "xsaves64")])
19134 (define_int_iterator ANY_XRSTOR
19135         [UNSPECV_XRSTOR
19136          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19138 (define_int_iterator ANY_XRSTOR64
19139         [UNSPECV_XRSTOR64
19140          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19142 (define_int_attr xrstor
19143         [(UNSPECV_XRSTOR "xrstor")
19144          (UNSPECV_XRSTOR64 "xrstor")
19145          (UNSPECV_XRSTORS "xrstors")
19146          (UNSPECV_XRSTORS64 "xrstors")])
19148 (define_insn "<xsave>"
19149   [(set (match_operand:BLK 0 "memory_operand" "=m")
19150         (unspec_volatile:BLK
19151          [(match_operand:DI 1 "register_operand" "A")]
19152          ANY_XSAVE))]
19153   "!TARGET_64BIT && TARGET_XSAVE"
19154   "<xsave>\t%0"
19155   [(set_attr "type" "other")
19156    (set_attr "memory" "store")
19157    (set (attr "length")
19158         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19160 (define_insn "<xsave>_rex64"
19161   [(set (match_operand:BLK 0 "memory_operand" "=m")
19162         (unspec_volatile:BLK
19163          [(match_operand:SI 1 "register_operand" "a")
19164           (match_operand:SI 2 "register_operand" "d")]
19165          ANY_XSAVE))]
19166   "TARGET_64BIT && TARGET_XSAVE"
19167   "<xsave>\t%0"
19168   [(set_attr "type" "other")
19169    (set_attr "memory" "store")
19170    (set (attr "length")
19171         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19173 (define_insn "<xsave>"
19174   [(set (match_operand:BLK 0 "memory_operand" "=m")
19175         (unspec_volatile:BLK
19176          [(match_operand:SI 1 "register_operand" "a")
19177           (match_operand:SI 2 "register_operand" "d")]
19178          ANY_XSAVE64))]
19179   "TARGET_64BIT && TARGET_XSAVE"
19180   "<xsave>\t%0"
19181   [(set_attr "type" "other")
19182    (set_attr "memory" "store")
19183    (set (attr "length")
19184         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19186 (define_insn "<xrstor>"
19187    [(unspec_volatile:BLK
19188      [(match_operand:BLK 0 "memory_operand" "m")
19189       (match_operand:DI 1 "register_operand" "A")]
19190      ANY_XRSTOR)]
19191   "!TARGET_64BIT && TARGET_XSAVE"
19192   "<xrstor>\t%0"
19193   [(set_attr "type" "other")
19194    (set_attr "memory" "load")
19195    (set (attr "length")
19196         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19198 (define_insn "<xrstor>_rex64"
19199    [(unspec_volatile:BLK
19200      [(match_operand:BLK 0 "memory_operand" "m")
19201       (match_operand:SI 1 "register_operand" "a")
19202       (match_operand:SI 2 "register_operand" "d")]
19203      ANY_XRSTOR)]
19204   "TARGET_64BIT && TARGET_XSAVE"
19205   "<xrstor>\t%0"
19206   [(set_attr "type" "other")
19207    (set_attr "memory" "load")
19208    (set (attr "length")
19209         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19211 (define_insn "<xrstor>64"
19212    [(unspec_volatile:BLK
19213      [(match_operand:BLK 0 "memory_operand" "m")
19214       (match_operand:SI 1 "register_operand" "a")
19215       (match_operand:SI 2 "register_operand" "d")]
19216      ANY_XRSTOR64)]
19217   "TARGET_64BIT && TARGET_XSAVE"
19218   "<xrstor>64\t%0"
19219   [(set_attr "type" "other")
19220    (set_attr "memory" "load")
19221    (set (attr "length")
19222         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19224 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19226 ;; Floating-point instructions for atomic compound assignments
19228 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19230 ; Clobber all floating-point registers on environment save and restore
19231 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19232 (define_insn "fnstenv"
19233   [(set (match_operand:BLK 0 "memory_operand" "=m")
19234         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19235    (clobber (reg:HI FPCR_REG))
19236    (clobber (reg:XF ST0_REG))
19237    (clobber (reg:XF ST1_REG))
19238    (clobber (reg:XF ST2_REG))
19239    (clobber (reg:XF ST3_REG))
19240    (clobber (reg:XF ST4_REG))
19241    (clobber (reg:XF ST5_REG))
19242    (clobber (reg:XF ST6_REG))
19243    (clobber (reg:XF ST7_REG))]
19244   "TARGET_80387"
19245   "fnstenv\t%0"
19246   [(set_attr "type" "other")
19247    (set_attr "memory" "store")
19248    (set (attr "length")
19249         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19251 (define_insn "fldenv"
19252   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19253                     UNSPECV_FLDENV)
19254    (clobber (reg:CCFP FPSR_REG))
19255    (clobber (reg:HI FPCR_REG))
19256    (clobber (reg:XF ST0_REG))
19257    (clobber (reg:XF ST1_REG))
19258    (clobber (reg:XF ST2_REG))
19259    (clobber (reg:XF ST3_REG))
19260    (clobber (reg:XF ST4_REG))
19261    (clobber (reg:XF ST5_REG))
19262    (clobber (reg:XF ST6_REG))
19263    (clobber (reg:XF ST7_REG))]
19264   "TARGET_80387"
19265   "fldenv\t%0"
19266   [(set_attr "type" "other")
19267    (set_attr "memory" "load")
19268    (set (attr "length")
19269         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19271 (define_insn "fnstsw"
19272   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19273         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19274   "TARGET_80387"
19275   "fnstsw\t%0"
19276   [(set_attr "type" "other,other")
19277    (set_attr "memory" "none,store")
19278    (set (attr "length")
19279         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19281 (define_insn "fnclex"
19282   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19283   "TARGET_80387"
19284   "fnclex"
19285   [(set_attr "type" "other")
19286    (set_attr "memory" "none")
19287    (set_attr "length" "2")])
19289 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19291 ;; LWP instructions
19293 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19295 (define_expand "lwp_llwpcb"
19296   [(unspec_volatile [(match_operand 0 "register_operand")]
19297                     UNSPECV_LLWP_INTRINSIC)]
19298   "TARGET_LWP")
19300 (define_insn "*lwp_llwpcb<mode>1"
19301   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19302                     UNSPECV_LLWP_INTRINSIC)]
19303   "TARGET_LWP"
19304   "llwpcb\t%0"
19305   [(set_attr "type" "lwp")
19306    (set_attr "mode" "<MODE>")
19307    (set_attr "length" "5")])
19309 (define_expand "lwp_slwpcb"
19310   [(set (match_operand 0 "register_operand")
19311         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19312   "TARGET_LWP"
19314   rtx (*insn)(rtx);
19316   insn = (Pmode == DImode
19317           ? gen_lwp_slwpcbdi
19318           : gen_lwp_slwpcbsi);
19320   emit_insn (insn (operands[0]));
19321   DONE;
19324 (define_insn "lwp_slwpcb<mode>"
19325   [(set (match_operand:P 0 "register_operand" "=r")
19326         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19327   "TARGET_LWP"
19328   "slwpcb\t%0"
19329   [(set_attr "type" "lwp")
19330    (set_attr "mode" "<MODE>")
19331    (set_attr "length" "5")])
19333 (define_expand "lwp_lwpval<mode>3"
19334   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19335                      (match_operand:SI 2 "nonimmediate_operand")
19336                      (match_operand:SI 3 "const_int_operand")]
19337                     UNSPECV_LWPVAL_INTRINSIC)]
19338   "TARGET_LWP"
19339   ;; Avoid unused variable warning.
19340   "(void) operands[0];")
19342 (define_insn "*lwp_lwpval<mode>3_1"
19343   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19344                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19345                      (match_operand:SI 2 "const_int_operand" "i")]
19346                     UNSPECV_LWPVAL_INTRINSIC)]
19347   "TARGET_LWP"
19348   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19349   [(set_attr "type" "lwp")
19350    (set_attr "mode" "<MODE>")
19351    (set (attr "length")
19352         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19354 (define_expand "lwp_lwpins<mode>3"
19355   [(set (reg:CCC FLAGS_REG)
19356         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19357                               (match_operand:SI 2 "nonimmediate_operand")
19358                               (match_operand:SI 3 "const_int_operand")]
19359                              UNSPECV_LWPINS_INTRINSIC))
19360    (set (match_operand:QI 0 "nonimmediate_operand")
19361         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19362   "TARGET_LWP")
19364 (define_insn "*lwp_lwpins<mode>3_1"
19365   [(set (reg:CCC FLAGS_REG)
19366         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19367                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19368                               (match_operand:SI 2 "const_int_operand" "i")]
19369                              UNSPECV_LWPINS_INTRINSIC))]
19370   "TARGET_LWP"
19371   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19372   [(set_attr "type" "lwp")
19373    (set_attr "mode" "<MODE>")
19374    (set (attr "length")
19375         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19377 (define_int_iterator RDFSGSBASE
19378         [UNSPECV_RDFSBASE
19379          UNSPECV_RDGSBASE])
19381 (define_int_iterator WRFSGSBASE
19382         [UNSPECV_WRFSBASE
19383          UNSPECV_WRGSBASE])
19385 (define_int_attr fsgs
19386         [(UNSPECV_RDFSBASE "fs")
19387          (UNSPECV_RDGSBASE "gs")
19388          (UNSPECV_WRFSBASE "fs")
19389          (UNSPECV_WRGSBASE "gs")])
19391 (define_insn "rd<fsgs>base<mode>"
19392   [(set (match_operand:SWI48 0 "register_operand" "=r")
19393         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19394   "TARGET_64BIT && TARGET_FSGSBASE"
19395   "rd<fsgs>base\t%0"
19396   [(set_attr "type" "other")
19397    (set_attr "prefix_extra" "2")])
19399 (define_insn "wr<fsgs>base<mode>"
19400   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19401                     WRFSGSBASE)]
19402   "TARGET_64BIT && TARGET_FSGSBASE"
19403   "wr<fsgs>base\t%0"
19404   [(set_attr "type" "other")
19405    (set_attr "prefix_extra" "2")])
19407 (define_insn "rdrand<mode>_1"
19408   [(set (match_operand:SWI248 0 "register_operand" "=r")
19409         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19410    (set (reg:CCC FLAGS_REG)
19411         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19412   "TARGET_RDRND"
19413   "rdrand\t%0"
19414   [(set_attr "type" "other")
19415    (set_attr "prefix_extra" "1")])
19417 (define_insn "rdseed<mode>_1"
19418   [(set (match_operand:SWI248 0 "register_operand" "=r")
19419         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19420    (set (reg:CCC FLAGS_REG)
19421         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19422   "TARGET_RDSEED"
19423   "rdseed\t%0"
19424   [(set_attr "type" "other")
19425    (set_attr "prefix_extra" "1")])
19427 (define_expand "pause"
19428   [(set (match_dup 0)
19429         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19430   ""
19432   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19433   MEM_VOLATILE_P (operands[0]) = 1;
19436 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19437 ;; They have the same encoding.
19438 (define_insn "*pause"
19439   [(set (match_operand:BLK 0)
19440         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19441   ""
19442   "rep%; nop"
19443   [(set_attr "length" "2")
19444    (set_attr "memory" "unknown")])
19446 (define_expand "xbegin"
19447   [(set (match_operand:SI 0 "register_operand")
19448         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19449   "TARGET_RTM"
19451   rtx_code_label *label = gen_label_rtx ();
19453   /* xbegin is emitted as jump_insn, so reload won't be able
19454      to reload its operand.  Force the value into AX hard register.  */
19455   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19456   emit_move_insn (ax_reg, constm1_rtx);
19458   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19460   emit_label (label);
19461   LABEL_NUSES (label) = 1;
19463   emit_move_insn (operands[0], ax_reg);
19465   DONE;
19468 (define_insn "xbegin_1"
19469   [(set (pc)
19470         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19471                           (const_int 0))
19472                       (label_ref (match_operand 1))
19473                       (pc)))
19474    (set (match_operand:SI 0 "register_operand" "+a")
19475         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19476   "TARGET_RTM"
19477   "xbegin\t%l1"
19478   [(set_attr "type" "other")
19479    (set_attr "length" "6")])
19481 (define_insn "xend"
19482   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19483   "TARGET_RTM"
19484   "xend"
19485   [(set_attr "type" "other")
19486    (set_attr "length" "3")])
19488 (define_insn "xabort"
19489   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19490                     UNSPECV_XABORT)]
19491   "TARGET_RTM"
19492   "xabort\t%0"
19493   [(set_attr "type" "other")
19494    (set_attr "length" "3")])
19496 (define_expand "xtest"
19497   [(set (match_operand:QI 0 "register_operand")
19498         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19499   "TARGET_RTM"
19501   emit_insn (gen_xtest_1 ());
19503   ix86_expand_setcc (operands[0], NE,
19504                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19505   DONE;
19508 (define_insn "xtest_1"
19509   [(set (reg:CCZ FLAGS_REG)
19510         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19511   "TARGET_RTM"
19512   "xtest"
19513   [(set_attr "type" "other")
19514    (set_attr "length" "3")])
19516 (define_insn "clwb"
19517   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19518                    UNSPECV_CLWB)]
19519   "TARGET_CLWB"
19520   "clwb\t%a0"
19521   [(set_attr "type" "sse")
19522    (set_attr "atom_sse_attr" "fence")
19523    (set_attr "memory" "unknown")])
19525 (define_insn "clflushopt"
19526   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19527                    UNSPECV_CLFLUSHOPT)]
19528   "TARGET_CLFLUSHOPT"
19529   "clflushopt\t%a0"
19530   [(set_attr "type" "sse")
19531    (set_attr "atom_sse_attr" "fence")
19532    (set_attr "memory" "unknown")])
19534 ;; MONITORX and MWAITX
19535 (define_insn "mwaitx"
19536   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19537                      (match_operand:SI 1 "register_operand" "a")
19538                      (match_operand:SI 2 "register_operand" "b")]
19539                    UNSPECV_MWAITX)]
19540   "TARGET_MWAITX"
19541 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19542 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19543 ;; we only need to set up 32bit registers.
19544   "mwaitx"
19545   [(set_attr "length" "3")])
19547 (define_insn "monitorx_<mode>"
19548   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19549                      (match_operand:SI 1 "register_operand" "c")
19550                      (match_operand:SI 2 "register_operand" "d")]
19551                    UNSPECV_MONITORX)]
19552   "TARGET_MWAITX"
19553 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19554 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19555 ;; zero extended to 64bit, we only need to set up 32bit registers.
19556   "%^monitorx"
19557   [(set (attr "length")
19558      (symbol_ref ("(Pmode != word_mode) + 3")))])
19560 ;; CLZERO
19561 (define_insn "clzero_<mode>"
19562   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19563                    UNSPECV_CLZERO)]
19564   "TARGET_CLZERO"
19565   "clzero"
19566   [(set_attr "length" "3")
19567   (set_attr "memory" "unknown")])
19569 ;; MPX instructions
19571 (define_expand "<mode>_mk"
19572   [(set (match_operand:BND 0 "register_operand")
19573         (unspec:BND
19574           [(mem:<bnd_ptr>
19575            (match_par_dup 3
19576              [(match_operand:<bnd_ptr> 1 "register_operand")
19577               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19578           UNSPEC_BNDMK))]
19579   "TARGET_MPX"
19581   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19582                                                   operands[2]),
19583                                 UNSPEC_BNDMK_ADDR);
19586 (define_insn "*<mode>_mk"
19587   [(set (match_operand:BND 0 "register_operand" "=w")
19588         (unspec:BND
19589           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19590              [(unspec:<bnd_ptr>
19591                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19592                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19593                 UNSPEC_BNDMK_ADDR)])]
19594           UNSPEC_BNDMK))]
19595   "TARGET_MPX"
19596   "bndmk\t{%3, %0|%0, %3}"
19597   [(set_attr "type" "mpxmk")])
19599 (define_expand "mov<mode>"
19600   [(set (match_operand:BND 0 "general_operand")
19601         (match_operand:BND 1 "general_operand"))]
19602   "TARGET_MPX"
19603   "ix86_expand_move (<MODE>mode, operands); DONE;")
19605 (define_insn "*mov<mode>_internal_mpx"
19606   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19607         (match_operand:BND 1 "general_operand" "wm,w"))]
19608   "TARGET_MPX"
19609   "bndmov\t{%1, %0|%0, %1}"
19610   [(set_attr "type" "mpxmov")])
19612 (define_expand "<mode>_<bndcheck>"
19613   [(parallel
19614      [(unspec
19615         [(match_operand:BND 0 "register_operand")
19616          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19617       (set (match_dup 2)
19618            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19619   "TARGET_MPX"
19621   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19622   MEM_VOLATILE_P (operands[2]) = 1;
19625 (define_insn "*<mode>_<bndcheck>"
19626   [(unspec
19627      [(match_operand:BND 0 "register_operand" "w")
19628       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19629    (set (match_operand:BLK 2 "bnd_mem_operator")
19630         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19631   "TARGET_MPX"
19632   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19633   [(set_attr "type" "mpxchk")])
19635 (define_expand "<mode>_ldx"
19636   [(parallel
19637      [(set (match_operand:BND 0 "register_operand")
19638            (unspec:BND
19639              [(mem:<bnd_ptr>
19640                 (match_par_dup 3
19641                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19642                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
19643              UNSPEC_BNDLDX))
19644       (use (mem:BLK (match_dup 1)))])]
19645   "TARGET_MPX"
19647   /* Avoid registers which cannot be used as index.  */
19648   if (!index_register_operand (operands[2], Pmode))
19649     operands[2] = copy_addr_to_reg (operands[2]);
19651   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19652                                                   operands[2]),
19653                                 UNSPEC_BNDLDX_ADDR);
19656 (define_insn "*<mode>_ldx"
19657   [(set (match_operand:BND 0 "register_operand" "=w")
19658         (unspec:BND
19659           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19660              [(unspec:<bnd_ptr>
19661                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19662                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19663                 UNSPEC_BNDLDX_ADDR)])]
19664           UNSPEC_BNDLDX))
19665    (use (mem:BLK (match_dup 1)))]
19666   "TARGET_MPX"
19667   "bndldx\t{%3, %0|%0, %3}"
19668   [(set_attr "type" "mpxld")])
19670 (define_expand "<mode>_stx"
19671   [(parallel
19672      [(unspec
19673         [(mem:<bnd_ptr>
19674            (match_par_dup 3
19675              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19676               (match_operand:<bnd_ptr> 1 "register_operand")]))
19677          (match_operand:BND 2 "register_operand")]
19678         UNSPEC_BNDSTX)
19679       (set (match_dup 4)
19680            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19681   "TARGET_MPX"
19683   /* Avoid registers which cannot be used as index.  */
19684   if (!index_register_operand (operands[1], Pmode))
19685     operands[1] = copy_addr_to_reg (operands[1]);
19687   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19688                                                   operands[1]),
19689                                 UNSPEC_BNDLDX_ADDR);
19690   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19691   MEM_VOLATILE_P (operands[4]) = 1;
19694 (define_insn "*<mode>_stx"
19695   [(unspec
19696      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19697         [(unspec:<bnd_ptr>
19698            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19699             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19700            UNSPEC_BNDLDX_ADDR)])
19701          (match_operand:BND 2 "register_operand" "w")]
19702         UNSPEC_BNDSTX)
19703    (set (match_operand:BLK 4 "bnd_mem_operator")
19704         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19705   "TARGET_MPX"
19706   "bndstx\t{%2, %3|%3, %2}"
19707   [(set_attr "type" "mpxst")])
19709 (define_insn "move_size_reloc_<mode>"
19710   [(set (match_operand:SWI48 0 "register_operand" "=r")
19711         (unspec:SWI48
19712           [(match_operand:SWI48 1 "symbol_operand")]
19713         UNSPEC_SIZEOF))]
19714   "TARGET_MPX"
19716   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19717     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19718   else
19719     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19721   [(set_attr "type" "imov")
19722    (set_attr "mode" "<MODE>")])
19724 ;; RDPKRU and WRPKRU
19726 (define_expand "rdpkru"
19727   [(parallel
19728      [(set (match_operand:SI 0 "register_operand")
19729            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19730       (set (match_dup 2) (const_int 0))])]
19731   "TARGET_PKU"
19733   operands[1] = force_reg (SImode, const0_rtx);
19734   operands[2] = gen_reg_rtx (SImode);
19737 (define_insn "*rdpkru"
19738   [(set (match_operand:SI 0 "register_operand" "=a")
19739         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19740                             UNSPECV_PKU))
19741    (set (match_operand:SI 1 "register_operand" "=d")
19742         (const_int 0))]
19743   "TARGET_PKU"
19744   "rdpkru"
19745   [(set_attr "type" "other")])
19747 (define_expand "wrpkru"
19748   [(unspec_volatile:SI
19749      [(match_operand:SI 0 "register_operand")
19750       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19751   "TARGET_PKU"
19753   operands[1] = force_reg (SImode, const0_rtx);
19754   operands[2] = force_reg (SImode, const0_rtx);
19757 (define_insn "*wrpkru"
19758   [(unspec_volatile:SI
19759      [(match_operand:SI 0 "register_operand" "a")
19760       (match_operand:SI 1 "register_operand" "d")
19761       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19762   "TARGET_PKU"
19763   "wrpkru"
19764   [(set_attr "type" "other")])
19766 (include "mmx.md")
19767 (include "sse.md")
19768 (include "sync.md")