PR target/82628
[official-gcc.git] / gcc / config / i386 / i386.md
blob49ad0394fb57dde3c155f39ec7d408229f1350cf
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81   UNSPEC_SIZEOF
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_PROBE_STACK
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
115   UNSPEC_SBB
117   ;; For SSE/MMX support:
118   UNSPEC_FIX_NOTRUNC
119   UNSPEC_MASKMOV
120   UNSPEC_MOVMSK
121   UNSPEC_RCP
122   UNSPEC_RSQRT
123   UNSPEC_PSADBW
125   ;; Generic math support
126   UNSPEC_COPYSIGN
127   UNSPEC_IEEE_MIN       ; not commutative
128   UNSPEC_IEEE_MAX       ; not commutative
130   ;; x87 Floating point
131   UNSPEC_SIN
132   UNSPEC_COS
133   UNSPEC_FPATAN
134   UNSPEC_FYL2X
135   UNSPEC_FYL2XP1
136   UNSPEC_FRNDINT
137   UNSPEC_FIST
138   UNSPEC_F2XM1
139   UNSPEC_TAN
140   UNSPEC_FXAM
142   ;; x87 Rounding
143   UNSPEC_FRNDINT_FLOOR
144   UNSPEC_FRNDINT_CEIL
145   UNSPEC_FRNDINT_TRUNC
146   UNSPEC_FRNDINT_MASK_PM
147   UNSPEC_FIST_FLOOR
148   UNSPEC_FIST_CEIL
150   ;; x87 Double output FP
151   UNSPEC_SINCOS_COS
152   UNSPEC_SINCOS_SIN
153   UNSPEC_XTRACT_FRACT
154   UNSPEC_XTRACT_EXP
155   UNSPEC_FSCALE_FRACT
156   UNSPEC_FSCALE_EXP
157   UNSPEC_FPREM_F
158   UNSPEC_FPREM_U
159   UNSPEC_FPREM1_F
160   UNSPEC_FPREM1_U
162   UNSPEC_C2_FLAG
163   UNSPEC_FXAM_MEM
165   ;; SSP patterns
166   UNSPEC_SP_SET
167   UNSPEC_SP_TEST
169   ;; For ROUND support
170   UNSPEC_ROUND
172   ;; For CRC32 support
173   UNSPEC_CRC32
175   ;; For LZCNT suppoprt
176   UNSPEC_LZCNT
178   ;; For BMI support
179   UNSPEC_TZCNT
180   UNSPEC_BEXTR
182   ;; For BMI2 support
183   UNSPEC_PDEP
184   UNSPEC_PEXT
186   UNSPEC_BNDMK
187   UNSPEC_BNDMK_ADDR
188   UNSPEC_BNDSTX
189   UNSPEC_BNDLDX
190   UNSPEC_BNDLDX_ADDR
191   UNSPEC_BNDCL
192   UNSPEC_BNDCU
193   UNSPEC_BNDCN
194   UNSPEC_MPX_FENCE
196   ;; IRET support
197   UNSPEC_INTERRUPT_RETURN
200 (define_c_enum "unspecv" [
201   UNSPECV_UD2
202   UNSPECV_BLOCKAGE
203   UNSPECV_STACK_PROBE
204   UNSPECV_PROBE_STACK_RANGE
205   UNSPECV_ALIGN
206   UNSPECV_PROLOGUE_USE
207   UNSPECV_SPLIT_STACK_RETURN
208   UNSPECV_CLD
209   UNSPECV_NOPS
210   UNSPECV_RDTSC
211   UNSPECV_RDTSCP
212   UNSPECV_RDPMC
213   UNSPECV_LLWP_INTRINSIC
214   UNSPECV_SLWP_INTRINSIC
215   UNSPECV_LWPVAL_INTRINSIC
216   UNSPECV_LWPINS_INTRINSIC
217   UNSPECV_RDFSBASE
218   UNSPECV_RDGSBASE
219   UNSPECV_WRFSBASE
220   UNSPECV_WRGSBASE
221   UNSPECV_FXSAVE
222   UNSPECV_FXRSTOR
223   UNSPECV_FXSAVE64
224   UNSPECV_FXRSTOR64
225   UNSPECV_XSAVE
226   UNSPECV_XRSTOR
227   UNSPECV_XSAVE64
228   UNSPECV_XRSTOR64
229   UNSPECV_XSAVEOPT
230   UNSPECV_XSAVEOPT64
231   UNSPECV_XSAVES
232   UNSPECV_XRSTORS
233   UNSPECV_XSAVES64
234   UNSPECV_XRSTORS64
235   UNSPECV_XSAVEC
236   UNSPECV_XSAVEC64
237   UNSPECV_XGETBV
238   UNSPECV_XSETBV
240   ;; For atomic compound assignments.
241   UNSPECV_FNSTENV
242   UNSPECV_FLDENV
243   UNSPECV_FNSTSW
244   UNSPECV_FNCLEX
246   ;; For RDRAND support
247   UNSPECV_RDRAND
249   ;; For RDSEED support
250   UNSPECV_RDSEED
252   ;; For RTM support
253   UNSPECV_XBEGIN
254   UNSPECV_XEND
255   UNSPECV_XABORT
256   UNSPECV_XTEST
258   UNSPECV_NLGR
260   ;; For CLWB support
261   UNSPECV_CLWB
263   ;; For CLFLUSHOPT support
264   UNSPECV_CLFLUSHOPT
266   ;; For MONITORX and MWAITX support 
267   UNSPECV_MONITORX
268   UNSPECV_MWAITX
270   ;; For CLZERO support
271   UNSPECV_CLZERO
273   ;; For RDPKRU and WRPKRU support
274   UNSPECV_PKU
276   ;; For RDPID support
277   UNSPECV_RDPID
279   ;; For CET support
280   UNSPECV_NOP_ENDBR
281   UNSPECV_NOP_RDSSP
282   UNSPECV_INCSSP
283   UNSPECV_SAVEPREVSSP
284   UNSPECV_RSTORSSP
285   UNSPECV_WRSS
286   UNSPECV_WRUSS
287   UNSPECV_SETSSBSY
288   UNSPECV_CLRSSBSY
291 ;; Constants to represent rounding modes in the ROUND instruction
292 (define_constants
293   [(ROUND_FLOOR                 0x1)
294    (ROUND_CEIL                  0x2)
295    (ROUND_TRUNC                 0x3)
296    (ROUND_MXCSR                 0x4)
297    (ROUND_NO_EXC                0x8)
298   ])
300 ;; Constants to represent AVX512F embeded rounding
301 (define_constants
302   [(ROUND_NEAREST_INT                   0)
303    (ROUND_NEG_INF                       1)
304    (ROUND_POS_INF                       2)
305    (ROUND_ZERO                          3)
306    (NO_ROUND                            4)
307    (ROUND_SAE                           8)
308   ])
310 ;; Constants to represent pcomtrue/pcomfalse variants
311 (define_constants
312   [(PCOM_FALSE                  0)
313    (PCOM_TRUE                   1)
314    (COM_FALSE_S                 2)
315    (COM_FALSE_P                 3)
316    (COM_TRUE_S                  4)
317    (COM_TRUE_P                  5)
318   ])
320 ;; Constants used in the XOP pperm instruction
321 (define_constants
322   [(PPERM_SRC                   0x00)   /* copy source */
323    (PPERM_INVERT                0x20)   /* invert source */
324    (PPERM_REVERSE               0x40)   /* bit reverse source */
325    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
326    (PPERM_ZERO                  0x80)   /* all 0's */
327    (PPERM_ONES                  0xa0)   /* all 1's */
328    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
329    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
330    (PPERM_SRC1                  0x00)   /* use first source byte */
331    (PPERM_SRC2                  0x10)   /* use second source byte */
332    ])
334 ;; Registers by name.
335 (define_constants
336   [(AX_REG                       0)
337    (DX_REG                       1)
338    (CX_REG                       2)
339    (BX_REG                       3)
340    (SI_REG                       4)
341    (DI_REG                       5)
342    (BP_REG                       6)
343    (SP_REG                       7)
344    (ST0_REG                      8)
345    (ST1_REG                      9)
346    (ST2_REG                     10)
347    (ST3_REG                     11)
348    (ST4_REG                     12)
349    (ST5_REG                     13)
350    (ST6_REG                     14)
351    (ST7_REG                     15)
352    (ARGP_REG                    16)
353    (FLAGS_REG                   17)
354    (FPSR_REG                    18)
355    (FPCR_REG                    19)
356    (FRAME_REG                   20)
357    (XMM0_REG                    21)
358    (XMM1_REG                    22)
359    (XMM2_REG                    23)
360    (XMM3_REG                    24)
361    (XMM4_REG                    25)
362    (XMM5_REG                    26)
363    (XMM6_REG                    27)
364    (XMM7_REG                    28)
365    (MM0_REG                     29)
366    (MM1_REG                     30)
367    (MM2_REG                     31)
368    (MM3_REG                     32)
369    (MM4_REG                     33)
370    (MM5_REG                     34)
371    (MM6_REG                     35)
372    (MM7_REG                     36)
373    (R8_REG                      37)
374    (R9_REG                      38)
375    (R10_REG                     39)
376    (R11_REG                     40)
377    (R12_REG                     41)
378    (R13_REG                     42)
379    (R14_REG                     43)
380    (R15_REG                     44)
381    (XMM8_REG                    45)
382    (XMM9_REG                    46)
383    (XMM10_REG                   47)
384    (XMM11_REG                   48)
385    (XMM12_REG                   49)
386    (XMM13_REG                   50)
387    (XMM14_REG                   51)
388    (XMM15_REG                   52)
389    (XMM16_REG                   53)
390    (XMM17_REG                   54)
391    (XMM18_REG                   55)
392    (XMM19_REG                   56)
393    (XMM20_REG                   57)
394    (XMM21_REG                   58)
395    (XMM22_REG                   59)
396    (XMM23_REG                   60)
397    (XMM24_REG                   61)
398    (XMM25_REG                   62)
399    (XMM26_REG                   63)
400    (XMM27_REG                   64)
401    (XMM28_REG                   65)
402    (XMM29_REG                   66)
403    (XMM30_REG                   67)
404    (XMM31_REG                   68)
405    (MASK0_REG                   69)
406    (MASK1_REG                   70)
407    (MASK2_REG                   71)
408    (MASK3_REG                   72)
409    (MASK4_REG                   73)
410    (MASK5_REG                   74)
411    (MASK6_REG                   75)
412    (MASK7_REG                   76)
413    (BND0_REG                    77)
414    (BND1_REG                    78)
415    (BND2_REG                    79)
416    (BND3_REG                    80)
417    (FIRST_PSEUDO_REG            81)
418   ])
420 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
421 ;; from i386.c.
423 ;; In C guard expressions, put expressions which may be compile-time
424 ;; constants first.  This allows for better optimization.  For
425 ;; example, write "TARGET_64BIT && reload_completed", not
426 ;; "reload_completed && TARGET_64BIT".
429 ;; Processor type.
430 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
431                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
432                     bdver4,btver2,znver1"
433   (const (symbol_ref "ix86_schedule")))
435 ;; A basic instruction type.  Refinements due to arguments to be
436 ;; provided in other attributes.
437 (define_attr "type"
438   "other,multi,
439    alu,alu1,negnot,imov,imovx,lea,
440    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
441    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
442    push,pop,call,callv,leave,
443    str,bitmanip,
444    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
445    fxch,fistp,fisttp,frndint,
446    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
447    ssemul,sseimul,ssediv,sselog,sselog1,
448    sseishft,sseishft1,ssecmp,ssecomi,
449    ssecvt,ssecvt1,sseicvt,sseins,
450    sseshuf,sseshuf1,ssemuladd,sse4arg,
451    lwp,mskmov,msklog,
452    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
453    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
454   (const_string "other"))
456 ;; Main data type used by the insn
457 (define_attr "mode"
458   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
459   V2DF,V2SF,V1DF,V8DF"
460   (const_string "unknown"))
462 ;; The CPU unit operations uses.
463 (define_attr "unit" "integer,i387,sse,mmx,unknown"
464   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
465                           fxch,fistp,fisttp,frndint")
466            (const_string "i387")
467          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
468                           ssemul,sseimul,ssediv,sselog,sselog1,
469                           sseishft,sseishft1,ssecmp,ssecomi,
470                           ssecvt,ssecvt1,sseicvt,sseins,
471                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
472            (const_string "sse")
473          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
474            (const_string "mmx")
475          (eq_attr "type" "other")
476            (const_string "unknown")]
477          (const_string "integer")))
479 ;; The (bounding maximum) length of an instruction immediate.
480 (define_attr "length_immediate" ""
481   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
482                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
483                           mpxld,mpxst")
484            (const_int 0)
485          (eq_attr "unit" "i387,sse,mmx")
486            (const_int 0)
487          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
488                           rotate,rotatex,rotate1,imul,icmp,push,pop")
489            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
490          (eq_attr "type" "imov,test")
491            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
492          (eq_attr "type" "call")
493            (if_then_else (match_operand 0 "constant_call_address_operand")
494              (const_int 4)
495              (const_int 0))
496          (eq_attr "type" "callv")
497            (if_then_else (match_operand 1 "constant_call_address_operand")
498              (const_int 4)
499              (const_int 0))
500          ;; We don't know the size before shorten_branches.  Expect
501          ;; the instruction to fit for better scheduling.
502          (eq_attr "type" "ibr")
503            (const_int 1)
504          ]
505          (symbol_ref "/* Update immediate_length and other attributes! */
506                       gcc_unreachable (),1")))
508 ;; The (bounding maximum) length of an instruction address.
509 (define_attr "length_address" ""
510   (cond [(eq_attr "type" "str,other,multi,fxch")
511            (const_int 0)
512          (and (eq_attr "type" "call")
513               (match_operand 0 "constant_call_address_operand"))
514              (const_int 0)
515          (and (eq_attr "type" "callv")
516               (match_operand 1 "constant_call_address_operand"))
517              (const_int 0)
518          ]
519          (symbol_ref "ix86_attr_length_address_default (insn)")))
521 ;; Set when length prefix is used.
522 (define_attr "prefix_data16" ""
523   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
524            (const_int 0)
525          (eq_attr "mode" "HI")
526            (const_int 1)
527          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
528            (const_int 1)
529         ]
530         (const_int 0)))
532 ;; Set when string REP prefix is used.
533 (define_attr "prefix_rep" ""
534   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
535            (const_int 0)
536          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
537            (const_int 1)
538          (and (eq_attr "type" "ibr,call,callv")
539               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
540            (const_int 1)
541         ]
542         (const_int 0)))
544 ;; Set when 0f opcode prefix is used.
545 (define_attr "prefix_0f" ""
546   (if_then_else
547     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
548                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
549          (eq_attr "unit" "sse,mmx"))
550     (const_int 1)
551     (const_int 0)))
553 ;; Set when REX opcode prefix is used.
554 (define_attr "prefix_rex" ""
555   (cond [(not (match_test "TARGET_64BIT"))
556            (const_int 0)
557          (and (eq_attr "mode" "DI")
558               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
559                    (eq_attr "unit" "!mmx")))
560            (const_int 1)
561          (and (eq_attr "mode" "QI")
562               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
563            (const_int 1)
564          (match_test "x86_extended_reg_mentioned_p (insn)")
565            (const_int 1)
566          (and (eq_attr "type" "imovx")
567               (match_operand:QI 1 "ext_QIreg_operand"))
568            (const_int 1)
569         ]
570         (const_int 0)))
572 ;; There are also additional prefixes in 3DNOW, SSSE3.
573 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
574 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
575 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
576 (define_attr "prefix_extra" ""
577   (cond [(eq_attr "type" "ssemuladd,sse4arg")
578            (const_int 2)
579          (eq_attr "type" "sseiadd1,ssecvt1")
580            (const_int 1)
581         ]
582         (const_int 0)))
584 ;; Set when BND opcode prefix may be used.
585 (define_attr "maybe_prefix_bnd" "" (const_int 0))
587 ;; Prefix used: original, VEX or maybe VEX.
588 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
589   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
590            (const_string "vex")
591          (eq_attr "mode" "XI,V16SF,V8DF")
592            (const_string "evex")
593         ]
594         (const_string "orig")))
596 ;; VEX W bit is used.
597 (define_attr "prefix_vex_w" "" (const_int 0))
599 ;; The length of VEX prefix
600 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
601 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
602 ;; still prefix_0f 1, with prefix_extra 1.
603 (define_attr "length_vex" ""
604   (if_then_else (and (eq_attr "prefix_0f" "1")
605                      (eq_attr "prefix_extra" "0"))
606     (if_then_else (eq_attr "prefix_vex_w" "1")
607       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
608       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
609     (if_then_else (eq_attr "prefix_vex_w" "1")
610       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
611       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
613 ;; 4-bytes evex prefix and 1 byte opcode.
614 (define_attr "length_evex" "" (const_int 5))
616 ;; Set when modrm byte is used.
617 (define_attr "modrm" ""
618   (cond [(eq_attr "type" "str,leave")
619            (const_int 0)
620          (eq_attr "unit" "i387")
621            (const_int 0)
622          (and (eq_attr "type" "incdec")
623               (and (not (match_test "TARGET_64BIT"))
624                    (ior (match_operand:SI 1 "register_operand")
625                         (match_operand:HI 1 "register_operand"))))
626            (const_int 0)
627          (and (eq_attr "type" "push")
628               (not (match_operand 1 "memory_operand")))
629            (const_int 0)
630          (and (eq_attr "type" "pop")
631               (not (match_operand 0 "memory_operand")))
632            (const_int 0)
633          (and (eq_attr "type" "imov")
634               (and (not (eq_attr "mode" "DI"))
635                    (ior (and (match_operand 0 "register_operand")
636                              (match_operand 1 "immediate_operand"))
637                         (ior (and (match_operand 0 "ax_reg_operand")
638                                   (match_operand 1 "memory_displacement_only_operand"))
639                              (and (match_operand 0 "memory_displacement_only_operand")
640                                   (match_operand 1 "ax_reg_operand"))))))
641            (const_int 0)
642          (and (eq_attr "type" "call")
643               (match_operand 0 "constant_call_address_operand"))
644              (const_int 0)
645          (and (eq_attr "type" "callv")
646               (match_operand 1 "constant_call_address_operand"))
647              (const_int 0)
648          (and (eq_attr "type" "alu,alu1,icmp,test")
649               (match_operand 0 "ax_reg_operand"))
650              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
651          ]
652          (const_int 1)))
654 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
655   (cond [(eq_attr "modrm" "0")
656            (const_string "none")
657          (eq_attr "type" "alu,imul,ishift")
658            (const_string "op02")
659          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
660            (const_string "op01")
661          (eq_attr "type" "incdec")
662            (const_string "incdec")
663          (eq_attr "type" "push,pop")
664            (const_string "pushpop")]
665          (const_string "unknown")))
667 ;; The (bounding maximum) length of an instruction in bytes.
668 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
669 ;; Later we may want to split them and compute proper length as for
670 ;; other insns.
671 (define_attr "length" ""
672   (cond [(eq_attr "type" "other,multi,fistp,frndint")
673            (const_int 16)
674          (eq_attr "type" "fcmp")
675            (const_int 4)
676          (eq_attr "unit" "i387")
677            (plus (const_int 2)
678                  (plus (attr "prefix_data16")
679                        (attr "length_address")))
680          (ior (eq_attr "prefix" "evex")
681               (and (ior (eq_attr "prefix" "maybe_evex")
682                         (eq_attr "prefix" "maybe_vex"))
683                    (match_test "TARGET_AVX512F")))
684            (plus (attr "length_evex")
685                  (plus (attr "length_immediate")
686                        (plus (attr "modrm")
687                              (attr "length_address"))))
688          (ior (eq_attr "prefix" "vex")
689               (and (ior (eq_attr "prefix" "maybe_vex")
690                         (eq_attr "prefix" "maybe_evex"))
691                    (match_test "TARGET_AVX")))
692            (plus (attr "length_vex")
693                  (plus (attr "length_immediate")
694                        (plus (attr "modrm")
695                              (attr "length_address"))))]
696          (plus (plus (attr "modrm")
697                      (plus (attr "prefix_0f")
698                            (plus (attr "prefix_rex")
699                                  (plus (attr "prefix_extra")
700                                        (const_int 1)))))
701                (plus (attr "prefix_rep")
702                      (plus (attr "prefix_data16")
703                            (plus (attr "length_immediate")
704                                  (attr "length_address")))))))
706 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
707 ;; `store' if there is a simple memory reference therein, or `unknown'
708 ;; if the instruction is complex.
710 (define_attr "memory" "none,load,store,both,unknown"
711   (cond [(eq_attr "type" "other,multi,str,lwp")
712            (const_string "unknown")
713          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
714            (const_string "none")
715          (eq_attr "type" "fistp,leave")
716            (const_string "both")
717          (eq_attr "type" "frndint")
718            (const_string "load")
719          (eq_attr "type" "mpxld")
720            (const_string "load")
721          (eq_attr "type" "mpxst")
722            (const_string "store")
723          (eq_attr "type" "push")
724            (if_then_else (match_operand 1 "memory_operand")
725              (const_string "both")
726              (const_string "store"))
727          (eq_attr "type" "pop")
728            (if_then_else (match_operand 0 "memory_operand")
729              (const_string "both")
730              (const_string "load"))
731          (eq_attr "type" "setcc")
732            (if_then_else (match_operand 0 "memory_operand")
733              (const_string "store")
734              (const_string "none"))
735          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
736            (if_then_else (ior (match_operand 0 "memory_operand")
737                               (match_operand 1 "memory_operand"))
738              (const_string "load")
739              (const_string "none"))
740          (eq_attr "type" "ibr")
741            (if_then_else (match_operand 0 "memory_operand")
742              (const_string "load")
743              (const_string "none"))
744          (eq_attr "type" "call")
745            (if_then_else (match_operand 0 "constant_call_address_operand")
746              (const_string "none")
747              (const_string "load"))
748          (eq_attr "type" "callv")
749            (if_then_else (match_operand 1 "constant_call_address_operand")
750              (const_string "none")
751              (const_string "load"))
752          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
753               (match_operand 1 "memory_operand"))
754            (const_string "both")
755          (and (match_operand 0 "memory_operand")
756               (match_operand 1 "memory_operand"))
757            (const_string "both")
758          (match_operand 0 "memory_operand")
759            (const_string "store")
760          (match_operand 1 "memory_operand")
761            (const_string "load")
762          (and (eq_attr "type"
763                  "!alu1,negnot,ishift1,
764                    imov,imovx,icmp,test,bitmanip,
765                    fmov,fcmp,fsgn,
766                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
767                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
768                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
769               (match_operand 2 "memory_operand"))
770            (const_string "load")
771          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
772               (match_operand 3 "memory_operand"))
773            (const_string "load")
774         ]
775         (const_string "none")))
777 ;; Indicates if an instruction has both an immediate and a displacement.
779 (define_attr "imm_disp" "false,true,unknown"
780   (cond [(eq_attr "type" "other,multi")
781            (const_string "unknown")
782          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
783               (and (match_operand 0 "memory_displacement_operand")
784                    (match_operand 1 "immediate_operand")))
785            (const_string "true")
786          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
787               (and (match_operand 0 "memory_displacement_operand")
788                    (match_operand 2 "immediate_operand")))
789            (const_string "true")
790         ]
791         (const_string "false")))
793 ;; Indicates if an FP operation has an integer source.
795 (define_attr "fp_int_src" "false,true"
796   (const_string "false"))
798 ;; Defines rounding mode of an FP operation.
800 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
801   (const_string "any"))
803 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
804 (define_attr "use_carry" "0,1" (const_string "0"))
806 ;; Define attribute to indicate unaligned ssemov insns
807 (define_attr "movu" "0,1" (const_string "0"))
809 ;; Used to control the "enabled" attribute on a per-instruction basis.
810 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
811                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
812                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
813                     avx512bw,noavx512bw,avx512dq,noavx512dq,
814                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
815   (const_string "base"))
817 (define_attr "enabled" ""
818   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
819          (eq_attr "isa" "x64_sse4")
820            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
821          (eq_attr "isa" "x64_sse4_noavx")
822            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
823          (eq_attr "isa" "x64_avx")
824            (symbol_ref "TARGET_64BIT && TARGET_AVX")
825          (eq_attr "isa" "x64_avx512dq")
826            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
827          (eq_attr "isa" "x64_avx512bw")
828            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
829          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
830          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
831          (eq_attr "isa" "sse2_noavx")
832            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
833          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
834          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
835          (eq_attr "isa" "sse4_noavx")
836            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
837          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
838          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
839          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
840          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
841          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
842          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
843          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
844          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
845          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
846          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
847          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
848          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
849          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
850          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
851          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
852          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
853         ]
854         (const_int 1)))
856 (define_attr "preferred_for_size" "" (const_int 1))
857 (define_attr "preferred_for_speed" "" (const_int 1))
859 ;; Describe a user's asm statement.
860 (define_asm_attributes
861   [(set_attr "length" "128")
862    (set_attr "type" "multi")])
864 (define_code_iterator plusminus [plus minus])
866 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
868 (define_code_iterator multdiv [mult div])
870 ;; Base name for define_insn
871 (define_code_attr plusminus_insn
872   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
873    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
875 ;; Base name for insn mnemonic.
876 (define_code_attr plusminus_mnemonic
877   [(plus "add") (ss_plus "adds") (us_plus "addus")
878    (minus "sub") (ss_minus "subs") (us_minus "subus")])
879 (define_code_attr multdiv_mnemonic
880   [(mult "mul") (div "div")])
882 ;; Mark commutative operators as such in constraints.
883 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
884                         (minus "") (ss_minus "") (us_minus "")])
886 ;; Mapping of max and min
887 (define_code_iterator maxmin [smax smin umax umin])
889 ;; Mapping of signed max and min
890 (define_code_iterator smaxmin [smax smin])
892 ;; Mapping of unsigned max and min
893 (define_code_iterator umaxmin [umax umin])
895 ;; Base name for integer and FP insn mnemonic
896 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
897                               (umax "maxu") (umin "minu")])
898 (define_code_attr maxmin_float [(smax "max") (smin "min")])
900 (define_int_iterator IEEE_MAXMIN
901         [UNSPEC_IEEE_MAX
902          UNSPEC_IEEE_MIN])
904 (define_int_attr ieee_maxmin
905         [(UNSPEC_IEEE_MAX "max")
906          (UNSPEC_IEEE_MIN "min")])
908 ;; Mapping of logic operators
909 (define_code_iterator any_logic [and ior xor])
910 (define_code_iterator any_or [ior xor])
911 (define_code_iterator fpint_logic [and xor])
913 ;; Base name for insn mnemonic.
914 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
916 ;; Mapping of logic-shift operators
917 (define_code_iterator any_lshift [ashift lshiftrt])
919 ;; Mapping of shift-right operators
920 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
922 ;; Mapping of all shift operators
923 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
925 ;; Base name for define_insn
926 (define_code_attr shift_insn
927   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
929 ;; Base name for insn mnemonic.
930 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
931 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
933 ;; Mapping of rotate operators
934 (define_code_iterator any_rotate [rotate rotatert])
936 ;; Base name for define_insn
937 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
939 ;; Base name for insn mnemonic.
940 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
942 ;; Mapping of abs neg operators
943 (define_code_iterator absneg [abs neg])
945 ;; Base name for x87 insn mnemonic.
946 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
948 ;; Used in signed and unsigned widening multiplications.
949 (define_code_iterator any_extend [sign_extend zero_extend])
951 ;; Prefix for insn menmonic.
952 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
954 ;; Prefix for define_insn
955 (define_code_attr u [(sign_extend "") (zero_extend "u")])
956 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
957 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
959 ;; Used in signed and unsigned truncations.
960 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
961 ;; Instruction suffix for truncations.
962 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
964 ;; Used in signed and unsigned fix.
965 (define_code_iterator any_fix [fix unsigned_fix])
966 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
968 ;; Used in signed and unsigned float.
969 (define_code_iterator any_float [float unsigned_float])
970 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
972 ;; All integer modes.
973 (define_mode_iterator SWI1248x [QI HI SI DI])
975 ;; All integer modes without QImode.
976 (define_mode_iterator SWI248x [HI SI DI])
978 ;; All integer modes without QImode and HImode.
979 (define_mode_iterator SWI48x [SI DI])
981 ;; All integer modes without SImode and DImode.
982 (define_mode_iterator SWI12 [QI HI])
984 ;; All integer modes without DImode.
985 (define_mode_iterator SWI124 [QI HI SI])
987 ;; All integer modes without QImode and DImode.
988 (define_mode_iterator SWI24 [HI SI])
990 ;; Single word integer modes.
991 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
993 ;; Single word integer modes without QImode.
994 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
996 ;; Single word integer modes without QImode and HImode.
997 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
999 ;; All math-dependant single and double word integer modes.
1000 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1001                              (HI "TARGET_HIMODE_MATH")
1002                              SI DI (TI "TARGET_64BIT")])
1004 ;; Math-dependant single word integer modes.
1005 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1006                             (HI "TARGET_HIMODE_MATH")
1007                             SI (DI "TARGET_64BIT")])
1009 ;; Math-dependant integer modes without DImode.
1010 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1011                                (HI "TARGET_HIMODE_MATH")
1012                                SI])
1014 ;; Math-dependant integer modes with DImode.
1015 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1016                                  (HI "TARGET_HIMODE_MATH")
1017                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1019 ;; Math-dependant single word integer modes without QImode.
1020 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1021                                SI (DI "TARGET_64BIT")])
1023 ;; Double word integer modes.
1024 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1025                            (TI "TARGET_64BIT")])
1027 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1028 ;; compile time constant, it is faster to use <MODE_SIZE> than
1029 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1030 ;; command line options just use GET_MODE_SIZE macro.
1031 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1032                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1033                              (V16QI "16") (V32QI "32") (V64QI "64")
1034                              (V8HI "16") (V16HI "32") (V32HI "64")
1035                              (V4SI "16") (V8SI "32") (V16SI "64")
1036                              (V2DI "16") (V4DI "32") (V8DI "64")
1037                              (V1TI "16") (V2TI "32") (V4TI "64")
1038                              (V2DF "16") (V4DF "32") (V8DF "64")
1039                              (V4SF "16") (V8SF "32") (V16SF "64")])
1041 ;; Double word integer modes as mode attribute.
1042 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1043 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1045 ;; LEA mode corresponding to an integer mode
1046 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1048 ;; Half mode for double word integer modes.
1049 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1050                             (DI "TARGET_64BIT")])
1052 ;; Bound modes.
1053 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1054                            (BND64 "TARGET_LP64")])
1056 ;; Pointer mode corresponding to bound mode.
1057 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1059 ;; MPX check types
1060 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1062 ;; Check name
1063 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1064                            (UNSPEC_BNDCU "cu")
1065                            (UNSPEC_BNDCN "cn")])
1067 ;; Instruction suffix for integer modes.
1068 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1070 ;; Instruction suffix for masks.
1071 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1073 ;; Pointer size prefix for integer modes (Intel asm dialect)
1074 (define_mode_attr iptrsize [(QI "BYTE")
1075                             (HI "WORD")
1076                             (SI "DWORD")
1077                             (DI "QWORD")])
1079 ;; Register class for integer modes.
1080 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1082 ;; Immediate operand constraint for integer modes.
1083 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1085 ;; General operand constraint for word modes.
1086 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1088 ;; Immediate operand constraint for double integer modes.
1089 (define_mode_attr di [(SI "nF") (DI "Wd")])
1091 ;; Immediate operand constraint for shifts.
1092 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1094 ;; Print register name in the specified mode.
1095 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1097 ;; General operand predicate for integer modes.
1098 (define_mode_attr general_operand
1099         [(QI "general_operand")
1100          (HI "general_operand")
1101          (SI "x86_64_general_operand")
1102          (DI "x86_64_general_operand")
1103          (TI "x86_64_general_operand")])
1105 ;; General operand predicate for integer modes, where for TImode
1106 ;; we need both words of the operand to be general operands.
1107 (define_mode_attr general_hilo_operand
1108         [(QI "general_operand")
1109          (HI "general_operand")
1110          (SI "x86_64_general_operand")
1111          (DI "x86_64_general_operand")
1112          (TI "x86_64_hilo_general_operand")])
1114 ;; General sign extend operand predicate for integer modes,
1115 ;; which disallows VOIDmode operands and thus it is suitable
1116 ;; for use inside sign_extend.
1117 (define_mode_attr general_sext_operand
1118         [(QI "sext_operand")
1119          (HI "sext_operand")
1120          (SI "x86_64_sext_operand")
1121          (DI "x86_64_sext_operand")])
1123 ;; General sign/zero extend operand predicate for integer modes.
1124 (define_mode_attr general_szext_operand
1125         [(QI "general_operand")
1126          (HI "general_operand")
1127          (SI "x86_64_szext_general_operand")
1128          (DI "x86_64_szext_general_operand")])
1130 ;; Immediate operand predicate for integer modes.
1131 (define_mode_attr immediate_operand
1132         [(QI "immediate_operand")
1133          (HI "immediate_operand")
1134          (SI "x86_64_immediate_operand")
1135          (DI "x86_64_immediate_operand")])
1137 ;; Nonmemory operand predicate for integer modes.
1138 (define_mode_attr nonmemory_operand
1139         [(QI "nonmemory_operand")
1140          (HI "nonmemory_operand")
1141          (SI "x86_64_nonmemory_operand")
1142          (DI "x86_64_nonmemory_operand")])
1144 ;; Operand predicate for shifts.
1145 (define_mode_attr shift_operand
1146         [(QI "nonimmediate_operand")
1147          (HI "nonimmediate_operand")
1148          (SI "nonimmediate_operand")
1149          (DI "shiftdi_operand")
1150          (TI "register_operand")])
1152 ;; Operand predicate for shift argument.
1153 (define_mode_attr shift_immediate_operand
1154         [(QI "const_1_to_31_operand")
1155          (HI "const_1_to_31_operand")
1156          (SI "const_1_to_31_operand")
1157          (DI "const_1_to_63_operand")])
1159 ;; Input operand predicate for arithmetic left shifts.
1160 (define_mode_attr ashl_input_operand
1161         [(QI "nonimmediate_operand")
1162          (HI "nonimmediate_operand")
1163          (SI "nonimmediate_operand")
1164          (DI "ashldi_input_operand")
1165          (TI "reg_or_pm1_operand")])
1167 ;; SSE and x87 SFmode and DFmode floating point modes
1168 (define_mode_iterator MODEF [SF DF])
1170 ;; All x87 floating point modes
1171 (define_mode_iterator X87MODEF [SF DF XF])
1173 ;; SSE instruction suffix for various modes
1174 (define_mode_attr ssemodesuffix
1175   [(SF "ss") (DF "sd")
1176    (V16SF "ps") (V8DF "pd")
1177    (V8SF "ps") (V4DF "pd")
1178    (V4SF "ps") (V2DF "pd")
1179    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1180    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1181    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1183 ;; SSE vector suffix for floating point modes
1184 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1186 ;; SSE vector mode corresponding to a scalar mode
1187 (define_mode_attr ssevecmode
1188   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1189 (define_mode_attr ssevecmodelower
1190   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1192 ;; AVX512F vector mode corresponding to a scalar mode
1193 (define_mode_attr avx512fvecmode
1194   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1196 ;; Instruction suffix for REX 64bit operators.
1197 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1199 ;; This mode iterator allows :P to be used for patterns that operate on
1200 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1201 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1203 ;; This mode iterator allows :W to be used for patterns that operate on
1204 ;; word_mode sized quantities.
1205 (define_mode_iterator W
1206   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1208 ;; This mode iterator allows :PTR to be used for patterns that operate on
1209 ;; ptr_mode sized quantities.
1210 (define_mode_iterator PTR
1211   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1213 ;; Scheduling descriptions
1215 (include "pentium.md")
1216 (include "ppro.md")
1217 (include "k6.md")
1218 (include "athlon.md")
1219 (include "bdver1.md")
1220 (include "bdver3.md")
1221 (include "btver2.md")
1222 (include "znver1.md")
1223 (include "geode.md")
1224 (include "atom.md")
1225 (include "slm.md")
1226 (include "core2.md")
1227 (include "haswell.md")
1230 ;; Operand and operator predicates and constraints
1232 (include "predicates.md")
1233 (include "constraints.md")
1236 ;; Compare and branch/compare and store instructions.
1238 (define_expand "cbranch<mode>4"
1239   [(set (reg:CC FLAGS_REG)
1240         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1241                     (match_operand:SDWIM 2 "<general_operand>")))
1242    (set (pc) (if_then_else
1243                (match_operator 0 "ordered_comparison_operator"
1244                 [(reg:CC FLAGS_REG) (const_int 0)])
1245                (label_ref (match_operand 3))
1246                (pc)))]
1247   ""
1249   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1250     operands[1] = force_reg (<MODE>mode, operands[1]);
1251   ix86_expand_branch (GET_CODE (operands[0]),
1252                       operands[1], operands[2], operands[3]);
1253   DONE;
1256 (define_expand "cstore<mode>4"
1257   [(set (reg:CC FLAGS_REG)
1258         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1259                     (match_operand:SWIM 3 "<general_operand>")))
1260    (set (match_operand:QI 0 "register_operand")
1261         (match_operator 1 "ordered_comparison_operator"
1262           [(reg:CC FLAGS_REG) (const_int 0)]))]
1263   ""
1265   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1266     operands[2] = force_reg (<MODE>mode, operands[2]);
1267   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1268                      operands[2], operands[3]);
1269   DONE;
1272 (define_expand "cmp<mode>_1"
1273   [(set (reg:CC FLAGS_REG)
1274         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1275                     (match_operand:SWI48 1 "<general_operand>")))])
1277 (define_insn "*cmp<mode>_ccno_1"
1278   [(set (reg FLAGS_REG)
1279         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1280                  (match_operand:SWI 1 "const0_operand")))]
1281   "ix86_match_ccmode (insn, CCNOmode)"
1282   "@
1283    test{<imodesuffix>}\t%0, %0
1284    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1285   [(set_attr "type" "test,icmp")
1286    (set_attr "length_immediate" "0,1")
1287    (set_attr "modrm_class" "op0,unknown")
1288    (set_attr "mode" "<MODE>")])
1290 (define_insn "*cmp<mode>_1"
1291   [(set (reg FLAGS_REG)
1292         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1293                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1294   "ix86_match_ccmode (insn, CCmode)"
1295   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1296   [(set_attr "type" "icmp")
1297    (set_attr "mode" "<MODE>")])
1299 (define_insn "*cmp<mode>_minus_1"
1300   [(set (reg FLAGS_REG)
1301         (compare
1302           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1303                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1304           (const_int 0)))]
1305   "ix86_match_ccmode (insn, CCGOCmode)"
1306   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1307   [(set_attr "type" "icmp")
1308    (set_attr "mode" "<MODE>")])
1310 (define_insn "*cmpqi_ext_1"
1311   [(set (reg FLAGS_REG)
1312         (compare
1313           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1314           (subreg:QI
1315             (zero_extract:SI
1316               (match_operand 1 "ext_register_operand" "Q,Q")
1317               (const_int 8)
1318               (const_int 8)) 0)))]
1319   "ix86_match_ccmode (insn, CCmode)"
1320   "cmp{b}\t{%h1, %0|%0, %h1}"
1321   [(set_attr "isa" "*,nox64")
1322    (set_attr "type" "icmp")
1323    (set_attr "mode" "QI")])
1325 (define_insn "*cmpqi_ext_2"
1326   [(set (reg FLAGS_REG)
1327         (compare
1328           (subreg:QI
1329             (zero_extract:SI
1330               (match_operand 0 "ext_register_operand" "Q")
1331               (const_int 8)
1332               (const_int 8)) 0)
1333           (match_operand:QI 1 "const0_operand")))]
1334   "ix86_match_ccmode (insn, CCNOmode)"
1335   "test{b}\t%h0, %h0"
1336   [(set_attr "type" "test")
1337    (set_attr "length_immediate" "0")
1338    (set_attr "mode" "QI")])
1340 (define_expand "cmpqi_ext_3"
1341   [(set (reg:CC FLAGS_REG)
1342         (compare:CC
1343           (subreg:QI
1344             (zero_extract:SI
1345               (match_operand 0 "ext_register_operand")
1346               (const_int 8)
1347               (const_int 8)) 0)
1348           (match_operand:QI 1 "const_int_operand")))])
1350 (define_insn "*cmpqi_ext_3"
1351   [(set (reg FLAGS_REG)
1352         (compare
1353           (subreg:QI
1354             (zero_extract:SI
1355               (match_operand 0 "ext_register_operand" "Q,Q")
1356               (const_int 8)
1357               (const_int 8)) 0)
1358           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1359   "ix86_match_ccmode (insn, CCmode)"
1360   "cmp{b}\t{%1, %h0|%h0, %1}"
1361   [(set_attr "isa" "*,nox64")
1362    (set_attr "type" "icmp")
1363    (set_attr "mode" "QI")])
1365 (define_insn "*cmpqi_ext_4"
1366   [(set (reg FLAGS_REG)
1367         (compare
1368           (subreg:QI
1369             (zero_extract:SI
1370               (match_operand 0 "ext_register_operand" "Q")
1371               (const_int 8)
1372               (const_int 8)) 0)
1373           (subreg:QI
1374             (zero_extract:SI
1375               (match_operand 1 "ext_register_operand" "Q")
1376               (const_int 8)
1377               (const_int 8)) 0)))]
1378   "ix86_match_ccmode (insn, CCmode)"
1379   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1380   [(set_attr "type" "icmp")
1381    (set_attr "mode" "QI")])
1383 ;; These implement float point compares.
1384 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1385 ;; which would allow mix and match FP modes on the compares.  Which is what
1386 ;; the old patterns did, but with many more of them.
1388 (define_expand "cbranchxf4"
1389   [(set (reg:CC FLAGS_REG)
1390         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1391                     (match_operand:XF 2 "nonmemory_operand")))
1392    (set (pc) (if_then_else
1393               (match_operator 0 "ix86_fp_comparison_operator"
1394                [(reg:CC FLAGS_REG)
1395                 (const_int 0)])
1396               (label_ref (match_operand 3))
1397               (pc)))]
1398   "TARGET_80387"
1400   ix86_expand_branch (GET_CODE (operands[0]),
1401                       operands[1], operands[2], operands[3]);
1402   DONE;
1405 (define_expand "cstorexf4"
1406   [(set (reg:CC FLAGS_REG)
1407         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1408                     (match_operand:XF 3 "nonmemory_operand")))
1409    (set (match_operand:QI 0 "register_operand")
1410               (match_operator 1 "ix86_fp_comparison_operator"
1411                [(reg:CC FLAGS_REG)
1412                 (const_int 0)]))]
1413   "TARGET_80387"
1415   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1416                      operands[2], operands[3]);
1417   DONE;
1420 (define_expand "cbranch<mode>4"
1421   [(set (reg:CC FLAGS_REG)
1422         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1423                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1424    (set (pc) (if_then_else
1425               (match_operator 0 "ix86_fp_comparison_operator"
1426                [(reg:CC FLAGS_REG)
1427                 (const_int 0)])
1428               (label_ref (match_operand 3))
1429               (pc)))]
1430   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1432   ix86_expand_branch (GET_CODE (operands[0]),
1433                       operands[1], operands[2], operands[3]);
1434   DONE;
1437 (define_expand "cstore<mode>4"
1438   [(set (reg:CC FLAGS_REG)
1439         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1440                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1441    (set (match_operand:QI 0 "register_operand")
1442               (match_operator 1 "ix86_fp_comparison_operator"
1443                [(reg:CC FLAGS_REG)
1444                 (const_int 0)]))]
1445   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1447   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1448                      operands[2], operands[3]);
1449   DONE;
1452 (define_expand "cbranchcc4"
1453   [(set (pc) (if_then_else
1454               (match_operator 0 "comparison_operator"
1455                [(match_operand 1 "flags_reg_operand")
1456                 (match_operand 2 "const0_operand")])
1457               (label_ref (match_operand 3))
1458               (pc)))]
1459   ""
1461   ix86_expand_branch (GET_CODE (operands[0]),
1462                       operands[1], operands[2], operands[3]);
1463   DONE;
1466 (define_expand "cstorecc4"
1467   [(set (match_operand:QI 0 "register_operand")
1468               (match_operator 1 "comparison_operator"
1469                [(match_operand 2 "flags_reg_operand")
1470                 (match_operand 3 "const0_operand")]))]
1471   ""
1473   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1474                      operands[2], operands[3]);
1475   DONE;
1479 ;; FP compares, step 1:
1480 ;; Set the FP condition codes.
1482 ;; CCFPmode     compare with exceptions
1483 ;; CCFPUmode    compare with no exceptions
1485 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1486 ;; used to manage the reg stack popping would not be preserved.
1488 (define_insn "*cmp<mode>_0_i387"
1489   [(set (match_operand:HI 0 "register_operand" "=a")
1490         (unspec:HI
1491           [(compare:CCFP
1492              (match_operand:X87MODEF 1 "register_operand" "f")
1493              (match_operand:X87MODEF 2 "const0_operand"))]
1494         UNSPEC_FNSTSW))]
1495   "TARGET_80387"
1496   "* return output_fp_compare (insn, operands, false, false);"
1497   [(set_attr "type" "multi")
1498    (set_attr "unit" "i387")
1499    (set_attr "mode" "<MODE>")])
1501 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1502   [(set (reg:CCFP FLAGS_REG)
1503         (compare:CCFP
1504           (match_operand:X87MODEF 1 "register_operand" "f")
1505           (match_operand:X87MODEF 2 "const0_operand")))
1506    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1507   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1508   "#"
1509   "&& reload_completed"
1510   [(set (match_dup 0)
1511         (unspec:HI
1512           [(compare:CCFP (match_dup 1)(match_dup 2))]
1513         UNSPEC_FNSTSW))
1514    (set (reg:CC FLAGS_REG)
1515         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1516   ""
1517   [(set_attr "type" "multi")
1518    (set_attr "unit" "i387")
1519    (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmpxf_i387"
1522   [(set (match_operand:HI 0 "register_operand" "=a")
1523         (unspec:HI
1524           [(compare:CCFP
1525              (match_operand:XF 1 "register_operand" "f")
1526              (match_operand:XF 2 "register_operand" "f"))]
1527           UNSPEC_FNSTSW))]
1528   "TARGET_80387"
1529   "* return output_fp_compare (insn, operands, false, false);"
1530   [(set_attr "type" "multi")
1531    (set_attr "unit" "i387")
1532    (set_attr "mode" "XF")])
1534 (define_insn_and_split "*cmpxf_cc_i387"
1535   [(set (reg:CCFP FLAGS_REG)
1536         (compare:CCFP
1537           (match_operand:XF 1 "register_operand" "f")
1538           (match_operand:XF 2 "register_operand" "f")))
1539    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1540   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1541   "#"
1542   "&& reload_completed"
1543   [(set (match_dup 0)
1544         (unspec:HI
1545           [(compare:CCFP (match_dup 1)(match_dup 2))]
1546         UNSPEC_FNSTSW))
1547    (set (reg:CC FLAGS_REG)
1548         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1549   ""
1550   [(set_attr "type" "multi")
1551    (set_attr "unit" "i387")
1552    (set_attr "mode" "XF")])
1554 (define_insn "*cmp<mode>_i387"
1555   [(set (match_operand:HI 0 "register_operand" "=a")
1556         (unspec:HI
1557           [(compare:CCFP
1558              (match_operand:MODEF 1 "register_operand" "f")
1559              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1560           UNSPEC_FNSTSW))]
1561   "TARGET_80387"
1562   "* return output_fp_compare (insn, operands, false, false);"
1563   [(set_attr "type" "multi")
1564    (set_attr "unit" "i387")
1565    (set_attr "mode" "<MODE>")])
1567 (define_insn_and_split "*cmp<mode>_cc_i387"
1568   [(set (reg:CCFP FLAGS_REG)
1569         (compare:CCFP
1570           (match_operand:MODEF 1 "register_operand" "f")
1571           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1572    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1573   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1574   "#"
1575   "&& reload_completed"
1576   [(set (match_dup 0)
1577         (unspec:HI
1578           [(compare:CCFP (match_dup 1)(match_dup 2))]
1579         UNSPEC_FNSTSW))
1580    (set (reg:CC FLAGS_REG)
1581         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1582   ""
1583   [(set_attr "type" "multi")
1584    (set_attr "unit" "i387")
1585    (set_attr "mode" "<MODE>")])
1587 (define_insn "*cmpu<mode>_i387"
1588   [(set (match_operand:HI 0 "register_operand" "=a")
1589         (unspec:HI
1590           [(compare:CCFPU
1591              (match_operand:X87MODEF 1 "register_operand" "f")
1592              (match_operand:X87MODEF 2 "register_operand" "f"))]
1593           UNSPEC_FNSTSW))]
1594   "TARGET_80387"
1595   "* return output_fp_compare (insn, operands, false, true);"
1596   [(set_attr "type" "multi")
1597    (set_attr "unit" "i387")
1598    (set_attr "mode" "<MODE>")])
1600 (define_insn_and_split "*cmpu<mode>_cc_i387"
1601   [(set (reg:CCFPU FLAGS_REG)
1602         (compare:CCFPU
1603           (match_operand:X87MODEF 1 "register_operand" "f")
1604           (match_operand:X87MODEF 2 "register_operand" "f")))
1605    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1606   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1607   "#"
1608   "&& reload_completed"
1609   [(set (match_dup 0)
1610         (unspec:HI
1611           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1612         UNSPEC_FNSTSW))
1613    (set (reg:CC FLAGS_REG)
1614         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1615   ""
1616   [(set_attr "type" "multi")
1617    (set_attr "unit" "i387")
1618    (set_attr "mode" "<MODE>")])
1620 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1621   [(set (match_operand:HI 0 "register_operand" "=a")
1622         (unspec:HI
1623           [(compare:CCFP
1624              (match_operand:X87MODEF 1 "register_operand" "f")
1625              (float:X87MODEF
1626                (match_operand:SWI24 2 "memory_operand" "m")))]
1627           UNSPEC_FNSTSW))]
1628   "TARGET_80387
1629    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1630        || optimize_function_for_size_p (cfun))"
1631   "* return output_fp_compare (insn, operands, false, false);"
1632   [(set_attr "type" "multi")
1633    (set_attr "unit" "i387")
1634    (set_attr "fp_int_src" "true")
1635    (set_attr "mode" "<SWI24:MODE>")])
1637 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1638   [(set (reg:CCFP FLAGS_REG)
1639         (compare:CCFP
1640           (match_operand:X87MODEF 1 "register_operand" "f")
1641           (float:X87MODEF
1642             (match_operand:SWI24 2 "memory_operand" "m"))))
1643    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1644   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1645    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1646        || optimize_function_for_size_p (cfun))"
1647   "#"
1648   "&& reload_completed"
1649   [(set (match_dup 0)
1650         (unspec:HI
1651           [(compare:CCFP
1652              (match_dup 1)
1653              (float:X87MODEF (match_dup 2)))]
1654         UNSPEC_FNSTSW))
1655    (set (reg:CC FLAGS_REG)
1656         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1657   ""
1658   [(set_attr "type" "multi")
1659    (set_attr "unit" "i387")
1660    (set_attr "fp_int_src" "true")
1661    (set_attr "mode" "<SWI24:MODE>")])
1663 ;; FP compares, step 2
1664 ;; Move the fpsw to ax.
1666 (define_insn "x86_fnstsw_1"
1667   [(set (match_operand:HI 0 "register_operand" "=a")
1668         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1669   "TARGET_80387"
1670   "fnstsw\t%0"
1671   [(set_attr "length" "2")
1672    (set_attr "mode" "SI")
1673    (set_attr "unit" "i387")])
1675 ;; FP compares, step 3
1676 ;; Get ax into flags, general case.
1678 (define_insn "x86_sahf_1"
1679   [(set (reg:CC FLAGS_REG)
1680         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1681                    UNSPEC_SAHF))]
1682   "TARGET_SAHF"
1684 #ifndef HAVE_AS_IX86_SAHF
1685   if (TARGET_64BIT)
1686     return ASM_BYTE "0x9e";
1687   else
1688 #endif
1689   return "sahf";
1691   [(set_attr "length" "1")
1692    (set_attr "athlon_decode" "vector")
1693    (set_attr "amdfam10_decode" "direct")
1694    (set_attr "bdver1_decode" "direct")
1695    (set_attr "mode" "SI")])
1697 ;; Pentium Pro can do steps 1 through 3 in one go.
1698 ;; (these instructions set flags directly)
1700 (define_mode_iterator FPCMP [CCFP CCFPU])
1701 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1703 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1704   [(set (reg:FPCMP FLAGS_REG)
1705         (compare:FPCMP
1706           (match_operand:MODEF 0 "register_operand" "f,v")
1707           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1708   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1709    || (TARGET_80387 && TARGET_CMOVE)"
1710   "@
1711    * return output_fp_compare (insn, operands, true, \
1712                                <FPCMP:MODE>mode == CCFPUmode);
1713    %v<FPCMP:unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1714   [(set_attr "type" "fcmp,ssecomi")
1715    (set_attr "prefix" "orig,maybe_vex")
1716    (set_attr "mode" "<MODEF:MODE>")
1717    (set_attr "prefix_rep" "*,0")
1718    (set (attr "prefix_data16")
1719         (cond [(eq_attr "alternative" "0")
1720                  (const_string "*")
1721                (eq_attr "mode" "DF")
1722                  (const_string "1")
1723               ]
1724               (const_string "0")))
1725    (set_attr "athlon_decode" "vector")
1726    (set_attr "amdfam10_decode" "direct")
1727    (set_attr "bdver1_decode" "double")
1728    (set_attr "znver1_decode" "double")
1729    (set (attr "enabled")
1730      (if_then_else
1731        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1732        (if_then_else
1733          (eq_attr "alternative" "0")
1734          (symbol_ref "TARGET_MIX_SSE_I387")
1735          (symbol_ref "true"))
1736        (if_then_else
1737          (eq_attr "alternative" "0")
1738          (symbol_ref "true")
1739          (symbol_ref "false"))))])
1741 (define_insn "*cmpi<unord>xf_i387"
1742   [(set (reg:FPCMP FLAGS_REG)
1743         (compare:FPCMP
1744           (match_operand:XF 0 "register_operand" "f")
1745           (match_operand:XF 1 "register_operand" "f")))]
1746   "TARGET_80387 && TARGET_CMOVE"
1747   "* return output_fp_compare (insn, operands, true,
1748                                <MODE>mode == CCFPUmode);"
1749   [(set_attr "type" "fcmp")
1750    (set_attr "mode" "XF")
1751    (set_attr "athlon_decode" "vector")
1752    (set_attr "amdfam10_decode" "direct")
1753    (set_attr "bdver1_decode" "double")
1754    (set_attr "znver1_decode" "double")])
1756 ;; Push/pop instructions.
1758 (define_insn "*push<mode>2"
1759   [(set (match_operand:DWI 0 "push_operand" "=<")
1760         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1761   ""
1762   "#"
1763   [(set_attr "type" "multi")
1764    (set_attr "mode" "<MODE>")])
1766 (define_split
1767   [(set (match_operand:DWI 0 "push_operand")
1768         (match_operand:DWI 1 "general_gr_operand"))]
1769   "reload_completed"
1770   [(const_int 0)]
1771   "ix86_split_long_move (operands); DONE;")
1773 (define_insn "*pushdi2_rex64"
1774   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1775         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1776   "TARGET_64BIT"
1777   "@
1778    push{q}\t%1
1779    #"
1780   [(set_attr "type" "push,multi")
1781    (set_attr "mode" "DI")])
1783 ;; Convert impossible pushes of immediate to existing instructions.
1784 ;; First try to get scratch register and go through it.  In case this
1785 ;; fails, push sign extended lower part first and then overwrite
1786 ;; upper part by 32bit move.
1787 (define_peephole2
1788   [(match_scratch:DI 2 "r")
1789    (set (match_operand:DI 0 "push_operand")
1790         (match_operand:DI 1 "immediate_operand"))]
1791   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1792    && !x86_64_immediate_operand (operands[1], DImode)"
1793   [(set (match_dup 2) (match_dup 1))
1794    (set (match_dup 0) (match_dup 2))])
1796 ;; We need to define this as both peepholer and splitter for case
1797 ;; peephole2 pass is not run.
1798 ;; "&& 1" is needed to keep it from matching the previous pattern.
1799 (define_peephole2
1800   [(set (match_operand:DI 0 "push_operand")
1801         (match_operand:DI 1 "immediate_operand"))]
1802   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1803    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1804   [(set (match_dup 0) (match_dup 1))
1805    (set (match_dup 2) (match_dup 3))]
1807   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1809   operands[1] = gen_lowpart (DImode, operands[2]);
1810   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1811                                                    GEN_INT (4)));
1814 (define_split
1815   [(set (match_operand:DI 0 "push_operand")
1816         (match_operand:DI 1 "immediate_operand"))]
1817   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1818                     ? epilogue_completed : reload_completed)
1819    && !symbolic_operand (operands[1], DImode)
1820    && !x86_64_immediate_operand (operands[1], DImode)"
1821   [(set (match_dup 0) (match_dup 1))
1822    (set (match_dup 2) (match_dup 3))]
1824   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1826   operands[1] = gen_lowpart (DImode, operands[2]);
1827   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1828                                                    GEN_INT (4)));
1831 (define_insn "*pushsi2"
1832   [(set (match_operand:SI 0 "push_operand" "=<")
1833         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1834   "!TARGET_64BIT"
1835   "push{l}\t%1"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "SI")])
1839 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1840 ;; "push a byte/word".  But actually we use pushl, which has the effect
1841 ;; of rounding the amount pushed up to a word.
1843 ;; For TARGET_64BIT we always round up to 8 bytes.
1844 (define_insn "*push<mode>2_rex64"
1845   [(set (match_operand:SWI124 0 "push_operand" "=X")
1846         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1847   "TARGET_64BIT"
1848   "push{q}\t%q1"
1849   [(set_attr "type" "push")
1850    (set_attr "mode" "DI")])
1852 (define_insn "*push<mode>2"
1853   [(set (match_operand:SWI12 0 "push_operand" "=X")
1854         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1855   "!TARGET_64BIT"
1856   "push{l}\t%k1"
1857   [(set_attr "type" "push")
1858    (set_attr "mode" "SI")])
1860 (define_insn "*push<mode>2_prologue"
1861   [(set (match_operand:W 0 "push_operand" "=<")
1862         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1863    (clobber (mem:BLK (scratch)))]
1864   ""
1865   "push{<imodesuffix>}\t%1"
1866   [(set_attr "type" "push")
1867    (set_attr "mode" "<MODE>")])
1869 (define_insn "*pop<mode>1"
1870   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1871         (match_operand:W 1 "pop_operand" ">"))]
1872   ""
1873   "pop{<imodesuffix>}\t%0"
1874   [(set_attr "type" "pop")
1875    (set_attr "mode" "<MODE>")])
1877 (define_insn "*pop<mode>1_epilogue"
1878   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1879         (match_operand:W 1 "pop_operand" ">"))
1880    (clobber (mem:BLK (scratch)))]
1881   ""
1882   "pop{<imodesuffix>}\t%0"
1883   [(set_attr "type" "pop")
1884    (set_attr "mode" "<MODE>")])
1886 (define_insn "*pushfl<mode>2"
1887   [(set (match_operand:W 0 "push_operand" "=<")
1888         (match_operand:W 1 "flags_reg_operand"))]
1889   ""
1890   "pushf{<imodesuffix>}"
1891   [(set_attr "type" "push")
1892    (set_attr "mode" "<MODE>")])
1894 (define_insn "*popfl<mode>1"
1895   [(set (match_operand:W 0 "flags_reg_operand")
1896         (match_operand:W 1 "pop_operand" ">"))]
1897   ""
1898   "popf{<imodesuffix>}"
1899   [(set_attr "type" "pop")
1900    (set_attr "mode" "<MODE>")])
1903 ;; Reload patterns to support multi-word load/store
1904 ;; with non-offsetable address.
1905 (define_expand "reload_noff_store"
1906   [(parallel [(match_operand 0 "memory_operand" "=m")
1907               (match_operand 1 "register_operand" "r")
1908               (match_operand:DI 2 "register_operand" "=&r")])]
1909   "TARGET_64BIT"
1911   rtx mem = operands[0];
1912   rtx addr = XEXP (mem, 0);
1914   emit_move_insn (operands[2], addr);
1915   mem = replace_equiv_address_nv (mem, operands[2]);
1917   emit_insn (gen_rtx_SET (mem, operands[1]));
1918   DONE;
1921 (define_expand "reload_noff_load"
1922   [(parallel [(match_operand 0 "register_operand" "=r")
1923               (match_operand 1 "memory_operand" "m")
1924               (match_operand:DI 2 "register_operand" "=r")])]
1925   "TARGET_64BIT"
1927   rtx mem = operands[1];
1928   rtx addr = XEXP (mem, 0);
1930   emit_move_insn (operands[2], addr);
1931   mem = replace_equiv_address_nv (mem, operands[2]);
1933   emit_insn (gen_rtx_SET (operands[0], mem));
1934   DONE;
1937 ;; Move instructions.
1939 (define_expand "movxi"
1940   [(set (match_operand:XI 0 "nonimmediate_operand")
1941         (match_operand:XI 1 "general_operand"))]
1942   "TARGET_AVX512F"
1943   "ix86_expand_vector_move (XImode, operands); DONE;")
1945 (define_expand "movoi"
1946   [(set (match_operand:OI 0 "nonimmediate_operand")
1947         (match_operand:OI 1 "general_operand"))]
1948   "TARGET_AVX"
1949   "ix86_expand_vector_move (OImode, operands); DONE;")
1951 (define_expand "movti"
1952   [(set (match_operand:TI 0 "nonimmediate_operand")
1953         (match_operand:TI 1 "general_operand"))]
1954   "TARGET_64BIT || TARGET_SSE"
1956   if (TARGET_64BIT)
1957     ix86_expand_move (TImode, operands);
1958   else
1959     ix86_expand_vector_move (TImode, operands);
1960   DONE;
1963 ;; This expands to what emit_move_complex would generate if we didn't
1964 ;; have a movti pattern.  Having this avoids problems with reload on
1965 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1966 ;; to have around all the time.
1967 (define_expand "movcdi"
1968   [(set (match_operand:CDI 0 "nonimmediate_operand")
1969         (match_operand:CDI 1 "general_operand"))]
1970   ""
1972   if (push_operand (operands[0], CDImode))
1973     emit_move_complex_push (CDImode, operands[0], operands[1]);
1974   else
1975     emit_move_complex_parts (operands[0], operands[1]);
1976   DONE;
1979 (define_expand "mov<mode>"
1980   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1981         (match_operand:SWI1248x 1 "general_operand"))]
1982   ""
1983   "ix86_expand_move (<MODE>mode, operands); DONE;")
1985 (define_insn "*mov<mode>_xor"
1986   [(set (match_operand:SWI48 0 "register_operand" "=r")
1987         (match_operand:SWI48 1 "const0_operand"))
1988    (clobber (reg:CC FLAGS_REG))]
1989   "reload_completed"
1990   "xor{l}\t%k0, %k0"
1991   [(set_attr "type" "alu1")
1992    (set_attr "modrm_class" "op0")
1993    (set_attr "mode" "SI")
1994    (set_attr "length_immediate" "0")])
1996 (define_insn "*mov<mode>_or"
1997   [(set (match_operand:SWI48 0 "register_operand" "=r")
1998         (match_operand:SWI48 1 "constm1_operand"))
1999    (clobber (reg:CC FLAGS_REG))]
2000   "reload_completed"
2001   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "alu1")
2003    (set_attr "mode" "<MODE>")
2004    (set_attr "length_immediate" "1")])
2006 (define_insn "*movxi_internal_avx512f"
2007   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2008         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2009   "TARGET_AVX512F
2010    && (register_operand (operands[0], XImode)
2011        || register_operand (operands[1], XImode))"
2013   switch (get_attr_type (insn))
2014     {
2015     case TYPE_SSELOG1:
2016       return standard_sse_constant_opcode (insn, operands[1]);
2018     case TYPE_SSEMOV:
2019       if (misaligned_operand (operands[0], XImode)
2020           || misaligned_operand (operands[1], XImode))
2021         return "vmovdqu32\t{%1, %0|%0, %1}";
2022       else
2023         return "vmovdqa32\t{%1, %0|%0, %1}";
2025     default:
2026       gcc_unreachable ();
2027     }
2029   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2030    (set_attr "prefix" "evex")
2031    (set_attr "mode" "XI")])
2033 (define_insn "*movoi_internal_avx"
2034   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2035         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2036   "TARGET_AVX
2037    && (register_operand (operands[0], OImode)
2038        || register_operand (operands[1], OImode))"
2040   switch (get_attr_type (insn))
2041     {
2042     case TYPE_SSELOG1:
2043       return standard_sse_constant_opcode (insn, operands[1]);
2045     case TYPE_SSEMOV:
2046       if (misaligned_operand (operands[0], OImode)
2047           || misaligned_operand (operands[1], OImode))
2048         {
2049           if (get_attr_mode (insn) == MODE_V8SF)
2050             return "vmovups\t{%1, %0|%0, %1}";
2051           else if (get_attr_mode (insn) == MODE_XI)
2052             return "vmovdqu32\t{%1, %0|%0, %1}";
2053           else
2054             return "vmovdqu\t{%1, %0|%0, %1}";
2055         }
2056       else
2057         {
2058           if (get_attr_mode (insn) == MODE_V8SF)
2059             return "vmovaps\t{%1, %0|%0, %1}";
2060           else if (get_attr_mode (insn) == MODE_XI)
2061             return "vmovdqa32\t{%1, %0|%0, %1}";
2062           else
2063             return "vmovdqa\t{%1, %0|%0, %1}";
2064         }
2066     default:
2067       gcc_unreachable ();
2068     }
2070   [(set_attr "isa" "*,avx2,*,*")
2071    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2072    (set_attr "prefix" "vex")
2073    (set (attr "mode")
2074         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2075                     (match_operand 1 "ext_sse_reg_operand"))
2076                  (const_string "XI")
2077                (and (eq_attr "alternative" "1")
2078                     (match_test "TARGET_AVX512VL"))
2079                  (const_string "XI")
2080                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2081                     (and (eq_attr "alternative" "3")
2082                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2083                  (const_string "V8SF")
2084               ]
2085               (const_string "OI")))])
2087 (define_insn "*movti_internal"
2088   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2089         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Ye,r"))]
2090   "(TARGET_64BIT
2091     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2092    || (TARGET_SSE
2093        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2094        && (register_operand (operands[0], TImode)
2095            || register_operand (operands[1], TImode)))"
2097   switch (get_attr_type (insn))
2098     {
2099     case TYPE_MULTI:
2100       return "#";
2102     case TYPE_SSELOG1:
2103       return standard_sse_constant_opcode (insn, operands[1]);
2105     case TYPE_SSEMOV:
2106       /* TDmode values are passed as TImode on the stack.  Moving them
2107          to stack may result in unaligned memory access.  */
2108       if (misaligned_operand (operands[0], TImode)
2109           || misaligned_operand (operands[1], TImode))
2110         {
2111           if (get_attr_mode (insn) == MODE_V4SF)
2112             return "%vmovups\t{%1, %0|%0, %1}";
2113           else if (get_attr_mode (insn) == MODE_XI)
2114             return "vmovdqu32\t{%1, %0|%0, %1}";
2115           else
2116             return "%vmovdqu\t{%1, %0|%0, %1}";
2117         }
2118       else
2119         {
2120           if (get_attr_mode (insn) == MODE_V4SF)
2121             return "%vmovaps\t{%1, %0|%0, %1}";
2122           else if (get_attr_mode (insn) == MODE_XI)
2123             return "vmovdqa32\t{%1, %0|%0, %1}";
2124           else
2125             return "%vmovdqa\t{%1, %0|%0, %1}";
2126         }
2128     default:
2129       gcc_unreachable ();
2130     }
2132   [(set (attr "isa")
2133      (cond [(eq_attr "alternative" "0,1,6,7")
2134               (const_string "x64")
2135             (eq_attr "alternative" "3")
2136               (const_string "sse2")
2137            ]
2138            (const_string "*")))
2139    (set (attr "type")
2140      (cond [(eq_attr "alternative" "0,1,6,7")
2141               (const_string "multi")
2142             (eq_attr "alternative" "2,3")
2143               (const_string "sselog1")
2144            ]
2145            (const_string "ssemov")))
2146    (set (attr "prefix")
2147      (if_then_else (eq_attr "type" "sselog1,ssemov")
2148        (const_string "maybe_vex")
2149        (const_string "orig")))
2150    (set (attr "mode")
2151         (cond [(eq_attr "alternative" "0,1")
2152                  (const_string "DI")
2153                (ior (match_operand 0 "ext_sse_reg_operand")
2154                     (match_operand 1 "ext_sse_reg_operand"))
2155                  (const_string "XI")
2156                (and (eq_attr "alternative" "3")
2157                     (match_test "TARGET_AVX512VL"))
2158                  (const_string "XI")
2159                (ior (not (match_test "TARGET_SSE2"))
2160                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2161                          (and (eq_attr "alternative" "5")
2162                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2163                  (const_string "V4SF")
2164                (match_test "TARGET_AVX")
2165                  (const_string "TI")
2166                (match_test "optimize_function_for_size_p (cfun)")
2167                  (const_string "V4SF")
2168                ]
2169                (const_string "TI")))])
2171 (define_split
2172   [(set (match_operand:TI 0 "sse_reg_operand")
2173         (match_operand:TI 1 "general_reg_operand"))]
2174   "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2175    && reload_completed"
2176   [(set (match_dup 2)
2177         (vec_merge:V2DI
2178           (vec_duplicate:V2DI (match_dup 3))
2179           (match_dup 2)
2180           (const_int 2)))]
2182   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2183   operands[3] = gen_highpart (DImode, operands[1]);
2185   emit_move_insn (gen_lowpart (DImode, operands[0]),
2186                   gen_lowpart (DImode, operands[1]));
2189 (define_insn "*movdi_internal"
2190   [(set (match_operand:DI 0 "nonimmediate_operand"
2191     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2192         (match_operand:DI 1 "general_operand"
2193     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Ye,r   ,*Yj,r   ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2194   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196   switch (get_attr_type (insn))
2197     {
2198     case TYPE_MSKMOV:
2199       return "kmovq\t{%1, %0|%0, %1}";
2201     case TYPE_MULTI:
2202       return "#";
2204     case TYPE_MMX:
2205       return "pxor\t%0, %0";
2207     case TYPE_MMXMOV:
2208       /* Handle broken assemblers that require movd instead of movq.  */
2209       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2210           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2211         return "movd\t{%1, %0|%0, %1}";
2212       return "movq\t{%1, %0|%0, %1}";
2214     case TYPE_SSELOG1:
2215       return standard_sse_constant_opcode (insn, operands[1]);
2217     case TYPE_SSEMOV:
2218       switch (get_attr_mode (insn))
2219         {
2220         case MODE_DI:
2221           /* Handle broken assemblers that require movd instead of movq.  */
2222           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2223               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2224             return "%vmovd\t{%1, %0|%0, %1}";
2225           return "%vmovq\t{%1, %0|%0, %1}";
2226         case MODE_TI:
2227           return "%vmovdqa\t{%1, %0|%0, %1}";
2228         case MODE_XI:
2229           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2231         case MODE_V2SF:
2232           gcc_assert (!TARGET_AVX);
2233           return "movlps\t{%1, %0|%0, %1}";
2234         case MODE_V4SF:
2235           return "%vmovaps\t{%1, %0|%0, %1}";
2237         default:
2238           gcc_unreachable ();
2239         }
2241     case TYPE_SSECVT:
2242       if (SSE_REG_P (operands[0]))
2243         return "movq2dq\t{%1, %0|%0, %1}";
2244       else
2245         return "movdq2q\t{%1, %0|%0, %1}";
2247     case TYPE_LEA:
2248       return "lea{q}\t{%E1, %0|%0, %E1}";
2250     case TYPE_IMOV:
2251       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2252       if (get_attr_mode (insn) == MODE_SI)
2253         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2254       else if (which_alternative == 4)
2255         return "movabs{q}\t{%1, %0|%0, %1}";
2256       else if (ix86_use_lea_for_mov (insn, operands))
2257         return "lea{q}\t{%E1, %0|%0, %E1}";
2258       else
2259         return "mov{q}\t{%1, %0|%0, %1}";
2261     default:
2262       gcc_unreachable ();
2263     }
2265   [(set (attr "isa")
2266      (cond [(eq_attr "alternative" "0,1,17,18")
2267               (const_string "nox64")
2268             (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2269               (const_string "x64")
2270            ]
2271            (const_string "*")))
2272    (set (attr "type")
2273      (cond [(eq_attr "alternative" "0,1,17,18")
2274               (const_string "multi")
2275             (eq_attr "alternative" "6")
2276               (const_string "mmx")
2277             (eq_attr "alternative" "7,8,9,10,11")
2278               (const_string "mmxmov")
2279             (eq_attr "alternative" "12")
2280               (const_string "sselog1")
2281             (eq_attr "alternative" "13,14,15,16,19,20")
2282               (const_string "ssemov")
2283             (eq_attr "alternative" "21,22")
2284               (const_string "ssecvt")
2285             (eq_attr "alternative" "23,24,25,26")
2286               (const_string "mskmov")
2287             (and (match_operand 0 "register_operand")
2288                  (match_operand 1 "pic_32bit_operand"))
2289               (const_string "lea")
2290            ]
2291            (const_string "imov")))
2292    (set (attr "modrm")
2293      (if_then_else
2294        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2295        (const_string "0")
2296        (const_string "*")))
2297    (set (attr "length_immediate")
2298      (if_then_else
2299        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2300        (const_string "8")
2301        (const_string "*")))
2302    (set (attr "prefix_rex")
2303      (if_then_else
2304        (eq_attr "alternative" "10,11,19,20")
2305        (const_string "1")
2306        (const_string "*")))
2307    (set (attr "prefix")
2308      (if_then_else (eq_attr "type" "sselog1,ssemov")
2309        (const_string "maybe_vex")
2310        (const_string "orig")))
2311    (set (attr "prefix_data16")
2312      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2313        (const_string "1")
2314        (const_string "*")))
2315    (set (attr "mode")
2316      (cond [(eq_attr "alternative" "2")
2317               (const_string "SI")
2318             (eq_attr "alternative" "12,13")
2319               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2320                           (match_operand 1 "ext_sse_reg_operand"))
2321                        (const_string "XI")
2322                      (ior (not (match_test "TARGET_SSE2"))
2323                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2324                        (const_string "V4SF")
2325                      (match_test "TARGET_AVX")
2326                        (const_string "TI")
2327                      (match_test "optimize_function_for_size_p (cfun)")
2328                        (const_string "V4SF")
2329                     ]
2330                     (const_string "TI"))
2332             (and (eq_attr "alternative" "14,15,16")
2333                  (not (match_test "TARGET_SSE2")))
2334               (const_string "V2SF")
2335            ]
2336            (const_string "DI")))
2337    (set (attr "enabled")
2338      (cond [(eq_attr "alternative" "15")
2339               (if_then_else
2340                 (match_test "TARGET_STV && TARGET_SSE2")
2341                 (symbol_ref "false")
2342                 (const_string "*"))
2343             (eq_attr "alternative" "16")
2344               (if_then_else
2345                 (match_test "TARGET_STV && TARGET_SSE2")
2346                 (symbol_ref "true")
2347                 (symbol_ref "false"))
2348            ]
2349            (const_string "*")))])
2351 (define_split
2352   [(set (match_operand:<DWI> 0 "general_reg_operand")
2353         (match_operand:<DWI> 1 "sse_reg_operand"))]
2354   "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2355    && reload_completed"
2356   [(set (match_dup 2)
2357         (vec_select:DWIH
2358           (match_dup 3)
2359           (parallel [(const_int 1)])))]
2361   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2362   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2364   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2365                   gen_lowpart (<MODE>mode, operands[1]));
2368 (define_split
2369   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2370         (match_operand:DWI 1 "general_gr_operand"))]
2371   "reload_completed"
2372   [(const_int 0)]
2373   "ix86_split_long_move (operands); DONE;")
2375 (define_split
2376   [(set (match_operand:DI 0 "sse_reg_operand")
2377         (match_operand:DI 1 "general_reg_operand"))]
2378   "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2379    && reload_completed"
2380   [(set (match_dup 2)
2381         (vec_merge:V4SI
2382           (vec_duplicate:V4SI (match_dup 3))
2383           (match_dup 2)
2384           (const_int 2)))]
2386   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2387   operands[3] = gen_highpart (SImode, operands[1]);
2389   emit_move_insn (gen_lowpart (SImode, operands[0]),
2390                   gen_lowpart (SImode, operands[1]));
2393 ;; movabsq $0x0012345678000000, %rax is longer
2394 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2395 (define_peephole2
2396   [(set (match_operand:DI 0 "register_operand")
2397         (match_operand:DI 1 "const_int_operand"))]
2398   "TARGET_64BIT
2399    && optimize_insn_for_size_p ()
2400    && LEGACY_INT_REG_P (operands[0])
2401    && !x86_64_immediate_operand (operands[1], DImode)
2402    && !x86_64_zext_immediate_operand (operands[1], DImode)
2403    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2404         & ~(HOST_WIDE_INT) 0xffffffff)
2405    && peep2_regno_dead_p (0, FLAGS_REG)"
2406   [(set (match_dup 0) (match_dup 1))
2407    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2408               (clobber (reg:CC FLAGS_REG))])]
2410   int shift = ctz_hwi (UINTVAL (operands[1]));
2411   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2412   operands[2] = gen_int_mode (shift, QImode);
2415 (define_insn "*movsi_internal"
2416   [(set (match_operand:SI 0 "nonimmediate_operand"
2417     "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2418         (match_operand:SI 1 "general_operand"
2419     "g ,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,r   ,*r,*km,*k"))]
2420   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2422   switch (get_attr_type (insn))
2423     {
2424     case TYPE_SSELOG1:
2425       return standard_sse_constant_opcode (insn, operands[1]);
2427     case TYPE_MSKMOV:
2428       return "kmovd\t{%1, %0|%0, %1}";
2430     case TYPE_SSEMOV:
2431       switch (get_attr_mode (insn))
2432         {
2433         case MODE_SI:
2434           return "%vmovd\t{%1, %0|%0, %1}";
2435         case MODE_TI:
2436           return "%vmovdqa\t{%1, %0|%0, %1}";
2437         case MODE_XI:
2438           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2440         case MODE_V4SF:
2441           return "%vmovaps\t{%1, %0|%0, %1}";
2443         case MODE_SF:
2444           gcc_assert (!TARGET_AVX);
2445           return "movss\t{%1, %0|%0, %1}";
2447         default:
2448           gcc_unreachable ();
2449         }
2451     case TYPE_MMX:
2452       return "pxor\t%0, %0";
2454     case TYPE_MMXMOV:
2455       switch (get_attr_mode (insn))
2456         {
2457         case MODE_DI:
2458           return "movq\t{%1, %0|%0, %1}";
2459         case MODE_SI:
2460           return "movd\t{%1, %0|%0, %1}";
2462         default:
2463           gcc_unreachable ();
2464         }
2466     case TYPE_LEA:
2467       return "lea{l}\t{%E1, %0|%0, %E1}";
2469     case TYPE_IMOV:
2470       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2471       if (ix86_use_lea_for_mov (insn, operands))
2472         return "lea{l}\t{%E1, %0|%0, %E1}";
2473       else
2474         return "mov{l}\t{%1, %0|%0, %1}";
2476     default:
2477       gcc_unreachable ();
2478     }
2480   [(set (attr "type")
2481      (cond [(eq_attr "alternative" "2")
2482               (const_string "mmx")
2483             (eq_attr "alternative" "3,4,5,6,7")
2484               (const_string "mmxmov")
2485             (eq_attr "alternative" "8")
2486               (const_string "sselog1")
2487             (eq_attr "alternative" "9,10,11,12,13")
2488               (const_string "ssemov")
2489             (eq_attr "alternative" "14,15,16")
2490               (const_string "mskmov")
2491             (and (match_operand 0 "register_operand")
2492                  (match_operand 1 "pic_32bit_operand"))
2493               (const_string "lea")
2494            ]
2495            (const_string "imov")))
2496    (set (attr "prefix")
2497      (if_then_else (eq_attr "type" "sselog1,ssemov")
2498        (const_string "maybe_vex")
2499        (const_string "orig")))
2500    (set (attr "prefix_data16")
2501      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2502        (const_string "1")
2503        (const_string "*")))
2504    (set (attr "mode")
2505      (cond [(eq_attr "alternative" "2,3")
2506               (const_string "DI")
2507             (eq_attr "alternative" "8,9")
2508               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2509                           (match_operand 1 "ext_sse_reg_operand"))
2510                        (const_string "XI")
2511                      (ior (not (match_test "TARGET_SSE2"))
2512                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2513                        (const_string "V4SF")
2514                      (match_test "TARGET_AVX")
2515                        (const_string "TI")
2516                      (match_test "optimize_function_for_size_p (cfun)")
2517                        (const_string "V4SF")
2518                     ]
2519                     (const_string "TI"))
2521             (and (eq_attr "alternative" "10,11")
2522                  (not (match_test "TARGET_SSE2")))
2523               (const_string "SF")
2524            ]
2525            (const_string "SI")))])
2527 (define_insn "*movhi_internal"
2528   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2529         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2530   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2532   switch (get_attr_type (insn))
2533     {
2534     case TYPE_IMOVX:
2535       /* movzwl is faster than movw on p2 due to partial word stalls,
2536          though not as fast as an aligned movl.  */
2537       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2539     case TYPE_MSKMOV:
2540       switch (which_alternative)
2541         {
2542         case 4:
2543           return "kmovw\t{%k1, %0|%0, %k1}";
2544         case 6:
2545           return "kmovw\t{%1, %k0|%k0, %1}";
2546         case 5:
2547         case 7:
2548           return "kmovw\t{%1, %0|%0, %1}";
2549         default:
2550           gcc_unreachable ();
2551         }
2553     default:
2554       if (get_attr_mode (insn) == MODE_SI)
2555         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2556       else
2557         return "mov{w}\t{%1, %0|%0, %1}";
2558     }
2560   [(set (attr "type")
2561      (cond [(eq_attr "alternative" "4,5,6,7")
2562               (const_string "mskmov")
2563             (match_test "optimize_function_for_size_p (cfun)")
2564               (const_string "imov")
2565             (and (eq_attr "alternative" "0")
2566                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2567                       (not (match_test "TARGET_HIMODE_MATH"))))
2568               (const_string "imov")
2569             (and (eq_attr "alternative" "1,2")
2570                  (match_operand:HI 1 "aligned_operand"))
2571               (const_string "imov")
2572             (and (match_test "TARGET_MOVX")
2573                  (eq_attr "alternative" "0,2"))
2574               (const_string "imovx")
2575            ]
2576            (const_string "imov")))
2577     (set (attr "prefix")
2578       (if_then_else (eq_attr "alternative" "4,5,6,7")
2579         (const_string "vex")
2580         (const_string "orig")))
2581     (set (attr "mode")
2582       (cond [(eq_attr "type" "imovx")
2583                (const_string "SI")
2584              (and (eq_attr "alternative" "1,2")
2585                   (match_operand:HI 1 "aligned_operand"))
2586                (const_string "SI")
2587              (and (eq_attr "alternative" "0")
2588                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2589                        (not (match_test "TARGET_HIMODE_MATH"))))
2590                (const_string "SI")
2591             ]
2592             (const_string "HI")))])
2594 ;; Situation is quite tricky about when to choose full sized (SImode) move
2595 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2596 ;; partial register dependency machines (such as AMD Athlon), where QImode
2597 ;; moves issue extra dependency and for partial register stalls machines
2598 ;; that don't use QImode patterns (and QImode move cause stall on the next
2599 ;; instruction).
2601 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2602 ;; register stall machines with, where we use QImode instructions, since
2603 ;; partial register stall can be caused there.  Then we use movzx.
2605 (define_insn "*movqi_internal"
2606   [(set (match_operand:QI 0 "nonimmediate_operand"
2607                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2608         (match_operand:QI 1 "general_operand"
2609                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2610   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2612   static char buf[128];
2613   const char *ops;
2614   const char *suffix;
2616   switch (get_attr_type (insn))
2617     {
2618     case TYPE_IMOVX:
2619       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2620       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2622     case TYPE_MSKMOV:
2623       switch (which_alternative)
2624         {
2625         case 9:
2626           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2627           break;
2628         case 11:
2629           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2630           break;
2631         case 12:
2632         case 13:
2633           gcc_assert (TARGET_AVX512DQ);
2634           /* FALLTHRU */
2635         case 10:
2636           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2637           break;
2638         default:
2639           gcc_unreachable ();
2640         }
2642       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2644       snprintf (buf, sizeof (buf), ops, suffix);
2645       return buf;
2647     default:
2648       if (get_attr_mode (insn) == MODE_SI)
2649         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2650       else
2651         return "mov{b}\t{%1, %0|%0, %1}";
2652     }
2654   [(set (attr "isa")
2655      (cond [(eq_attr "alternative" "1,2")
2656               (const_string "x64")
2657             (eq_attr "alternative" "12,13")
2658               (const_string "avx512dq")
2659            ]
2660            (const_string "*")))
2661    (set (attr "type")
2662      (cond [(eq_attr "alternative" "9,10,11,12,13")
2663               (const_string "mskmov")
2664             (and (eq_attr "alternative" "7")
2665                  (not (match_operand:QI 1 "aligned_operand")))
2666               (const_string "imovx")
2667             (match_test "optimize_function_for_size_p (cfun)")
2668               (const_string "imov")
2669             (and (eq_attr "alternative" "5")
2670                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2671                       (not (match_test "TARGET_QIMODE_MATH"))))
2672               (const_string "imov")
2673             (eq_attr "alternative" "5,7")
2674               (const_string "imovx")
2675             (and (match_test "TARGET_MOVX")
2676                  (eq_attr "alternative" "4"))
2677               (const_string "imovx")
2678            ]
2679            (const_string "imov")))
2680    (set (attr "prefix")
2681      (if_then_else (eq_attr "alternative" "9,10,11")
2682        (const_string "vex")
2683        (const_string "orig")))
2684    (set (attr "mode")
2685       (cond [(eq_attr "alternative" "5,6,7")
2686                (const_string "SI")
2687              (eq_attr "alternative" "8")
2688                (const_string "QI")
2689              (and (eq_attr "alternative" "9,10,11")
2690                   (not (match_test "TARGET_AVX512DQ")))
2691                (const_string "HI")
2692              (eq_attr "type" "imovx")
2693                (const_string "SI")
2694              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2695              ;; ones.
2696              (and (eq_attr "type" "imov")
2697                   (and (eq_attr "alternative" "3")
2698                        (match_test "optimize_function_for_size_p (cfun)")))
2699                (const_string "QI")
2700              ;; For -Os, movl where one or both operands are NON_Q_REGS
2701              ;; and both are LEGACY_REGS is shorter than movb.
2702              ;; Otherwise movb and movl sizes are the same, so decide purely
2703              ;; based on speed factors.
2704              (and (eq_attr "type" "imov")
2705                   (and (eq_attr "alternative" "1")
2706                        (match_test "optimize_function_for_size_p (cfun)")))
2707                (const_string "SI")
2708              (and (eq_attr "type" "imov")
2709                   (and (eq_attr "alternative" "0,1,2,3")
2710                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2711                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2712                (const_string "SI")
2713              ;; Avoid partial register stalls when not using QImode arithmetic
2714              (and (eq_attr "type" "imov")
2715                   (and (eq_attr "alternative" "0,1,2,3")
2716                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2717                             (not (match_test "TARGET_QIMODE_MATH")))))
2718                (const_string "SI")
2719            ]
2720            (const_string "QI")))])
2722 ;; Stores and loads of ax to arbitrary constant address.
2723 ;; We fake an second form of instruction to force reload to load address
2724 ;; into register when rax is not available
2725 (define_insn "*movabs<mode>_1"
2726   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2727         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2728   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2730   /* Recover the full memory rtx.  */
2731   operands[0] = SET_DEST (PATTERN (insn));
2732   switch (which_alternative)
2733     {
2734     case 0:
2735       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2736     case 1:
2737       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2738     default:
2739       gcc_unreachable ();
2740     }
2742   [(set_attr "type" "imov")
2743    (set_attr "modrm" "0,*")
2744    (set_attr "length_address" "8,0")
2745    (set_attr "length_immediate" "0,*")
2746    (set_attr "memory" "store")
2747    (set_attr "mode" "<MODE>")])
2749 (define_insn "*movabs<mode>_2"
2750   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2751         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2752   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2754   /* Recover the full memory rtx.  */
2755   operands[1] = SET_SRC (PATTERN (insn));
2756   switch (which_alternative)
2757     {
2758     case 0:
2759       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2760     case 1:
2761       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2762     default:
2763       gcc_unreachable ();
2764     }
2766   [(set_attr "type" "imov")
2767    (set_attr "modrm" "0,*")
2768    (set_attr "length_address" "8,0")
2769    (set_attr "length_immediate" "0")
2770    (set_attr "memory" "load")
2771    (set_attr "mode" "<MODE>")])
2773 (define_insn "*swap<mode>"
2774   [(set (match_operand:SWI48 0 "register_operand" "+r")
2775         (match_operand:SWI48 1 "register_operand" "+r"))
2776    (set (match_dup 1)
2777         (match_dup 0))]
2778   ""
2779   "xchg{<imodesuffix>}\t%1, %0"
2780   [(set_attr "type" "imov")
2781    (set_attr "mode" "<MODE>")
2782    (set_attr "pent_pair" "np")
2783    (set_attr "athlon_decode" "vector")
2784    (set_attr "amdfam10_decode" "double")
2785    (set_attr "bdver1_decode" "double")])
2787 (define_insn "*swap<mode>"
2788   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2789         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2790    (set (match_dup 1)
2791         (match_dup 0))]
2792   ""
2793   "@
2794    xchg{<imodesuffix>}\t%1, %0
2795    xchg{l}\t%k1, %k0"
2796   [(set_attr "type" "imov")
2797    (set_attr "mode" "<MODE>,SI")
2798    (set (attr "preferred_for_size")
2799      (cond [(eq_attr "alternative" "0")
2800               (symbol_ref "false")]
2801            (symbol_ref "true")))
2802    ;; Potential partial reg stall on alternative 1.
2803    (set (attr "preferred_for_speed")
2804      (cond [(eq_attr "alternative" "1")
2805               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2806            (symbol_ref "true")))
2807    (set_attr "pent_pair" "np")
2808    (set_attr "athlon_decode" "vector")
2809    (set_attr "amdfam10_decode" "double")
2810    (set_attr "bdver1_decode" "double")])
2812 (define_expand "movstrict<mode>"
2813   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2814         (match_operand:SWI12 1 "general_operand"))]
2815   ""
2817   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2818     FAIL;
2819   if (SUBREG_P (operands[0])
2820       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2821     FAIL;
2822   /* Don't generate memory->memory moves, go through a register */
2823   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2824     operands[1] = force_reg (<MODE>mode, operands[1]);
2827 (define_insn "*movstrict<mode>_1"
2828   [(set (strict_low_part
2829           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2830         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2831   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2832    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2833   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2834   [(set_attr "type" "imov")
2835    (set_attr "mode" "<MODE>")])
2837 (define_insn "*movstrict<mode>_xor"
2838   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2839         (match_operand:SWI12 1 "const0_operand"))
2840    (clobber (reg:CC FLAGS_REG))]
2841   "reload_completed"
2842   "xor{<imodesuffix>}\t%0, %0"
2843   [(set_attr "type" "alu1")
2844    (set_attr "modrm_class" "op0")
2845    (set_attr "mode" "<MODE>")
2846    (set_attr "length_immediate" "0")])
2848 (define_expand "extv<mode>"
2849   [(set (match_operand:SWI24 0 "register_operand")
2850         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2851                             (match_operand:SI 2 "const_int_operand")
2852                             (match_operand:SI 3 "const_int_operand")))]
2853   ""
2855   /* Handle extractions from %ah et al.  */
2856   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2857     FAIL;
2859   unsigned int regno = reg_or_subregno (operands[1]);
2861   /* Be careful to expand only with registers having upper parts.  */
2862   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2863     operands[1] = copy_to_reg (operands[1]);
2866 (define_insn "*extv<mode>"
2867   [(set (match_operand:SWI24 0 "register_operand" "=R")
2868         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2869                             (const_int 8)
2870                             (const_int 8)))]
2871   ""
2872   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2873   [(set_attr "type" "imovx")
2874    (set_attr "mode" "SI")])
2876 (define_expand "extzv<mode>"
2877   [(set (match_operand:SWI248 0 "register_operand")
2878         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2879                              (match_operand:SI 2 "const_int_operand")
2880                              (match_operand:SI 3 "const_int_operand")))]
2881   ""
2883   if (ix86_expand_pextr (operands))
2884     DONE;
2886   /* Handle extractions from %ah et al.  */
2887   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2888     FAIL;
2890   unsigned int regno = reg_or_subregno (operands[1]);
2892   /* Be careful to expand only with registers having upper parts.  */
2893   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2894     operands[1] = copy_to_reg (operands[1]);
2897 (define_insn "*extzvqi_mem_rex64"
2898   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2899         (subreg:QI
2900           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2901                            (const_int 8)
2902                            (const_int 8)) 0))]
2903   "TARGET_64BIT && reload_completed"
2904   "mov{b}\t{%h1, %0|%0, %h1}"
2905   [(set_attr "type" "imov")
2906    (set_attr "mode" "QI")])
2908 (define_insn "*extzv<mode>"
2909   [(set (match_operand:SWI248 0 "register_operand" "=R")
2910         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2911                              (const_int 8)
2912                              (const_int 8)))]
2913   ""
2914   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2915   [(set_attr "type" "imovx")
2916    (set_attr "mode" "SI")])
2918 (define_insn "*extzvqi"
2919   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2920         (subreg:QI
2921           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2922                            (const_int 8)
2923                            (const_int 8)) 0))]
2924   ""
2926   switch (get_attr_type (insn))
2927     {
2928     case TYPE_IMOVX:
2929       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2930     default:
2931       return "mov{b}\t{%h1, %0|%0, %h1}";
2932     }
2934   [(set_attr "isa" "*,*,nox64")
2935    (set (attr "type")
2936      (if_then_else (and (match_operand:QI 0 "register_operand")
2937                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2938                              (match_test "TARGET_MOVX")))
2939         (const_string "imovx")
2940         (const_string "imov")))
2941    (set (attr "mode")
2942      (if_then_else (eq_attr "type" "imovx")
2943         (const_string "SI")
2944         (const_string "QI")))])
2946 (define_peephole2
2947   [(set (match_operand:QI 0 "register_operand")
2948         (subreg:QI
2949           (zero_extract:SI (match_operand 1 "ext_register_operand")
2950                            (const_int 8)
2951                            (const_int 8)) 0))
2952    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2953   "TARGET_64BIT
2954    && peep2_reg_dead_p (2, operands[0])"
2955   [(set (match_dup 2)
2956         (subreg:QI
2957           (zero_extract:SI (match_dup 1)
2958                            (const_int 8)
2959                            (const_int 8)) 0))])
2961 (define_expand "insv<mode>"
2962   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2963                              (match_operand:SI 1 "const_int_operand")
2964                              (match_operand:SI 2 "const_int_operand"))
2965         (match_operand:SWI248 3 "register_operand"))]
2966   ""
2968   rtx dst;
2970   if (ix86_expand_pinsr (operands))
2971     DONE;
2973   /* Handle insertions to %ah et al.  */
2974   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2975     FAIL;
2977   unsigned int regno = reg_or_subregno (operands[0]);
2979   /* Be careful to expand only with registers having upper parts.  */
2980   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2981     dst = copy_to_reg (operands[0]);
2982   else
2983     dst = operands[0];
2985   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2987   /* Fix up the destination if needed.  */
2988   if (dst != operands[0])
2989     emit_move_insn (operands[0], dst);
2991   DONE;
2994 (define_insn "*insvqi_1_mem_rex64"
2995   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2996                          (const_int 8)
2997                          (const_int 8))
2998         (subreg:SI
2999           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3000   "TARGET_64BIT && reload_completed"
3001   "mov{b}\t{%1, %h0|%h0, %1}"
3002   [(set_attr "type" "imov")
3003    (set_attr "mode" "QI")])
3005 (define_insn "insv<mode>_1"
3006   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3007                              (const_int 8)
3008                              (const_int 8))
3009         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3010   ""
3012   if (CONST_INT_P (operands[1]))
3013     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3014   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3016   [(set_attr "isa" "*,nox64")
3017    (set_attr "type" "imov")
3018    (set_attr "mode" "QI")])
3020 (define_insn "*insvqi_1"
3021   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3022                          (const_int 8)
3023                          (const_int 8))
3024         (subreg:SI
3025           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3026   ""
3027   "mov{b}\t{%1, %h0|%h0, %1}"
3028   [(set_attr "isa" "*,nox64")
3029    (set_attr "type" "imov")
3030    (set_attr "mode" "QI")])
3032 (define_peephole2
3033   [(set (match_operand:QI 0 "register_operand")
3034         (match_operand:QI 1 "norex_memory_operand"))
3035    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3036                          (const_int 8)
3037                          (const_int 8))
3038         (subreg:SI (match_dup 0) 0))]
3039   "TARGET_64BIT
3040    && peep2_reg_dead_p (2, operands[0])"
3041   [(set (zero_extract:SI (match_dup 2)
3042                          (const_int 8)
3043                          (const_int 8))
3044            (subreg:SI (match_dup 1) 0))])
3046 (define_code_iterator any_extract [sign_extract zero_extract])
3048 (define_insn "*insvqi_2"
3049   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3050                          (const_int 8)
3051                          (const_int 8))
3052         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3053                         (const_int 8)
3054                         (const_int 8)))]
3055   ""
3056   "mov{b}\t{%h1, %h0|%h0, %h1}"
3057   [(set_attr "type" "imov")
3058    (set_attr "mode" "QI")])
3060 (define_insn "*insvqi_3"
3061   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3062                          (const_int 8)
3063                          (const_int 8))
3064         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3065                         (const_int 8)))]
3066   ""
3067   "mov{b}\t{%h1, %h0|%h0, %h1}"
3068   [(set_attr "type" "imov")
3069    (set_attr "mode" "QI")])
3071 ;; Floating point push instructions.
3073 (define_insn "*pushtf"
3074   [(set (match_operand:TF 0 "push_operand" "=<,<")
3075         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3076   "TARGET_64BIT || TARGET_SSE"
3078   /* This insn should be already split before reg-stack.  */
3079   gcc_unreachable ();
3081   [(set_attr "isa" "*,x64")
3082    (set_attr "type" "multi")
3083    (set_attr "unit" "sse,*")
3084    (set_attr "mode" "TF,DI")])
3086 ;; %%% Kill this when call knows how to work this out.
3087 (define_split
3088   [(set (match_operand:TF 0 "push_operand")
3089         (match_operand:TF 1 "sse_reg_operand"))]
3090   "TARGET_SSE && reload_completed"
3091   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3092    (set (match_dup 0) (match_dup 1))]
3094   /* Preserve memory attributes. */
3095   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3098 (define_insn_and_split "*pushxf_rounded"
3099   [(set (mem:XF
3100           (pre_modify:P
3101             (reg:P SP_REG)
3102             (plus:P (reg:P SP_REG) (const_int -16))))
3103         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3104   "TARGET_64BIT"
3105   "#"
3106   "&& 1"
3107   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3108    (set (match_dup 1) (match_dup 0))]
3110   rtx pat = PATTERN (curr_insn);
3111   operands[1] = SET_DEST (pat);
3113   /* Preserve memory attributes. */
3114   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3116   [(set_attr "type" "multi")
3117    (set_attr "unit" "i387,*,*,*")
3118    (set (attr "mode")
3119         (cond [(eq_attr "alternative" "1,2,3")
3120                  (const_string "DI")
3121               ]
3122               (const_string "XF")))
3123    (set (attr "preferred_for_size")
3124      (cond [(eq_attr "alternative" "1")
3125               (symbol_ref "false")]
3126            (symbol_ref "true")))])
3128 (define_insn "*pushxf"
3129   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3130         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3131   ""
3133   /* This insn should be already split before reg-stack.  */
3134   gcc_unreachable ();
3136   [(set_attr "isa" "*,*,*,nox64,x64")
3137    (set_attr "type" "multi")
3138    (set_attr "unit" "i387,*,*,*,*")
3139    (set (attr "mode")
3140         (cond [(eq_attr "alternative" "1,2,3,4")
3141                  (if_then_else (match_test "TARGET_64BIT")
3142                    (const_string "DI")
3143                    (const_string "SI"))
3144               ]
3145               (const_string "XF")))
3146    (set (attr "preferred_for_size")
3147      (cond [(eq_attr "alternative" "1")
3148               (symbol_ref "false")]
3149            (symbol_ref "true")))])
3151 ;; %%% Kill this when call knows how to work this out.
3152 (define_split
3153   [(set (match_operand:XF 0 "push_operand")
3154         (match_operand:XF 1 "fp_register_operand"))]
3155   "reload_completed"
3156   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3157    (set (match_dup 0) (match_dup 1))]
3159   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3160   /* Preserve memory attributes. */
3161   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3164 (define_insn "*pushdf"
3165   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3166         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3167   ""
3169   /* This insn should be already split before reg-stack.  */
3170   gcc_unreachable ();
3172   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3173    (set_attr "type" "multi")
3174    (set_attr "unit" "i387,*,*,*,*,sse")
3175    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3176    (set (attr "preferred_for_size")
3177      (cond [(eq_attr "alternative" "1")
3178               (symbol_ref "false")]
3179            (symbol_ref "true")))
3180    (set (attr "preferred_for_speed")
3181      (cond [(eq_attr "alternative" "1")
3182               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3183            (symbol_ref "true")))])
3184    
3185 ;; %%% Kill this when call knows how to work this out.
3186 (define_split
3187   [(set (match_operand:DF 0 "push_operand")
3188         (match_operand:DF 1 "any_fp_register_operand"))]
3189   "reload_completed"
3190   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3191    (set (match_dup 0) (match_dup 1))]
3193   /* Preserve memory attributes. */
3194   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3197 (define_insn "*pushsf_rex64"
3198   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3199         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3200   "TARGET_64BIT"
3202   /* Anything else should be already split before reg-stack.  */
3203   gcc_assert (which_alternative == 1);
3204   return "push{q}\t%q1";
3206   [(set_attr "type" "multi,push,multi")
3207    (set_attr "unit" "i387,*,*")
3208    (set_attr "mode" "SF,DI,SF")])
3210 (define_insn "*pushsf"
3211   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3212         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3213   "!TARGET_64BIT"
3215   /* Anything else should be already split before reg-stack.  */
3216   gcc_assert (which_alternative == 1);
3217   return "push{l}\t%1";
3219   [(set_attr "type" "multi,push,multi")
3220    (set_attr "unit" "i387,*,*")
3221    (set_attr "mode" "SF,SI,SF")])
3223 ;; %%% Kill this when call knows how to work this out.
3224 (define_split
3225   [(set (match_operand:SF 0 "push_operand")
3226         (match_operand:SF 1 "any_fp_register_operand"))]
3227   "reload_completed"
3228   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3229    (set (match_dup 0) (match_dup 1))]
3231   rtx op = XEXP (operands[0], 0);
3232   if (GET_CODE (op) == PRE_DEC)
3233     {
3234       gcc_assert (!TARGET_64BIT);
3235       op = GEN_INT (-4);
3236     }
3237   else
3238     {
3239       op = XEXP (XEXP (op, 1), 1);
3240       gcc_assert (CONST_INT_P (op));
3241     }
3242   operands[2] = op;
3243   /* Preserve memory attributes. */
3244   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3247 (define_split
3248   [(set (match_operand:SF 0 "push_operand")
3249         (match_operand:SF 1 "memory_operand"))]
3250   "reload_completed
3251    && find_constant_src (insn)"
3252   [(set (match_dup 0) (match_dup 2))]
3253   "operands[2] = find_constant_src (curr_insn);")
3255 (define_split
3256   [(set (match_operand 0 "push_operand")
3257         (match_operand 1 "general_gr_operand"))]
3258   "reload_completed
3259    && (GET_MODE (operands[0]) == TFmode
3260        || GET_MODE (operands[0]) == XFmode
3261        || GET_MODE (operands[0]) == DFmode)"
3262   [(const_int 0)]
3263   "ix86_split_long_move (operands); DONE;")
3265 ;; Floating point move instructions.
3267 (define_expand "movtf"
3268   [(set (match_operand:TF 0 "nonimmediate_operand")
3269         (match_operand:TF 1 "nonimmediate_operand"))]
3270   "TARGET_64BIT || TARGET_SSE"
3271   "ix86_expand_move (TFmode, operands); DONE;")
3273 (define_expand "mov<mode>"
3274   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3275         (match_operand:X87MODEF 1 "general_operand"))]
3276   ""
3277   "ix86_expand_move (<MODE>mode, operands); DONE;")
3279 (define_insn "*movtf_internal"
3280   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3281         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3282   "(TARGET_64BIT || TARGET_SSE)
3283    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3284    && (lra_in_progress || reload_completed
3285        || !CONST_DOUBLE_P (operands[1])
3286        || ((optimize_function_for_size_p (cfun)
3287             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3288            && standard_sse_constant_p (operands[1], TFmode) == 1
3289            && !memory_operand (operands[0], TFmode))
3290        || (!TARGET_MEMORY_MISMATCH_STALL
3291            && memory_operand (operands[0], TFmode)))"
3293   switch (get_attr_type (insn))
3294     {
3295     case TYPE_SSELOG1:
3296       return standard_sse_constant_opcode (insn, operands[1]);
3298     case TYPE_SSEMOV:
3299       /* Handle misaligned load/store since we
3300          don't have movmisaligntf pattern. */
3301       if (misaligned_operand (operands[0], TFmode)
3302           || misaligned_operand (operands[1], TFmode))
3303         {
3304           if (get_attr_mode (insn) == MODE_V4SF)
3305             return "%vmovups\t{%1, %0|%0, %1}";
3306           else if (TARGET_AVX512VL
3307                    && (EXT_REX_SSE_REG_P (operands[0])
3308                        || EXT_REX_SSE_REG_P (operands[1])))
3309             return "vmovdqu64\t{%1, %0|%0, %1}";
3310           else
3311             return "%vmovdqu\t{%1, %0|%0, %1}";
3312         }
3313       else
3314         {
3315           if (get_attr_mode (insn) == MODE_V4SF)
3316             return "%vmovaps\t{%1, %0|%0, %1}";
3317           else if (TARGET_AVX512VL
3318                    && (EXT_REX_SSE_REG_P (operands[0])
3319                        || EXT_REX_SSE_REG_P (operands[1])))
3320             return "vmovdqa64\t{%1, %0|%0, %1}";
3321           else
3322             return "%vmovdqa\t{%1, %0|%0, %1}";
3323         }
3325     case TYPE_MULTI:
3326         return "#";
3328     default:
3329       gcc_unreachable ();
3330     }
3332   [(set_attr "isa" "*,*,*,x64,x64")
3333    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3334    (set (attr "prefix")
3335      (if_then_else (eq_attr "type" "sselog1,ssemov")
3336        (const_string "maybe_vex")
3337        (const_string "orig")))
3338    (set (attr "mode")
3339         (cond [(eq_attr "alternative" "3,4")
3340                  (const_string "DI")
3341                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3342                  (const_string "V4SF")
3343                (and (eq_attr "alternative" "2")
3344                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3345                  (const_string "V4SF")
3346                (match_test "TARGET_AVX")
3347                  (const_string "TI")
3348                (ior (not (match_test "TARGET_SSE2"))
3349                     (match_test "optimize_function_for_size_p (cfun)"))
3350                  (const_string "V4SF")
3351                ]
3352                (const_string "TI")))])
3354 (define_split
3355   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3356         (match_operand:TF 1 "general_gr_operand"))]
3357   "reload_completed"
3358   [(const_int 0)]
3359   "ix86_split_long_move (operands); DONE;")
3361 ;; Possible store forwarding (partial memory) stall
3362 ;; in alternatives 4, 6, 7 and 8.
3363 (define_insn "*movxf_internal"
3364   [(set (match_operand:XF 0 "nonimmediate_operand"
3365          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3366         (match_operand:XF 1 "general_operand"
3367          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3368   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3369    && (lra_in_progress || reload_completed
3370        || !CONST_DOUBLE_P (operands[1])
3371        || ((optimize_function_for_size_p (cfun)
3372             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3373            && standard_80387_constant_p (operands[1]) > 0
3374            && !memory_operand (operands[0], XFmode))
3375        || (!TARGET_MEMORY_MISMATCH_STALL
3376            && memory_operand (operands[0], XFmode))
3377        || !TARGET_HARD_XF_REGS)"
3379   switch (get_attr_type (insn))
3380     {
3381     case TYPE_FMOV:
3382       if (which_alternative == 2)
3383         return standard_80387_constant_opcode (operands[1]);
3384       return output_387_reg_move (insn, operands);
3386     case TYPE_MULTI:
3387       return "#";
3389     default:
3390       gcc_unreachable ();
3391     }
3393   [(set (attr "isa")
3394         (cond [(eq_attr "alternative" "7,10")
3395                  (const_string "nox64")
3396                (eq_attr "alternative" "8,11")
3397                  (const_string "x64")
3398               ]
3399               (const_string "*")))
3400    (set (attr "type")
3401         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3402                  (const_string "multi")
3403               ]
3404               (const_string "fmov")))
3405    (set (attr "mode")
3406         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3407                  (if_then_else (match_test "TARGET_64BIT")
3408                    (const_string "DI")
3409                    (const_string "SI"))
3410               ]
3411               (const_string "XF")))
3412    (set (attr "preferred_for_size")
3413      (cond [(eq_attr "alternative" "3,4")
3414               (symbol_ref "false")]
3415            (symbol_ref "true")))
3416    (set (attr "enabled")
3417      (cond [(eq_attr "alternative" "9,10,11")
3418               (if_then_else
3419                 (match_test "TARGET_HARD_XF_REGS")
3420                 (symbol_ref "false")
3421                 (const_string "*"))
3422             (not (match_test "TARGET_HARD_XF_REGS"))
3423               (symbol_ref "false")
3424            ]
3425            (const_string "*")))])
3426    
3427 (define_split
3428   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3429         (match_operand:XF 1 "general_gr_operand"))]
3430   "reload_completed"
3431   [(const_int 0)]
3432   "ix86_split_long_move (operands); DONE;")
3434 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3435 (define_insn "*movdf_internal"
3436   [(set (match_operand:DF 0 "nonimmediate_operand"
3437     "=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")
3438         (match_operand:DF 1 "general_operand"
3439     "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"))]
3440   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3441    && (lra_in_progress || reload_completed
3442        || !CONST_DOUBLE_P (operands[1])
3443        || ((optimize_function_for_size_p (cfun)
3444             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3445            && ((IS_STACK_MODE (DFmode)
3446                 && standard_80387_constant_p (operands[1]) > 0)
3447                || (TARGET_SSE2 && TARGET_SSE_MATH
3448                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3449            && !memory_operand (operands[0], DFmode))
3450        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3451            && memory_operand (operands[0], DFmode))
3452        || !TARGET_HARD_DF_REGS)"
3454   switch (get_attr_type (insn))
3455     {
3456     case TYPE_FMOV:
3457       if (which_alternative == 2)
3458         return standard_80387_constant_opcode (operands[1]);
3459       return output_387_reg_move (insn, operands);
3461     case TYPE_MULTI:
3462       return "#";
3464     case TYPE_IMOV:
3465       if (get_attr_mode (insn) == MODE_SI)
3466         return "mov{l}\t{%1, %k0|%k0, %1}";
3467       else if (which_alternative == 11)
3468         return "movabs{q}\t{%1, %0|%0, %1}";
3469       else
3470         return "mov{q}\t{%1, %0|%0, %1}";
3472     case TYPE_SSELOG1:
3473       return standard_sse_constant_opcode (insn, operands[1]);
3475     case TYPE_SSEMOV:
3476       switch (get_attr_mode (insn))
3477         {
3478         case MODE_DF:
3479           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3480             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3481           return "%vmovsd\t{%1, %0|%0, %1}";
3483         case MODE_V4SF:
3484           return "%vmovaps\t{%1, %0|%0, %1}";
3485         case MODE_V8DF:
3486           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3487         case MODE_V2DF:
3488           return "%vmovapd\t{%1, %0|%0, %1}";
3490         case MODE_V2SF:
3491           gcc_assert (!TARGET_AVX);
3492           return "movlps\t{%1, %0|%0, %1}";
3493         case MODE_V1DF:
3494           gcc_assert (!TARGET_AVX);
3495           return "movlpd\t{%1, %0|%0, %1}";
3497         case MODE_DI:
3498           /* Handle broken assemblers that require movd instead of movq.  */
3499           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3500               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3501             return "%vmovd\t{%1, %0|%0, %1}";
3502           return "%vmovq\t{%1, %0|%0, %1}";
3504         default:
3505           gcc_unreachable ();
3506         }
3508     default:
3509       gcc_unreachable ();
3510     }
3512   [(set (attr "isa")
3513         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3514                  (const_string "nox64")
3515                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3516                  (const_string "x64")
3517                (eq_attr "alternative" "12,13,14,15")
3518                  (const_string "sse2")
3519               ]
3520               (const_string "*")))
3521    (set (attr "type")
3522         (cond [(eq_attr "alternative" "0,1,2")
3523                  (const_string "fmov")
3524                (eq_attr "alternative" "3,4,5,6,7,22,23")
3525                  (const_string "multi")
3526                (eq_attr "alternative" "8,9,10,11,24,25")
3527                  (const_string "imov")
3528                (eq_attr "alternative" "12,16")
3529                  (const_string "sselog1")
3530               ]
3531               (const_string "ssemov")))
3532    (set (attr "modrm")
3533      (if_then_else (eq_attr "alternative" "11")
3534        (const_string "0")
3535        (const_string "*")))
3536    (set (attr "length_immediate")
3537      (if_then_else (eq_attr "alternative" "11")
3538        (const_string "8")
3539        (const_string "*")))
3540    (set (attr "prefix")
3541      (if_then_else (eq_attr "type" "sselog1,ssemov")
3542        (const_string "maybe_vex")
3543        (const_string "orig")))
3544    (set (attr "prefix_data16")
3545      (if_then_else
3546        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3547             (eq_attr "mode" "V1DF"))
3548        (const_string "1")
3549        (const_string "*")))
3550    (set (attr "mode")
3551         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3552                  (const_string "SI")
3553                (eq_attr "alternative" "8,9,11,20,21,24,25")
3554                  (const_string "DI")
3556                /* xorps is one byte shorter for non-AVX targets.  */
3557                (eq_attr "alternative" "12,16")
3558                  (cond [(not (match_test "TARGET_SSE2"))
3559                           (const_string "V4SF")
3560                         (and (match_test "TARGET_AVX512F")
3561                           (not (match_test "TARGET_PREFER_AVX256")))
3562                           (const_string "XI")
3563                         (match_test "TARGET_AVX")
3564                           (const_string "V2DF")
3565                         (match_test "optimize_function_for_size_p (cfun)")
3566                           (const_string "V4SF")
3567                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3568                           (const_string "TI")
3569                        ]
3570                        (const_string "V2DF"))
3572                /* For architectures resolving dependencies on
3573                   whole SSE registers use movapd to break dependency
3574                   chains, otherwise use short move to avoid extra work.  */
3576                /* movaps is one byte shorter for non-AVX targets.  */
3577                (eq_attr "alternative" "13,17")
3578                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3579                                   (not (match_test "TARGET_AVX512VL")))
3580                              (ior (match_operand 0 "ext_sse_reg_operand")
3581                                   (match_operand 1 "ext_sse_reg_operand")))
3582                           (const_string "V8DF")
3583                         (ior (not (match_test "TARGET_SSE2"))
3584                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3585                           (const_string "V4SF")
3586                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3587                           (const_string "V2DF")
3588                         (match_test "TARGET_AVX")
3589                           (const_string "DF")
3590                         (match_test "optimize_function_for_size_p (cfun)")
3591                           (const_string "V4SF")
3592                        ]
3593                        (const_string "DF"))
3595                /* For architectures resolving dependencies on register
3596                   parts we may avoid extra work to zero out upper part
3597                   of register.  */
3598                (eq_attr "alternative" "14,18")
3599                  (cond [(not (match_test "TARGET_SSE2"))
3600                           (const_string "V2SF")
3601                         (match_test "TARGET_AVX")
3602                           (const_string "DF")
3603                         (match_test "TARGET_SSE_SPLIT_REGS")
3604                           (const_string "V1DF")
3605                        ]
3606                        (const_string "DF"))
3608                (and (eq_attr "alternative" "15,19")
3609                     (not (match_test "TARGET_SSE2")))
3610                  (const_string "V2SF")
3611               ]
3612               (const_string "DF")))
3613    (set (attr "preferred_for_size")
3614      (cond [(eq_attr "alternative" "3,4")
3615               (symbol_ref "false")]
3616            (symbol_ref "true")))
3617    (set (attr "preferred_for_speed")
3618      (cond [(eq_attr "alternative" "3,4")
3619               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3620            (symbol_ref "true")))
3621    (set (attr "enabled")
3622      (cond [(eq_attr "alternative" "22,23,24,25")
3623               (if_then_else
3624                 (match_test "TARGET_HARD_DF_REGS")
3625                 (symbol_ref "false")
3626                 (const_string "*"))
3627             (not (match_test "TARGET_HARD_DF_REGS"))
3628               (symbol_ref "false")
3629            ]
3630            (const_string "*")))])
3632 (define_split
3633   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3634         (match_operand:DF 1 "general_gr_operand"))]
3635   "!TARGET_64BIT && reload_completed"
3636   [(const_int 0)]
3637   "ix86_split_long_move (operands); DONE;")
3639 (define_insn "*movsf_internal"
3640   [(set (match_operand:SF 0 "nonimmediate_operand"
3641           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3642         (match_operand:SF 1 "general_operand"
3643           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3644   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3645    && (lra_in_progress || reload_completed
3646        || !CONST_DOUBLE_P (operands[1])
3647        || ((optimize_function_for_size_p (cfun)
3648             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3649            && ((IS_STACK_MODE (SFmode)
3650                 && standard_80387_constant_p (operands[1]) > 0)
3651                || (TARGET_SSE && TARGET_SSE_MATH
3652                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3653        || memory_operand (operands[0], SFmode)
3654        || !TARGET_HARD_SF_REGS)"
3656   switch (get_attr_type (insn))
3657     {
3658     case TYPE_FMOV:
3659       if (which_alternative == 2)
3660         return standard_80387_constant_opcode (operands[1]);
3661       return output_387_reg_move (insn, operands);
3663     case TYPE_IMOV:
3664       return "mov{l}\t{%1, %0|%0, %1}";
3666     case TYPE_SSELOG1:
3667       return standard_sse_constant_opcode (insn, operands[1]);
3669     case TYPE_SSEMOV:
3670       switch (get_attr_mode (insn))
3671         {
3672         case MODE_SF:
3673           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3674             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3675           return "%vmovss\t{%1, %0|%0, %1}";
3677         case MODE_V16SF:
3678           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3679         case MODE_V4SF:
3680           return "%vmovaps\t{%1, %0|%0, %1}";
3682         case MODE_SI:
3683           return "%vmovd\t{%1, %0|%0, %1}";
3685         default:
3686           gcc_unreachable ();
3687         }
3689     case TYPE_MMXMOV:
3690       switch (get_attr_mode (insn))
3691         {
3692         case MODE_DI:
3693           return "movq\t{%1, %0|%0, %1}";
3694         case MODE_SI:
3695           return "movd\t{%1, %0|%0, %1}";
3697         default:
3698           gcc_unreachable ();
3699         }
3701     default:
3702       gcc_unreachable ();
3703     }
3705   [(set (attr "type")
3706         (cond [(eq_attr "alternative" "0,1,2")
3707                  (const_string "fmov")
3708                (eq_attr "alternative" "3,4,16,17")
3709                  (const_string "imov")
3710                (eq_attr "alternative" "5")
3711                  (const_string "sselog1")
3712                (eq_attr "alternative" "11,12,13,14,15")
3713                  (const_string "mmxmov")
3714               ]
3715               (const_string "ssemov")))
3716    (set (attr "prefix")
3717      (if_then_else (eq_attr "type" "sselog1,ssemov")
3718        (const_string "maybe_vex")
3719        (const_string "orig")))
3720    (set (attr "prefix_data16")
3721      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3722        (const_string "1")
3723        (const_string "*")))
3724    (set (attr "mode")
3725         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3726                  (const_string "SI")
3727                (eq_attr "alternative" "11")
3728                  (const_string "DI")
3729                (eq_attr "alternative" "5")
3730                  (cond [(not (match_test "TARGET_SSE2"))
3731                           (const_string "V4SF")
3732                         (and (match_test "TARGET_AVX512F")
3733                           (not (match_test "TARGET_PREFER_AVX256")))
3734                           (const_string "V16SF")
3735                         (match_test "TARGET_AVX")
3736                           (const_string "V4SF")
3737                         (match_test "optimize_function_for_size_p (cfun)")
3738                           (const_string "V4SF")
3739                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3740                           (const_string "TI")
3741                        ]
3742                        (const_string "V4SF"))
3744                /* For architectures resolving dependencies on
3745                   whole SSE registers use APS move to break dependency
3746                   chains, otherwise use short move to avoid extra work.
3748                   Do the same for architectures resolving dependencies on
3749                   the parts.  While in DF mode it is better to always handle
3750                   just register parts, the SF mode is different due to lack
3751                   of instructions to load just part of the register.  It is
3752                   better to maintain the whole registers in single format
3753                   to avoid problems on using packed logical operations.  */
3754                (eq_attr "alternative" "6")
3755                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3756                                   (not (match_test "TARGET_AVX512VL")))
3757                              (ior (match_operand 0 "ext_sse_reg_operand")
3758                                   (match_operand 1 "ext_sse_reg_operand")))
3759                           (const_string "V16SF")
3760                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3761                              (match_test "TARGET_SSE_SPLIT_REGS"))
3762                           (const_string "V4SF")
3763                        ]
3764                        (const_string "SF"))
3765               ]
3766               (const_string "SF")))
3767    (set (attr "enabled")
3768      (cond [(eq_attr "alternative" "16,17")
3769               (if_then_else
3770                 (match_test "TARGET_HARD_SF_REGS")
3771                 (symbol_ref "false")
3772                 (const_string "*"))
3773             (not (match_test "TARGET_HARD_SF_REGS"))
3774               (symbol_ref "false")
3775            ]
3776            (const_string "*")))])
3778 (define_split
3779   [(set (match_operand 0 "any_fp_register_operand")
3780         (match_operand 1 "nonimmediate_operand"))]
3781   "reload_completed
3782    && (GET_MODE (operands[0]) == TFmode
3783        || GET_MODE (operands[0]) == XFmode
3784        || GET_MODE (operands[0]) == DFmode
3785        || GET_MODE (operands[0]) == SFmode)
3786    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3787   [(set (match_dup 0) (match_dup 2))]
3788   "operands[2] = find_constant_src (curr_insn);")
3790 (define_split
3791   [(set (match_operand 0 "any_fp_register_operand")
3792         (float_extend (match_operand 1 "nonimmediate_operand")))]
3793   "reload_completed
3794    && (GET_MODE (operands[0]) == TFmode
3795        || GET_MODE (operands[0]) == XFmode
3796        || GET_MODE (operands[0]) == DFmode)
3797    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3798   [(set (match_dup 0) (match_dup 2))]
3799   "operands[2] = find_constant_src (curr_insn);")
3801 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3802 (define_split
3803   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3804         (match_operand:X87MODEF 1 "immediate_operand"))]
3805   "reload_completed
3806    && (standard_80387_constant_p (operands[1]) == 8
3807        || standard_80387_constant_p (operands[1]) == 9)"
3808   [(set (match_dup 0)(match_dup 1))
3809    (set (match_dup 0)
3810         (neg:X87MODEF (match_dup 0)))]
3812   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3813     operands[1] = CONST0_RTX (<MODE>mode);
3814   else
3815     operands[1] = CONST1_RTX (<MODE>mode);
3818 (define_insn "swapxf"
3819   [(set (match_operand:XF 0 "register_operand" "+f")
3820         (match_operand:XF 1 "register_operand" "+f"))
3821    (set (match_dup 1)
3822         (match_dup 0))]
3823   "TARGET_80387"
3825   if (STACK_TOP_P (operands[0]))
3826     return "fxch\t%1";
3827   else
3828     return "fxch\t%0";
3830   [(set_attr "type" "fxch")
3831    (set_attr "mode" "XF")])
3833 (define_insn "*swap<mode>"
3834   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3835         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3836    (set (match_dup 1)
3837         (match_dup 0))]
3838   "TARGET_80387 || reload_completed"
3840   if (STACK_TOP_P (operands[0]))
3841     return "fxch\t%1";
3842   else
3843     return "fxch\t%0";
3845   [(set_attr "type" "fxch")
3846    (set_attr "mode" "<MODE>")])
3848 ;; Zero extension instructions
3850 (define_expand "zero_extendsidi2"
3851   [(set (match_operand:DI 0 "nonimmediate_operand")
3852         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3854 (define_insn "*zero_extendsidi2"
3855   [(set (match_operand:DI 0 "nonimmediate_operand"
3856                 "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?*Yi,*x,*x,*v,*r")
3857         (zero_extend:DI
3858          (match_operand:SI 1 "x86_64_zext_operand"
3859                 "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,r   ,m ,*x,*v,*k")))]
3860   ""
3862   switch (get_attr_type (insn))
3863     {
3864     case TYPE_IMOVX:
3865       if (ix86_use_lea_for_mov (insn, operands))
3866         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3867       else
3868         return "mov{l}\t{%1, %k0|%k0, %1}";
3870     case TYPE_MULTI:
3871       return "#";
3873     case TYPE_MMXMOV:
3874       return "movd\t{%1, %0|%0, %1}";
3876     case TYPE_SSEMOV:
3877       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3878         {
3879           if (EXT_REX_SSE_REG_P (operands[0])
3880               || EXT_REX_SSE_REG_P (operands[1]))
3881             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3882           else
3883             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3884         }
3886       if (GENERAL_REG_P (operands[0]))
3887         return "%vmovd\t{%1, %k0|%k0, %1}";
3889       return "%vmovd\t{%1, %0|%0, %1}";
3891     case TYPE_MSKMOV:
3892       return "kmovd\t{%1, %k0|%k0, %1}";
3894     default:
3895       gcc_unreachable ();
3896     }
3898   [(set (attr "isa")
3899      (cond [(eq_attr "alternative" "0,1,2")
3900               (const_string "nox64")
3901             (eq_attr "alternative" "3")
3902               (const_string "x64")
3903             (eq_attr "alternative" "9")
3904               (const_string "sse2")
3905             (eq_attr "alternative" "10")
3906               (const_string "sse4")
3907             (eq_attr "alternative" "11")
3908               (const_string "avx512f")
3909             (eq_attr "alternative" "12")
3910               (const_string "x64_avx512bw")
3911            ]
3912            (const_string "*")))
3913    (set (attr "type")
3914      (cond [(eq_attr "alternative" "0,1,2,4")
3915               (const_string "multi")
3916             (eq_attr "alternative" "5,6")
3917               (const_string "mmxmov")
3918             (eq_attr "alternative" "7")
3919               (if_then_else (match_test "TARGET_64BIT")
3920                 (const_string "ssemov")
3921                 (const_string "multi"))
3922             (eq_attr "alternative" "8,9,10,11")
3923               (const_string "ssemov")
3924             (eq_attr "alternative" "12")
3925               (const_string "mskmov")
3926            ]
3927            (const_string "imovx")))
3928    (set (attr "prefix_extra")
3929      (if_then_else (eq_attr "alternative" "10,11")
3930        (const_string "1")
3931        (const_string "*")))
3932    (set (attr "prefix")
3933      (if_then_else (eq_attr "type" "ssemov")
3934        (const_string "maybe_vex")
3935        (const_string "orig")))
3936    (set (attr "prefix_0f")
3937      (if_then_else (eq_attr "type" "imovx")
3938        (const_string "0")
3939        (const_string "*")))
3940    (set (attr "mode")
3941      (cond [(eq_attr "alternative" "5,6")
3942               (const_string "DI")
3943             (and (eq_attr "alternative" "7")
3944                  (match_test "TARGET_64BIT"))
3945               (const_string "TI")
3946             (eq_attr "alternative" "8,10,11")
3947               (const_string "TI")
3948            ]
3949            (const_string "SI")))])
3951 (define_split
3952   [(set (match_operand:DI 0 "memory_operand")
3953         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3954   "reload_completed"
3955   [(set (match_dup 4) (const_int 0))]
3956   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3958 (define_split
3959   [(set (match_operand:DI 0 "general_reg_operand")
3960         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3961   "!TARGET_64BIT && reload_completed
3962    && REGNO (operands[0]) == REGNO (operands[1])"
3963   [(set (match_dup 4) (const_int 0))]
3964   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3966 (define_split
3967   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3968         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3969   "!TARGET_64BIT && reload_completed
3970    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3971   [(set (match_dup 3) (match_dup 1))
3972    (set (match_dup 4) (const_int 0))]
3973   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3975 (define_peephole2
3976   [(set (match_operand:DI 0 "general_reg_operand")
3977         (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))
3978    (set (match_operand:DI 2 "sse_reg_operand") (match_dup 0))]
3979   "TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
3980    && peep2_reg_dead_p (2, operands[0])"
3981   [(set (match_dup 2)
3982         (zero_extend:DI (match_dup 1)))])
3984 (define_mode_attr kmov_isa
3985   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3987 (define_insn "zero_extend<mode>di2"
3988   [(set (match_operand:DI 0 "register_operand" "=r,*r")
3989         (zero_extend:DI
3990          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3991   "TARGET_64BIT"
3992   "@
3993    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3994    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3995   [(set_attr "isa" "*,<kmov_isa>")
3996    (set_attr "type" "imovx,mskmov")
3997    (set_attr "mode" "SI,<MODE>")])
3999 (define_expand "zero_extend<mode>si2"
4000   [(set (match_operand:SI 0 "register_operand")
4001         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4002   ""
4004   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4005     {
4006       operands[1] = force_reg (<MODE>mode, operands[1]);
4007       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4008       DONE;
4009     }
4012 (define_insn_and_split "zero_extend<mode>si2_and"
4013   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4014         (zero_extend:SI
4015           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4016    (clobber (reg:CC FLAGS_REG))]
4017   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4018   "#"
4019   "&& reload_completed"
4020   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4021               (clobber (reg:CC FLAGS_REG))])]
4023   if (!REG_P (operands[1])
4024       || REGNO (operands[0]) != REGNO (operands[1]))
4025     {
4026       ix86_expand_clear (operands[0]);
4028       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4029       emit_insn (gen_movstrict<mode>
4030                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4031       DONE;
4032     }
4034   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4036   [(set_attr "type" "alu1")
4037    (set_attr "mode" "SI")])
4039 (define_insn "*zero_extend<mode>si2"
4040   [(set (match_operand:SI 0 "register_operand" "=r,*r")
4041         (zero_extend:SI
4042           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4043   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4044   "@
4045    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4046    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4047   [(set_attr "isa" "*,<kmov_isa>")
4048    (set_attr "type" "imovx,mskmov")
4049    (set_attr "mode" "SI,<MODE>")])
4051 (define_expand "zero_extendqihi2"
4052   [(set (match_operand:HI 0 "register_operand")
4053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4054   ""
4056   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4057     {
4058       operands[1] = force_reg (QImode, operands[1]);
4059       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4060       DONE;
4061     }
4064 (define_insn_and_split "zero_extendqihi2_and"
4065   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4066         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4067    (clobber (reg:CC FLAGS_REG))]
4068   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4069   "#"
4070   "&& reload_completed"
4071   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4072               (clobber (reg:CC FLAGS_REG))])]
4074   if (!REG_P (operands[1])
4075       || REGNO (operands[0]) != REGNO (operands[1]))
4076     {
4077       ix86_expand_clear (operands[0]);
4079       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4080       emit_insn (gen_movstrictqi
4081                   (gen_lowpart (QImode, operands[0]), operands[1]));
4082       DONE;
4083     }
4085   operands[0] = gen_lowpart (SImode, operands[0]);
4087   [(set_attr "type" "alu1")
4088    (set_attr "mode" "SI")])
4090 ; zero extend to SImode to avoid partial register stalls
4091 (define_insn "*zero_extendqihi2"
4092   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4093         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4094   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4095   "@
4096    movz{bl|x}\t{%1, %k0|%k0, %1}
4097    kmovb\t{%1, %k0|%k0, %1}"
4098   [(set_attr "isa" "*,avx512dq")
4099    (set_attr "type" "imovx,mskmov")
4100    (set_attr "mode" "SI,QI")])
4102 (define_insn_and_split "*zext<mode>_doubleword_and"
4103   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4104         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4105   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4106    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4107   "#"
4108   "&& reload_completed && GENERAL_REG_P (operands[0])"
4109   [(set (match_dup 2) (const_int 0))]
4111   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4113   emit_move_insn (operands[0], const0_rtx);
4115   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4116   emit_insn (gen_movstrict<mode>
4117              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4120 (define_insn_and_split "*zext<mode>_doubleword"
4121   [(set (match_operand:DI 0 "register_operand" "=r")
4122         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4123   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4124    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4125   "#"
4126   "&& reload_completed && GENERAL_REG_P (operands[0])"
4127   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4128    (set (match_dup 2) (const_int 0))]
4129   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4131 (define_insn_and_split "*zextsi_doubleword"
4132   [(set (match_operand:DI 0 "register_operand" "=r")
4133         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4134   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4135   "#"
4136   "&& reload_completed && GENERAL_REG_P (operands[0])"
4137   [(set (match_dup 0) (match_dup 1))
4138    (set (match_dup 2) (const_int 0))]
4139   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4141 ;; Sign extension instructions
4143 (define_expand "extendsidi2"
4144   [(set (match_operand:DI 0 "register_operand")
4145         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4146   ""
4148   if (!TARGET_64BIT)
4149     {
4150       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4151       DONE;
4152     }
4155 (define_insn "*extendsidi2_rex64"
4156   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4157         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4158   "TARGET_64BIT"
4159   "@
4160    {cltq|cdqe}
4161    movs{lq|x}\t{%1, %0|%0, %1}"
4162   [(set_attr "type" "imovx")
4163    (set_attr "mode" "DI")
4164    (set_attr "prefix_0f" "0")
4165    (set_attr "modrm" "0,1")])
4167 (define_insn "extendsidi2_1"
4168   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4169         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4170    (clobber (reg:CC FLAGS_REG))
4171    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4172   "!TARGET_64BIT"
4173   "#")
4175 ;; Split the memory case.  If the source register doesn't die, it will stay
4176 ;; this way, if it does die, following peephole2s take care of it.
4177 (define_split
4178   [(set (match_operand:DI 0 "memory_operand")
4179         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4180    (clobber (reg:CC FLAGS_REG))
4181    (clobber (match_operand:SI 2 "register_operand"))]
4182   "reload_completed"
4183   [(const_int 0)]
4185   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4187   emit_move_insn (operands[3], operands[1]);
4189   /* Generate a cltd if possible and doing so it profitable.  */
4190   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4191       && REGNO (operands[1]) == AX_REG
4192       && REGNO (operands[2]) == DX_REG)
4193     {
4194       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4195     }
4196   else
4197     {
4198       emit_move_insn (operands[2], operands[1]);
4199       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4200     }
4201   emit_move_insn (operands[4], operands[2]);
4202   DONE;
4205 ;; Peepholes for the case where the source register does die, after
4206 ;; being split with the above splitter.
4207 (define_peephole2
4208   [(set (match_operand:SI 0 "memory_operand")
4209         (match_operand:SI 1 "general_reg_operand"))
4210    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4211    (parallel [(set (match_dup 2)
4212                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4213                (clobber (reg:CC FLAGS_REG))])
4214    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4215   "REGNO (operands[1]) != REGNO (operands[2])
4216    && peep2_reg_dead_p (2, operands[1])
4217    && peep2_reg_dead_p (4, operands[2])
4218    && !reg_mentioned_p (operands[2], operands[3])"
4219   [(set (match_dup 0) (match_dup 1))
4220    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4221               (clobber (reg:CC FLAGS_REG))])
4222    (set (match_dup 3) (match_dup 1))])
4224 (define_peephole2
4225   [(set (match_operand:SI 0 "memory_operand")
4226         (match_operand:SI 1 "general_reg_operand"))
4227    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4228                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4229                (clobber (reg:CC FLAGS_REG))])
4230    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4231   "/* cltd is shorter than sarl $31, %eax */
4232    !optimize_function_for_size_p (cfun)
4233    && REGNO (operands[1]) == AX_REG
4234    && REGNO (operands[2]) == DX_REG
4235    && peep2_reg_dead_p (2, operands[1])
4236    && peep2_reg_dead_p (3, operands[2])
4237    && !reg_mentioned_p (operands[2], operands[3])"
4238   [(set (match_dup 0) (match_dup 1))
4239    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4240               (clobber (reg:CC FLAGS_REG))])
4241    (set (match_dup 3) (match_dup 1))])
4243 ;; Extend to register case.  Optimize case where source and destination
4244 ;; registers match and cases where we can use cltd.
4245 (define_split
4246   [(set (match_operand:DI 0 "register_operand")
4247         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4248    (clobber (reg:CC FLAGS_REG))
4249    (clobber (match_scratch:SI 2))]
4250   "reload_completed"
4251   [(const_int 0)]
4253   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4255   if (REGNO (operands[3]) != REGNO (operands[1]))
4256     emit_move_insn (operands[3], operands[1]);
4258   /* Generate a cltd if possible and doing so it profitable.  */
4259   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4260       && REGNO (operands[3]) == AX_REG
4261       && REGNO (operands[4]) == DX_REG)
4262     {
4263       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4264       DONE;
4265     }
4267   if (REGNO (operands[4]) != REGNO (operands[1]))
4268     emit_move_insn (operands[4], operands[1]);
4270   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4271   DONE;
4274 (define_insn "extend<mode>di2"
4275   [(set (match_operand:DI 0 "register_operand" "=r")
4276         (sign_extend:DI
4277          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4278   "TARGET_64BIT"
4279   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4280   [(set_attr "type" "imovx")
4281    (set_attr "mode" "DI")])
4283 (define_insn "extendhisi2"
4284   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4285         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4286   ""
4288   switch (get_attr_prefix_0f (insn))
4289     {
4290     case 0:
4291       return "{cwtl|cwde}";
4292     default:
4293       return "movs{wl|x}\t{%1, %0|%0, %1}";
4294     }
4296   [(set_attr "type" "imovx")
4297    (set_attr "mode" "SI")
4298    (set (attr "prefix_0f")
4299      ;; movsx is short decodable while cwtl is vector decoded.
4300      (if_then_else (and (eq_attr "cpu" "!k6")
4301                         (eq_attr "alternative" "0"))
4302         (const_string "0")
4303         (const_string "1")))
4304    (set (attr "znver1_decode")
4305      (if_then_else (eq_attr "prefix_0f" "0")
4306         (const_string "double")
4307         (const_string "direct")))
4308    (set (attr "modrm")
4309      (if_then_else (eq_attr "prefix_0f" "0")
4310         (const_string "0")
4311         (const_string "1")))])
4313 (define_insn "*extendhisi2_zext"
4314   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4315         (zero_extend:DI
4316          (sign_extend:SI
4317           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4318   "TARGET_64BIT"
4320   switch (get_attr_prefix_0f (insn))
4321     {
4322     case 0:
4323       return "{cwtl|cwde}";
4324     default:
4325       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4326     }
4328   [(set_attr "type" "imovx")
4329    (set_attr "mode" "SI")
4330    (set (attr "prefix_0f")
4331      ;; movsx is short decodable while cwtl is vector decoded.
4332      (if_then_else (and (eq_attr "cpu" "!k6")
4333                         (eq_attr "alternative" "0"))
4334         (const_string "0")
4335         (const_string "1")))
4336    (set (attr "modrm")
4337      (if_then_else (eq_attr "prefix_0f" "0")
4338         (const_string "0")
4339         (const_string "1")))])
4341 (define_insn "extendqisi2"
4342   [(set (match_operand:SI 0 "register_operand" "=r")
4343         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4344   ""
4345   "movs{bl|x}\t{%1, %0|%0, %1}"
4346    [(set_attr "type" "imovx")
4347     (set_attr "mode" "SI")])
4349 (define_insn "*extendqisi2_zext"
4350   [(set (match_operand:DI 0 "register_operand" "=r")
4351         (zero_extend:DI
4352           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4353   "TARGET_64BIT"
4354   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4355    [(set_attr "type" "imovx")
4356     (set_attr "mode" "SI")])
4358 (define_insn "extendqihi2"
4359   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4360         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4361   ""
4363   switch (get_attr_prefix_0f (insn))
4364     {
4365     case 0:
4366       return "{cbtw|cbw}";
4367     default:
4368       return "movs{bw|x}\t{%1, %0|%0, %1}";
4369     }
4371   [(set_attr "type" "imovx")
4372    (set_attr "mode" "HI")
4373    (set (attr "prefix_0f")
4374      ;; movsx is short decodable while cwtl is vector decoded.
4375      (if_then_else (and (eq_attr "cpu" "!k6")
4376                         (eq_attr "alternative" "0"))
4377         (const_string "0")
4378         (const_string "1")))
4379    (set (attr "modrm")
4380      (if_then_else (eq_attr "prefix_0f" "0")
4381         (const_string "0")
4382         (const_string "1")))])
4384 ;; Conversions between float and double.
4386 ;; These are all no-ops in the model used for the 80387.
4387 ;; So just emit moves.
4389 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4390 (define_split
4391   [(set (match_operand:DF 0 "push_operand")
4392         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4393   "reload_completed"
4394   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4395    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4397 (define_split
4398   [(set (match_operand:XF 0 "push_operand")
4399         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4400   "reload_completed"
4401   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4402    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4403   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4405 (define_expand "extendsfdf2"
4406   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4407         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4408   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4410   /* ??? Needed for compress_float_constant since all fp constants
4411      are TARGET_LEGITIMATE_CONSTANT_P.  */
4412   if (CONST_DOUBLE_P (operands[1]))
4413     {
4414       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4415           && standard_80387_constant_p (operands[1]) > 0)
4416         {
4417           operands[1] = simplify_const_unary_operation
4418             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4419           emit_move_insn_1 (operands[0], operands[1]);
4420           DONE;
4421         }
4422       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4423     }
4426 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4427    cvtss2sd:
4428       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4429       cvtps2pd xmm2,xmm1
4430    We do the conversion post reload to avoid producing of 128bit spills
4431    that might lead to ICE on 32bit target.  The sequence unlikely combine
4432    anyway.  */
4433 (define_split
4434   [(set (match_operand:DF 0 "sse_reg_operand")
4435         (float_extend:DF
4436           (match_operand:SF 1 "nonimmediate_operand")))]
4437   "TARGET_USE_VECTOR_FP_CONVERTS
4438    && optimize_insn_for_speed_p ()
4439    && reload_completed
4440    && (!EXT_REX_SSE_REG_P (operands[0])
4441        || TARGET_AVX512VL)"
4442    [(set (match_dup 2)
4443          (float_extend:V2DF
4444            (vec_select:V2SF
4445              (match_dup 3)
4446              (parallel [(const_int 0) (const_int 1)]))))]
4448   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4449   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4450   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4451      Try to avoid move when unpacking can be done in source.  */
4452   if (REG_P (operands[1]))
4453     {
4454       /* If it is unsafe to overwrite upper half of source, we need
4455          to move to destination and unpack there.  */
4456       if (REGNO (operands[0]) != REGNO (operands[1])
4457           || (EXT_REX_SSE_REG_P (operands[1])
4458               && !TARGET_AVX512VL))
4459         {
4460           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4461           emit_move_insn (tmp, operands[1]);
4462         }
4463       else
4464         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4465       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4466          =v, v, then vbroadcastss will be only needed for AVX512F without
4467          AVX512VL.  */
4468       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4469         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4470                                                operands[3]));
4471       else
4472         {
4473           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4474           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4475         }
4476     }
4477   else
4478     emit_insn (gen_vec_setv4sf_0 (operands[3],
4479                                   CONST0_RTX (V4SFmode), operands[1]));
4482 ;; It's more profitable to split and then extend in the same register.
4483 (define_peephole2
4484   [(set (match_operand:DF 0 "sse_reg_operand")
4485         (float_extend:DF
4486           (match_operand:SF 1 "memory_operand")))]
4487   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4488    && optimize_insn_for_speed_p ()"
4489   [(set (match_dup 2) (match_dup 1))
4490    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4491   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4493 (define_insn "*extendsfdf2"
4494   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4495         (float_extend:DF
4496           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4497   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4499   switch (which_alternative)
4500     {
4501     case 0:
4502     case 1:
4503       return output_387_reg_move (insn, operands);
4505     case 2:
4506       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4508     default:
4509       gcc_unreachable ();
4510     }
4512   [(set_attr "type" "fmov,fmov,ssecvt")
4513    (set_attr "prefix" "orig,orig,maybe_vex")
4514    (set_attr "mode" "SF,XF,DF")
4515    (set (attr "enabled")
4516      (if_then_else
4517        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4518        (if_then_else
4519          (eq_attr "alternative" "0,1")
4520          (symbol_ref "TARGET_MIX_SSE_I387")
4521          (symbol_ref "true"))
4522        (if_then_else
4523          (eq_attr "alternative" "0,1")
4524          (symbol_ref "true")
4525          (symbol_ref "false"))))])
4527 (define_expand "extend<mode>xf2"
4528   [(set (match_operand:XF 0 "nonimmediate_operand")
4529         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4530   "TARGET_80387"
4532   /* ??? Needed for compress_float_constant since all fp constants
4533      are TARGET_LEGITIMATE_CONSTANT_P.  */
4534   if (CONST_DOUBLE_P (operands[1]))
4535     {
4536       if (standard_80387_constant_p (operands[1]) > 0)
4537         {
4538           operands[1] = simplify_const_unary_operation
4539             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4540           emit_move_insn_1 (operands[0], operands[1]);
4541           DONE;
4542         }
4543       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4544     }
4547 (define_insn "*extend<mode>xf2_i387"
4548   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4549         (float_extend:XF
4550           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4551   "TARGET_80387"
4552   "* return output_387_reg_move (insn, operands);"
4553   [(set_attr "type" "fmov")
4554    (set_attr "mode" "<MODE>,XF")])
4556 ;; %%% This seems like bad news.
4557 ;; This cannot output into an f-reg because there is no way to be sure
4558 ;; of truncating in that case.  Otherwise this is just like a simple move
4559 ;; insn.  So we pretend we can output to a reg in order to get better
4560 ;; register preferencing, but we really use a stack slot.
4562 ;; Conversion from DFmode to SFmode.
4564 (define_expand "truncdfsf2"
4565   [(set (match_operand:SF 0 "nonimmediate_operand")
4566         (float_truncate:SF
4567           (match_operand:DF 1 "nonimmediate_operand")))]
4568   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4570   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4571     ;
4572   else if (flag_unsafe_math_optimizations)
4573     ;
4574   else
4575     {
4576       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4577       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4578       DONE;
4579     }
4582 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4583    cvtsd2ss:
4584       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4585       cvtpd2ps xmm2,xmm1
4586    We do the conversion post reload to avoid producing of 128bit spills
4587    that might lead to ICE on 32bit target.  The sequence unlikely combine
4588    anyway.  */
4589 (define_split
4590   [(set (match_operand:SF 0 "sse_reg_operand")
4591         (float_truncate:SF
4592           (match_operand:DF 1 "nonimmediate_operand")))]
4593   "TARGET_USE_VECTOR_FP_CONVERTS
4594    && optimize_insn_for_speed_p ()
4595    && reload_completed
4596    && (!EXT_REX_SSE_REG_P (operands[0])
4597        || TARGET_AVX512VL)"
4598    [(set (match_dup 2)
4599          (vec_concat:V4SF
4600            (float_truncate:V2SF
4601              (match_dup 4))
4602            (match_dup 3)))]
4604   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4605   operands[3] = CONST0_RTX (V2SFmode);
4606   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4607   /* Use movsd for loading from memory, unpcklpd for registers.
4608      Try to avoid move when unpacking can be done in source, or SSE3
4609      movddup is available.  */
4610   if (REG_P (operands[1]))
4611     {
4612       if (!TARGET_SSE3
4613           && REGNO (operands[0]) != REGNO (operands[1]))
4614         {
4615           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4616           emit_move_insn (tmp, operands[1]);
4617           operands[1] = tmp;
4618         }
4619       else if (!TARGET_SSE3)
4620         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4621       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4622     }
4623   else
4624     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4625                                    CONST0_RTX (DFmode)));
4628 ;; It's more profitable to split and then extend in the same register.
4629 (define_peephole2
4630   [(set (match_operand:SF 0 "sse_reg_operand")
4631         (float_truncate:SF
4632           (match_operand:DF 1 "memory_operand")))]
4633   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4634    && optimize_insn_for_speed_p ()"
4635   [(set (match_dup 2) (match_dup 1))
4636    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4637   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4639 (define_expand "truncdfsf2_with_temp"
4640   [(parallel [(set (match_operand:SF 0)
4641                    (float_truncate:SF (match_operand:DF 1)))
4642               (clobber (match_operand:SF 2))])])
4644 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4645 ;; because nothing we do there is unsafe.
4646 (define_insn "*truncdfsf_fast_mixed"
4647   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4648         (float_truncate:SF
4649           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4650   "TARGET_SSE2 && TARGET_SSE_MATH"
4652   switch (which_alternative)
4653     {
4654     case 0:
4655       return output_387_reg_move (insn, operands);
4656     case 1:
4657       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4658     default:
4659       gcc_unreachable ();
4660     }
4662   [(set_attr "type" "fmov,ssecvt")
4663    (set_attr "prefix" "orig,maybe_vex")
4664    (set_attr "mode" "SF")
4665    (set (attr "enabled")
4666      (cond [(eq_attr "alternative" "0")
4667               (symbol_ref "TARGET_MIX_SSE_I387
4668                            && flag_unsafe_math_optimizations")
4669            ]
4670            (symbol_ref "true")))])
4672 (define_insn "*truncdfsf_fast_i387"
4673   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4674         (float_truncate:SF
4675           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4676   "TARGET_80387 && flag_unsafe_math_optimizations"
4677   "* return output_387_reg_move (insn, operands);"
4678   [(set_attr "type" "fmov")
4679    (set_attr "mode" "SF")])
4681 (define_insn "*truncdfsf_mixed"
4682   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4683         (float_truncate:SF
4684           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4685    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4686   "TARGET_MIX_SSE_I387"
4688   switch (which_alternative)
4689     {
4690     case 0:
4691       return output_387_reg_move (insn, operands);
4692     case 1:
4693       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4695     default:
4696       return "#";
4697     }
4699   [(set_attr "isa" "*,sse2,*,*,*")
4700    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4701    (set_attr "unit" "*,*,i387,i387,i387")
4702    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4703    (set_attr "mode" "SF")])
4705 (define_insn "*truncdfsf_i387"
4706   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4707         (float_truncate:SF
4708           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4709    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4710   "TARGET_80387"
4712   switch (which_alternative)
4713     {
4714     case 0:
4715       return output_387_reg_move (insn, operands);
4717     default:
4718       return "#";
4719     }
4721   [(set_attr "type" "fmov,multi,multi,multi")
4722    (set_attr "unit" "*,i387,i387,i387")
4723    (set_attr "mode" "SF")])
4725 (define_insn "*truncdfsf2_i387_1"
4726   [(set (match_operand:SF 0 "memory_operand" "=m")
4727         (float_truncate:SF
4728           (match_operand:DF 1 "register_operand" "f")))]
4729   "TARGET_80387
4730    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4731    && !TARGET_MIX_SSE_I387"
4732   "* return output_387_reg_move (insn, operands);"
4733   [(set_attr "type" "fmov")
4734    (set_attr "mode" "SF")])
4736 (define_split
4737   [(set (match_operand:SF 0 "register_operand")
4738         (float_truncate:SF
4739          (match_operand:DF 1 "fp_register_operand")))
4740    (clobber (match_operand 2))]
4741   "reload_completed"
4742   [(set (match_dup 2) (match_dup 1))
4743    (set (match_dup 0) (match_dup 2))]
4744   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4746 ;; Conversion from XFmode to {SF,DF}mode
4748 (define_expand "truncxf<mode>2"
4749   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4750                    (float_truncate:MODEF
4751                      (match_operand:XF 1 "register_operand")))
4752               (clobber (match_dup 2))])]
4753   "TARGET_80387"
4755   if (flag_unsafe_math_optimizations)
4756     {
4757       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4758       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4759       if (reg != operands[0])
4760         emit_move_insn (operands[0], reg);
4761       DONE;
4762     }
4763   else
4764     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4767 (define_insn "*truncxfsf2_mixed"
4768   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4769         (float_truncate:SF
4770           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4771    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4772   "TARGET_80387"
4774   gcc_assert (!which_alternative);
4775   return output_387_reg_move (insn, operands);
4777   [(set_attr "type" "fmov,multi,multi,multi")
4778    (set_attr "unit" "*,i387,i387,i387")
4779    (set_attr "mode" "SF")])
4781 (define_insn "*truncxfdf2_mixed"
4782   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4783         (float_truncate:DF
4784           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4785    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4786   "TARGET_80387"
4788   gcc_assert (!which_alternative);
4789   return output_387_reg_move (insn, operands);
4791   [(set_attr "isa" "*,*,sse2,*")
4792    (set_attr "type" "fmov,multi,multi,multi")
4793    (set_attr "unit" "*,i387,i387,i387")
4794    (set_attr "mode" "DF")])
4796 (define_insn "truncxf<mode>2_i387_noop"
4797   [(set (match_operand:MODEF 0 "register_operand" "=f")
4798         (float_truncate:MODEF
4799           (match_operand:XF 1 "register_operand" "f")))]
4800   "TARGET_80387 && flag_unsafe_math_optimizations"
4801   "* return output_387_reg_move (insn, operands);"
4802   [(set_attr "type" "fmov")
4803    (set_attr "mode" "<MODE>")])
4805 (define_insn "*truncxf<mode>2_i387"
4806   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4807         (float_truncate:MODEF
4808           (match_operand:XF 1 "register_operand" "f")))]
4809   "TARGET_80387"
4810   "* return output_387_reg_move (insn, operands);"
4811   [(set_attr "type" "fmov")
4812    (set_attr "mode" "<MODE>")])
4814 (define_split
4815   [(set (match_operand:MODEF 0 "register_operand")
4816         (float_truncate:MODEF
4817           (match_operand:XF 1 "register_operand")))
4818    (clobber (match_operand:MODEF 2 "memory_operand"))]
4819   "TARGET_80387 && reload_completed"
4820   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4821    (set (match_dup 0) (match_dup 2))])
4823 (define_split
4824   [(set (match_operand:MODEF 0 "memory_operand")
4825         (float_truncate:MODEF
4826           (match_operand:XF 1 "register_operand")))
4827    (clobber (match_operand:MODEF 2 "memory_operand"))]
4828   "TARGET_80387"
4829   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4831 ;; Signed conversion to DImode.
4833 (define_expand "fix_truncxfdi2"
4834   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4835                    (fix:DI (match_operand:XF 1 "register_operand")))
4836               (clobber (reg:CC FLAGS_REG))])]
4837   "TARGET_80387"
4839   if (TARGET_FISTTP)
4840    {
4841      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4842      DONE;
4843    }
4846 (define_expand "fix_trunc<mode>di2"
4847   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4848                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4849               (clobber (reg:CC FLAGS_REG))])]
4850   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4852   if (TARGET_FISTTP
4853       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4854    {
4855      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4856      DONE;
4857    }
4858   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4859    {
4860      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4861      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4862      if (out != operands[0])
4863         emit_move_insn (operands[0], out);
4864      DONE;
4865    }
4868 ;; Signed conversion to SImode.
4870 (define_expand "fix_truncxfsi2"
4871   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4872                    (fix:SI (match_operand:XF 1 "register_operand")))
4873               (clobber (reg:CC FLAGS_REG))])]
4874   "TARGET_80387"
4876   if (TARGET_FISTTP)
4877    {
4878      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4879      DONE;
4880    }
4883 (define_expand "fix_trunc<mode>si2"
4884   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4885                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4886               (clobber (reg:CC FLAGS_REG))])]
4887   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4889   if (TARGET_FISTTP
4890       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4891    {
4892      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4893      DONE;
4894    }
4895   if (SSE_FLOAT_MODE_P (<MODE>mode))
4896    {
4897      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4898      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4899      if (out != operands[0])
4900         emit_move_insn (operands[0], out);
4901      DONE;
4902    }
4905 ;; Signed conversion to HImode.
4907 (define_expand "fix_trunc<mode>hi2"
4908   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4909                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4910               (clobber (reg:CC FLAGS_REG))])]
4911   "TARGET_80387
4912    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4914   if (TARGET_FISTTP)
4915    {
4916      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4917      DONE;
4918    }
4921 ;; Unsigned conversion to SImode.
4923 (define_expand "fixuns_trunc<mode>si2"
4924   [(parallel
4925     [(set (match_operand:SI 0 "register_operand")
4926           (unsigned_fix:SI
4927             (match_operand:MODEF 1 "nonimmediate_operand")))
4928      (use (match_dup 2))
4929      (clobber (match_scratch:<ssevecmode> 3))
4930      (clobber (match_scratch:<ssevecmode> 4))])]
4931   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4933   machine_mode mode = <MODE>mode;
4934   machine_mode vecmode = <ssevecmode>mode;
4935   REAL_VALUE_TYPE TWO31r;
4936   rtx two31;
4938   if (optimize_insn_for_size_p ())
4939     FAIL;
4941   real_ldexp (&TWO31r, &dconst1, 31);
4942   two31 = const_double_from_real_value (TWO31r, mode);
4943   two31 = ix86_build_const_vector (vecmode, true, two31);
4944   operands[2] = force_reg (vecmode, two31);
4947 (define_insn_and_split "*fixuns_trunc<mode>_1"
4948   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4949         (unsigned_fix:SI
4950           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4951    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4952    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4953    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4954   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4955    && optimize_function_for_speed_p (cfun)"
4956   "#"
4957   "&& reload_completed"
4958   [(const_int 0)]
4960   ix86_split_convert_uns_si_sse (operands);
4961   DONE;
4964 ;; Unsigned conversion to HImode.
4965 ;; Without these patterns, we'll try the unsigned SI conversion which
4966 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4968 (define_expand "fixuns_trunc<mode>hi2"
4969   [(set (match_dup 2)
4970         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4971    (set (match_operand:HI 0 "nonimmediate_operand")
4972         (subreg:HI (match_dup 2) 0))]
4973   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4974   "operands[2] = gen_reg_rtx (SImode);")
4976 ;; When SSE is available, it is always faster to use it!
4977 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4978   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4979         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4980   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4981    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4982   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4983   [(set_attr "type" "sseicvt")
4984    (set_attr "prefix" "maybe_vex")
4985    (set (attr "prefix_rex")
4986         (if_then_else
4987           (match_test "<SWI48:MODE>mode == DImode")
4988           (const_string "1")
4989           (const_string "*")))
4990    (set_attr "mode" "<MODEF:MODE>")
4991    (set_attr "athlon_decode" "double,vector")
4992    (set_attr "amdfam10_decode" "double,double")
4993    (set_attr "bdver1_decode" "double,double")])
4995 ;; Avoid vector decoded forms of the instruction.
4996 (define_peephole2
4997   [(match_scratch:MODEF 2 "x")
4998    (set (match_operand:SWI48 0 "register_operand")
4999         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5000   "TARGET_AVOID_VECTOR_DECODE
5001    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5002    && optimize_insn_for_speed_p ()"
5003   [(set (match_dup 2) (match_dup 1))
5004    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5006 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5007   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5008         (fix:SWI248x (match_operand 1 "register_operand")))]
5009   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5010    && TARGET_FISTTP
5011    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5012          && (TARGET_64BIT || <MODE>mode != DImode))
5013         && TARGET_SSE_MATH)
5014    && can_create_pseudo_p ()"
5015   "#"
5016   "&& 1"
5017   [(const_int 0)]
5019   if (memory_operand (operands[0], VOIDmode))
5020     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5021   else
5022     {
5023       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5024       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5025                                                             operands[1],
5026                                                             operands[2]));
5027     }
5028   DONE;
5030   [(set_attr "type" "fisttp")
5031    (set_attr "mode" "<MODE>")])
5033 (define_insn "fix_trunc<mode>_i387_fisttp"
5034   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5035         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5036    (clobber (match_scratch:XF 2 "=&1f"))]
5037   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5038    && TARGET_FISTTP
5039    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5040          && (TARGET_64BIT || <MODE>mode != DImode))
5041         && TARGET_SSE_MATH)"
5042   "* return output_fix_trunc (insn, operands, true);"
5043   [(set_attr "type" "fisttp")
5044    (set_attr "mode" "<MODE>")])
5046 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5047   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5048         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5049    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5050    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5051   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5052    && TARGET_FISTTP
5053    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5054         && (TARGET_64BIT || <MODE>mode != DImode))
5055         && TARGET_SSE_MATH)"
5056   "#"
5057   [(set_attr "type" "fisttp")
5058    (set_attr "mode" "<MODE>")])
5060 (define_split
5061   [(set (match_operand:SWI248x 0 "register_operand")
5062         (fix:SWI248x (match_operand 1 "register_operand")))
5063    (clobber (match_operand:SWI248x 2 "memory_operand"))
5064    (clobber (match_scratch 3))]
5065   "reload_completed"
5066   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5067               (clobber (match_dup 3))])
5068    (set (match_dup 0) (match_dup 2))])
5070 (define_split
5071   [(set (match_operand:SWI248x 0 "memory_operand")
5072         (fix:SWI248x (match_operand 1 "register_operand")))
5073    (clobber (match_operand:SWI248x 2 "memory_operand"))
5074    (clobber (match_scratch 3))]
5075   "reload_completed"
5076   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5077               (clobber (match_dup 3))])])
5079 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5080 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5081 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5082 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5083 ;; function in i386.c.
5084 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5085   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5086         (fix:SWI248x (match_operand 1 "register_operand")))
5087    (clobber (reg:CC FLAGS_REG))]
5088   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5089    && !TARGET_FISTTP
5090    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5091          && (TARGET_64BIT || <MODE>mode != DImode))
5092    && can_create_pseudo_p ()"
5093   "#"
5094   "&& 1"
5095   [(const_int 0)]
5097   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5099   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5100   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5101   if (memory_operand (operands[0], VOIDmode))
5102     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5103                                          operands[2], operands[3]));
5104   else
5105     {
5106       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5107       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5108                                                      operands[2], operands[3],
5109                                                      operands[4]));
5110     }
5111   DONE;
5113   [(set_attr "type" "fistp")
5114    (set_attr "i387_cw" "trunc")
5115    (set_attr "mode" "<MODE>")])
5117 (define_insn "fix_truncdi_i387"
5118   [(set (match_operand:DI 0 "memory_operand" "=m")
5119         (fix:DI (match_operand 1 "register_operand" "f")))
5120    (use (match_operand:HI 2 "memory_operand" "m"))
5121    (use (match_operand:HI 3 "memory_operand" "m"))
5122    (clobber (match_scratch:XF 4 "=&1f"))]
5123   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5124    && !TARGET_FISTTP
5125    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5126   "* return output_fix_trunc (insn, operands, false);"
5127   [(set_attr "type" "fistp")
5128    (set_attr "i387_cw" "trunc")
5129    (set_attr "mode" "DI")])
5131 (define_insn "fix_truncdi_i387_with_temp"
5132   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5133         (fix:DI (match_operand 1 "register_operand" "f,f")))
5134    (use (match_operand:HI 2 "memory_operand" "m,m"))
5135    (use (match_operand:HI 3 "memory_operand" "m,m"))
5136    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5137    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5138   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5139    && !TARGET_FISTTP
5140    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5141   "#"
5142   [(set_attr "type" "fistp")
5143    (set_attr "i387_cw" "trunc")
5144    (set_attr "mode" "DI")])
5146 (define_split
5147   [(set (match_operand:DI 0 "register_operand")
5148         (fix:DI (match_operand 1 "register_operand")))
5149    (use (match_operand:HI 2 "memory_operand"))
5150    (use (match_operand:HI 3 "memory_operand"))
5151    (clobber (match_operand:DI 4 "memory_operand"))
5152    (clobber (match_scratch 5))]
5153   "reload_completed"
5154   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5155               (use (match_dup 2))
5156               (use (match_dup 3))
5157               (clobber (match_dup 5))])
5158    (set (match_dup 0) (match_dup 4))])
5160 (define_split
5161   [(set (match_operand:DI 0 "memory_operand")
5162         (fix:DI (match_operand 1 "register_operand")))
5163    (use (match_operand:HI 2 "memory_operand"))
5164    (use (match_operand:HI 3 "memory_operand"))
5165    (clobber (match_operand:DI 4 "memory_operand"))
5166    (clobber (match_scratch 5))]
5167   "reload_completed"
5168   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5169               (use (match_dup 2))
5170               (use (match_dup 3))
5171               (clobber (match_dup 5))])])
5173 (define_insn "fix_trunc<mode>_i387"
5174   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5175         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5176    (use (match_operand:HI 2 "memory_operand" "m"))
5177    (use (match_operand:HI 3 "memory_operand" "m"))]
5178   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5179    && !TARGET_FISTTP
5180    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5181   "* return output_fix_trunc (insn, operands, false);"
5182   [(set_attr "type" "fistp")
5183    (set_attr "i387_cw" "trunc")
5184    (set_attr "mode" "<MODE>")])
5186 (define_insn "fix_trunc<mode>_i387_with_temp"
5187   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5188         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5189    (use (match_operand:HI 2 "memory_operand" "m,m"))
5190    (use (match_operand:HI 3 "memory_operand" "m,m"))
5191    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5192   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5193    && !TARGET_FISTTP
5194    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5195   "#"
5196   [(set_attr "type" "fistp")
5197    (set_attr "i387_cw" "trunc")
5198    (set_attr "mode" "<MODE>")])
5200 (define_split
5201   [(set (match_operand:SWI24 0 "register_operand")
5202         (fix:SWI24 (match_operand 1 "register_operand")))
5203    (use (match_operand:HI 2 "memory_operand"))
5204    (use (match_operand:HI 3 "memory_operand"))
5205    (clobber (match_operand:SWI24 4 "memory_operand"))]
5206   "reload_completed"
5207   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5208               (use (match_dup 2))
5209               (use (match_dup 3))])
5210    (set (match_dup 0) (match_dup 4))])
5212 (define_split
5213   [(set (match_operand:SWI24 0 "memory_operand")
5214         (fix:SWI24 (match_operand 1 "register_operand")))
5215    (use (match_operand:HI 2 "memory_operand"))
5216    (use (match_operand:HI 3 "memory_operand"))
5217    (clobber (match_operand:SWI24 4 "memory_operand"))]
5218   "reload_completed"
5219   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5220               (use (match_dup 2))
5221               (use (match_dup 3))])])
5223 (define_insn "x86_fnstcw_1"
5224   [(set (match_operand:HI 0 "memory_operand" "=m")
5225         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5226   "TARGET_80387"
5227   "fnstcw\t%0"
5228   [(set (attr "length")
5229         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5230    (set_attr "mode" "HI")
5231    (set_attr "unit" "i387")
5232    (set_attr "bdver1_decode" "vector")])
5234 (define_insn "x86_fldcw_1"
5235   [(set (reg:HI FPCR_REG)
5236         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5237   "TARGET_80387"
5238   "fldcw\t%0"
5239   [(set (attr "length")
5240         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5241    (set_attr "mode" "HI")
5242    (set_attr "unit" "i387")
5243    (set_attr "athlon_decode" "vector")
5244    (set_attr "amdfam10_decode" "vector")
5245    (set_attr "bdver1_decode" "vector")])
5247 ;; Conversion between fixed point and floating point.
5249 ;; Even though we only accept memory inputs, the backend _really_
5250 ;; wants to be able to do this between registers.  Thankfully, LRA
5251 ;; will fix this up for us during register allocation.
5253 (define_insn "floathi<mode>2"
5254   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5255         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5256   "TARGET_80387
5257    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5258        || TARGET_MIX_SSE_I387)"
5259   "fild%Z1\t%1"
5260   [(set_attr "type" "fmov")
5261    (set_attr "mode" "<MODE>")
5262    (set_attr "znver1_decode" "double")
5263    (set_attr "fp_int_src" "true")])
5265 (define_insn "float<SWI48x:mode>xf2"
5266   [(set (match_operand:XF 0 "register_operand" "=f")
5267         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5268   "TARGET_80387"
5269   "fild%Z1\t%1"
5270   [(set_attr "type" "fmov")
5271    (set_attr "mode" "XF")
5272    (set_attr "znver1_decode" "double")
5273    (set_attr "fp_int_src" "true")])
5275 (define_expand "float<SWI48:mode><MODEF:mode>2"
5276   [(set (match_operand:MODEF 0 "register_operand")
5277         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5278   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5280   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5281       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5282     {
5283       rtx reg = gen_reg_rtx (XFmode);
5284       rtx (*insn)(rtx, rtx);
5286       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5288       if (<MODEF:MODE>mode == SFmode)
5289         insn = gen_truncxfsf2;
5290       else if (<MODEF:MODE>mode == DFmode)
5291         insn = gen_truncxfdf2;
5292       else
5293         gcc_unreachable ();
5295       emit_insn (insn (operands[0], reg));
5296       DONE;
5297     }
5300 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5301   [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5302         (float:MODEF
5303           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5304   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5305   "@
5306    fild%Z1\t%1
5307    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5308    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5309   [(set_attr "type" "fmov,sseicvt,sseicvt")
5310    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5311    (set_attr "mode" "<MODEF:MODE>")
5312    (set (attr "prefix_rex")
5313      (if_then_else
5314        (and (eq_attr "prefix" "maybe_vex")
5315             (match_test "<SWI48:MODE>mode == DImode"))
5316        (const_string "1")
5317        (const_string "*")))
5318    (set_attr "unit" "i387,*,*")
5319    (set_attr "athlon_decode" "*,double,direct")
5320    (set_attr "amdfam10_decode" "*,vector,double")
5321    (set_attr "bdver1_decode" "*,double,direct")
5322    (set_attr "znver1_decode" "double,*,*")
5323    (set_attr "fp_int_src" "true")
5324    (set (attr "enabled")
5325      (cond [(eq_attr "alternative" "0")
5326               (symbol_ref "TARGET_MIX_SSE_I387
5327                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5328                                                 <SWI48:MODE>mode)")
5329            ]
5330            (symbol_ref "true")))])
5332 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5333   [(set (match_operand:MODEF 0 "register_operand" "=f")
5334         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5335   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5336   "fild%Z1\t%1"
5337   [(set_attr "type" "fmov")
5338    (set_attr "mode" "<MODEF:MODE>")
5339    (set_attr "znver1_decode" "double")
5340    (set_attr "fp_int_src" "true")])
5342 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5343 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5344 ;; alternative in sse2_loadld.
5345 (define_split
5346   [(set (match_operand:MODEF 0 "sse_reg_operand")
5347         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5348   "TARGET_SSE2
5349    && TARGET_USE_VECTOR_CONVERTS
5350    && optimize_function_for_speed_p (cfun)
5351    && reload_completed
5352    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5353    && (!EXT_REX_SSE_REG_P (operands[0])
5354        || TARGET_AVX512VL)"
5355   [(const_int 0)]
5357   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5358   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5360   emit_insn (gen_sse2_loadld (operands[4],
5361                               CONST0_RTX (V4SImode), operands[1]));
5363   if (<ssevecmode>mode == V4SFmode)
5364     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5365   else
5366     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5367   DONE;
5370 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5371 ;; late in the pass sequence (after register rename pass), so allocated
5372 ;; registers won't change anymore
5374 (define_split
5375   [(set (match_operand:MODEF 0 "sse_reg_operand")
5376         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5377   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5378    && optimize_function_for_speed_p (cfun)
5379    && (!EXT_REX_SSE_REG_P (operands[0])
5380        || TARGET_AVX512VL)"
5381   [(set (match_dup 0)
5382         (vec_merge:<MODEF:ssevecmode>
5383           (vec_duplicate:<MODEF:ssevecmode>
5384             (float:MODEF
5385               (match_dup 1)))
5386           (match_dup 0)
5387           (const_int 1)))]
5389   const machine_mode vmode = <MODEF:ssevecmode>mode;
5391   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5392   emit_move_insn (operands[0], CONST0_RTX (vmode));
5395 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5396 ;; late in the pass sequence (after register rename pass),
5397 ;; so allocated registers won't change anymore.
5399 (define_split
5400   [(set (match_operand:SF 0 "sse_reg_operand")
5401         (float_truncate:SF
5402           (match_operand:DF 1 "nonimmediate_operand")))]
5403   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5404    && optimize_function_for_speed_p (cfun)
5405    && (!REG_P (operands[1])
5406        || REGNO (operands[0]) != REGNO (operands[1]))
5407    && (!EXT_REX_SSE_REG_P (operands[0])
5408        || TARGET_AVX512VL)"
5409   [(set (match_dup 0)
5410         (vec_merge:V4SF
5411           (vec_duplicate:V4SF
5412             (float_truncate:SF
5413               (match_dup 1)))
5414           (match_dup 0)
5415           (const_int 1)))]
5417   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5418   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5421 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5422 ;; late in the pass sequence (after register rename pass),
5423 ;; so allocated registers won't change anymore.
5425 (define_split
5426   [(set (match_operand:DF 0 "sse_reg_operand")
5427         (float_extend:DF
5428           (match_operand:SF 1 "nonimmediate_operand")))]
5429   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5430    && optimize_function_for_speed_p (cfun)
5431    && (!REG_P (operands[1])
5432        || REGNO (operands[0]) != REGNO (operands[1]))
5433    && (!EXT_REX_SSE_REG_P (operands[0])
5434        || TARGET_AVX512VL)"
5435   [(set (match_dup 0)
5436         (vec_merge:V2DF
5437           (vec_duplicate:V2DF
5438             (float_extend:DF
5439               (match_dup 1)))
5440           (match_dup 0)
5441           (const_int 1)))]
5443   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5444   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5447 ;; Avoid store forwarding (partial memory) stall penalty
5448 ;; by passing DImode value through XMM registers.  */
5450 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5451   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5452         (float:X87MODEF
5453           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5454    (clobber (match_scratch:V4SI 3 "=X,x"))
5455    (clobber (match_scratch:V4SI 4 "=X,x"))
5456    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5457   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5458    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5459    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5460   "#"
5461   [(set_attr "type" "multi")
5462    (set_attr "mode" "<X87MODEF:MODE>")
5463    (set_attr "unit" "i387")
5464    (set_attr "fp_int_src" "true")])
5466 (define_split
5467   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5468         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5469    (clobber (match_scratch:V4SI 3))
5470    (clobber (match_scratch:V4SI 4))
5471    (clobber (match_operand:DI 2 "memory_operand"))]
5472   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5473    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5474    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5475    && reload_completed"
5476   [(set (match_dup 2) (match_dup 3))
5477    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5479   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5480      Assemble the 64-bit DImode value in an xmm register.  */
5481   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5482                               gen_lowpart (SImode, operands[1])));
5483   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5484                               gen_highpart (SImode, operands[1])));
5485   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5486                                          operands[4]));
5488   operands[3] = gen_lowpart (DImode, operands[3]);
5491 (define_split
5492   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5493         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5494    (clobber (match_scratch:V4SI 3))
5495    (clobber (match_scratch:V4SI 4))
5496    (clobber (match_operand:DI 2 "memory_operand"))]
5497   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5498    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5499    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5500    && reload_completed"
5501   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5503 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5504   [(set (match_operand:MODEF 0 "register_operand")
5505         (unsigned_float:MODEF
5506           (match_operand:SWI12 1 "nonimmediate_operand")))]
5507   "!TARGET_64BIT
5508    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5510   operands[1] = convert_to_mode (SImode, operands[1], 1);
5511   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5512   DONE;
5515 ;; Avoid store forwarding (partial memory) stall penalty by extending
5516 ;; SImode value to DImode through XMM register instead of pushing two
5517 ;; SImode values to stack. Also note that fild loads from memory only.
5519 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5520   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5521         (unsigned_float:X87MODEF
5522           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5523    (clobber (match_scratch:DI 3 "=x"))
5524    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5525   "!TARGET_64BIT
5526    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5527    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5528   "#"
5529   "&& reload_completed"
5530   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5531    (set (match_dup 2) (match_dup 3))
5532    (set (match_dup 0)
5533         (float:X87MODEF (match_dup 2)))]
5534   ""
5535   [(set_attr "type" "multi")
5536    (set_attr "mode" "<MODE>")])
5538 (define_expand "floatunssi<mode>2"
5539   [(parallel
5540      [(set (match_operand:X87MODEF 0 "register_operand")
5541            (unsigned_float:X87MODEF
5542              (match_operand:SI 1 "nonimmediate_operand")))
5543       (clobber (match_scratch:DI 3))
5544       (clobber (match_dup 2))])]
5545   "!TARGET_64BIT
5546    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5547         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5548        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5550   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5551     {
5552       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5553       DONE;
5554     }
5555   else
5556     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5559 (define_expand "floatunsdisf2"
5560   [(use (match_operand:SF 0 "register_operand"))
5561    (use (match_operand:DI 1 "nonimmediate_operand"))]
5562   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5563   "x86_emit_floatuns (operands); DONE;")
5565 (define_expand "floatunsdidf2"
5566   [(use (match_operand:DF 0 "register_operand"))
5567    (use (match_operand:DI 1 "nonimmediate_operand"))]
5568   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5569    && TARGET_SSE2 && TARGET_SSE_MATH"
5571   if (TARGET_64BIT)
5572     x86_emit_floatuns (operands);
5573   else
5574     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5575   DONE;
5578 ;; Load effective address instructions
5580 (define_insn_and_split "*lea<mode>"
5581   [(set (match_operand:SWI48 0 "register_operand" "=r")
5582         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5583   ""
5585   if (SImode_address_operand (operands[1], VOIDmode))
5586     {
5587       gcc_assert (TARGET_64BIT);
5588       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5589     }
5590   else 
5591     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5593   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5594   [(const_int 0)]
5596   machine_mode mode = <MODE>mode;
5597   rtx pat;
5599   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5600      change operands[] array behind our back.  */
5601   pat = PATTERN (curr_insn);
5603   operands[0] = SET_DEST (pat);
5604   operands[1] = SET_SRC (pat);
5606   /* Emit all operations in SImode for zero-extended addresses.  */
5607   if (SImode_address_operand (operands[1], VOIDmode))
5608     mode = SImode;
5610   ix86_split_lea_for_addr (curr_insn, operands, mode);
5612   /* Zero-extend return register to DImode for zero-extended addresses.  */
5613   if (mode != <MODE>mode)
5614     emit_insn (gen_zero_extendsidi2
5615                (operands[0], gen_lowpart (mode, operands[0])));
5617   DONE;
5619   [(set_attr "type" "lea")
5620    (set (attr "mode")
5621      (if_then_else
5622        (match_operand 1 "SImode_address_operand")
5623        (const_string "SI")
5624        (const_string "<MODE>")))])
5626 ;; Add instructions
5628 (define_expand "add<mode>3"
5629   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5630         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5631                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5632   ""
5633   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5635 (define_insn_and_split "*add<dwi>3_doubleword"
5636   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5637         (plus:<DWI>
5638           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5639           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5640                                                         "ro<di>,r<di>")))
5641    (clobber (reg:CC FLAGS_REG))]
5642   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5643   "#"
5644   "reload_completed"
5645   [(parallel [(set (reg:CCC FLAGS_REG)
5646                    (compare:CCC
5647                      (plus:DWIH (match_dup 1) (match_dup 2))
5648                      (match_dup 1)))
5649               (set (match_dup 0)
5650                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5651    (parallel [(set (match_dup 3)
5652                    (plus:DWIH
5653                      (plus:DWIH
5654                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5655                        (match_dup 4))
5656                      (match_dup 5)))
5657               (clobber (reg:CC FLAGS_REG))])]
5659   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5660   if (operands[2] == const0_rtx)
5661     {
5662       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5663       DONE;
5664     }
5667 (define_insn "*add<mode>_1"
5668   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5669         (plus:SWI48
5670           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5671           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5672    (clobber (reg:CC FLAGS_REG))]
5673   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5675   switch (get_attr_type (insn))
5676     {
5677     case TYPE_LEA:
5678       return "#";
5680     case TYPE_INCDEC:
5681       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5682       if (operands[2] == const1_rtx)
5683         return "inc{<imodesuffix>}\t%0";
5684       else
5685         {
5686           gcc_assert (operands[2] == constm1_rtx);
5687           return "dec{<imodesuffix>}\t%0";
5688         }
5690     default:
5691       /* For most processors, ADD is faster than LEA.  This alternative
5692          was added to use ADD as much as possible.  */
5693       if (which_alternative == 2)
5694         std::swap (operands[1], operands[2]);
5695         
5696       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5698         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5700       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5701     }
5703   [(set (attr "type")
5704      (cond [(eq_attr "alternative" "3")
5705               (const_string "lea")
5706             (match_operand:SWI48 2 "incdec_operand")
5707               (const_string "incdec")
5708            ]
5709            (const_string "alu")))
5710    (set (attr "length_immediate")
5711       (if_then_else
5712         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713         (const_string "1")
5714         (const_string "*")))
5715    (set_attr "mode" "<MODE>")])
5717 ;; It may seem that nonimmediate operand is proper one for operand 1.
5718 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5719 ;; we take care in ix86_binary_operator_ok to not allow two memory
5720 ;; operands so proper swapping will be done in reload.  This allow
5721 ;; patterns constructed from addsi_1 to match.
5723 (define_insn "addsi_1_zext"
5724   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5725         (zero_extend:DI
5726           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5727                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5728    (clobber (reg:CC FLAGS_REG))]
5729   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_LEA:
5734       return "#";
5736     case TYPE_INCDEC:
5737       if (operands[2] == const1_rtx)
5738         return "inc{l}\t%k0";
5739       else
5740         {
5741           gcc_assert (operands[2] == constm1_rtx);
5742           return "dec{l}\t%k0";
5743         }
5745     default:
5746       /* For most processors, ADD is faster than LEA.  This alternative
5747          was added to use ADD as much as possible.  */
5748       if (which_alternative == 1)
5749         std::swap (operands[1], operands[2]);
5751       if (x86_maybe_negate_const_int (&operands[2], SImode))
5752         return "sub{l}\t{%2, %k0|%k0, %2}";
5754       return "add{l}\t{%2, %k0|%k0, %2}";
5755     }
5757   [(set (attr "type")
5758      (cond [(eq_attr "alternative" "2")
5759               (const_string "lea")
5760             (match_operand:SI 2 "incdec_operand")
5761               (const_string "incdec")
5762            ]
5763            (const_string "alu")))
5764    (set (attr "length_immediate")
5765       (if_then_else
5766         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5767         (const_string "1")
5768         (const_string "*")))
5769    (set_attr "mode" "SI")])
5771 (define_insn "*addhi_1"
5772   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5773         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5774                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5775    (clobber (reg:CC FLAGS_REG))]
5776   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5778   switch (get_attr_type (insn))
5779     {
5780     case TYPE_LEA:
5781       return "#";
5783     case TYPE_INCDEC:
5784       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785       if (operands[2] == const1_rtx)
5786         return "inc{w}\t%0";
5787       else
5788         {
5789           gcc_assert (operands[2] == constm1_rtx);
5790           return "dec{w}\t%0";
5791         }
5793     default:
5794       /* For most processors, ADD is faster than LEA.  This alternative
5795          was added to use ADD as much as possible.  */
5796       if (which_alternative == 2)
5797         std::swap (operands[1], operands[2]);
5799       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5800       if (x86_maybe_negate_const_int (&operands[2], HImode))
5801         return "sub{w}\t{%2, %0|%0, %2}";
5803       return "add{w}\t{%2, %0|%0, %2}";
5804     }
5806   [(set (attr "type")
5807      (cond [(eq_attr "alternative" "3")
5808               (const_string "lea")
5809             (match_operand:HI 2 "incdec_operand")
5810               (const_string "incdec")
5811            ]
5812            (const_string "alu")))
5813    (set (attr "length_immediate")
5814       (if_then_else
5815         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5816         (const_string "1")
5817         (const_string "*")))
5818    (set_attr "mode" "HI,HI,HI,SI")])
5820 (define_insn "*addqi_1"
5821   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5822         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5823                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5824    (clobber (reg:CC FLAGS_REG))]
5825   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5827   bool widen = (get_attr_mode (insn) != MODE_QI);
5829   switch (get_attr_type (insn))
5830     {
5831     case TYPE_LEA:
5832       return "#";
5834     case TYPE_INCDEC:
5835       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836       if (operands[2] == const1_rtx)
5837         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5838       else
5839         {
5840           gcc_assert (operands[2] == constm1_rtx);
5841           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5842         }
5844     default:
5845       /* For most processors, ADD is faster than LEA.  These alternatives
5846          were added to use ADD as much as possible.  */
5847       if (which_alternative == 2 || which_alternative == 4)
5848         std::swap (operands[1], operands[2]);
5850       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851       if (x86_maybe_negate_const_int (&operands[2], QImode))
5852         {
5853           if (widen)
5854             return "sub{l}\t{%2, %k0|%k0, %2}";
5855           else
5856             return "sub{b}\t{%2, %0|%0, %2}";
5857         }
5858       if (widen)
5859         return "add{l}\t{%k2, %k0|%k0, %k2}";
5860       else
5861         return "add{b}\t{%2, %0|%0, %2}";
5862     }
5864   [(set (attr "type")
5865      (cond [(eq_attr "alternative" "5")
5866               (const_string "lea")
5867             (match_operand:QI 2 "incdec_operand")
5868               (const_string "incdec")
5869            ]
5870            (const_string "alu")))
5871    (set (attr "length_immediate")
5872       (if_then_else
5873         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5874         (const_string "1")
5875         (const_string "*")))
5876    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5877    ;; Potential partial reg stall on alternatives 3 and 4.
5878    (set (attr "preferred_for_speed")
5879      (cond [(eq_attr "alternative" "3,4")
5880               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5881            (symbol_ref "true")))])
5883 (define_insn "*addqi_1_slp"
5884   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5885         (plus:QI (match_dup 0)
5886                  (match_operand:QI 1 "general_operand" "qn,qm")))
5887    (clobber (reg:CC FLAGS_REG))]
5888   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5889    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5891   switch (get_attr_type (insn))
5892     {
5893     case TYPE_INCDEC:
5894       if (operands[1] == const1_rtx)
5895         return "inc{b}\t%0";
5896       else
5897         {
5898           gcc_assert (operands[1] == constm1_rtx);
5899           return "dec{b}\t%0";
5900         }
5902     default:
5903       if (x86_maybe_negate_const_int (&operands[1], QImode))
5904         return "sub{b}\t{%1, %0|%0, %1}";
5906       return "add{b}\t{%1, %0|%0, %1}";
5907     }
5909   [(set (attr "type")
5910      (if_then_else (match_operand:QI 1 "incdec_operand")
5911         (const_string "incdec")
5912         (const_string "alu1")))
5913    (set (attr "memory")
5914      (if_then_else (match_operand 1 "memory_operand")
5915         (const_string "load")
5916         (const_string "none")))
5917    (set_attr "mode" "QI")])
5919 ;; Split non destructive adds if we cannot use lea.
5920 (define_split
5921   [(set (match_operand:SWI48 0 "register_operand")
5922         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5923                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5924    (clobber (reg:CC FLAGS_REG))]
5925   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5926   [(set (match_dup 0) (match_dup 1))
5927    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5928               (clobber (reg:CC FLAGS_REG))])])
5930 ;; Split non destructive adds if we cannot use lea.
5931 (define_split
5932   [(set (match_operand:DI 0 "register_operand")
5933         (zero_extend:DI
5934           (plus:SI (match_operand:SI 1 "register_operand")
5935                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5936    (clobber (reg:CC FLAGS_REG))]
5937   "TARGET_64BIT
5938    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5939   [(set (match_dup 3) (match_dup 1))
5940    (parallel [(set (match_dup 0)
5941                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5942               (clobber (reg:CC FLAGS_REG))])]
5943   "operands[3] = gen_lowpart (SImode, operands[0]);")
5945 ;; Convert add to the lea pattern to avoid flags dependency.
5946 (define_split
5947   [(set (match_operand:SWI 0 "register_operand")
5948         (plus:SWI (match_operand:SWI 1 "register_operand")
5949                   (match_operand:SWI 2 "<nonmemory_operand>")))
5950    (clobber (reg:CC FLAGS_REG))]
5951   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5952   [(set (match_dup 0)
5953         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5955   if (<MODE>mode != <LEAMODE>mode)
5956     {
5957       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5958       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5959       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5960     }
5963 ;; Convert add to the lea pattern to avoid flags dependency.
5964 (define_split
5965   [(set (match_operand:DI 0 "register_operand")
5966         (zero_extend:DI
5967           (plus:SI (match_operand:SI 1 "register_operand")
5968                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5969    (clobber (reg:CC FLAGS_REG))]
5970   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5971   [(set (match_dup 0)
5972         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5974 (define_insn "*add<mode>_2"
5975   [(set (reg FLAGS_REG)
5976         (compare
5977           (plus:SWI
5978             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5979             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5980           (const_int 0)))
5981    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5982         (plus:SWI (match_dup 1) (match_dup 2)))]
5983   "ix86_match_ccmode (insn, CCGOCmode)
5984    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{<imodesuffix>}\t%0";
5991       else
5992         {
5993           gcc_assert (operands[2] == constm1_rtx);
5994           return "dec{<imodesuffix>}\t%0";
5995         }
5997     default:
5998       if (which_alternative == 2)
5999         std::swap (operands[1], operands[2]);
6000         
6001       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6003         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6005       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6006     }
6008   [(set (attr "type")
6009      (if_then_else (match_operand:SWI 2 "incdec_operand")
6010         (const_string "incdec")
6011         (const_string "alu")))
6012    (set (attr "length_immediate")
6013       (if_then_else
6014         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6015         (const_string "1")
6016         (const_string "*")))
6017    (set_attr "mode" "<MODE>")])
6019 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6020 (define_insn "*addsi_2_zext"
6021   [(set (reg FLAGS_REG)
6022         (compare
6023           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6024                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6025           (const_int 0)))
6026    (set (match_operand:DI 0 "register_operand" "=r,r")
6027         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6028   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6029    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6031   switch (get_attr_type (insn))
6032     {
6033     case TYPE_INCDEC:
6034       if (operands[2] == const1_rtx)
6035         return "inc{l}\t%k0";
6036       else
6037         {
6038           gcc_assert (operands[2] == constm1_rtx);
6039           return "dec{l}\t%k0";
6040         }
6042     default:
6043       if (which_alternative == 1)
6044         std::swap (operands[1], operands[2]);
6046       if (x86_maybe_negate_const_int (&operands[2], SImode))
6047         return "sub{l}\t{%2, %k0|%k0, %2}";
6049       return "add{l}\t{%2, %k0|%k0, %2}";
6050     }
6052   [(set (attr "type")
6053      (if_then_else (match_operand:SI 2 "incdec_operand")
6054         (const_string "incdec")
6055         (const_string "alu")))
6056    (set (attr "length_immediate")
6057       (if_then_else
6058         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6059         (const_string "1")
6060         (const_string "*")))
6061    (set_attr "mode" "SI")])
6063 (define_insn "*add<mode>_3"
6064   [(set (reg FLAGS_REG)
6065         (compare
6066           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6067           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6068    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6069   "ix86_match_ccmode (insn, CCZmode)
6070    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_INCDEC:
6075       if (operands[2] == const1_rtx)
6076         return "inc{<imodesuffix>}\t%0";
6077       else
6078         {
6079           gcc_assert (operands[2] == constm1_rtx);
6080           return "dec{<imodesuffix>}\t%0";
6081         }
6083     default:
6084       if (which_alternative == 1)
6085         std::swap (operands[1], operands[2]);
6087       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6088       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6089         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6091       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6092     }
6094   [(set (attr "type")
6095      (if_then_else (match_operand:SWI 2 "incdec_operand")
6096         (const_string "incdec")
6097         (const_string "alu")))
6098    (set (attr "length_immediate")
6099       (if_then_else
6100         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6101         (const_string "1")
6102         (const_string "*")))
6103    (set_attr "mode" "<MODE>")])
6105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6106 (define_insn "*addsi_3_zext"
6107   [(set (reg FLAGS_REG)
6108         (compare
6109           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6110           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6111    (set (match_operand:DI 0 "register_operand" "=r,r")
6112         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6113   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6114    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6116   switch (get_attr_type (insn))
6117     {
6118     case TYPE_INCDEC:
6119       if (operands[2] == const1_rtx)
6120         return "inc{l}\t%k0";
6121       else
6122         {
6123           gcc_assert (operands[2] == constm1_rtx);
6124           return "dec{l}\t%k0";
6125         }
6127     default:
6128       if (which_alternative == 1)
6129         std::swap (operands[1], operands[2]);
6131       if (x86_maybe_negate_const_int (&operands[2], SImode))
6132         return "sub{l}\t{%2, %k0|%k0, %2}";
6134       return "add{l}\t{%2, %k0|%k0, %2}";
6135     }
6137   [(set (attr "type")
6138      (if_then_else (match_operand:SI 2 "incdec_operand")
6139         (const_string "incdec")
6140         (const_string "alu")))
6141    (set (attr "length_immediate")
6142       (if_then_else
6143         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6144         (const_string "1")
6145         (const_string "*")))
6146    (set_attr "mode" "SI")])
6148 ; For comparisons against 1, -1 and 128, we may generate better code
6149 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6150 ; is matched then.  We can't accept general immediate, because for
6151 ; case of overflows,  the result is messed up.
6152 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6153 ; only for comparisons not depending on it.
6155 (define_insn "*adddi_4"
6156   [(set (reg FLAGS_REG)
6157         (compare
6158           (match_operand:DI 1 "nonimmediate_operand" "0")
6159           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6160    (clobber (match_scratch:DI 0 "=rm"))]
6161   "TARGET_64BIT
6162    && ix86_match_ccmode (insn, CCGCmode)"
6164   switch (get_attr_type (insn))
6165     {
6166     case TYPE_INCDEC:
6167       if (operands[2] == constm1_rtx)
6168         return "inc{q}\t%0";
6169       else
6170         {
6171           gcc_assert (operands[2] == const1_rtx);
6172           return "dec{q}\t%0";
6173         }
6175     default:
6176       if (x86_maybe_negate_const_int (&operands[2], DImode))
6177         return "add{q}\t{%2, %0|%0, %2}";
6179       return "sub{q}\t{%2, %0|%0, %2}";
6180     }
6182   [(set (attr "type")
6183      (if_then_else (match_operand:DI 2 "incdec_operand")
6184         (const_string "incdec")
6185         (const_string "alu")))
6186    (set (attr "length_immediate")
6187       (if_then_else
6188         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6189         (const_string "1")
6190         (const_string "*")))
6191    (set_attr "mode" "DI")])
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6195 ; is matched then.  We can't accept general immediate, because for
6196 ; case of overflows,  the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6200 (define_insn "*add<mode>_4"
6201   [(set (reg FLAGS_REG)
6202         (compare
6203           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6204           (match_operand:SWI124 2 "const_int_operand" "n")))
6205    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6206   "ix86_match_ccmode (insn, CCGCmode)"
6208   switch (get_attr_type (insn))
6209     {
6210     case TYPE_INCDEC:
6211       if (operands[2] == constm1_rtx)
6212         return "inc{<imodesuffix>}\t%0";
6213       else
6214         {
6215           gcc_assert (operands[2] == const1_rtx);
6216           return "dec{<imodesuffix>}\t%0";
6217         }
6219     default:
6220       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6221         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6223       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6224     }
6226   [(set (attr "type")
6227      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6228         (const_string "incdec")
6229         (const_string "alu")))
6230    (set (attr "length_immediate")
6231       (if_then_else
6232         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6233         (const_string "1")
6234         (const_string "*")))
6235    (set_attr "mode" "<MODE>")])
6237 (define_insn "*add<mode>_5"
6238   [(set (reg FLAGS_REG)
6239         (compare
6240           (plus:SWI
6241             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6242             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6243           (const_int 0)))
6244    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6245   "ix86_match_ccmode (insn, CCGOCmode)
6246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6248   switch (get_attr_type (insn))
6249     {
6250     case TYPE_INCDEC:
6251       if (operands[2] == const1_rtx)
6252         return "inc{<imodesuffix>}\t%0";
6253       else
6254         {
6255           gcc_assert (operands[2] == constm1_rtx);
6256           return "dec{<imodesuffix>}\t%0";
6257         }
6259     default:
6260       if (which_alternative == 1)
6261         std::swap (operands[1], operands[2]);
6263       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6264       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6265         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6267       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6268     }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:SWI 2 "incdec_operand")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set (attr "length_immediate")
6275       (if_then_else
6276         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6277         (const_string "1")
6278         (const_string "*")))
6279    (set_attr "mode" "<MODE>")])
6281 (define_insn "addqi_ext_1"
6282   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6283                          (const_int 8)
6284                          (const_int 8))
6285         (subreg:SI
6286           (plus:QI
6287             (subreg:QI
6288               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6289                                (const_int 8)
6290                                (const_int 8)) 0)
6291             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6292    (clobber (reg:CC FLAGS_REG))]
6293   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6294    rtx_equal_p (operands[0], operands[1])"
6296   switch (get_attr_type (insn))
6297     {
6298     case TYPE_INCDEC:
6299       if (operands[2] == const1_rtx)
6300         return "inc{b}\t%h0";
6301       else
6302         {
6303           gcc_assert (operands[2] == constm1_rtx);
6304           return "dec{b}\t%h0";
6305         }
6307     default:
6308       return "add{b}\t{%2, %h0|%h0, %2}";
6309     }
6311   [(set_attr "isa" "*,nox64")
6312    (set (attr "type")
6313      (if_then_else (match_operand:QI 2 "incdec_operand")
6314         (const_string "incdec")
6315         (const_string "alu")))
6316    (set_attr "mode" "QI")])
6318 (define_insn "*addqi_ext_2"
6319   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6320                          (const_int 8)
6321                          (const_int 8))
6322         (subreg:SI
6323           (plus:QI
6324             (subreg:QI
6325               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6326                                (const_int 8)
6327                                (const_int 8)) 0)
6328             (subreg:QI
6329               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6330                                (const_int 8)
6331                                (const_int 8)) 0)) 0))
6332   (clobber (reg:CC FLAGS_REG))]
6333   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6334    rtx_equal_p (operands[0], operands[1])
6335    || rtx_equal_p (operands[0], operands[2])"
6336   "add{b}\t{%h2, %h0|%h0, %h2}"
6337   [(set_attr "type" "alu")
6338    (set_attr "mode" "QI")])
6340 ;; Add with jump on overflow.
6341 (define_expand "addv<mode>4"
6342   [(parallel [(set (reg:CCO FLAGS_REG)
6343                    (eq:CCO (plus:<DWI>
6344                               (sign_extend:<DWI>
6345                                  (match_operand:SWI 1 "nonimmediate_operand"))
6346                               (match_dup 4))
6347                            (sign_extend:<DWI>
6348                               (plus:SWI (match_dup 1)
6349                                         (match_operand:SWI 2
6350                                            "<general_operand>")))))
6351               (set (match_operand:SWI 0 "register_operand")
6352                    (plus:SWI (match_dup 1) (match_dup 2)))])
6353    (set (pc) (if_then_else
6354                (eq (reg:CCO FLAGS_REG) (const_int 0))
6355                (label_ref (match_operand 3))
6356                (pc)))]
6357   ""
6359   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6360   if (CONST_INT_P (operands[2]))
6361     operands[4] = operands[2];
6362   else
6363     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6366 (define_insn "*addv<mode>4"
6367   [(set (reg:CCO FLAGS_REG)
6368         (eq:CCO (plus:<DWI>
6369                    (sign_extend:<DWI>
6370                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6371                    (sign_extend:<DWI>
6372                       (match_operand:SWI 2 "<general_sext_operand>"
6373                                            "<r>mWe,<r>We")))
6374                 (sign_extend:<DWI>
6375                    (plus:SWI (match_dup 1) (match_dup 2)))))
6376    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6377         (plus:SWI (match_dup 1) (match_dup 2)))]
6378   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6379   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6380   [(set_attr "type" "alu")
6381    (set_attr "mode" "<MODE>")])
6383 (define_insn "*addv<mode>4_1"
6384   [(set (reg:CCO FLAGS_REG)
6385         (eq:CCO (plus:<DWI>
6386                    (sign_extend:<DWI>
6387                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6388                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6389                 (sign_extend:<DWI>
6390                    (plus:SWI (match_dup 1)
6391                              (match_operand:SWI 2 "x86_64_immediate_operand"
6392                                                   "<i>")))))
6393    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6394         (plus:SWI (match_dup 1) (match_dup 2)))]
6395   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6396    && CONST_INT_P (operands[2])
6397    && INTVAL (operands[2]) == INTVAL (operands[3])"
6398   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6399   [(set_attr "type" "alu")
6400    (set_attr "mode" "<MODE>")
6401    (set (attr "length_immediate")
6402         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6403                   (const_string "1")
6404                (match_test "<MODE_SIZE> == 8")
6405                   (const_string "4")]
6406               (const_string "<MODE_SIZE>")))])
6408 (define_expand "uaddv<mode>4"
6409   [(parallel [(set (reg:CCC FLAGS_REG)
6410                    (compare:CCC
6411                      (plus:SWI
6412                        (match_operand:SWI 1 "nonimmediate_operand")
6413                        (match_operand:SWI 2 "<general_operand>"))
6414                      (match_dup 1)))
6415               (set (match_operand:SWI 0 "register_operand")
6416                    (plus:SWI (match_dup 1) (match_dup 2)))])
6417    (set (pc) (if_then_else
6418                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6419                (label_ref (match_operand 3))
6420                (pc)))]
6421   ""
6422   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6424 ;; The lea patterns for modes less than 32 bits need to be matched by
6425 ;; several insns converted to real lea by splitters.
6427 (define_insn_and_split "*lea<mode>_general_1"
6428   [(set (match_operand:SWI12 0 "register_operand" "=r")
6429         (plus:SWI12
6430           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6431                       (match_operand:SWI12 2 "register_operand" "r"))
6432           (match_operand:SWI12 3 "immediate_operand" "i")))]
6433   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6434   "#"
6435   "&& reload_completed"
6436   [(set (match_dup 0)
6437         (plus:SI
6438           (plus:SI (match_dup 1) (match_dup 2))
6439           (match_dup 3)))]
6441   operands[0] = gen_lowpart (SImode, operands[0]);
6442   operands[1] = gen_lowpart (SImode, operands[1]);
6443   operands[2] = gen_lowpart (SImode, operands[2]);
6444   operands[3] = gen_lowpart (SImode, operands[3]);
6446   [(set_attr "type" "lea")
6447    (set_attr "mode" "SI")])
6449 (define_insn_and_split "*lea<mode>_general_2"
6450   [(set (match_operand:SWI12 0 "register_operand" "=r")
6451         (plus:SWI12
6452           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6453                       (match_operand 2 "const248_operand" "n"))
6454           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6455   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6456   "#"
6457   "&& reload_completed"
6458   [(set (match_dup 0)
6459         (plus:SI
6460           (mult:SI (match_dup 1) (match_dup 2))
6461           (match_dup 3)))]
6463   operands[0] = gen_lowpart (SImode, operands[0]);
6464   operands[1] = gen_lowpart (SImode, operands[1]);
6465   operands[3] = gen_lowpart (SImode, operands[3]);
6467   [(set_attr "type" "lea")
6468    (set_attr "mode" "SI")])
6470 (define_insn_and_split "*lea<mode>_general_2b"
6471   [(set (match_operand:SWI12 0 "register_operand" "=r")
6472         (plus:SWI12
6473           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6474                         (match_operand 2 "const123_operand" "n"))
6475           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6476   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6477   "#"
6478   "&& reload_completed"
6479   [(set (match_dup 0)
6480         (plus:SI
6481           (ashift:SI (match_dup 1) (match_dup 2))
6482           (match_dup 3)))]
6484   operands[0] = gen_lowpart (SImode, operands[0]);
6485   operands[1] = gen_lowpart (SImode, operands[1]);
6486   operands[3] = gen_lowpart (SImode, operands[3]);
6488   [(set_attr "type" "lea")
6489    (set_attr "mode" "SI")])
6491 (define_insn_and_split "*lea<mode>_general_3"
6492   [(set (match_operand:SWI12 0 "register_operand" "=r")
6493         (plus:SWI12
6494           (plus:SWI12
6495             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6496                         (match_operand 2 "const248_operand" "n"))
6497             (match_operand:SWI12 3 "register_operand" "r"))
6498           (match_operand:SWI12 4 "immediate_operand" "i")))]
6499   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6500   "#"
6501   "&& reload_completed"
6502   [(set (match_dup 0)
6503         (plus:SI
6504           (plus:SI
6505             (mult:SI (match_dup 1) (match_dup 2))
6506             (match_dup 3))
6507           (match_dup 4)))]
6509   operands[0] = gen_lowpart (SImode, operands[0]);
6510   operands[1] = gen_lowpart (SImode, operands[1]);
6511   operands[3] = gen_lowpart (SImode, operands[3]);
6512   operands[4] = gen_lowpart (SImode, operands[4]);
6514   [(set_attr "type" "lea")
6515    (set_attr "mode" "SI")])
6517 (define_insn_and_split "*lea<mode>_general_3b"
6518   [(set (match_operand:SWI12 0 "register_operand" "=r")
6519         (plus:SWI12
6520           (plus:SWI12
6521             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6522                           (match_operand 2 "const123_operand" "n"))
6523             (match_operand:SWI12 3 "register_operand" "r"))
6524           (match_operand:SWI12 4 "immediate_operand" "i")))]
6525   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6526   "#"
6527   "&& reload_completed"
6528   [(set (match_dup 0)
6529         (plus:SI
6530           (plus:SI
6531             (ashift:SI (match_dup 1) (match_dup 2))
6532             (match_dup 3))
6533           (match_dup 4)))]
6535   operands[0] = gen_lowpart (SImode, operands[0]);
6536   operands[1] = gen_lowpart (SImode, operands[1]);
6537   operands[3] = gen_lowpart (SImode, operands[3]);
6538   operands[4] = gen_lowpart (SImode, operands[4]);
6540   [(set_attr "type" "lea")
6541    (set_attr "mode" "SI")])
6543 (define_insn_and_split "*lea<mode>_general_4"
6544   [(set (match_operand:SWI12 0 "register_operand" "=r")
6545         (any_or:SWI12
6546           (ashift:SWI12
6547             (match_operand:SWI12 1 "index_register_operand" "l")
6548             (match_operand 2 "const_0_to_3_operand" "n"))
6549           (match_operand 3 "const_int_operand" "n")))]
6550   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6551    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6552        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6553   "#"
6554   "&& reload_completed"
6555   [(set (match_dup 0)
6556         (plus:SI
6557           (mult:SI (match_dup 1) (match_dup 2))
6558           (match_dup 3)))]
6560   operands[0] = gen_lowpart (SImode, operands[0]);
6561   operands[1] = gen_lowpart (SImode, operands[1]);
6562   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6564   [(set_attr "type" "lea")
6565    (set_attr "mode" "SI")])
6567 (define_insn_and_split "*lea<mode>_general_4"
6568   [(set (match_operand:SWI48 0 "register_operand" "=r")
6569         (any_or:SWI48
6570           (ashift:SWI48
6571             (match_operand:SWI48 1 "index_register_operand" "l")
6572             (match_operand 2 "const_0_to_3_operand" "n"))
6573           (match_operand 3 "const_int_operand" "n")))]
6574   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6575    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6576   "#"
6577   "&& reload_completed"
6578   [(set (match_dup 0)
6579         (plus:SWI48
6580           (mult:SWI48 (match_dup 1) (match_dup 2))
6581           (match_dup 3)))]
6582   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6583   [(set_attr "type" "lea")
6584    (set_attr "mode" "<MODE>")])
6586 ;; Subtract instructions
6588 (define_expand "sub<mode>3"
6589   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6590         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6591                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6592   ""
6593   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6595 (define_insn_and_split "*sub<dwi>3_doubleword"
6596   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6597         (minus:<DWI>
6598           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6599           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6600                                                         "ro<di>,r<di>")))
6601    (clobber (reg:CC FLAGS_REG))]
6602   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6603   "#"
6604   "reload_completed"
6605   [(parallel [(set (reg:CC FLAGS_REG)
6606                    (compare:CC (match_dup 1) (match_dup 2)))
6607               (set (match_dup 0)
6608                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6609    (parallel [(set (match_dup 3)
6610                    (minus:DWIH
6611                      (minus:DWIH
6612                        (match_dup 4)
6613                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6614                      (match_dup 5)))
6615               (clobber (reg:CC FLAGS_REG))])]
6617   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6618   if (operands[2] == const0_rtx)
6619     {
6620       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6621       DONE;
6622     }
6625 (define_insn "*sub<mode>_1"
6626   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6627         (minus:SWI
6628           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6629           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6630    (clobber (reg:CC FLAGS_REG))]
6631   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6632   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6633   [(set_attr "type" "alu")
6634    (set_attr "mode" "<MODE>")])
6636 (define_insn "*subsi_1_zext"
6637   [(set (match_operand:DI 0 "register_operand" "=r")
6638         (zero_extend:DI
6639           (minus:SI (match_operand:SI 1 "register_operand" "0")
6640                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6641    (clobber (reg:CC FLAGS_REG))]
6642   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6643   "sub{l}\t{%2, %k0|%k0, %2}"
6644   [(set_attr "type" "alu")
6645    (set_attr "mode" "SI")])
6647 (define_insn "*subqi_1_slp"
6648   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6649         (minus:QI (match_dup 0)
6650                   (match_operand:QI 1 "general_operand" "qn,qm")))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6653    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6654   "sub{b}\t{%1, %0|%0, %1}"
6655   [(set_attr "type" "alu1")
6656    (set_attr "mode" "QI")])
6658 (define_insn "*sub<mode>_2"
6659   [(set (reg FLAGS_REG)
6660         (compare
6661           (minus:SWI
6662             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6663             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6664           (const_int 0)))
6665    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6666         (minus:SWI (match_dup 1) (match_dup 2)))]
6667   "ix86_match_ccmode (insn, CCGOCmode)
6668    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6669   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6670   [(set_attr "type" "alu")
6671    (set_attr "mode" "<MODE>")])
6673 (define_insn "*subsi_2_zext"
6674   [(set (reg FLAGS_REG)
6675         (compare
6676           (minus:SI (match_operand:SI 1 "register_operand" "0")
6677                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6678           (const_int 0)))
6679    (set (match_operand:DI 0 "register_operand" "=r")
6680         (zero_extend:DI
6681           (minus:SI (match_dup 1)
6682                     (match_dup 2))))]
6683   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6684    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685   "sub{l}\t{%2, %k0|%k0, %2}"
6686   [(set_attr "type" "alu")
6687    (set_attr "mode" "SI")])
6689 ;; Subtract with jump on overflow.
6690 (define_expand "subv<mode>4"
6691   [(parallel [(set (reg:CCO FLAGS_REG)
6692                    (eq:CCO (minus:<DWI>
6693                               (sign_extend:<DWI>
6694                                  (match_operand:SWI 1 "nonimmediate_operand"))
6695                               (match_dup 4))
6696                            (sign_extend:<DWI>
6697                               (minus:SWI (match_dup 1)
6698                                          (match_operand:SWI 2
6699                                             "<general_operand>")))))
6700               (set (match_operand:SWI 0 "register_operand")
6701                    (minus:SWI (match_dup 1) (match_dup 2)))])
6702    (set (pc) (if_then_else
6703                (eq (reg:CCO FLAGS_REG) (const_int 0))
6704                (label_ref (match_operand 3))
6705                (pc)))]
6706   ""
6708   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6709   if (CONST_INT_P (operands[2]))
6710     operands[4] = operands[2];
6711   else
6712     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6715 (define_insn "*subv<mode>4"
6716   [(set (reg:CCO FLAGS_REG)
6717         (eq:CCO (minus:<DWI>
6718                    (sign_extend:<DWI>
6719                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6720                    (sign_extend:<DWI>
6721                       (match_operand:SWI 2 "<general_sext_operand>"
6722                                            "<r>We,<r>m")))
6723                 (sign_extend:<DWI>
6724                    (minus:SWI (match_dup 1) (match_dup 2)))))
6725    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6726         (minus:SWI (match_dup 1) (match_dup 2)))]
6727   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6728   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "<MODE>")])
6732 (define_insn "*subv<mode>4_1"
6733   [(set (reg:CCO FLAGS_REG)
6734         (eq:CCO (minus:<DWI>
6735                    (sign_extend:<DWI>
6736                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6737                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6738                 (sign_extend:<DWI>
6739                    (minus:SWI (match_dup 1)
6740                               (match_operand:SWI 2 "x86_64_immediate_operand"
6741                                                    "<i>")))))
6742    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6743         (minus:SWI (match_dup 1) (match_dup 2)))]
6744   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6745    && CONST_INT_P (operands[2])
6746    && INTVAL (operands[2]) == INTVAL (operands[3])"
6747   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6748   [(set_attr "type" "alu")
6749    (set_attr "mode" "<MODE>")
6750    (set (attr "length_immediate")
6751         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6752                   (const_string "1")
6753                (match_test "<MODE_SIZE> == 8")
6754                   (const_string "4")]
6755               (const_string "<MODE_SIZE>")))])
6757 (define_expand "usubv<mode>4"
6758   [(parallel [(set (reg:CC FLAGS_REG)
6759                    (compare:CC
6760                      (match_operand:SWI 1 "nonimmediate_operand")
6761                      (match_operand:SWI 2 "<general_operand>")))
6762               (set (match_operand:SWI 0 "register_operand")
6763                    (minus:SWI (match_dup 1) (match_dup 2)))])
6764    (set (pc) (if_then_else
6765                (ltu (reg:CC FLAGS_REG) (const_int 0))
6766                (label_ref (match_operand 3))
6767                (pc)))]
6768   ""
6769   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6771 (define_insn "*sub<mode>_3"
6772   [(set (reg FLAGS_REG)
6773         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6774                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6775    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6776         (minus:SWI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCmode)
6778    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6779   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "<MODE>")])
6783 (define_peephole2
6784   [(parallel
6785      [(set (reg:CC FLAGS_REG)
6786            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6787                        (match_operand:SWI 1 "general_gr_operand")))
6788       (set (match_dup 0)
6789            (minus:SWI (match_dup 0) (match_dup 1)))])]
6790   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6791   [(set (reg:CC FLAGS_REG)
6792         (compare:CC (match_dup 0) (match_dup 1)))])
6794 (define_insn "*subsi_3_zext"
6795   [(set (reg FLAGS_REG)
6796         (compare (match_operand:SI 1 "register_operand" "0")
6797                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6798    (set (match_operand:DI 0 "register_operand" "=r")
6799         (zero_extend:DI
6800           (minus:SI (match_dup 1)
6801                     (match_dup 2))))]
6802   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6803    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6804   "sub{l}\t{%2, %1|%1, %2}"
6805   [(set_attr "type" "alu")
6806    (set_attr "mode" "SI")])
6808 ;; Add with carry and subtract with borrow
6810 (define_insn "add<mode>3_carry"
6811   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6812         (plus:SWI
6813           (plus:SWI
6814             (match_operator:SWI 4 "ix86_carry_flag_operator"
6815              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6816             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6817           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6818    (clobber (reg:CC FLAGS_REG))]
6819   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6820   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "use_carry" "1")
6823    (set_attr "pent_pair" "pu")
6824    (set_attr "mode" "<MODE>")])
6826 (define_insn "*addsi3_carry_zext"
6827   [(set (match_operand:DI 0 "register_operand" "=r")
6828         (zero_extend:DI
6829           (plus:SI
6830             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6831                       [(reg FLAGS_REG) (const_int 0)])
6832                      (match_operand:SI 1 "register_operand" "%0"))
6833             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6834    (clobber (reg:CC FLAGS_REG))]
6835   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6836   "adc{l}\t{%2, %k0|%k0, %2}"
6837   [(set_attr "type" "alu")
6838    (set_attr "use_carry" "1")
6839    (set_attr "pent_pair" "pu")
6840    (set_attr "mode" "SI")])
6842 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6844 (define_insn "addcarry<mode>"
6845   [(set (reg:CCC FLAGS_REG)
6846         (compare:CCC
6847           (zero_extend:<DWI>
6848             (plus:SWI48
6849               (plus:SWI48
6850                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6851                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
6852                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6853               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6854           (plus:<DWI>
6855             (zero_extend:<DWI> (match_dup 2))
6856             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6857               [(match_dup 3) (const_int 0)]))))
6858    (set (match_operand:SWI48 0 "register_operand" "=r")
6859         (plus:SWI48 (plus:SWI48 (match_op_dup 5
6860                                  [(match_dup 3) (const_int 0)])
6861                                 (match_dup 1))
6862                     (match_dup 2)))]
6863   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6864   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6865   [(set_attr "type" "alu")
6866    (set_attr "use_carry" "1")
6867    (set_attr "pent_pair" "pu")
6868    (set_attr "mode" "<MODE>")])
6870 (define_expand "addcarry<mode>_0"
6871   [(parallel
6872      [(set (reg:CCC FLAGS_REG)
6873            (compare:CCC
6874              (plus:SWI48
6875                (match_operand:SWI48 1 "nonimmediate_operand")
6876                (match_operand:SWI48 2 "x86_64_general_operand"))
6877              (match_dup 1)))
6878       (set (match_operand:SWI48 0 "register_operand")
6879            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6880   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6882 (define_insn "sub<mode>3_carry"
6883   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6884         (minus:SWI
6885           (minus:SWI
6886             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6887             (match_operator:SWI 4 "ix86_carry_flag_operator"
6888              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6889           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6890    (clobber (reg:CC FLAGS_REG))]
6891   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6892   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6893   [(set_attr "type" "alu")
6894    (set_attr "use_carry" "1")
6895    (set_attr "pent_pair" "pu")
6896    (set_attr "mode" "<MODE>")])
6898 (define_insn "*subsi3_carry_zext"
6899   [(set (match_operand:DI 0 "register_operand" "=r")
6900         (zero_extend:DI
6901           (minus:SI
6902             (minus:SI
6903               (match_operand:SI 1 "register_operand" "0")
6904               (match_operator:SI 3 "ix86_carry_flag_operator"
6905                [(reg FLAGS_REG) (const_int 0)]))
6906             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6909   "sbb{l}\t{%2, %k0|%k0, %2}"
6910   [(set_attr "type" "alu")
6911    (set_attr "use_carry" "1")
6912    (set_attr "pent_pair" "pu")
6913    (set_attr "mode" "SI")])
6915 (define_insn "sub<mode>3_carry_ccc"
6916   [(set (reg:CCC FLAGS_REG)
6917         (compare:CCC
6918           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6919           (plus:<DWI>
6920             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6921             (zero_extend:<DWI>
6922               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6923    (clobber (match_scratch:DWIH 0 "=r"))]
6924   ""
6925   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6926   [(set_attr "type" "alu")
6927    (set_attr "mode" "<MODE>")])
6929 (define_insn "*sub<mode>3_carry_ccc_1"
6930   [(set (reg:CCC FLAGS_REG)
6931         (compare:CCC
6932           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6933           (plus:<DWI>
6934             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6935             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6936    (clobber (match_scratch:DWIH 0 "=r"))]
6937   ""
6939   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6940   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6942   [(set_attr "type" "alu")
6943    (set_attr "mode" "<MODE>")])
6945 ;; The sign flag is set from the
6946 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6947 ;; result, the overflow flag likewise, but the overflow flag is also
6948 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6949 (define_insn "sub<mode>3_carry_ccgz"
6950   [(set (reg:CCGZ FLAGS_REG)
6951         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6952                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6953                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6954                      UNSPEC_SBB))
6955    (clobber (match_scratch:DWIH 0 "=r"))]
6956   ""
6957   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6958   [(set_attr "type" "alu")
6959    (set_attr "mode" "<MODE>")])
6961 (define_insn "subborrow<mode>"
6962   [(set (reg:CCC FLAGS_REG)
6963         (compare:CCC
6964           (zero_extend:<DWI>
6965             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6966           (plus:<DWI>
6967             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6968               [(match_operand 3 "flags_reg_operand") (const_int 0)])
6969             (zero_extend:<DWI>
6970               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6971    (set (match_operand:SWI48 0 "register_operand" "=r")
6972         (minus:SWI48 (minus:SWI48
6973                        (match_dup 1)
6974                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
6975                          [(match_dup 3) (const_int 0)]))
6976                      (match_dup 2)))]
6977   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6978   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "use_carry" "1")
6981    (set_attr "pent_pair" "pu")
6982    (set_attr "mode" "<MODE>")])
6984 (define_expand "subborrow<mode>_0"
6985   [(parallel
6986      [(set (reg:CC FLAGS_REG)
6987            (compare:CC
6988              (match_operand:SWI48 1 "nonimmediate_operand")
6989              (match_operand:SWI48 2 "<general_operand>")))
6990       (set (match_operand:SWI48 0 "register_operand")
6991            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6992   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6994 ;; Overflow setting add instructions
6996 (define_expand "addqi3_cconly_overflow"
6997   [(parallel
6998      [(set (reg:CCC FLAGS_REG)
6999            (compare:CCC
7000              (plus:QI
7001                (match_operand:QI 0 "nonimmediate_operand")
7002                (match_operand:QI 1 "general_operand"))
7003              (match_dup 0)))
7004       (clobber (match_scratch:QI 2))])]
7005   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7007 (define_insn "*add<mode>3_cconly_overflow_1"
7008   [(set (reg:CCC FLAGS_REG)
7009         (compare:CCC
7010           (plus:SWI
7011             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7012             (match_operand:SWI 2 "<general_operand>" "<g>"))
7013           (match_dup 1)))
7014    (clobber (match_scratch:SWI 0 "=<r>"))]
7015   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7016   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7017   [(set_attr "type" "alu")
7018    (set_attr "mode" "<MODE>")])
7020 (define_insn "*add<mode>3_cc_overflow_1"
7021   [(set (reg:CCC FLAGS_REG)
7022         (compare:CCC
7023             (plus:SWI
7024                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7025                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7026             (match_dup 1)))
7027    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7028         (plus:SWI (match_dup 1) (match_dup 2)))]
7029   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7030   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7031   [(set_attr "type" "alu")
7032    (set_attr "mode" "<MODE>")])
7034 (define_insn "*addsi3_zext_cc_overflow_1"
7035   [(set (reg:CCC FLAGS_REG)
7036         (compare:CCC
7037           (plus:SI
7038             (match_operand:SI 1 "nonimmediate_operand" "%0")
7039             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7040           (match_dup 1)))
7041    (set (match_operand:DI 0 "register_operand" "=r")
7042         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7043   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7044   "add{l}\t{%2, %k0|%k0, %2}"
7045   [(set_attr "type" "alu")
7046    (set_attr "mode" "SI")])
7048 (define_insn "*add<mode>3_cconly_overflow_2"
7049   [(set (reg:CCC FLAGS_REG)
7050         (compare:CCC
7051           (plus:SWI
7052             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7053             (match_operand:SWI 2 "<general_operand>" "<g>"))
7054           (match_dup 2)))
7055    (clobber (match_scratch:SWI 0 "=<r>"))]
7056   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7057   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7058   [(set_attr "type" "alu")
7059    (set_attr "mode" "<MODE>")])
7061 (define_insn "*add<mode>3_cc_overflow_2"
7062   [(set (reg:CCC FLAGS_REG)
7063         (compare:CCC
7064             (plus:SWI
7065                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7066                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7067             (match_dup 2)))
7068    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7069         (plus:SWI (match_dup 1) (match_dup 2)))]
7070   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7071   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7072   [(set_attr "type" "alu")
7073    (set_attr "mode" "<MODE>")])
7075 (define_insn "*addsi3_zext_cc_overflow_2"
7076   [(set (reg:CCC FLAGS_REG)
7077         (compare:CCC
7078           (plus:SI
7079             (match_operand:SI 1 "nonimmediate_operand" "%0")
7080             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7081           (match_dup 2)))
7082    (set (match_operand:DI 0 "register_operand" "=r")
7083         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7084   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7085   "add{l}\t{%2, %k0|%k0, %2}"
7086   [(set_attr "type" "alu")
7087    (set_attr "mode" "SI")])
7089 ;; The patterns that match these are at the end of this file.
7091 (define_expand "<plusminus_insn>xf3"
7092   [(set (match_operand:XF 0 "register_operand")
7093         (plusminus:XF
7094           (match_operand:XF 1 "register_operand")
7095           (match_operand:XF 2 "register_operand")))]
7096   "TARGET_80387")
7098 (define_expand "<plusminus_insn><mode>3"
7099   [(set (match_operand:MODEF 0 "register_operand")
7100         (plusminus:MODEF
7101           (match_operand:MODEF 1 "register_operand")
7102           (match_operand:MODEF 2 "nonimmediate_operand")))]
7103   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7104     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7106 ;; Multiply instructions
7108 (define_expand "mul<mode>3"
7109   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7110                    (mult:SWIM248
7111                      (match_operand:SWIM248 1 "register_operand")
7112                      (match_operand:SWIM248 2 "<general_operand>")))
7113               (clobber (reg:CC FLAGS_REG))])])
7115 (define_expand "mulqi3"
7116   [(parallel [(set (match_operand:QI 0 "register_operand")
7117                    (mult:QI
7118                      (match_operand:QI 1 "register_operand")
7119                      (match_operand:QI 2 "nonimmediate_operand")))
7120               (clobber (reg:CC FLAGS_REG))])]
7121   "TARGET_QIMODE_MATH")
7123 ;; On AMDFAM10
7124 ;; IMUL reg32/64, reg32/64, imm8        Direct
7125 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7126 ;; IMUL reg32/64, reg32/64, imm32       Direct
7127 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7128 ;; IMUL reg32/64, reg32/64              Direct
7129 ;; IMUL reg32/64, mem32/64              Direct
7131 ;; On BDVER1, all above IMULs use DirectPath
7133 ;; On AMDFAM10
7134 ;; IMUL reg16, reg16, imm8      VectorPath
7135 ;; IMUL reg16, mem16, imm8      VectorPath
7136 ;; IMUL reg16, reg16, imm16     VectorPath
7137 ;; IMUL reg16, mem16, imm16     VectorPath
7138 ;; IMUL reg16, reg16            Direct
7139 ;; IMUL reg16, mem16            Direct
7141 ;; On BDVER1, all HI MULs use DoublePath
7143 (define_insn "*mul<mode>3_1"
7144   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7145         (mult:SWIM248
7146           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7147           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7148    (clobber (reg:CC FLAGS_REG))]
7149   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7150   "@
7151    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7152    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7153    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7154   [(set_attr "type" "imul")
7155    (set_attr "prefix_0f" "0,0,1")
7156    (set (attr "athlon_decode")
7157         (cond [(eq_attr "cpu" "athlon")
7158                   (const_string "vector")
7159                (eq_attr "alternative" "1")
7160                   (const_string "vector")
7161                (and (eq_attr "alternative" "2")
7162                     (ior (match_test "<MODE>mode == HImode")
7163                          (match_operand 1 "memory_operand")))
7164                   (const_string "vector")]
7165               (const_string "direct")))
7166    (set (attr "amdfam10_decode")
7167         (cond [(and (eq_attr "alternative" "0,1")
7168                     (ior (match_test "<MODE>mode == HImode")
7169                          (match_operand 1 "memory_operand")))
7170                   (const_string "vector")]
7171               (const_string "direct")))
7172    (set (attr "bdver1_decode")
7173         (if_then_else
7174           (match_test "<MODE>mode == HImode")
7175             (const_string "double")
7176             (const_string "direct")))
7177    (set_attr "mode" "<MODE>")])
7179 (define_insn "*mulsi3_1_zext"
7180   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7181         (zero_extend:DI
7182           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7183                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7184    (clobber (reg:CC FLAGS_REG))]
7185   "TARGET_64BIT
7186    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7187   "@
7188    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7189    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7190    imul{l}\t{%2, %k0|%k0, %2}"
7191   [(set_attr "type" "imul")
7192    (set_attr "prefix_0f" "0,0,1")
7193    (set (attr "athlon_decode")
7194         (cond [(eq_attr "cpu" "athlon")
7195                   (const_string "vector")
7196                (eq_attr "alternative" "1")
7197                   (const_string "vector")
7198                (and (eq_attr "alternative" "2")
7199                     (match_operand 1 "memory_operand"))
7200                   (const_string "vector")]
7201               (const_string "direct")))
7202    (set (attr "amdfam10_decode")
7203         (cond [(and (eq_attr "alternative" "0,1")
7204                     (match_operand 1 "memory_operand"))
7205                   (const_string "vector")]
7206               (const_string "direct")))
7207    (set_attr "bdver1_decode" "direct")
7208    (set_attr "mode" "SI")])
7210 ;;On AMDFAM10 and BDVER1
7211 ;; MUL reg8     Direct
7212 ;; MUL mem8     Direct
7214 (define_insn "*mulqi3_1"
7215   [(set (match_operand:QI 0 "register_operand" "=a")
7216         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7217                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7218    (clobber (reg:CC FLAGS_REG))]
7219   "TARGET_QIMODE_MATH
7220    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7221   "mul{b}\t%2"
7222   [(set_attr "type" "imul")
7223    (set_attr "length_immediate" "0")
7224    (set (attr "athlon_decode")
7225      (if_then_else (eq_attr "cpu" "athlon")
7226         (const_string "vector")
7227         (const_string "direct")))
7228    (set_attr "amdfam10_decode" "direct")
7229    (set_attr "bdver1_decode" "direct")
7230    (set_attr "mode" "QI")])
7232 ;; Multiply with jump on overflow.
7233 (define_expand "mulv<mode>4"
7234   [(parallel [(set (reg:CCO FLAGS_REG)
7235                    (eq:CCO (mult:<DWI>
7236                               (sign_extend:<DWI>
7237                                  (match_operand:SWI248 1 "register_operand"))
7238                               (match_dup 4))
7239                            (sign_extend:<DWI>
7240                               (mult:SWI248 (match_dup 1)
7241                                            (match_operand:SWI248 2
7242                                               "<general_operand>")))))
7243               (set (match_operand:SWI248 0 "register_operand")
7244                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7245    (set (pc) (if_then_else
7246                (eq (reg:CCO FLAGS_REG) (const_int 0))
7247                (label_ref (match_operand 3))
7248                (pc)))]
7249   ""
7251   if (CONST_INT_P (operands[2]))
7252     operands[4] = operands[2];
7253   else
7254     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7257 (define_insn "*mulv<mode>4"
7258   [(set (reg:CCO FLAGS_REG)
7259         (eq:CCO (mult:<DWI>
7260                    (sign_extend:<DWI>
7261                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7262                    (sign_extend:<DWI>
7263                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7264                 (sign_extend:<DWI>
7265                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7266    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7267         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7268   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269   "@
7270    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7271    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7272   [(set_attr "type" "imul")
7273    (set_attr "prefix_0f" "0,1")
7274    (set (attr "athlon_decode")
7275         (cond [(eq_attr "cpu" "athlon")
7276                   (const_string "vector")
7277                (eq_attr "alternative" "0")
7278                   (const_string "vector")
7279                (and (eq_attr "alternative" "1")
7280                     (match_operand 1 "memory_operand"))
7281                   (const_string "vector")]
7282               (const_string "direct")))
7283    (set (attr "amdfam10_decode")
7284         (cond [(and (eq_attr "alternative" "1")
7285                     (match_operand 1 "memory_operand"))
7286                   (const_string "vector")]
7287               (const_string "direct")))
7288    (set_attr "bdver1_decode" "direct")
7289    (set_attr "mode" "<MODE>")])
7291 (define_insn "*mulvhi4"
7292   [(set (reg:CCO FLAGS_REG)
7293         (eq:CCO (mult:SI
7294                    (sign_extend:SI
7295                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7296                    (sign_extend:SI
7297                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7298                 (sign_extend:SI
7299                    (mult:HI (match_dup 1) (match_dup 2)))))
7300    (set (match_operand:HI 0 "register_operand" "=r")
7301         (mult:HI (match_dup 1) (match_dup 2)))]
7302   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7303   "imul{w}\t{%2, %0|%0, %2}"
7304   [(set_attr "type" "imul")
7305    (set_attr "prefix_0f" "1")
7306    (set_attr "athlon_decode" "vector")
7307    (set_attr "amdfam10_decode" "direct")
7308    (set_attr "bdver1_decode" "double")
7309    (set_attr "mode" "HI")])
7311 (define_insn "*mulv<mode>4_1"
7312   [(set (reg:CCO FLAGS_REG)
7313         (eq:CCO (mult:<DWI>
7314                    (sign_extend:<DWI>
7315                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7316                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7317                 (sign_extend:<DWI>
7318                    (mult:SWI248 (match_dup 1)
7319                                 (match_operand:SWI248 2
7320                                    "<immediate_operand>" "K,<i>")))))
7321    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7322         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7323   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7324    && CONST_INT_P (operands[2])
7325    && INTVAL (operands[2]) == INTVAL (operands[3])"
7326   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7327   [(set_attr "type" "imul")
7328    (set (attr "prefix_0f")
7329         (if_then_else
7330           (match_test "<MODE>mode == HImode")
7331             (const_string "0")
7332             (const_string "*")))
7333    (set (attr "athlon_decode")
7334         (cond [(eq_attr "cpu" "athlon")
7335                   (const_string "vector")
7336                (eq_attr "alternative" "1")
7337                   (const_string "vector")]
7338               (const_string "direct")))
7339    (set (attr "amdfam10_decode")
7340         (cond [(ior (match_test "<MODE>mode == HImode")
7341                     (match_operand 1 "memory_operand"))
7342                   (const_string "vector")]
7343               (const_string "direct")))
7344    (set (attr "bdver1_decode")
7345         (if_then_else
7346           (match_test "<MODE>mode == HImode")
7347             (const_string "double")
7348             (const_string "direct")))
7349    (set_attr "mode" "<MODE>")
7350    (set (attr "length_immediate")
7351         (cond [(eq_attr "alternative" "0")
7352                   (const_string "1")
7353                (match_test "<MODE_SIZE> == 8")
7354                   (const_string "4")]
7355               (const_string "<MODE_SIZE>")))])
7357 (define_expand "umulv<mode>4"
7358   [(parallel [(set (reg:CCO FLAGS_REG)
7359                    (eq:CCO (mult:<DWI>
7360                               (zero_extend:<DWI>
7361                                  (match_operand:SWI248 1
7362                                                       "nonimmediate_operand"))
7363                               (zero_extend:<DWI>
7364                                  (match_operand:SWI248 2
7365                                                       "nonimmediate_operand")))
7366                            (zero_extend:<DWI>
7367                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7368               (set (match_operand:SWI248 0 "register_operand")
7369                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7370               (clobber (match_scratch:SWI248 4))])
7371    (set (pc) (if_then_else
7372                (eq (reg:CCO FLAGS_REG) (const_int 0))
7373                (label_ref (match_operand 3))
7374                (pc)))]
7375   ""
7377   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7378     operands[1] = force_reg (<MODE>mode, operands[1]);
7381 (define_insn "*umulv<mode>4"
7382   [(set (reg:CCO FLAGS_REG)
7383         (eq:CCO (mult:<DWI>
7384                    (zero_extend:<DWI>
7385                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7386                    (zero_extend:<DWI>
7387                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7388                 (zero_extend:<DWI>
7389                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7390    (set (match_operand:SWI248 0 "register_operand" "=a")
7391         (mult:SWI248 (match_dup 1) (match_dup 2)))
7392    (clobber (match_scratch:SWI248 3 "=d"))]
7393   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7394   "mul{<imodesuffix>}\t%2"
7395   [(set_attr "type" "imul")
7396    (set_attr "length_immediate" "0")
7397    (set (attr "athlon_decode")
7398      (if_then_else (eq_attr "cpu" "athlon")
7399        (const_string "vector")
7400        (const_string "double")))
7401    (set_attr "amdfam10_decode" "double")
7402    (set_attr "bdver1_decode" "direct")
7403    (set_attr "mode" "<MODE>")])
7405 (define_expand "<u>mulvqi4"
7406   [(parallel [(set (reg:CCO FLAGS_REG)
7407                    (eq:CCO (mult:HI
7408                               (any_extend:HI
7409                                  (match_operand:QI 1 "nonimmediate_operand"))
7410                               (any_extend:HI
7411                                  (match_operand:QI 2 "nonimmediate_operand")))
7412                            (any_extend:HI
7413                               (mult:QI (match_dup 1) (match_dup 2)))))
7414               (set (match_operand:QI 0 "register_operand")
7415                    (mult:QI (match_dup 1) (match_dup 2)))])
7416    (set (pc) (if_then_else
7417                (eq (reg:CCO FLAGS_REG) (const_int 0))
7418                (label_ref (match_operand 3))
7419                (pc)))]
7420   "TARGET_QIMODE_MATH"
7422   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7423     operands[1] = force_reg (QImode, operands[1]);
7426 (define_insn "*<u>mulvqi4"
7427   [(set (reg:CCO FLAGS_REG)
7428         (eq:CCO (mult:HI
7429                    (any_extend:HI
7430                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7431                    (any_extend:HI
7432                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7433                 (any_extend:HI
7434                    (mult:QI (match_dup 1) (match_dup 2)))))
7435    (set (match_operand:QI 0 "register_operand" "=a")
7436         (mult:QI (match_dup 1) (match_dup 2)))]
7437   "TARGET_QIMODE_MATH
7438    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7439   "<sgnprefix>mul{b}\t%2"
7440   [(set_attr "type" "imul")
7441    (set_attr "length_immediate" "0")
7442    (set (attr "athlon_decode")
7443      (if_then_else (eq_attr "cpu" "athlon")
7444         (const_string "vector")
7445         (const_string "direct")))
7446    (set_attr "amdfam10_decode" "direct")
7447    (set_attr "bdver1_decode" "direct")
7448    (set_attr "mode" "QI")])
7450 (define_expand "<u>mul<mode><dwi>3"
7451   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7452                    (mult:<DWI>
7453                      (any_extend:<DWI>
7454                        (match_operand:DWIH 1 "nonimmediate_operand"))
7455                      (any_extend:<DWI>
7456                        (match_operand:DWIH 2 "register_operand"))))
7457               (clobber (reg:CC FLAGS_REG))])])
7459 (define_expand "<u>mulqihi3"
7460   [(parallel [(set (match_operand:HI 0 "register_operand")
7461                    (mult:HI
7462                      (any_extend:HI
7463                        (match_operand:QI 1 "nonimmediate_operand"))
7464                      (any_extend:HI
7465                        (match_operand:QI 2 "register_operand"))))
7466               (clobber (reg:CC FLAGS_REG))])]
7467   "TARGET_QIMODE_MATH")
7469 (define_insn "*bmi2_umul<mode><dwi>3_1"
7470   [(set (match_operand:DWIH 0 "register_operand" "=r")
7471         (mult:DWIH
7472           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7473           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7474    (set (match_operand:DWIH 1 "register_operand" "=r")
7475         (truncate:DWIH
7476           (lshiftrt:<DWI>
7477             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7478                         (zero_extend:<DWI> (match_dup 3)))
7479             (match_operand:QI 4 "const_int_operand" "n"))))]
7480   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7481    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7482   "mulx\t{%3, %0, %1|%1, %0, %3}"
7483   [(set_attr "type" "imulx")
7484    (set_attr "prefix" "vex")
7485    (set_attr "mode" "<MODE>")])
7487 (define_insn "*umul<mode><dwi>3_1"
7488   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7489         (mult:<DWI>
7490           (zero_extend:<DWI>
7491             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7492           (zero_extend:<DWI>
7493             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7496   "@
7497    #
7498    mul{<imodesuffix>}\t%2"
7499   [(set_attr "isa" "bmi2,*")
7500    (set_attr "type" "imulx,imul")
7501    (set_attr "length_immediate" "*,0")
7502    (set (attr "athlon_decode")
7503         (cond [(eq_attr "alternative" "1")
7504                  (if_then_else (eq_attr "cpu" "athlon")
7505                    (const_string "vector")
7506                    (const_string "double"))]
7507               (const_string "*")))
7508    (set_attr "amdfam10_decode" "*,double")
7509    (set_attr "bdver1_decode" "*,direct")
7510    (set_attr "prefix" "vex,orig")
7511    (set_attr "mode" "<MODE>")])
7513 ;; Convert mul to the mulx pattern to avoid flags dependency.
7514 (define_split
7515  [(set (match_operand:<DWI> 0 "register_operand")
7516        (mult:<DWI>
7517          (zero_extend:<DWI>
7518            (match_operand:DWIH 1 "register_operand"))
7519          (zero_extend:<DWI>
7520            (match_operand:DWIH 2 "nonimmediate_operand"))))
7521   (clobber (reg:CC FLAGS_REG))]
7522  "TARGET_BMI2 && reload_completed
7523   && REGNO (operands[1]) == DX_REG"
7524   [(parallel [(set (match_dup 3)
7525                    (mult:DWIH (match_dup 1) (match_dup 2)))
7526               (set (match_dup 4)
7527                    (truncate:DWIH
7528                      (lshiftrt:<DWI>
7529                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7530                                    (zero_extend:<DWI> (match_dup 2)))
7531                        (match_dup 5))))])]
7533   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7535   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7538 (define_insn "*mul<mode><dwi>3_1"
7539   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7540         (mult:<DWI>
7541           (sign_extend:<DWI>
7542             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7543           (sign_extend:<DWI>
7544             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7545    (clobber (reg:CC FLAGS_REG))]
7546   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547   "imul{<imodesuffix>}\t%2"
7548   [(set_attr "type" "imul")
7549    (set_attr "length_immediate" "0")
7550    (set (attr "athlon_decode")
7551      (if_then_else (eq_attr "cpu" "athlon")
7552         (const_string "vector")
7553         (const_string "double")))
7554    (set_attr "amdfam10_decode" "double")
7555    (set_attr "bdver1_decode" "direct")
7556    (set_attr "mode" "<MODE>")])
7558 (define_insn "*<u>mulqihi3_1"
7559   [(set (match_operand:HI 0 "register_operand" "=a")
7560         (mult:HI
7561           (any_extend:HI
7562             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7563           (any_extend:HI
7564             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "TARGET_QIMODE_MATH
7567    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7568   "<sgnprefix>mul{b}\t%2"
7569   [(set_attr "type" "imul")
7570    (set_attr "length_immediate" "0")
7571    (set (attr "athlon_decode")
7572      (if_then_else (eq_attr "cpu" "athlon")
7573         (const_string "vector")
7574         (const_string "direct")))
7575    (set_attr "amdfam10_decode" "direct")
7576    (set_attr "bdver1_decode" "direct")
7577    (set_attr "mode" "QI")])
7579 (define_expand "<s>mul<mode>3_highpart"
7580   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7581                    (truncate:SWI48
7582                      (lshiftrt:<DWI>
7583                        (mult:<DWI>
7584                          (any_extend:<DWI>
7585                            (match_operand:SWI48 1 "nonimmediate_operand"))
7586                          (any_extend:<DWI>
7587                            (match_operand:SWI48 2 "register_operand")))
7588                        (match_dup 3))))
7589               (clobber (match_scratch:SWI48 4))
7590               (clobber (reg:CC FLAGS_REG))])]
7591   ""
7592   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7594 (define_insn "*<s>muldi3_highpart_1"
7595   [(set (match_operand:DI 0 "register_operand" "=d")
7596         (truncate:DI
7597           (lshiftrt:TI
7598             (mult:TI
7599               (any_extend:TI
7600                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7601               (any_extend:TI
7602                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7603             (const_int 64))))
7604    (clobber (match_scratch:DI 3 "=1"))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "TARGET_64BIT
7607    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7608   "<sgnprefix>mul{q}\t%2"
7609   [(set_attr "type" "imul")
7610    (set_attr "length_immediate" "0")
7611    (set (attr "athlon_decode")
7612      (if_then_else (eq_attr "cpu" "athlon")
7613         (const_string "vector")
7614         (const_string "double")))
7615    (set_attr "amdfam10_decode" "double")
7616    (set_attr "bdver1_decode" "direct")
7617    (set_attr "mode" "DI")])
7619 (define_insn "*<s>mulsi3_highpart_zext"
7620   [(set (match_operand:DI 0 "register_operand" "=d")
7621         (zero_extend:DI (truncate:SI
7622           (lshiftrt:DI
7623             (mult:DI (any_extend:DI
7624                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7625                      (any_extend:DI
7626                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7627             (const_int 32)))))
7628    (clobber (match_scratch:SI 3 "=1"))
7629    (clobber (reg:CC FLAGS_REG))]
7630   "TARGET_64BIT
7631    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632   "<sgnprefix>mul{l}\t%2"
7633   [(set_attr "type" "imul")
7634    (set_attr "length_immediate" "0")
7635    (set (attr "athlon_decode")
7636      (if_then_else (eq_attr "cpu" "athlon")
7637         (const_string "vector")
7638         (const_string "double")))
7639    (set_attr "amdfam10_decode" "double")
7640    (set_attr "bdver1_decode" "direct")
7641    (set_attr "mode" "SI")])
7643 (define_insn "*<s>mulsi3_highpart_1"
7644   [(set (match_operand:SI 0 "register_operand" "=d")
7645         (truncate:SI
7646           (lshiftrt:DI
7647             (mult:DI
7648               (any_extend:DI
7649                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7650               (any_extend:DI
7651                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7652             (const_int 32))))
7653    (clobber (match_scratch:SI 3 "=1"))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656   "<sgnprefix>mul{l}\t%2"
7657   [(set_attr "type" "imul")
7658    (set_attr "length_immediate" "0")
7659    (set (attr "athlon_decode")
7660      (if_then_else (eq_attr "cpu" "athlon")
7661         (const_string "vector")
7662         (const_string "double")))
7663    (set_attr "amdfam10_decode" "double")
7664    (set_attr "bdver1_decode" "direct")
7665    (set_attr "mode" "SI")])
7667 ;; The patterns that match these are at the end of this file.
7669 (define_expand "mulxf3"
7670   [(set (match_operand:XF 0 "register_operand")
7671         (mult:XF (match_operand:XF 1 "register_operand")
7672                  (match_operand:XF 2 "register_operand")))]
7673   "TARGET_80387")
7675 (define_expand "mul<mode>3"
7676   [(set (match_operand:MODEF 0 "register_operand")
7677         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7678                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7679   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7680     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7682 ;; Divide instructions
7684 ;; The patterns that match these are at the end of this file.
7686 (define_expand "divxf3"
7687   [(set (match_operand:XF 0 "register_operand")
7688         (div:XF (match_operand:XF 1 "register_operand")
7689                 (match_operand:XF 2 "register_operand")))]
7690   "TARGET_80387")
7692 (define_expand "div<mode>3"
7693   [(set (match_operand:MODEF 0 "register_operand")
7694         (div:MODEF (match_operand:MODEF 1 "register_operand")
7695                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7696   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7697     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7699   if (<MODE>mode == SFmode
7700       && TARGET_SSE && TARGET_SSE_MATH
7701       && TARGET_RECIP_DIV
7702       && optimize_insn_for_speed_p ()
7703       && flag_finite_math_only && !flag_trapping_math
7704       && flag_unsafe_math_optimizations)
7705     {
7706       ix86_emit_swdivsf (operands[0], operands[1],
7707                          operands[2], SFmode);
7708       DONE;
7709     }
7712 ;; Divmod instructions.
7714 (define_expand "divmod<mode>4"
7715   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7716                    (div:SWIM248
7717                      (match_operand:SWIM248 1 "register_operand")
7718                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7719               (set (match_operand:SWIM248 3 "register_operand")
7720                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7721               (clobber (reg:CC FLAGS_REG))])])
7723 ;; Split with 8bit unsigned divide:
7724 ;;      if (dividend an divisor are in [0-255])
7725 ;;         use 8bit unsigned integer divide
7726 ;;       else
7727 ;;         use original integer divide
7728 (define_split
7729   [(set (match_operand:SWI48 0 "register_operand")
7730         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7731                     (match_operand:SWI48 3 "nonimmediate_operand")))
7732    (set (match_operand:SWI48 1 "register_operand")
7733         (mod:SWI48 (match_dup 2) (match_dup 3)))
7734    (clobber (reg:CC FLAGS_REG))]
7735   "TARGET_USE_8BIT_IDIV
7736    && TARGET_QIMODE_MATH
7737    && can_create_pseudo_p ()
7738    && !optimize_insn_for_size_p ()"
7739   [(const_int 0)]
7740   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7742 (define_split
7743   [(set (match_operand:DI 0 "register_operand")
7744         (zero_extend:DI
7745           (div:SI (match_operand:SI 2 "register_operand")
7746                   (match_operand:SI 3 "nonimmediate_operand"))))
7747    (set (match_operand:SI 1 "register_operand")
7748         (mod:SI (match_dup 2) (match_dup 3)))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "TARGET_USE_8BIT_IDIV
7751    && TARGET_QIMODE_MATH
7752    && can_create_pseudo_p ()
7753    && !optimize_insn_for_size_p ()"
7754   [(const_int 0)]
7755   "ix86_split_idivmod (SImode, operands, true); DONE;")
7757 (define_split
7758   [(set (match_operand:DI 1 "register_operand")
7759         (zero_extend:DI
7760           (mod:SI (match_operand:SI 2 "register_operand")
7761                   (match_operand:SI 3 "nonimmediate_operand"))))
7762    (set (match_operand:SI 0 "register_operand")
7763         (div:SI  (match_dup 2) (match_dup 3)))
7764    (clobber (reg:CC FLAGS_REG))]
7765   "TARGET_USE_8BIT_IDIV
7766    && TARGET_QIMODE_MATH
7767    && can_create_pseudo_p ()
7768    && !optimize_insn_for_size_p ()"
7769   [(const_int 0)]
7770   "ix86_split_idivmod (SImode, operands, true); DONE;")
7772 (define_insn_and_split "divmod<mode>4_1"
7773   [(set (match_operand:SWI48 0 "register_operand" "=a")
7774         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7775                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7776    (set (match_operand:SWI48 1 "register_operand" "=&d")
7777         (mod:SWI48 (match_dup 2) (match_dup 3)))
7778    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7779    (clobber (reg:CC FLAGS_REG))]
7780   ""
7781   "#"
7782   "reload_completed"
7783   [(parallel [(set (match_dup 1)
7784                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7785               (clobber (reg:CC FLAGS_REG))])
7786    (parallel [(set (match_dup 0)
7787                    (div:SWI48 (match_dup 2) (match_dup 3)))
7788               (set (match_dup 1)
7789                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7790               (use (match_dup 1))
7791               (clobber (reg:CC FLAGS_REG))])]
7793   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7795   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7796     operands[4] = operands[2];
7797   else
7798     {
7799       /* Avoid use of cltd in favor of a mov+shift.  */
7800       emit_move_insn (operands[1], operands[2]);
7801       operands[4] = operands[1];
7802     }
7804   [(set_attr "type" "multi")
7805    (set_attr "mode" "<MODE>")])
7807 (define_insn_and_split "divmodsi4_zext_1"
7808   [(set (match_operand:DI 0 "register_operand" "=a")
7809         (zero_extend:DI
7810           (div:SI (match_operand:SI 2 "register_operand" "0")
7811                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7812    (set (match_operand:SI 1 "register_operand" "=&d")
7813         (mod:SI (match_dup 2) (match_dup 3)))
7814    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7815    (clobber (reg:CC FLAGS_REG))]
7816   "TARGET_64BIT"
7817   "#"
7818   "reload_completed"
7819   [(parallel [(set (match_dup 1)
7820                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7821               (clobber (reg:CC FLAGS_REG))])
7822    (parallel [(set (match_dup 0)
7823                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7824               (set (match_dup 1)
7825                    (mod:SI (match_dup 2) (match_dup 3)))
7826               (use (match_dup 1))
7827               (clobber (reg:CC FLAGS_REG))])]
7829   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7831   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7832     operands[4] = operands[2];
7833   else
7834     {
7835       /* Avoid use of cltd in favor of a mov+shift.  */
7836       emit_move_insn (operands[1], operands[2]);
7837       operands[4] = operands[1];
7838     }
7840   [(set_attr "type" "multi")
7841    (set_attr "mode" "SI")])
7843 (define_insn_and_split "divmodsi4_zext_2"
7844   [(set (match_operand:DI 1 "register_operand" "=&d")
7845         (zero_extend:DI
7846           (mod:SI (match_operand:SI 2 "register_operand" "0")
7847                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7848    (set (match_operand:SI 0 "register_operand" "=a")
7849         (div:SI (match_dup 2) (match_dup 3)))
7850    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7851    (clobber (reg:CC FLAGS_REG))]
7852   "TARGET_64BIT"
7853   "#"
7854   "reload_completed"
7855   [(parallel [(set (match_dup 6)
7856                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7857               (clobber (reg:CC FLAGS_REG))])
7858    (parallel [(set (match_dup 1)
7859                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7860               (set (match_dup 0)
7861                    (div:SI (match_dup 2) (match_dup 3)))
7862               (use (match_dup 6))
7863               (clobber (reg:CC FLAGS_REG))])]
7865   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7866   operands[6] = gen_lowpart (SImode, operands[1]);
7868   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7869     operands[4] = operands[2];
7870   else
7871     {
7872       /* Avoid use of cltd in favor of a mov+shift.  */
7873       emit_move_insn (operands[6], operands[2]);
7874       operands[4] = operands[6];
7875     }
7877   [(set_attr "type" "multi")
7878    (set_attr "mode" "SI")])
7880 (define_insn_and_split "*divmod<mode>4"
7881   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7882         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7883                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7884    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7885         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7886    (clobber (reg:CC FLAGS_REG))]
7887   ""
7888   "#"
7889   "reload_completed"
7890   [(parallel [(set (match_dup 1)
7891                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7892               (clobber (reg:CC FLAGS_REG))])
7893    (parallel [(set (match_dup 0)
7894                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7895               (set (match_dup 1)
7896                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7897               (use (match_dup 1))
7898               (clobber (reg:CC FLAGS_REG))])]
7900   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7902   if (<MODE>mode != HImode
7903       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7904     operands[4] = operands[2];
7905   else
7906     {
7907       /* Avoid use of cltd in favor of a mov+shift.  */
7908       emit_move_insn (operands[1], operands[2]);
7909       operands[4] = operands[1];
7910     }
7912   [(set_attr "type" "multi")
7913    (set_attr "mode" "<MODE>")])
7915 (define_insn_and_split "*divmodsi4_zext_1"
7916   [(set (match_operand:DI 0 "register_operand" "=a")
7917         (zero_extend:DI
7918           (div:SI (match_operand:SI 2 "register_operand" "0")
7919                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7920    (set (match_operand:SI 1 "register_operand" "=&d")
7921         (mod:SI (match_dup 2) (match_dup 3)))
7922    (clobber (reg:CC FLAGS_REG))]
7923   "TARGET_64BIT"
7924   "#"
7925   "reload_completed"
7926   [(parallel [(set (match_dup 1)
7927                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7928               (clobber (reg:CC FLAGS_REG))])
7929    (parallel [(set (match_dup 0)
7930                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7931               (set (match_dup 1)
7932                    (mod:SI (match_dup 2) (match_dup 3)))
7933               (use (match_dup 1))
7934               (clobber (reg:CC FLAGS_REG))])]
7936   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7938   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7939     operands[4] = operands[2];
7940   else
7941     {
7942       /* Avoid use of cltd in favor of a mov+shift.  */
7943       emit_move_insn (operands[1], operands[2]);
7944       operands[4] = operands[1];
7945     }
7947   [(set_attr "type" "multi")
7948    (set_attr "mode" "SI")])
7950 (define_insn_and_split "*divmodsi4_zext_2"
7951   [(set (match_operand:DI 1 "register_operand" "=&d")
7952         (zero_extend:DI
7953           (mod:SI (match_operand:SI 2 "register_operand" "0")
7954                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7955    (set (match_operand:SI 0 "register_operand" "=a")
7956         (div:SI (match_dup 2) (match_dup 3)))
7957    (clobber (reg:CC FLAGS_REG))]
7958   "TARGET_64BIT"
7959   "#"
7960   "reload_completed"
7961   [(parallel [(set (match_dup 6)
7962                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7963               (clobber (reg:CC FLAGS_REG))])
7964    (parallel [(set (match_dup 1)
7965                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7966               (set (match_dup 0)
7967                    (div:SI (match_dup 2) (match_dup 3)))
7968               (use (match_dup 6))
7969               (clobber (reg:CC FLAGS_REG))])]
7971   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7972   operands[6] = gen_lowpart (SImode, operands[1]);
7974   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7975     operands[4] = operands[2];
7976   else
7977     {
7978       /* Avoid use of cltd in favor of a mov+shift.  */
7979       emit_move_insn (operands[6], operands[2]);
7980       operands[4] = operands[6];
7981     }
7983   [(set_attr "type" "multi")
7984    (set_attr "mode" "SI")])
7986 (define_insn "*divmod<mode>4_noext"
7987   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7988         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7989                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7990    (set (match_operand:SWIM248 1 "register_operand" "=d")
7991         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7992    (use (match_operand:SWIM248 4 "register_operand" "1"))
7993    (clobber (reg:CC FLAGS_REG))]
7994   ""
7995   "idiv{<imodesuffix>}\t%3"
7996   [(set_attr "type" "idiv")
7997    (set_attr "mode" "<MODE>")])
7999 (define_insn "*divmodsi4_noext_zext_1"
8000   [(set (match_operand:DI 0 "register_operand" "=a")
8001         (zero_extend:DI
8002           (div:SI (match_operand:SI 2 "register_operand" "0")
8003                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8004    (set (match_operand:SI 1 "register_operand" "=d")
8005         (mod:SI (match_dup 2) (match_dup 3)))
8006    (use (match_operand:SI 4 "register_operand" "1"))
8007    (clobber (reg:CC FLAGS_REG))]
8008   "TARGET_64BIT"
8009   "idiv{l}\t%3"
8010   [(set_attr "type" "idiv")
8011    (set_attr "mode" "SI")])
8013 (define_insn "*divmodsi4_noext_zext_2"
8014   [(set (match_operand:DI 1 "register_operand" "=d")
8015         (zero_extend:DI
8016           (mod:SI (match_operand:SI 2 "register_operand" "0")
8017                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8018    (set (match_operand:SI 0 "register_operand" "=a")
8019         (div:SI (match_dup 2) (match_dup 3)))
8020    (use (match_operand:SI 4 "register_operand" "1"))
8021    (clobber (reg:CC FLAGS_REG))]
8022   "TARGET_64BIT"
8023   "idiv{l}\t%3"
8024   [(set_attr "type" "idiv")
8025    (set_attr "mode" "SI")])
8027 (define_expand "divmodqi4"
8028   [(parallel [(set (match_operand:QI 0 "register_operand")
8029                    (div:QI
8030                      (match_operand:QI 1 "register_operand")
8031                      (match_operand:QI 2 "nonimmediate_operand")))
8032               (set (match_operand:QI 3 "register_operand")
8033                    (mod:QI (match_dup 1) (match_dup 2)))
8034               (clobber (reg:CC FLAGS_REG))])]
8035   "TARGET_QIMODE_MATH"
8037   rtx div, mod;
8038   rtx tmp0, tmp1;
8039   
8040   tmp0 = gen_reg_rtx (HImode);
8041   tmp1 = gen_reg_rtx (HImode);
8043   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8044   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8045   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8047   /* Extract remainder from AH.  */
8048   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8049   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8050   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8052   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8053   set_unique_reg_note (insn, REG_EQUAL, mod);
8055   /* Extract quotient from AL.  */
8056   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8058   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8059   set_unique_reg_note (insn, REG_EQUAL, div);
8061   DONE;
8064 ;; Divide AX by r/m8, with result stored in
8065 ;; AL <- Quotient
8066 ;; AH <- Remainder
8067 ;; Change div/mod to HImode and extend the second argument to HImode
8068 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8069 ;; combine may fail.
8070 (define_insn "divmodhiqi3"
8071   [(set (match_operand:HI 0 "register_operand" "=a")
8072         (ior:HI
8073           (ashift:HI
8074             (zero_extend:HI
8075               (truncate:QI
8076                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8077                         (sign_extend:HI
8078                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8079             (const_int 8))
8080           (zero_extend:HI
8081             (truncate:QI
8082               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8083    (clobber (reg:CC FLAGS_REG))]
8084   "TARGET_QIMODE_MATH"
8085   "idiv{b}\t%2"
8086   [(set_attr "type" "idiv")
8087    (set_attr "mode" "QI")])
8089 (define_expand "udivmod<mode>4"
8090   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8091                    (udiv:SWIM248
8092                      (match_operand:SWIM248 1 "register_operand")
8093                      (match_operand:SWIM248 2 "nonimmediate_operand")))
8094               (set (match_operand:SWIM248 3 "register_operand")
8095                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8096               (clobber (reg:CC FLAGS_REG))])])
8098 ;; Split with 8bit unsigned divide:
8099 ;;      if (dividend an divisor are in [0-255])
8100 ;;         use 8bit unsigned integer divide
8101 ;;       else
8102 ;;         use original integer divide
8103 (define_split
8104   [(set (match_operand:SWI48 0 "register_operand")
8105         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8106                     (match_operand:SWI48 3 "nonimmediate_operand")))
8107    (set (match_operand:SWI48 1 "register_operand")
8108         (umod:SWI48 (match_dup 2) (match_dup 3)))
8109    (clobber (reg:CC FLAGS_REG))]
8110   "TARGET_USE_8BIT_IDIV
8111    && TARGET_QIMODE_MATH
8112    && can_create_pseudo_p ()
8113    && !optimize_insn_for_size_p ()"
8114   [(const_int 0)]
8115   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8117 (define_split
8118   [(set (match_operand:DI 0 "register_operand")
8119         (zero_extend:DI
8120           (udiv:SI (match_operand:SI 2 "register_operand")
8121                    (match_operand:SI 3 "nonimmediate_operand"))))
8122    (set (match_operand:SI 1 "register_operand")
8123         (umod:SI (match_dup 2) (match_dup 3)))
8124    (clobber (reg:CC FLAGS_REG))]
8125   "TARGET_64BIT
8126    && TARGET_USE_8BIT_IDIV
8127    && TARGET_QIMODE_MATH
8128    && can_create_pseudo_p ()
8129    && !optimize_insn_for_size_p ()"
8130   [(const_int 0)]
8131   "ix86_split_idivmod (SImode, operands, false); DONE;")
8133 (define_split
8134   [(set (match_operand:DI 1 "register_operand")
8135         (zero_extend:DI
8136           (umod:SI (match_operand:SI 2 "register_operand")
8137                    (match_operand:SI 3 "nonimmediate_operand"))))
8138    (set (match_operand:SI 0 "register_operand")
8139         (udiv:SI (match_dup 2) (match_dup 3)))
8140    (clobber (reg:CC FLAGS_REG))]
8141   "TARGET_64BIT
8142    && TARGET_USE_8BIT_IDIV
8143    && TARGET_QIMODE_MATH
8144    && can_create_pseudo_p ()
8145    && !optimize_insn_for_size_p ()"
8146   [(const_int 0)]
8147   "ix86_split_idivmod (SImode, operands, false); DONE;")
8149 (define_insn_and_split "udivmod<mode>4_1"
8150   [(set (match_operand:SWI48 0 "register_operand" "=a")
8151         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8152                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8153    (set (match_operand:SWI48 1 "register_operand" "=&d")
8154         (umod:SWI48 (match_dup 2) (match_dup 3)))
8155    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8156    (clobber (reg:CC FLAGS_REG))]
8157   ""
8158   "#"
8159   "reload_completed"
8160   [(set (match_dup 1) (const_int 0))
8161    (parallel [(set (match_dup 0)
8162                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
8163               (set (match_dup 1)
8164                    (umod:SWI48 (match_dup 2) (match_dup 3)))
8165               (use (match_dup 1))
8166               (clobber (reg:CC FLAGS_REG))])]
8167   ""
8168   [(set_attr "type" "multi")
8169    (set_attr "mode" "<MODE>")])
8171 (define_insn_and_split "udivmodsi4_zext_1"
8172   [(set (match_operand:DI 0 "register_operand" "=a")
8173         (zero_extend:DI
8174           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8175                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8176    (set (match_operand:SI 1 "register_operand" "=&d")
8177         (umod:SI (match_dup 2) (match_dup 3)))
8178    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8179    (clobber (reg:CC FLAGS_REG))]
8180   "TARGET_64BIT"
8181   "#"
8182   "reload_completed"
8183   [(set (match_dup 1) (const_int 0))
8184    (parallel [(set (match_dup 0)
8185                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8186               (set (match_dup 1)
8187                    (umod:SI (match_dup 2) (match_dup 3)))
8188               (use (match_dup 1))
8189               (clobber (reg:CC FLAGS_REG))])]
8190   ""
8191   [(set_attr "type" "multi")
8192    (set_attr "mode" "SI")])
8194 (define_insn_and_split "udivmodsi4_zext_2"
8195   [(set (match_operand:DI 1 "register_operand" "=&d")
8196         (zero_extend:DI
8197           (umod:SI (match_operand:SI 2 "register_operand" "0")
8198                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8199    (set (match_operand:SI 0 "register_operand" "=a")
8200         (udiv:SI (match_dup 2) (match_dup 3)))
8201    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8202    (clobber (reg:CC FLAGS_REG))]
8203   "TARGET_64BIT"
8204   "#"
8205   "reload_completed"
8206   [(set (match_dup 4) (const_int 0))
8207    (parallel [(set (match_dup 1)
8208                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8209               (set (match_dup 0)
8210                    (udiv:SI (match_dup 2) (match_dup 3)))
8211               (use (match_dup 4))
8212               (clobber (reg:CC FLAGS_REG))])]
8213   "operands[4] = gen_lowpart (SImode, operands[1]);"
8214   [(set_attr "type" "multi")
8215    (set_attr "mode" "SI")])
8217 (define_insn_and_split "*udivmod<mode>4"
8218   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8219         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8220                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8221    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8222         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8223    (clobber (reg:CC FLAGS_REG))]
8224   ""
8225   "#"
8226   "reload_completed"
8227   [(set (match_dup 1) (const_int 0))
8228    (parallel [(set (match_dup 0)
8229                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8230               (set (match_dup 1)
8231                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8232               (use (match_dup 1))
8233               (clobber (reg:CC FLAGS_REG))])]
8234   ""
8235   [(set_attr "type" "multi")
8236    (set_attr "mode" "<MODE>")])
8238 (define_insn_and_split "*udivmodsi4_zext_1"
8239   [(set (match_operand:DI 0 "register_operand" "=a")
8240         (zero_extend:DI
8241           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8242                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8243    (set (match_operand:SI 1 "register_operand" "=&d")
8244         (umod:SI (match_dup 2) (match_dup 3)))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "TARGET_64BIT"
8247   "#"
8248   "reload_completed"
8249   [(set (match_dup 1) (const_int 0))
8250    (parallel [(set (match_dup 0)
8251                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8252               (set (match_dup 1)
8253                    (umod:SI (match_dup 2) (match_dup 3)))
8254               (use (match_dup 1))
8255               (clobber (reg:CC FLAGS_REG))])]
8256   ""
8257   [(set_attr "type" "multi")
8258    (set_attr "mode" "SI")])
8260 (define_insn_and_split "*udivmodsi4_zext_2"
8261   [(set (match_operand:DI 1 "register_operand" "=&d")
8262         (zero_extend:DI
8263           (umod:SI (match_operand:SI 2 "register_operand" "0")
8264                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8265    (set (match_operand:SI 0 "register_operand" "=a")
8266         (udiv:SI (match_dup 2) (match_dup 3)))
8267    (clobber (reg:CC FLAGS_REG))]
8268   "TARGET_64BIT"
8269   "#"
8270   "reload_completed"
8271   [(set (match_dup 4) (const_int 0))
8272    (parallel [(set (match_dup 1)
8273                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8274               (set (match_dup 0)
8275                    (udiv:SI (match_dup 2) (match_dup 3)))
8276               (use (match_dup 4))
8277               (clobber (reg:CC FLAGS_REG))])]
8278   "operands[4] = gen_lowpart (SImode, operands[1]);"
8279   [(set_attr "type" "multi")
8280    (set_attr "mode" "SI")])
8282 ;; Optimize division or modulo by constant power of 2, if the constant
8283 ;; materializes only after expansion.
8284 (define_insn_and_split "*udivmod<mode>4_pow2"
8285   [(set (match_operand:SWI48 0 "register_operand" "=r")
8286         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8287                     (match_operand:SWI48 3 "const_int_operand" "n")))
8288    (set (match_operand:SWI48 1 "register_operand" "=r")
8289         (umod:SWI48 (match_dup 2) (match_dup 3)))
8290    (clobber (reg:CC FLAGS_REG))]
8291   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8292    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8293   "#"
8294   "&& 1"
8295   [(set (match_dup 1) (match_dup 2))
8296    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8297               (clobber (reg:CC FLAGS_REG))])
8298    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8299               (clobber (reg:CC FLAGS_REG))])]
8301   int v = exact_log2 (UINTVAL (operands[3]));
8302   operands[4] = GEN_INT (v);
8303   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8305   [(set_attr "type" "multi")
8306    (set_attr "mode" "<MODE>")])
8308 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8309   [(set (match_operand:DI 0 "register_operand" "=r")
8310         (zero_extend:DI
8311           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8312                    (match_operand:SI 3 "const_int_operand" "n"))))
8313    (set (match_operand:SI 1 "register_operand" "=r")
8314         (umod:SI (match_dup 2) (match_dup 3)))
8315    (clobber (reg:CC FLAGS_REG))]
8316   "TARGET_64BIT
8317    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8318    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8319   "#"
8320   "&& 1"
8321   [(set (match_dup 1) (match_dup 2))
8322    (parallel [(set (match_dup 0)
8323                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8324               (clobber (reg:CC FLAGS_REG))])
8325    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8326               (clobber (reg:CC FLAGS_REG))])]
8328   int v = exact_log2 (UINTVAL (operands[3]));
8329   operands[4] = GEN_INT (v);
8330   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8332   [(set_attr "type" "multi")
8333    (set_attr "mode" "SI")])
8335 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8336   [(set (match_operand:DI 1 "register_operand" "=r")
8337         (zero_extend:DI
8338           (umod:SI (match_operand:SI 2 "register_operand" "0")
8339                    (match_operand:SI 3 "const_int_operand" "n"))))
8340    (set (match_operand:SI 0 "register_operand" "=r")
8341         (umod:SI (match_dup 2) (match_dup 3)))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "TARGET_64BIT
8344    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8345    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8346   "#"
8347   "&& 1"
8348   [(set (match_dup 1) (match_dup 2))
8349    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8350               (clobber (reg:CC FLAGS_REG))])
8351    (parallel [(set (match_dup 1)
8352                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8353               (clobber (reg:CC FLAGS_REG))])]
8355   int v = exact_log2 (UINTVAL (operands[3]));
8356   operands[4] = GEN_INT (v);
8357   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8359   [(set_attr "type" "multi")
8360    (set_attr "mode" "SI")])
8362 (define_insn "*udivmod<mode>4_noext"
8363   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8364         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8365                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8366    (set (match_operand:SWIM248 1 "register_operand" "=d")
8367         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8368    (use (match_operand:SWIM248 4 "register_operand" "1"))
8369    (clobber (reg:CC FLAGS_REG))]
8370   ""
8371   "div{<imodesuffix>}\t%3"
8372   [(set_attr "type" "idiv")
8373    (set_attr "mode" "<MODE>")])
8375 (define_insn "*udivmodsi4_noext_zext_1"
8376   [(set (match_operand:DI 0 "register_operand" "=a")
8377         (zero_extend:DI
8378           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8379                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8380    (set (match_operand:SI 1 "register_operand" "=d")
8381         (umod:SI (match_dup 2) (match_dup 3)))
8382    (use (match_operand:SI 4 "register_operand" "1"))
8383    (clobber (reg:CC FLAGS_REG))]
8384   "TARGET_64BIT"
8385   "div{l}\t%3"
8386   [(set_attr "type" "idiv")
8387    (set_attr "mode" "SI")])
8389 (define_insn "*udivmodsi4_noext_zext_2"
8390   [(set (match_operand:DI 1 "register_operand" "=d")
8391         (zero_extend:DI
8392           (umod:SI (match_operand:SI 2 "register_operand" "0")
8393                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8394    (set (match_operand:SI 0 "register_operand" "=a")
8395         (udiv:SI (match_dup 2) (match_dup 3)))
8396    (use (match_operand:SI 4 "register_operand" "1"))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "TARGET_64BIT"
8399   "div{l}\t%3"
8400   [(set_attr "type" "idiv")
8401    (set_attr "mode" "SI")])
8403 (define_expand "udivmodqi4"
8404   [(parallel [(set (match_operand:QI 0 "register_operand")
8405                    (udiv:QI
8406                      (match_operand:QI 1 "register_operand")
8407                      (match_operand:QI 2 "nonimmediate_operand")))
8408               (set (match_operand:QI 3 "register_operand")
8409                    (umod:QI (match_dup 1) (match_dup 2)))
8410               (clobber (reg:CC FLAGS_REG))])]
8411   "TARGET_QIMODE_MATH"
8413   rtx div, mod;
8414   rtx tmp0, tmp1;
8415   
8416   tmp0 = gen_reg_rtx (HImode);
8417   tmp1 = gen_reg_rtx (HImode);
8419   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8420   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8421   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8423   /* Extract remainder from AH.  */
8424   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8425   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8426   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8428   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8429   set_unique_reg_note (insn, REG_EQUAL, mod);
8431   /* Extract quotient from AL.  */
8432   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8434   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8435   set_unique_reg_note (insn, REG_EQUAL, div);
8437   DONE;
8440 (define_insn "udivmodhiqi3"
8441   [(set (match_operand:HI 0 "register_operand" "=a")
8442         (ior:HI
8443           (ashift:HI
8444             (zero_extend:HI
8445               (truncate:QI
8446                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8447                         (zero_extend:HI
8448                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8449             (const_int 8))
8450           (zero_extend:HI
8451             (truncate:QI
8452               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8453    (clobber (reg:CC FLAGS_REG))]
8454   "TARGET_QIMODE_MATH"
8455   "div{b}\t%2"
8456   [(set_attr "type" "idiv")
8457    (set_attr "mode" "QI")])
8459 ;; We cannot use div/idiv for double division, because it causes
8460 ;; "division by zero" on the overflow and that's not what we expect
8461 ;; from truncate.  Because true (non truncating) double division is
8462 ;; never generated, we can't create this insn anyway.
8464 ;(define_insn ""
8465 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8466 ;       (truncate:SI
8467 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8468 ;                  (zero_extend:DI
8469 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8470 ;   (set (match_operand:SI 3 "register_operand" "=d")
8471 ;       (truncate:SI
8472 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8473 ;   (clobber (reg:CC FLAGS_REG))]
8474 ;  ""
8475 ;  "div{l}\t{%2, %0|%0, %2}"
8476 ;  [(set_attr "type" "idiv")])
8478 ;;- Logical AND instructions
8480 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8481 ;; Note that this excludes ah.
8483 (define_expand "testsi_ccno_1"
8484   [(set (reg:CCNO FLAGS_REG)
8485         (compare:CCNO
8486           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8487                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8488           (const_int 0)))])
8490 (define_expand "testqi_ccz_1"
8491   [(set (reg:CCZ FLAGS_REG)
8492         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8493                              (match_operand:QI 1 "nonmemory_operand"))
8494                  (const_int 0)))])
8496 (define_expand "testdi_ccno_1"
8497   [(set (reg:CCNO FLAGS_REG)
8498         (compare:CCNO
8499           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8500                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8501           (const_int 0)))]
8502   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8504 (define_insn "*testdi_1"
8505   [(set (reg FLAGS_REG)
8506         (compare
8507          (and:DI
8508           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8509           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8510          (const_int 0)))]
8511   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8512    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8513   "@
8514    test{l}\t{%k1, %k0|%k0, %k1}
8515    test{l}\t{%k1, %k0|%k0, %k1}
8516    test{q}\t{%1, %0|%0, %1}
8517    test{q}\t{%1, %0|%0, %1}
8518    test{q}\t{%1, %0|%0, %1}"
8519   [(set_attr "type" "test")
8520    (set_attr "modrm" "0,1,0,1,1")
8521    (set_attr "mode" "SI,SI,DI,DI,DI")])
8523 (define_insn "*testqi_1_maybe_si"
8524   [(set (reg FLAGS_REG)
8525         (compare
8526           (and:QI
8527             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8528             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8529           (const_int 0)))]
8530    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8531     && ix86_match_ccmode (insn,
8532                          CONST_INT_P (operands[1])
8533                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8535   if (which_alternative == 3)
8536     {
8537       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8538         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8539       return "test{l}\t{%1, %k0|%k0, %1}";
8540     }
8541   return "test{b}\t{%1, %0|%0, %1}";
8543   [(set_attr "type" "test")
8544    (set_attr "modrm" "0,1,1,1")
8545    (set_attr "mode" "QI,QI,QI,SI")
8546    (set_attr "pent_pair" "uv,np,uv,np")])
8548 (define_insn "*test<mode>_1"
8549   [(set (reg FLAGS_REG)
8550         (compare
8551          (and:SWI124
8552           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8553           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8554          (const_int 0)))]
8555   "ix86_match_ccmode (insn, CCNOmode)
8556    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8558   [(set_attr "type" "test")
8559    (set_attr "modrm" "0,1,1")
8560    (set_attr "mode" "<MODE>")
8561    (set_attr "pent_pair" "uv,np,uv")])
8563 (define_expand "testqi_ext_1_ccno"
8564   [(set (reg:CCNO FLAGS_REG)
8565         (compare:CCNO
8566           (and:QI
8567             (subreg:QI
8568               (zero_extract:SI (match_operand 0 "ext_register_operand")
8569                                (const_int 8)
8570                                (const_int 8)) 0)
8571               (match_operand 1 "const_int_operand"))
8572           (const_int 0)))])
8574 (define_insn "*testqi_ext_1"
8575   [(set (reg FLAGS_REG)
8576         (compare
8577           (and:QI
8578             (subreg:QI
8579               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8580                                (const_int 8)
8581                                (const_int 8)) 0)
8582             (match_operand:QI 1 "general_operand" "QnBc,m"))
8583           (const_int 0)))]
8584   "ix86_match_ccmode (insn, CCNOmode)"
8585   "test{b}\t{%1, %h0|%h0, %1}"
8586   [(set_attr "isa" "*,nox64")
8587    (set_attr "type" "test")
8588    (set_attr "mode" "QI")])
8590 (define_insn "*testqi_ext_2"
8591   [(set (reg FLAGS_REG)
8592         (compare
8593           (and:QI
8594             (subreg:QI
8595               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8596                                (const_int 8)
8597                                (const_int 8)) 0)
8598             (subreg:QI
8599               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8600                                (const_int 8)
8601                                (const_int 8)) 0))
8602           (const_int 0)))]
8603   "ix86_match_ccmode (insn, CCNOmode)"
8604   "test{b}\t{%h1, %h0|%h0, %h1}"
8605   [(set_attr "type" "test")
8606    (set_attr "mode" "QI")])
8608 ;; Combine likes to form bit extractions for some tests.  Humor it.
8609 (define_insn_and_split "*testqi_ext_3"
8610   [(set (match_operand 0 "flags_reg_operand")
8611         (match_operator 1 "compare_operator"
8612           [(zero_extract:SWI248
8613              (match_operand 2 "nonimmediate_operand" "rm")
8614              (match_operand 3 "const_int_operand" "n")
8615              (match_operand 4 "const_int_operand" "n"))
8616            (const_int 0)]))]
8617   "ix86_match_ccmode (insn, CCNOmode)
8618    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8619        || GET_MODE (operands[2]) == SImode
8620        || GET_MODE (operands[2]) == HImode
8621        || GET_MODE (operands[2]) == QImode)
8622    /* Ensure that resulting mask is zero or sign extended operand.  */
8623    && INTVAL (operands[4]) >= 0
8624    && ((INTVAL (operands[3]) > 0
8625         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8626        || (<MODE>mode == DImode
8627            && INTVAL (operands[3]) > 32
8628            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8629   "#"
8630   "&& 1"
8631   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8633   rtx val = operands[2];
8634   HOST_WIDE_INT len = INTVAL (operands[3]);
8635   HOST_WIDE_INT pos = INTVAL (operands[4]);
8636   machine_mode mode = GET_MODE (val);
8638   if (SUBREG_P (val))
8639     {
8640       machine_mode submode = GET_MODE (SUBREG_REG (val));
8642       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8643       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8644           && GET_MODE_CLASS (submode) == MODE_INT)
8645         {
8646           val = SUBREG_REG (val);
8647           mode = submode;
8648         }
8649     }
8651   /* Small HImode tests can be converted to QImode.  */
8652   if (register_operand (val, HImode) && pos + len <= 8)
8653     {
8654       val = gen_lowpart (QImode, val);
8655       mode = QImode;
8656     }
8658   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8660   wide_int mask
8661     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8663   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8666 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8667 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8668 ;; this is relatively important trick.
8669 ;; Do the conversion only post-reload to avoid limiting of the register class
8670 ;; to QI regs.
8671 (define_split
8672   [(set (match_operand 0 "flags_reg_operand")
8673         (match_operator 1 "compare_operator"
8674           [(and (match_operand 2 "QIreg_operand")
8675                 (match_operand 3 "const_int_operand"))
8676            (const_int 0)]))]
8677    "reload_completed
8678     && GET_MODE (operands[2]) != QImode
8679     && ((ix86_match_ccmode (insn, CCZmode)
8680          && !(INTVAL (operands[3]) & ~(255 << 8)))
8681         || (ix86_match_ccmode (insn, CCNOmode)
8682             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8683   [(set (match_dup 0)
8684         (match_op_dup 1
8685           [(and:QI
8686              (subreg:QI
8687                (zero_extract:SI (match_dup 2)
8688                                 (const_int 8)
8689                                 (const_int 8)) 0)
8690              (match_dup 3))
8691            (const_int 0)]))]
8693   operands[2] = gen_lowpart (SImode, operands[2]);
8694   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8697 (define_split
8698   [(set (match_operand 0 "flags_reg_operand")
8699         (match_operator 1 "compare_operator"
8700           [(and (match_operand 2 "nonimmediate_operand")
8701                 (match_operand 3 "const_int_operand"))
8702            (const_int 0)]))]
8703    "reload_completed
8704     && GET_MODE (operands[2]) != QImode
8705     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8706     && ((ix86_match_ccmode (insn, CCZmode)
8707          && !(INTVAL (operands[3]) & ~255))
8708         || (ix86_match_ccmode (insn, CCNOmode)
8709             && !(INTVAL (operands[3]) & ~127)))"
8710   [(set (match_dup 0)
8711         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8712                          (const_int 0)]))]
8714   operands[2] = gen_lowpart (QImode, operands[2]);
8715   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8718 ;; %%% This used to optimize known byte-wide and operations to memory,
8719 ;; and sometimes to QImode registers.  If this is considered useful,
8720 ;; it should be done with splitters.
8722 (define_expand "and<mode>3"
8723   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8724         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8725                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8726   ""
8728   machine_mode mode = <MODE>mode;
8729   rtx (*insn) (rtx, rtx);
8731   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8732     {
8733       HOST_WIDE_INT ival = INTVAL (operands[2]);
8735       if (ival == (HOST_WIDE_INT) 0xffffffff)
8736         mode = SImode;
8737       else if (ival == 0xffff)
8738         mode = HImode;
8739       else if (ival == 0xff)
8740         mode = QImode;
8741       }
8743   if (mode == <MODE>mode)
8744     {
8745       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8746       DONE;
8747     }
8749   if (<MODE>mode == DImode)
8750     insn = (mode == SImode)
8751            ? gen_zero_extendsidi2
8752            : (mode == HImode)
8753            ? gen_zero_extendhidi2
8754            : gen_zero_extendqidi2;
8755   else if (<MODE>mode == SImode)
8756     insn = (mode == HImode)
8757            ? gen_zero_extendhisi2
8758            : gen_zero_extendqisi2;
8759   else if (<MODE>mode == HImode)
8760     insn = gen_zero_extendqihi2;
8761   else
8762     gcc_unreachable ();
8764   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8765   DONE;
8768 (define_insn_and_split "*anddi3_doubleword"
8769   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8770         (and:DI
8771          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8772          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8775    && ix86_binary_operator_ok (AND, DImode, operands)"
8776   "#"
8777   "&& reload_completed"
8778   [(const_int 0)]
8780   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8781   if (operands[2] == const0_rtx)
8782     {
8783       operands[1] = const0_rtx;
8784       ix86_expand_move (SImode, &operands[0]);
8785     }
8786   else if (operands[2] != constm1_rtx)
8787     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8788   else if (operands[5] == constm1_rtx)
8789     emit_note (NOTE_INSN_DELETED);
8790   if (operands[5] == const0_rtx)
8791     {
8792       operands[4] = const0_rtx;
8793       ix86_expand_move (SImode, &operands[3]);
8794     }
8795   else if (operands[5] != constm1_rtx)
8796     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8797   DONE;
8800 (define_insn "*anddi_1"
8801   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8802         (and:DI
8803          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8804          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8805    (clobber (reg:CC FLAGS_REG))]
8806   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8807   "@
8808    and{l}\t{%k2, %k0|%k0, %k2}
8809    and{q}\t{%2, %0|%0, %2}
8810    and{q}\t{%2, %0|%0, %2}
8811    #"
8812   [(set_attr "type" "alu,alu,alu,imovx")
8813    (set_attr "length_immediate" "*,*,*,0")
8814    (set (attr "prefix_rex")
8815      (if_then_else
8816        (and (eq_attr "type" "imovx")
8817             (and (match_test "INTVAL (operands[2]) == 0xff")
8818                  (match_operand 1 "ext_QIreg_operand")))
8819        (const_string "1")
8820        (const_string "*")))
8821    (set_attr "mode" "SI,DI,DI,SI")])
8823 (define_insn_and_split "*anddi_1_btr"
8824   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8825         (and:DI
8826          (match_operand:DI 1 "nonimmediate_operand" "%0")
8827          (match_operand:DI 2 "const_int_operand" "n")))
8828    (clobber (reg:CC FLAGS_REG))]
8829   "TARGET_64BIT && TARGET_USE_BT
8830    && ix86_binary_operator_ok (AND, DImode, operands)
8831    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8832   "#"
8833   "&& reload_completed"
8834   [(parallel [(set (zero_extract:DI (match_dup 0)
8835                                     (const_int 1)
8836                                     (match_dup 3))
8837                    (const_int 0))
8838               (clobber (reg:CC FLAGS_REG))])]
8839   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8840   [(set_attr "type" "alu1")
8841    (set_attr "prefix_0f" "1")
8842    (set_attr "znver1_decode" "double")
8843    (set_attr "mode" "DI")])
8845 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8846 (define_split
8847   [(set (match_operand:DI 0 "register_operand")
8848         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8849                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "TARGET_64BIT"
8852   [(parallel [(set (match_dup 0)
8853                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8854               (clobber (reg:CC FLAGS_REG))])]
8855   "operands[2] = gen_lowpart (SImode, operands[2]);")
8857 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8858 (define_insn "*andsi_1_zext"
8859   [(set (match_operand:DI 0 "register_operand" "=r")
8860         (zero_extend:DI
8861           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8862                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8863    (clobber (reg:CC FLAGS_REG))]
8864   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8865   "and{l}\t{%2, %k0|%k0, %2}"
8866   [(set_attr "type" "alu")
8867    (set_attr "mode" "SI")])
8869 (define_insn "*and<mode>_1"
8870   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8871         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8872                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8873    (clobber (reg:CC FLAGS_REG))]
8874   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8875   "@
8876    and{<imodesuffix>}\t{%2, %0|%0, %2}
8877    and{<imodesuffix>}\t{%2, %0|%0, %2}
8878    #"
8879   [(set_attr "type" "alu,alu,imovx")
8880    (set_attr "length_immediate" "*,*,0")
8881    (set (attr "prefix_rex")
8882      (if_then_else
8883        (and (eq_attr "type" "imovx")
8884             (and (match_test "INTVAL (operands[2]) == 0xff")
8885                  (match_operand 1 "ext_QIreg_operand")))
8886        (const_string "1")
8887        (const_string "*")))
8888    (set_attr "mode" "<MODE>,<MODE>,SI")])
8890 (define_insn "*andqi_1"
8891   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8892         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8893                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "ix86_binary_operator_ok (AND, QImode, operands)"
8896   "@
8897    and{b}\t{%2, %0|%0, %2}
8898    and{b}\t{%2, %0|%0, %2}
8899    and{l}\t{%k2, %k0|%k0, %k2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "QI,QI,SI")
8902    ;; Potential partial reg stall on alternative 2.
8903    (set (attr "preferred_for_speed")
8904      (cond [(eq_attr "alternative" "2")
8905               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8906            (symbol_ref "true")))])
8908 (define_insn "*andqi_1_slp"
8909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8910         (and:QI (match_dup 0)
8911                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8912    (clobber (reg:CC FLAGS_REG))]
8913   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8914    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8915   "and{b}\t{%1, %0|%0, %1}"
8916   [(set_attr "type" "alu1")
8917    (set_attr "mode" "QI")])
8919 (define_split
8920   [(set (match_operand:SWI248 0 "register_operand")
8921         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8922                     (match_operand:SWI248 2 "const_int_operand")))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "reload_completed
8925    && (!REG_P (operands[1])
8926        || REGNO (operands[0]) != REGNO (operands[1]))"
8927   [(const_int 0)]
8929   HOST_WIDE_INT ival = INTVAL (operands[2]);
8930   machine_mode mode;
8931   rtx (*insn) (rtx, rtx);
8933   if (ival == (HOST_WIDE_INT) 0xffffffff)
8934     mode = SImode;
8935   else if (ival == 0xffff)
8936     mode = HImode;
8937   else
8938     {
8939       gcc_assert (ival == 0xff);
8940       mode = QImode;
8941     }
8943   if (<MODE>mode == DImode)
8944     insn = (mode == SImode)
8945            ? gen_zero_extendsidi2
8946            : (mode == HImode)
8947            ? gen_zero_extendhidi2
8948            : gen_zero_extendqidi2;
8949   else
8950     {
8951       if (<MODE>mode != SImode)
8952         /* Zero extend to SImode to avoid partial register stalls.  */
8953         operands[0] = gen_lowpart (SImode, operands[0]);
8955       insn = (mode == HImode)
8956              ? gen_zero_extendhisi2
8957              : gen_zero_extendqisi2;
8958     }
8959   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8960   DONE;
8963 (define_split
8964   [(set (match_operand:SWI48 0 "register_operand")
8965         (and:SWI48 (match_dup 0)
8966                    (const_int -65536)))
8967    (clobber (reg:CC FLAGS_REG))]
8968   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8969     || optimize_function_for_size_p (cfun)"
8970   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8971   "operands[1] = gen_lowpart (HImode, operands[0]);")
8973 (define_split
8974   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8975         (and:SWI248 (match_dup 0)
8976                     (const_int -256)))
8977    (clobber (reg:CC FLAGS_REG))]
8978   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8979    && reload_completed"
8980   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8981   "operands[1] = gen_lowpart (QImode, operands[0]);")
8983 (define_split
8984   [(set (match_operand:SWI248 0 "QIreg_operand")
8985         (and:SWI248 (match_dup 0)
8986                     (const_int -65281)))
8987    (clobber (reg:CC FLAGS_REG))]
8988   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8989    && reload_completed"
8990   [(parallel
8991      [(set (zero_extract:SI (match_dup 0)
8992                             (const_int 8)
8993                             (const_int 8))
8994            (subreg:SI
8995              (xor:QI
8996                (subreg:QI
8997                  (zero_extract:SI (match_dup 0)
8998                                   (const_int 8)
8999                                   (const_int 8)) 0)
9000                (subreg:QI
9001                  (zero_extract:SI (match_dup 0)
9002                                   (const_int 8)
9003                                   (const_int 8)) 0)) 0))
9004       (clobber (reg:CC FLAGS_REG))])]
9005   "operands[0] = gen_lowpart (SImode, operands[0]);")
9007 (define_insn "*anddi_2"
9008   [(set (reg FLAGS_REG)
9009         (compare
9010          (and:DI
9011           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9012           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9013          (const_int 0)))
9014    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9015         (and:DI (match_dup 1) (match_dup 2)))]
9016   "TARGET_64BIT
9017    && ix86_match_ccmode
9018         (insn,
9019          /* If we are going to emit andl instead of andq, and the operands[2]
9020             constant might have the SImode sign bit set, make sure the sign
9021             flag isn't tested, because the instruction will set the sign flag
9022             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9023             conservatively assume it might have bit 31 set.  */
9024          (satisfies_constraint_Z (operands[2])
9025           && (!CONST_INT_P (operands[2])
9026               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9027          ? CCZmode : CCNOmode)
9028    && ix86_binary_operator_ok (AND, DImode, operands)"
9029   "@
9030    and{l}\t{%k2, %k0|%k0, %k2}
9031    and{q}\t{%2, %0|%0, %2}
9032    and{q}\t{%2, %0|%0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI,DI,DI")])
9036 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9037 (define_insn "*andsi_2_zext"
9038   [(set (reg FLAGS_REG)
9039         (compare (and:SI
9040                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9041                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
9042                  (const_int 0)))
9043    (set (match_operand:DI 0 "register_operand" "=r")
9044         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9045   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046    && ix86_binary_operator_ok (AND, SImode, operands)"
9047   "and{l}\t{%2, %k0|%k0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "SI")])
9051 (define_insn "*andqi_2_maybe_si"
9052   [(set (reg FLAGS_REG)
9053         (compare (and:QI
9054                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9055                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9056                  (const_int 0)))
9057    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9058         (and:QI (match_dup 1) (match_dup 2)))]
9059   "ix86_binary_operator_ok (AND, QImode, operands)
9060    && ix86_match_ccmode (insn,
9061                          CONST_INT_P (operands[2])
9062                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9064   if (which_alternative == 2)
9065     {
9066       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9067         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9068       return "and{l}\t{%2, %k0|%k0, %2}";
9069     }
9070   return "and{b}\t{%2, %0|%0, %2}";
9072   [(set_attr "type" "alu")
9073    (set_attr "mode" "QI,QI,SI")])
9075 (define_insn "*and<mode>_2"
9076   [(set (reg FLAGS_REG)
9077         (compare (and:SWI124
9078                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9079                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9080                  (const_int 0)))
9081    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9082         (and:SWI124 (match_dup 1) (match_dup 2)))]
9083   "ix86_match_ccmode (insn, CCNOmode)
9084    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9085   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "<MODE>")])
9089 (define_insn "*andqi_2_slp"
9090   [(set (reg FLAGS_REG)
9091         (compare (and:QI
9092                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9093                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9094                  (const_int 0)))
9095    (set (strict_low_part (match_dup 0))
9096         (and:QI (match_dup 0) (match_dup 1)))]
9097   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9098    && ix86_match_ccmode (insn, CCNOmode)
9099    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9100   "and{b}\t{%1, %0|%0, %1}"
9101   [(set_attr "type" "alu1")
9102    (set_attr "mode" "QI")])
9104 (define_insn "andqi_ext_1"
9105   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9106                          (const_int 8)
9107                          (const_int 8))
9108         (subreg:SI
9109           (and:QI
9110             (subreg:QI
9111               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9112                                (const_int 8)
9113                                (const_int 8)) 0)
9114             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9117    rtx_equal_p (operands[0], operands[1])"
9118   "and{b}\t{%2, %h0|%h0, %2}"
9119   [(set_attr "isa" "*,nox64")
9120    (set_attr "type" "alu")
9121    (set_attr "mode" "QI")])
9123 ;; Generated by peephole translating test to and.  This shows up
9124 ;; often in fp comparisons.
9125 (define_insn "*andqi_ext_1_cc"
9126   [(set (reg FLAGS_REG)
9127         (compare
9128           (and:QI
9129             (subreg:QI
9130               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9131                                (const_int 8)
9132                                (const_int 8)) 0)
9133             (match_operand:QI 2 "general_operand" "QnBc,m"))
9134           (const_int 0)))
9135    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9136                          (const_int 8)
9137                          (const_int 8))
9138         (subreg:SI
9139           (and:QI
9140             (subreg:QI
9141               (zero_extract:SI (match_dup 1)
9142                                (const_int 8)
9143                                (const_int 8)) 0)
9144             (match_dup 2)) 0))]
9145   "ix86_match_ccmode (insn, CCNOmode)
9146    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9147    && rtx_equal_p (operands[0], operands[1])"
9148   "and{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "isa" "*,nox64")
9150    (set_attr "type" "alu")
9151    (set_attr "mode" "QI")])
9153 (define_insn "*andqi_ext_2"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (subreg:SI
9158           (and:QI
9159             (subreg:QI
9160               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9161                                (const_int 8)
9162                                (const_int 8)) 0)
9163             (subreg:QI
9164               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9165                                (const_int 8)
9166                                (const_int 8)) 0)) 0))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9169    rtx_equal_p (operands[0], operands[1])
9170    || rtx_equal_p (operands[0], operands[2])"
9171   "and{b}\t{%h2, %h0|%h0, %h2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "QI")])
9175 ;; Convert wide AND instructions with immediate operand to shorter QImode
9176 ;; equivalents when possible.
9177 ;; Don't do the splitting with memory operands, since it introduces risk
9178 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9179 ;; for size, but that can (should?) be handled by generic code instead.
9180 (define_split
9181   [(set (match_operand:SWI248 0 "QIreg_operand")
9182         (and:SWI248 (match_operand:SWI248 1 "register_operand")
9183                     (match_operand:SWI248 2 "const_int_operand")))
9184    (clobber (reg:CC FLAGS_REG))]
9185    "reload_completed
9186     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9187     && !(~INTVAL (operands[2]) & ~(255 << 8))"
9188   [(parallel
9189      [(set (zero_extract:SI (match_dup 0)
9190                             (const_int 8)
9191                             (const_int 8))
9192            (subreg:SI
9193              (and:QI
9194                (subreg:QI
9195                  (zero_extract:SI (match_dup 1)
9196                                   (const_int 8)
9197                                   (const_int 8)) 0)
9198                (match_dup 2)) 0))
9199       (clobber (reg:CC FLAGS_REG))])]
9201   operands[0] = gen_lowpart (SImode, operands[0]);
9202   operands[1] = gen_lowpart (SImode, operands[1]);
9203   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9206 ;; Since AND can be encoded with sign extended immediate, this is only
9207 ;; profitable when 7th bit is not set.
9208 (define_split
9209   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9210         (and:SWI248 (match_operand:SWI248 1 "general_operand")
9211                     (match_operand:SWI248 2 "const_int_operand")))
9212    (clobber (reg:CC FLAGS_REG))]
9213    "reload_completed
9214     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9215     && !(~INTVAL (operands[2]) & ~255)
9216     && !(INTVAL (operands[2]) & 128)"
9217   [(parallel [(set (strict_low_part (match_dup 0))
9218                    (and:QI (match_dup 1)
9219                            (match_dup 2)))
9220               (clobber (reg:CC FLAGS_REG))])]
9222   operands[0] = gen_lowpart (QImode, operands[0]);
9223   operands[1] = gen_lowpart (QImode, operands[1]);
9224   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9227 (define_insn "*andndi3_doubleword"
9228   [(set (match_operand:DI 0 "register_operand" "=r,&r")
9229         (and:DI
9230           (not:DI (match_operand:DI 1 "register_operand" "r,0"))
9231           (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
9232    (clobber (reg:CC FLAGS_REG))]
9233   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9234   "#"
9235   [(set_attr "isa" "bmi,*")])
9237 (define_split
9238   [(set (match_operand:DI 0 "register_operand")
9239         (and:DI
9240           (not:DI (match_operand:DI 1 "register_operand"))
9241           (match_operand:DI 2 "nonimmediate_operand")))
9242    (clobber (reg:CC FLAGS_REG))]
9243   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9244    && reload_completed"
9245   [(parallel [(set (match_dup 0)
9246                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9247               (clobber (reg:CC FLAGS_REG))])
9248    (parallel [(set (match_dup 3)
9249                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9250               (clobber (reg:CC FLAGS_REG))])]
9251   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9253 (define_split
9254   [(set (match_operand:DI 0 "register_operand")
9255         (and:DI
9256           (not:DI (match_dup 0))
9257           (match_operand:DI 1 "nonimmediate_operand")))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9260    && reload_completed"
9261   [(set (match_dup 0) (not:SI (match_dup 0)))
9262    (parallel [(set (match_dup 0)
9263                    (and:SI (match_dup 0) (match_dup 1)))
9264               (clobber (reg:CC FLAGS_REG))])
9265    (set (match_dup 2) (not:SI (match_dup 2)))
9266    (parallel [(set (match_dup 2)
9267                    (and:SI (match_dup 2) (match_dup 3)))
9268               (clobber (reg:CC FLAGS_REG))])]
9269   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9271 (define_insn "*andn<mode>_1"
9272   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9273         (and:SWI48
9274           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9275           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "TARGET_BMI"
9278   "andn\t{%2, %1, %0|%0, %1, %2}"
9279   [(set_attr "type" "bitmanip")
9280    (set_attr "btver2_decode" "direct, double")
9281    (set_attr "mode" "<MODE>")])
9283 (define_insn "*andn<mode>_1"
9284   [(set (match_operand:SWI12 0 "register_operand" "=r")
9285         (and:SWI12
9286           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9287           (match_operand:SWI12 2 "register_operand" "r")))
9288    (clobber (reg:CC FLAGS_REG))]
9289   "TARGET_BMI"
9290   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9291   [(set_attr "type" "bitmanip")
9292    (set_attr "btver2_decode" "direct")
9293    (set_attr "mode" "SI")])
9295 (define_insn "*andn_<mode>_ccno"
9296   [(set (reg FLAGS_REG)
9297         (compare
9298           (and:SWI48
9299             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9300             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9301           (const_int 0)))
9302    (clobber (match_scratch:SWI48 0 "=r,r"))]
9303   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9304   "andn\t{%2, %1, %0|%0, %1, %2}"
9305   [(set_attr "type" "bitmanip")
9306    (set_attr "btver2_decode" "direct, double")
9307    (set_attr "mode" "<MODE>")])
9309 ;; Logical inclusive and exclusive OR instructions
9311 ;; %%% This used to optimize known byte-wide and operations to memory.
9312 ;; If this is considered useful, it should be done with splitters.
9314 (define_expand "<code><mode>3"
9315   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9316         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9317                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9318   ""
9319   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9321 (define_insn_and_split "*<code>di3_doubleword"
9322   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9323         (any_or:DI
9324          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9325          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9328    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9329   "#"
9330   "&& reload_completed"
9331   [(const_int 0)]
9333   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9334   if (operands[2] == constm1_rtx)
9335     {
9336       if (<CODE> == IOR)
9337         {
9338           operands[1] = constm1_rtx;
9339           ix86_expand_move (SImode, &operands[0]);
9340         }
9341       else
9342         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9343     }
9344   else if (operands[2] != const0_rtx)
9345     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9346   else if (operands[5] == const0_rtx)
9347     emit_note (NOTE_INSN_DELETED);
9348   if (operands[5] == constm1_rtx)
9349     {
9350       if (<CODE> == IOR)
9351         {
9352           operands[4] = constm1_rtx;
9353           ix86_expand_move (SImode, &operands[3]);
9354         }
9355       else
9356         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9357     }
9358   else if (operands[5] != const0_rtx)
9359     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9360   DONE;
9363 (define_insn "*<code><mode>_1"
9364   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9365         (any_or:SWI248
9366          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9367          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9370   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9371   [(set_attr "type" "alu")
9372    (set_attr "mode" "<MODE>")])
9374 (define_insn_and_split "*iordi_1_bts"
9375   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9376         (ior:DI
9377          (match_operand:DI 1 "nonimmediate_operand" "%0")
9378          (match_operand:DI 2 "const_int_operand" "n")))
9379    (clobber (reg:CC FLAGS_REG))]
9380   "TARGET_64BIT && TARGET_USE_BT
9381    && ix86_binary_operator_ok (IOR, DImode, operands)
9382    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9383   "#"
9384   "&& reload_completed"
9385   [(parallel [(set (zero_extract:DI (match_dup 0)
9386                                     (const_int 1)
9387                                     (match_dup 3))
9388                    (const_int 1))
9389               (clobber (reg:CC FLAGS_REG))])]
9390   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9391   [(set_attr "type" "alu1")
9392    (set_attr "prefix_0f" "1")
9393    (set_attr "znver1_decode" "double")
9394    (set_attr "mode" "DI")])
9396 (define_insn_and_split "*xordi_1_btc"
9397   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9398         (xor:DI
9399          (match_operand:DI 1 "nonimmediate_operand" "%0")
9400          (match_operand:DI 2 "const_int_operand" "n")))
9401    (clobber (reg:CC FLAGS_REG))]
9402   "TARGET_64BIT && TARGET_USE_BT
9403    && ix86_binary_operator_ok (XOR, DImode, operands)
9404    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9405   "#"
9406   "&& reload_completed"
9407   [(parallel [(set (zero_extract:DI (match_dup 0)
9408                                     (const_int 1)
9409                                     (match_dup 3))
9410                    (not:DI (zero_extract:DI (match_dup 0)
9411                                             (const_int 1)
9412                                             (match_dup 3))))
9413               (clobber (reg:CC FLAGS_REG))])]
9414   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9415   [(set_attr "type" "alu1")
9416    (set_attr "prefix_0f" "1")
9417    (set_attr "znver1_decode" "double")
9418    (set_attr "mode" "DI")])
9420 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9421 (define_insn "*<code>si_1_zext"
9422   [(set (match_operand:DI 0 "register_operand" "=r")
9423         (zero_extend:DI
9424          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9425                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9428   "<logic>{l}\t{%2, %k0|%k0, %2}"
9429   [(set_attr "type" "alu")
9430    (set_attr "mode" "SI")])
9432 (define_insn "*<code>si_1_zext_imm"
9433   [(set (match_operand:DI 0 "register_operand" "=r")
9434         (any_or:DI
9435          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9439   "<logic>{l}\t{%2, %k0|%k0, %2}"
9440   [(set_attr "type" "alu")
9441    (set_attr "mode" "SI")])
9443 (define_insn "*<code>qi_1"
9444   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9445         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9446                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9449   "@
9450    <logic>{b}\t{%2, %0|%0, %2}
9451    <logic>{b}\t{%2, %0|%0, %2}
9452    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "mode" "QI,QI,SI")
9455    ;; Potential partial reg stall on alternative 2.
9456    (set (attr "preferred_for_speed")
9457      (cond [(eq_attr "alternative" "2")
9458               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9459            (symbol_ref "true")))])
9461 (define_insn "*<code>qi_1_slp"
9462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9463         (any_or:QI (match_dup 0)
9464                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9465    (clobber (reg:CC FLAGS_REG))]
9466   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9467    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9468   "<logic>{b}\t{%1, %0|%0, %1}"
9469   [(set_attr "type" "alu1")
9470    (set_attr "mode" "QI")])
9472 (define_insn "*<code><mode>_2"
9473   [(set (reg FLAGS_REG)
9474         (compare (any_or:SWI
9475                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9476                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9477                  (const_int 0)))
9478    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9479         (any_or:SWI (match_dup 1) (match_dup 2)))]
9480   "ix86_match_ccmode (insn, CCNOmode)
9481    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9482   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9483   [(set_attr "type" "alu")
9484    (set_attr "mode" "<MODE>")])
9486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9487 ;; ??? Special case for immediate operand is missing - it is tricky.
9488 (define_insn "*<code>si_2_zext"
9489   [(set (reg FLAGS_REG)
9490         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9491                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9492                  (const_int 0)))
9493    (set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9495   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9496    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9497   "<logic>{l}\t{%2, %k0|%k0, %2}"
9498   [(set_attr "type" "alu")
9499    (set_attr "mode" "SI")])
9501 (define_insn "*<code>si_2_zext_imm"
9502   [(set (reg FLAGS_REG)
9503         (compare (any_or:SI
9504                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9505                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9506                  (const_int 0)))
9507    (set (match_operand:DI 0 "register_operand" "=r")
9508         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9509   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9510    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9511   "<logic>{l}\t{%2, %k0|%k0, %2}"
9512   [(set_attr "type" "alu")
9513    (set_attr "mode" "SI")])
9515 (define_insn "*<code>qi_2_slp"
9516   [(set (reg FLAGS_REG)
9517         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9518                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9519                  (const_int 0)))
9520    (set (strict_low_part (match_dup 0))
9521         (any_or:QI (match_dup 0) (match_dup 1)))]
9522   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9523    && ix86_match_ccmode (insn, CCNOmode)
9524    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9525   "<logic>{b}\t{%1, %0|%0, %1}"
9526   [(set_attr "type" "alu1")
9527    (set_attr "mode" "QI")])
9529 (define_insn "*<code><mode>_3"
9530   [(set (reg FLAGS_REG)
9531         (compare (any_or:SWI
9532                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9533                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9534                  (const_int 0)))
9535    (clobber (match_scratch:SWI 0 "=<r>"))]
9536   "ix86_match_ccmode (insn, CCNOmode)
9537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9538   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9539   [(set_attr "type" "alu")
9540    (set_attr "mode" "<MODE>")])
9542 (define_insn "*<code>qi_ext_1"
9543   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9544                          (const_int 8)
9545                          (const_int 8))
9546         (subreg:SI
9547           (any_or:QI
9548             (subreg:QI
9549               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9550                                (const_int 8)
9551                                (const_int 8)) 0)
9552             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9553    (clobber (reg:CC FLAGS_REG))]
9554   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9555    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9556    && rtx_equal_p (operands[0], operands[1])"
9557   "<logic>{b}\t{%2, %h0|%h0, %2}"
9558   [(set_attr "isa" "*,nox64")
9559    (set_attr "type" "alu")
9560    (set_attr "mode" "QI")])
9562 (define_insn "*<code>qi_ext_2"
9563   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9564                          (const_int 8)
9565                          (const_int 8))
9566         (subreg:SI
9567           (any_or:QI
9568             (subreg:QI
9569               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9570                                (const_int 8)
9571                                (const_int 8)) 0)
9572             (subreg:QI
9573               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9574                                (const_int 8)
9575                                (const_int 8)) 0)) 0))
9576    (clobber (reg:CC FLAGS_REG))]
9577   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9578    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9579    && (rtx_equal_p (operands[0], operands[1])
9580        || rtx_equal_p (operands[0], operands[2]))"
9581   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9582   [(set_attr "type" "alu")
9583    (set_attr "mode" "QI")])
9585 ;; Convert wide OR instructions with immediate operand to shorter QImode
9586 ;; equivalents when possible.
9587 ;; Don't do the splitting with memory operands, since it introduces risk
9588 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9589 ;; for size, but that can (should?) be handled by generic code instead.
9590 (define_split
9591   [(set (match_operand:SWI248 0 "QIreg_operand")
9592         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9593                        (match_operand:SWI248 2 "const_int_operand")))
9594    (clobber (reg:CC FLAGS_REG))]
9595    "reload_completed
9596     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9597     && !(INTVAL (operands[2]) & ~(255 << 8))"
9598   [(parallel
9599      [(set (zero_extract:SI (match_dup 0)
9600                             (const_int 8)
9601                             (const_int 8))
9602            (subreg:SI
9603              (any_or:QI
9604                (subreg:QI
9605                  (zero_extract:SI (match_dup 1)
9606                                   (const_int 8)
9607                                   (const_int 8)) 0)
9608                (match_dup 2)) 0))
9609       (clobber (reg:CC FLAGS_REG))])]
9611   operands[0] = gen_lowpart (SImode, operands[0]);
9612   operands[1] = gen_lowpart (SImode, operands[1]);
9613   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9616 ;; Since OR can be encoded with sign extended immediate, this is only
9617 ;; profitable when 7th bit is set.
9618 (define_split
9619   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9620         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9621                        (match_operand:SWI248 2 "const_int_operand")))
9622    (clobber (reg:CC FLAGS_REG))]
9623    "reload_completed
9624     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9625     && !(INTVAL (operands[2]) & ~255)
9626     && (INTVAL (operands[2]) & 128)"
9627   [(parallel [(set (strict_low_part (match_dup 0))
9628                    (any_or:QI (match_dup 1)
9629                               (match_dup 2)))
9630               (clobber (reg:CC FLAGS_REG))])]
9632   operands[0] = gen_lowpart (QImode, operands[0]);
9633   operands[1] = gen_lowpart (QImode, operands[1]);
9634   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9637 (define_expand "xorqi_ext_1_cc"
9638   [(parallel [
9639      (set (reg:CCNO FLAGS_REG)
9640           (compare:CCNO
9641             (xor:QI
9642               (subreg:QI
9643                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9644                                  (const_int 8)
9645                                  (const_int 8)) 0)
9646               (match_operand 2 "const_int_operand"))
9647             (const_int 0)))
9648      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9649                            (const_int 8)
9650                            (const_int 8))
9651           (subreg:SI
9652             (xor:QI
9653               (subreg:QI
9654                 (zero_extract:SI (match_dup 1)
9655                                  (const_int 8)
9656                                  (const_int 8)) 0)
9657             (match_dup 2)) 0))])])
9659 (define_insn "*xorqi_ext_1_cc"
9660   [(set (reg FLAGS_REG)
9661         (compare
9662           (xor:QI
9663             (subreg:QI
9664               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9665                                (const_int 8)
9666                                (const_int 8)) 0)
9667             (match_operand:QI 2 "general_operand" "QnBc,m"))
9668           (const_int 0)))
9669    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9670                          (const_int 8)
9671                          (const_int 8))
9672         (subreg:SI
9673           (xor:QI
9674             (subreg:QI
9675               (zero_extract:SI (match_dup 1)
9676                                (const_int 8)
9677                                (const_int 8)) 0)
9678           (match_dup 2)) 0))]
9679   "ix86_match_ccmode (insn, CCNOmode)
9680    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9681    && rtx_equal_p (operands[0], operands[1])"
9682   "xor{b}\t{%2, %h0|%h0, %2}"
9683   [(set_attr "isa" "*,nox64")
9684    (set_attr "type" "alu")
9685    (set_attr "mode" "QI")])
9687 ;; Negation instructions
9689 (define_expand "neg<mode>2"
9690   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9691         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9692   ""
9693   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9695 (define_insn_and_split "*neg<dwi>2_doubleword"
9696   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9697         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9698    (clobber (reg:CC FLAGS_REG))]
9699   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9700   "#"
9701   "reload_completed"
9702   [(parallel
9703     [(set (reg:CCZ FLAGS_REG)
9704           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9705      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9706    (parallel
9707     [(set (match_dup 2)
9708           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9709                                 (match_dup 3))
9710                      (const_int 0)))
9711      (clobber (reg:CC FLAGS_REG))])
9712    (parallel
9713     [(set (match_dup 2)
9714           (neg:DWIH (match_dup 2)))
9715      (clobber (reg:CC FLAGS_REG))])]
9716   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9718 (define_insn "*neg<mode>2_1"
9719   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9720         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9721    (clobber (reg:CC FLAGS_REG))]
9722   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9723   "neg{<imodesuffix>}\t%0"
9724   [(set_attr "type" "negnot")
9725    (set_attr "mode" "<MODE>")])
9727 ;; Combine is quite creative about this pattern.
9728 (define_insn "*negsi2_1_zext"
9729   [(set (match_operand:DI 0 "register_operand" "=r")
9730         (lshiftrt:DI
9731           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9732                              (const_int 32)))
9733         (const_int 32)))
9734    (clobber (reg:CC FLAGS_REG))]
9735   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9736   "neg{l}\t%k0"
9737   [(set_attr "type" "negnot")
9738    (set_attr "mode" "SI")])
9740 ;; The problem with neg is that it does not perform (compare x 0),
9741 ;; it really performs (compare 0 x), which leaves us with the zero
9742 ;; flag being the only useful item.
9744 (define_insn "*neg<mode>2_cmpz"
9745   [(set (reg:CCZ FLAGS_REG)
9746         (compare:CCZ
9747           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9748                    (const_int 0)))
9749    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9750         (neg:SWI (match_dup 1)))]
9751   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9752   "neg{<imodesuffix>}\t%0"
9753   [(set_attr "type" "negnot")
9754    (set_attr "mode" "<MODE>")])
9756 (define_insn "*negsi2_cmpz_zext"
9757   [(set (reg:CCZ FLAGS_REG)
9758         (compare:CCZ
9759           (lshiftrt:DI
9760             (neg:DI (ashift:DI
9761                       (match_operand:DI 1 "register_operand" "0")
9762                       (const_int 32)))
9763             (const_int 32))
9764           (const_int 0)))
9765    (set (match_operand:DI 0 "register_operand" "=r")
9766         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9767                                         (const_int 32)))
9768                      (const_int 32)))]
9769   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9770   "neg{l}\t%k0"
9771   [(set_attr "type" "negnot")
9772    (set_attr "mode" "SI")])
9774 ;; Negate with jump on overflow.
9775 (define_expand "negv<mode>3"
9776   [(parallel [(set (reg:CCO FLAGS_REG)
9777                    (ne:CCO (match_operand:SWI 1 "register_operand")
9778                            (match_dup 3)))
9779               (set (match_operand:SWI 0 "register_operand")
9780                    (neg:SWI (match_dup 1)))])
9781    (set (pc) (if_then_else
9782                (eq (reg:CCO FLAGS_REG) (const_int 0))
9783                (label_ref (match_operand 2))
9784                (pc)))]
9785   ""
9787   operands[3]
9788     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9789                     <MODE>mode);
9792 (define_insn "*negv<mode>3"
9793   [(set (reg:CCO FLAGS_REG)
9794         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9795                 (match_operand:SWI 2 "const_int_operand")))
9796    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9797         (neg:SWI (match_dup 1)))]
9798   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9799    && mode_signbit_p (<MODE>mode, operands[2])"
9800   "neg{<imodesuffix>}\t%0"
9801   [(set_attr "type" "negnot")
9802    (set_attr "mode" "<MODE>")])
9804 ;; Changing of sign for FP values is doable using integer unit too.
9806 (define_expand "<code><mode>2"
9807   [(set (match_operand:X87MODEF 0 "register_operand")
9808         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9809   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9810   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9812 (define_insn "*absneg<mode>2"
9813   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9814         (match_operator:MODEF 3 "absneg_operator"
9815           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9816    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9819   "#"
9820   [(set (attr "enabled")
9821      (if_then_else
9822        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9823        (if_then_else
9824          (eq_attr "alternative" "2")
9825          (symbol_ref "TARGET_MIX_SSE_I387")
9826          (symbol_ref "true"))
9827        (if_then_else
9828          (eq_attr "alternative" "2,3")
9829          (symbol_ref "true")
9830          (symbol_ref "false"))))])
9832 (define_insn "*absnegxf2_i387"
9833   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9834         (match_operator:XF 3 "absneg_operator"
9835           [(match_operand:XF 1 "register_operand" "0,0")]))
9836    (use (match_operand 2))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "TARGET_80387"
9839   "#")
9841 (define_expand "<code>tf2"
9842   [(set (match_operand:TF 0 "register_operand")
9843         (absneg:TF (match_operand:TF 1 "register_operand")))]
9844   "TARGET_SSE"
9845   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9847 (define_insn "*absnegtf2_sse"
9848   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9849         (match_operator:TF 3 "absneg_operator"
9850           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9851    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "TARGET_SSE"
9854   "#")
9856 ;; Splitters for fp abs and neg.
9858 (define_split
9859   [(set (match_operand 0 "fp_register_operand")
9860         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9861    (use (match_operand 2))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "reload_completed"
9864   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9866 (define_split
9867   [(set (match_operand 0 "sse_reg_operand")
9868         (match_operator 3 "absneg_operator"
9869           [(match_operand 1 "register_operand")]))
9870    (use (match_operand 2 "nonimmediate_operand"))
9871    (clobber (reg:CC FLAGS_REG))]
9872   "reload_completed"
9873   [(set (match_dup 0) (match_dup 3))]
9875   machine_mode mode = GET_MODE (operands[0]);
9876   machine_mode vmode = GET_MODE (operands[2]);
9877   rtx tmp;
9879   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9880   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9881   if (operands_match_p (operands[0], operands[2]))
9882     std::swap (operands[1], operands[2]);
9883   if (GET_CODE (operands[3]) == ABS)
9884     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9885   else
9886     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9887   operands[3] = tmp;
9890 (define_split
9891   [(set (match_operand:SF 0 "general_reg_operand")
9892         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9893    (use (match_operand:V4SF 2))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "reload_completed"
9896   [(parallel [(set (match_dup 0) (match_dup 1))
9897               (clobber (reg:CC FLAGS_REG))])]
9899   rtx tmp;
9900   operands[0] = gen_lowpart (SImode, operands[0]);
9901   if (GET_CODE (operands[1]) == ABS)
9902     {
9903       tmp = gen_int_mode (0x7fffffff, SImode);
9904       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9905     }
9906   else
9907     {
9908       tmp = gen_int_mode (0x80000000, SImode);
9909       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9910     }
9911   operands[1] = tmp;
9914 (define_split
9915   [(set (match_operand:DF 0 "general_reg_operand")
9916         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9917    (use (match_operand 2))
9918    (clobber (reg:CC FLAGS_REG))]
9919   "reload_completed"
9920   [(parallel [(set (match_dup 0) (match_dup 1))
9921               (clobber (reg:CC FLAGS_REG))])]
9923   rtx tmp;
9924   if (TARGET_64BIT)
9925     {
9926       tmp = gen_lowpart (DImode, operands[0]);
9927       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9928       operands[0] = tmp;
9930       if (GET_CODE (operands[1]) == ABS)
9931         tmp = const0_rtx;
9932       else
9933         tmp = gen_rtx_NOT (DImode, tmp);
9934     }
9935   else
9936     {
9937       operands[0] = gen_highpart (SImode, operands[0]);
9938       if (GET_CODE (operands[1]) == ABS)
9939         {
9940           tmp = gen_int_mode (0x7fffffff, SImode);
9941           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9942         }
9943       else
9944         {
9945           tmp = gen_int_mode (0x80000000, SImode);
9946           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9947         }
9948     }
9949   operands[1] = tmp;
9952 (define_split
9953   [(set (match_operand:XF 0 "general_reg_operand")
9954         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9955    (use (match_operand 2))
9956    (clobber (reg:CC FLAGS_REG))]
9957   "reload_completed"
9958   [(parallel [(set (match_dup 0) (match_dup 1))
9959               (clobber (reg:CC FLAGS_REG))])]
9961   rtx tmp;
9962   operands[0] = gen_rtx_REG (SImode,
9963                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9964   if (GET_CODE (operands[1]) == ABS)
9965     {
9966       tmp = GEN_INT (0x7fff);
9967       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9968     }
9969   else
9970     {
9971       tmp = GEN_INT (0x8000);
9972       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9973     }
9974   operands[1] = tmp;
9977 ;; Conditionalize these after reload. If they match before reload, we
9978 ;; lose the clobber and ability to use integer instructions.
9980 (define_insn "*<code><mode>2_1"
9981   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9982         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9983   "TARGET_80387
9984    && (reload_completed
9985        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9986   "f<absneg_mnemonic>"
9987   [(set_attr "type" "fsgn")
9988    (set_attr "mode" "<MODE>")])
9990 (define_insn "*<code>extendsfdf2"
9991   [(set (match_operand:DF 0 "register_operand" "=f")
9992         (absneg:DF (float_extend:DF
9993                      (match_operand:SF 1 "register_operand" "0"))))]
9994   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9995   "f<absneg_mnemonic>"
9996   [(set_attr "type" "fsgn")
9997    (set_attr "mode" "DF")])
9999 (define_insn "*<code>extendsfxf2"
10000   [(set (match_operand:XF 0 "register_operand" "=f")
10001         (absneg:XF (float_extend:XF
10002                      (match_operand:SF 1 "register_operand" "0"))))]
10003   "TARGET_80387"
10004   "f<absneg_mnemonic>"
10005   [(set_attr "type" "fsgn")
10006    (set_attr "mode" "XF")])
10008 (define_insn "*<code>extenddfxf2"
10009   [(set (match_operand:XF 0 "register_operand" "=f")
10010         (absneg:XF (float_extend:XF
10011                      (match_operand:DF 1 "register_operand" "0"))))]
10012   "TARGET_80387"
10013   "f<absneg_mnemonic>"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "XF")])
10017 ;; Copysign instructions
10019 (define_mode_iterator CSGNMODE [SF DF TF])
10020 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10022 (define_expand "copysign<mode>3"
10023   [(match_operand:CSGNMODE 0 "register_operand")
10024    (match_operand:CSGNMODE 1 "nonmemory_operand")
10025    (match_operand:CSGNMODE 2 "register_operand")]
10026   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10027    || (TARGET_SSE && (<MODE>mode == TFmode))"
10028   "ix86_expand_copysign (operands); DONE;")
10030 (define_insn_and_split "copysign<mode>3_const"
10031   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10032         (unspec:CSGNMODE
10033           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10034            (match_operand:CSGNMODE 2 "register_operand" "0")
10035            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10036           UNSPEC_COPYSIGN))]
10037   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10038    || (TARGET_SSE && (<MODE>mode == TFmode))"
10039   "#"
10040   "&& reload_completed"
10041   [(const_int 0)]
10042   "ix86_split_copysign_const (operands); DONE;")
10044 (define_insn "copysign<mode>3_var"
10045   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10046         (unspec:CSGNMODE
10047           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10048            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10049            (match_operand:<CSGNVMODE> 4
10050              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10051            (match_operand:<CSGNVMODE> 5
10052              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10053           UNSPEC_COPYSIGN))
10054    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10055   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10056    || (TARGET_SSE && (<MODE>mode == TFmode))"
10057   "#")
10059 (define_split
10060   [(set (match_operand:CSGNMODE 0 "register_operand")
10061         (unspec:CSGNMODE
10062           [(match_operand:CSGNMODE 2 "register_operand")
10063            (match_operand:CSGNMODE 3 "register_operand")
10064            (match_operand:<CSGNVMODE> 4)
10065            (match_operand:<CSGNVMODE> 5)]
10066           UNSPEC_COPYSIGN))
10067    (clobber (match_scratch:<CSGNVMODE> 1))]
10068   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10069     || (TARGET_SSE && (<MODE>mode == TFmode)))
10070    && reload_completed"
10071   [(const_int 0)]
10072   "ix86_split_copysign_var (operands); DONE;")
10074 ;; One complement instructions
10076 (define_expand "one_cmpl<mode>2"
10077   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10078         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10079   ""
10080   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10082 (define_insn_and_split "*one_cmpldi2_doubleword"
10083   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10085   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10086    && ix86_unary_operator_ok (NOT, DImode, operands)"
10087   "#"
10088   "&& reload_completed"
10089   [(set (match_dup 0)
10090         (not:SI (match_dup 1)))
10091    (set (match_dup 2)
10092         (not:SI (match_dup 3)))]
10093   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10095 (define_insn "*one_cmpl<mode>2_1"
10096   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10097         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10098   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10099   "not{<imodesuffix>}\t%0"
10100   [(set_attr "type" "negnot")
10101    (set_attr "mode" "<MODE>")])
10103 ;; ??? Currently never generated - xor is used instead.
10104 (define_insn "*one_cmplsi2_1_zext"
10105   [(set (match_operand:DI 0 "register_operand" "=r")
10106         (zero_extend:DI
10107           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10108   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10109   "not{l}\t%k0"
10110   [(set_attr "type" "negnot")
10111    (set_attr "mode" "SI")])
10113 (define_insn "*one_cmplqi2_1"
10114   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10115         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10116   "ix86_unary_operator_ok (NOT, QImode, operands)"
10117   "@
10118    not{b}\t%0
10119    not{l}\t%k0"
10120   [(set_attr "type" "negnot")
10121    (set_attr "mode" "QI,SI")
10122    ;; Potential partial reg stall on alternative 1.
10123    (set (attr "preferred_for_speed")
10124      (cond [(eq_attr "alternative" "1")
10125               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10126            (symbol_ref "true")))])
10128 (define_insn "*one_cmpl<mode>2_2"
10129   [(set (reg FLAGS_REG)
10130         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10131                  (const_int 0)))
10132    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10133         (not:SWI (match_dup 1)))]
10134   "ix86_match_ccmode (insn, CCNOmode)
10135    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10136   "#"
10137   [(set_attr "type" "alu1")
10138    (set_attr "mode" "<MODE>")])
10140 (define_split
10141   [(set (match_operand 0 "flags_reg_operand")
10142         (match_operator 2 "compare_operator"
10143           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10144            (const_int 0)]))
10145    (set (match_operand:SWI 1 "nonimmediate_operand")
10146         (not:SWI (match_dup 3)))]
10147   "ix86_match_ccmode (insn, CCNOmode)"
10148   [(parallel [(set (match_dup 0)
10149                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10150                                     (const_int 0)]))
10151               (set (match_dup 1)
10152                    (xor:SWI (match_dup 3) (const_int -1)))])])
10154 ;; ??? Currently never generated - xor is used instead.
10155 (define_insn "*one_cmplsi2_2_zext"
10156   [(set (reg FLAGS_REG)
10157         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10158                  (const_int 0)))
10159    (set (match_operand:DI 0 "register_operand" "=r")
10160         (zero_extend:DI (not:SI (match_dup 1))))]
10161   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10162    && ix86_unary_operator_ok (NOT, SImode, operands)"
10163   "#"
10164   [(set_attr "type" "alu1")
10165    (set_attr "mode" "SI")])
10167 (define_split
10168   [(set (match_operand 0 "flags_reg_operand")
10169         (match_operator 2 "compare_operator"
10170           [(not:SI (match_operand:SI 3 "register_operand"))
10171            (const_int 0)]))
10172    (set (match_operand:DI 1 "register_operand")
10173         (zero_extend:DI (not:SI (match_dup 3))))]
10174   "ix86_match_ccmode (insn, CCNOmode)"
10175   [(parallel [(set (match_dup 0)
10176                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10177                                     (const_int 0)]))
10178               (set (match_dup 1)
10179                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10181 ;; Shift instructions
10183 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10184 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10185 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10186 ;; from the assembler input.
10188 ;; This instruction shifts the target reg/mem as usual, but instead of
10189 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10190 ;; is a left shift double, bits are taken from the high order bits of
10191 ;; reg, else if the insn is a shift right double, bits are taken from the
10192 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10193 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10195 ;; Since sh[lr]d does not change the `reg' operand, that is done
10196 ;; separately, making all shifts emit pairs of shift double and normal
10197 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10198 ;; support a 63 bit shift, each shift where the count is in a reg expands
10199 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10201 ;; If the shift count is a constant, we need never emit more than one
10202 ;; shift pair, instead using moves and sign extension for counts greater
10203 ;; than 31.
10205 (define_expand "ashl<mode>3"
10206   [(set (match_operand:SDWIM 0 "<shift_operand>")
10207         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10208                       (match_operand:QI 2 "nonmemory_operand")))]
10209   ""
10210   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10212 (define_insn "*ashl<mode>3_doubleword"
10213   [(set (match_operand:DWI 0 "register_operand" "=&r")
10214         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10215                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10216    (clobber (reg:CC FLAGS_REG))]
10217   ""
10218   "#"
10219   [(set_attr "type" "multi")])
10221 (define_split
10222   [(set (match_operand:DWI 0 "register_operand")
10223         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10224                     (match_operand:QI 2 "nonmemory_operand")))
10225    (clobber (reg:CC FLAGS_REG))]
10226   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10227   [(const_int 0)]
10228   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10230 ;; By default we don't ask for a scratch register, because when DWImode
10231 ;; values are manipulated, registers are already at a premium.  But if
10232 ;; we have one handy, we won't turn it away.
10234 (define_peephole2
10235   [(match_scratch:DWIH 3 "r")
10236    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10237                    (ashift:<DWI>
10238                      (match_operand:<DWI> 1 "nonmemory_operand")
10239                      (match_operand:QI 2 "nonmemory_operand")))
10240               (clobber (reg:CC FLAGS_REG))])
10241    (match_dup 3)]
10242   "TARGET_CMOVE"
10243   [(const_int 0)]
10244   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10246 (define_insn "x86_64_shld"
10247   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10248         (ior:DI (ashift:DI (match_dup 0)
10249                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10250                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10251                   (minus:QI (const_int 64) (match_dup 2)))))
10252    (clobber (reg:CC FLAGS_REG))]
10253   "TARGET_64BIT"
10254   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10255   [(set_attr "type" "ishift")
10256    (set_attr "prefix_0f" "1")
10257    (set_attr "mode" "DI")
10258    (set_attr "athlon_decode" "vector")
10259    (set_attr "amdfam10_decode" "vector")
10260    (set_attr "bdver1_decode" "vector")])
10262 (define_insn "x86_shld"
10263   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10264         (ior:SI (ashift:SI (match_dup 0)
10265                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10266                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10267                   (minus:QI (const_int 32) (match_dup 2)))))
10268    (clobber (reg:CC FLAGS_REG))]
10269   ""
10270   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10271   [(set_attr "type" "ishift")
10272    (set_attr "prefix_0f" "1")
10273    (set_attr "mode" "SI")
10274    (set_attr "pent_pair" "np")
10275    (set_attr "athlon_decode" "vector")
10276    (set_attr "amdfam10_decode" "vector")
10277    (set_attr "bdver1_decode" "vector")])
10279 (define_expand "x86_shift<mode>_adj_1"
10280   [(set (reg:CCZ FLAGS_REG)
10281         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10282                              (match_dup 4))
10283                      (const_int 0)))
10284    (set (match_operand:SWI48 0 "register_operand")
10285         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286                             (match_operand:SWI48 1 "register_operand")
10287                             (match_dup 0)))
10288    (set (match_dup 1)
10289         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10290                             (match_operand:SWI48 3 "register_operand")
10291                             (match_dup 1)))]
10292   "TARGET_CMOVE"
10293   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10295 (define_expand "x86_shift<mode>_adj_2"
10296   [(use (match_operand:SWI48 0 "register_operand"))
10297    (use (match_operand:SWI48 1 "register_operand"))
10298    (use (match_operand:QI 2 "register_operand"))]
10299   ""
10301   rtx_code_label *label = gen_label_rtx ();
10302   rtx tmp;
10304   emit_insn (gen_testqi_ccz_1 (operands[2],
10305                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10307   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10308   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10309   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10310                               gen_rtx_LABEL_REF (VOIDmode, label),
10311                               pc_rtx);
10312   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10313   JUMP_LABEL (tmp) = label;
10315   emit_move_insn (operands[0], operands[1]);
10316   ix86_expand_clear (operands[1]);
10318   emit_label (label);
10319   LABEL_NUSES (label) = 1;
10321   DONE;
10324 ;; Avoid useless masking of count operand.
10325 (define_insn_and_split "*ashl<mode>3_mask"
10326   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10327         (ashift:SWI48
10328           (match_operand:SWI48 1 "nonimmediate_operand")
10329           (subreg:QI
10330             (and:SI
10331               (match_operand:SI 2 "register_operand")
10332               (match_operand:SI 3 "const_int_operand")) 0)))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10335    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10336       == GET_MODE_BITSIZE (<MODE>mode)-1
10337    && can_create_pseudo_p ()"
10338   "#"
10339   "&& 1"
10340   [(parallel
10341      [(set (match_dup 0)
10342            (ashift:SWI48 (match_dup 1)
10343                          (match_dup 2)))
10344       (clobber (reg:CC FLAGS_REG))])]
10345   "operands[2] = gen_lowpart (QImode, operands[2]);")
10347 (define_insn_and_split "*ashl<mode>3_mask_1"
10348   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10349         (ashift:SWI48
10350           (match_operand:SWI48 1 "nonimmediate_operand")
10351           (and:QI
10352             (match_operand:QI 2 "register_operand")
10353             (match_operand:QI 3 "const_int_operand"))))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10356    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10357       == GET_MODE_BITSIZE (<MODE>mode)-1
10358    && can_create_pseudo_p ()"
10359   "#"
10360   "&& 1"
10361   [(parallel
10362      [(set (match_dup 0)
10363            (ashift:SWI48 (match_dup 1)
10364                          (match_dup 2)))
10365       (clobber (reg:CC FLAGS_REG))])])
10367 (define_insn "*bmi2_ashl<mode>3_1"
10368   [(set (match_operand:SWI48 0 "register_operand" "=r")
10369         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10370                       (match_operand:SWI48 2 "register_operand" "r")))]
10371   "TARGET_BMI2"
10372   "shlx\t{%2, %1, %0|%0, %1, %2}"
10373   [(set_attr "type" "ishiftx")
10374    (set_attr "mode" "<MODE>")])
10376 (define_insn "*ashl<mode>3_1"
10377   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10378         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10379                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10380    (clobber (reg:CC FLAGS_REG))]
10381   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10383   switch (get_attr_type (insn))
10384     {
10385     case TYPE_LEA:
10386     case TYPE_ISHIFTX:
10387       return "#";
10389     case TYPE_ALU:
10390       gcc_assert (operands[2] == const1_rtx);
10391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10392       return "add{<imodesuffix>}\t%0, %0";
10394     default:
10395       if (operands[2] == const1_rtx
10396           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10397         return "sal{<imodesuffix>}\t%0";
10398       else
10399         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10400     }
10402   [(set_attr "isa" "*,*,bmi2")
10403    (set (attr "type")
10404      (cond [(eq_attr "alternative" "1")
10405               (const_string "lea")
10406             (eq_attr "alternative" "2")
10407               (const_string "ishiftx")
10408             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10409                       (match_operand 0 "register_operand"))
10410                  (match_operand 2 "const1_operand"))
10411               (const_string "alu")
10412            ]
10413            (const_string "ishift")))
10414    (set (attr "length_immediate")
10415      (if_then_else
10416        (ior (eq_attr "type" "alu")
10417             (and (eq_attr "type" "ishift")
10418                  (and (match_operand 2 "const1_operand")
10419                       (ior (match_test "TARGET_SHIFT1")
10420                            (match_test "optimize_function_for_size_p (cfun)")))))
10421        (const_string "0")
10422        (const_string "*")))
10423    (set_attr "mode" "<MODE>")])
10425 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10426 (define_split
10427   [(set (match_operand:SWI48 0 "register_operand")
10428         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10429                       (match_operand:QI 2 "register_operand")))
10430    (clobber (reg:CC FLAGS_REG))]
10431   "TARGET_BMI2 && reload_completed"
10432   [(set (match_dup 0)
10433         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10434   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10436 (define_insn "*bmi2_ashlsi3_1_zext"
10437   [(set (match_operand:DI 0 "register_operand" "=r")
10438         (zero_extend:DI
10439           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10440                      (match_operand:SI 2 "register_operand" "r"))))]
10441   "TARGET_64BIT && TARGET_BMI2"
10442   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10443   [(set_attr "type" "ishiftx")
10444    (set_attr "mode" "SI")])
10446 (define_insn "*ashlsi3_1_zext"
10447   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10448         (zero_extend:DI
10449           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10450                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10451    (clobber (reg:CC FLAGS_REG))]
10452   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10454   switch (get_attr_type (insn))
10455     {
10456     case TYPE_LEA:
10457     case TYPE_ISHIFTX:
10458       return "#";
10460     case TYPE_ALU:
10461       gcc_assert (operands[2] == const1_rtx);
10462       return "add{l}\t%k0, %k0";
10464     default:
10465       if (operands[2] == const1_rtx
10466           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10467         return "sal{l}\t%k0";
10468       else
10469         return "sal{l}\t{%2, %k0|%k0, %2}";
10470     }
10472   [(set_attr "isa" "*,*,bmi2")
10473    (set (attr "type")
10474      (cond [(eq_attr "alternative" "1")
10475               (const_string "lea")
10476             (eq_attr "alternative" "2")
10477               (const_string "ishiftx")
10478             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10479                  (match_operand 2 "const1_operand"))
10480               (const_string "alu")
10481            ]
10482            (const_string "ishift")))
10483    (set (attr "length_immediate")
10484      (if_then_else
10485        (ior (eq_attr "type" "alu")
10486             (and (eq_attr "type" "ishift")
10487                  (and (match_operand 2 "const1_operand")
10488                       (ior (match_test "TARGET_SHIFT1")
10489                            (match_test "optimize_function_for_size_p (cfun)")))))
10490        (const_string "0")
10491        (const_string "*")))
10492    (set_attr "mode" "SI")])
10494 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10495 (define_split
10496   [(set (match_operand:DI 0 "register_operand")
10497         (zero_extend:DI
10498           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10499                      (match_operand:QI 2 "register_operand"))))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10502   [(set (match_dup 0)
10503         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10504   "operands[2] = gen_lowpart (SImode, operands[2]);")
10506 (define_insn "*ashlhi3_1"
10507   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10508         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10509                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10513   switch (get_attr_type (insn))
10514     {
10515     case TYPE_LEA:
10516       return "#";
10518     case TYPE_ALU:
10519       gcc_assert (operands[2] == const1_rtx);
10520       return "add{w}\t%0, %0";
10522     default:
10523       if (operands[2] == const1_rtx
10524           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10525         return "sal{w}\t%0";
10526       else
10527         return "sal{w}\t{%2, %0|%0, %2}";
10528     }
10530   [(set (attr "type")
10531      (cond [(eq_attr "alternative" "1")
10532               (const_string "lea")
10533             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10534                       (match_operand 0 "register_operand"))
10535                  (match_operand 2 "const1_operand"))
10536               (const_string "alu")
10537            ]
10538            (const_string "ishift")))
10539    (set (attr "length_immediate")
10540      (if_then_else
10541        (ior (eq_attr "type" "alu")
10542             (and (eq_attr "type" "ishift")
10543                  (and (match_operand 2 "const1_operand")
10544                       (ior (match_test "TARGET_SHIFT1")
10545                            (match_test "optimize_function_for_size_p (cfun)")))))
10546        (const_string "0")
10547        (const_string "*")))
10548    (set_attr "mode" "HI,SI")])
10550 (define_insn "*ashlqi3_1"
10551   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10552         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10553                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10554    (clobber (reg:CC FLAGS_REG))]
10555   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10557   switch (get_attr_type (insn))
10558     {
10559     case TYPE_LEA:
10560       return "#";
10562     case TYPE_ALU:
10563       gcc_assert (operands[2] == const1_rtx);
10564       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10565         return "add{l}\t%k0, %k0";
10566       else
10567         return "add{b}\t%0, %0";
10569     default:
10570       if (operands[2] == const1_rtx
10571           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10572         {
10573           if (get_attr_mode (insn) == MODE_SI)
10574             return "sal{l}\t%k0";
10575           else
10576             return "sal{b}\t%0";
10577         }
10578       else
10579         {
10580           if (get_attr_mode (insn) == MODE_SI)
10581             return "sal{l}\t{%2, %k0|%k0, %2}";
10582           else
10583             return "sal{b}\t{%2, %0|%0, %2}";
10584         }
10585     }
10587   [(set (attr "type")
10588      (cond [(eq_attr "alternative" "2")
10589               (const_string "lea")
10590             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10591                       (match_operand 0 "register_operand"))
10592                  (match_operand 2 "const1_operand"))
10593               (const_string "alu")
10594            ]
10595            (const_string "ishift")))
10596    (set (attr "length_immediate")
10597      (if_then_else
10598        (ior (eq_attr "type" "alu")
10599             (and (eq_attr "type" "ishift")
10600                  (and (match_operand 2 "const1_operand")
10601                       (ior (match_test "TARGET_SHIFT1")
10602                            (match_test "optimize_function_for_size_p (cfun)")))))
10603        (const_string "0")
10604        (const_string "*")))
10605    (set_attr "mode" "QI,SI,SI")
10606    ;; Potential partial reg stall on alternative 1.
10607    (set (attr "preferred_for_speed")
10608      (cond [(eq_attr "alternative" "1")
10609               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10610            (symbol_ref "true")))])
10612 (define_insn "*ashlqi3_1_slp"
10613   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10614         (ashift:QI (match_dup 0)
10615                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10616    (clobber (reg:CC FLAGS_REG))]
10617   "(optimize_function_for_size_p (cfun)
10618     || !TARGET_PARTIAL_FLAG_REG_STALL
10619     || (operands[1] == const1_rtx
10620         && (TARGET_SHIFT1
10621             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10623   switch (get_attr_type (insn))
10624     {
10625     case TYPE_ALU:
10626       gcc_assert (operands[1] == const1_rtx);
10627       return "add{b}\t%0, %0";
10629     default:
10630       if (operands[1] == const1_rtx
10631           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10632         return "sal{b}\t%0";
10633       else
10634         return "sal{b}\t{%1, %0|%0, %1}";
10635     }
10637   [(set (attr "type")
10638      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10639                       (match_operand 0 "register_operand"))
10640                  (match_operand 1 "const1_operand"))
10641               (const_string "alu")
10642            ]
10643            (const_string "ishift1")))
10644    (set (attr "length_immediate")
10645      (if_then_else
10646        (ior (eq_attr "type" "alu")
10647             (and (eq_attr "type" "ishift1")
10648                  (and (match_operand 1 "const1_operand")
10649                       (ior (match_test "TARGET_SHIFT1")
10650                            (match_test "optimize_function_for_size_p (cfun)")))))
10651        (const_string "0")
10652        (const_string "*")))
10653    (set_attr "mode" "QI")])
10655 ;; Convert ashift to the lea pattern to avoid flags dependency.
10656 (define_split
10657   [(set (match_operand:SWI 0 "register_operand")
10658         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10659                     (match_operand 2 "const_0_to_3_operand")))
10660    (clobber (reg:CC FLAGS_REG))]
10661   "reload_completed
10662    && REGNO (operands[0]) != REGNO (operands[1])"
10663   [(set (match_dup 0)
10664         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10666   if (<MODE>mode != <LEAMODE>mode)
10667     {
10668       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10669       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10670     }
10671   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10674 ;; Convert ashift to the lea pattern to avoid flags dependency.
10675 (define_split
10676   [(set (match_operand:DI 0 "register_operand")
10677         (zero_extend:DI
10678           (ashift:SI (match_operand:SI 1 "index_register_operand")
10679                      (match_operand 2 "const_0_to_3_operand"))))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "TARGET_64BIT && reload_completed
10682    && REGNO (operands[0]) != REGNO (operands[1])"
10683   [(set (match_dup 0)
10684         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10686   operands[1] = gen_lowpart (SImode, operands[1]);
10687   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10690 ;; This pattern can't accept a variable shift count, since shifts by
10691 ;; zero don't affect the flags.  We assume that shifts by constant
10692 ;; zero are optimized away.
10693 (define_insn "*ashl<mode>3_cmp"
10694   [(set (reg FLAGS_REG)
10695         (compare
10696           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10697                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10698           (const_int 0)))
10699    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10700         (ashift:SWI (match_dup 1) (match_dup 2)))]
10701   "(optimize_function_for_size_p (cfun)
10702     || !TARGET_PARTIAL_FLAG_REG_STALL
10703     || (operands[2] == const1_rtx
10704         && (TARGET_SHIFT1
10705             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10706    && ix86_match_ccmode (insn, CCGOCmode)
10707    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10709   switch (get_attr_type (insn))
10710     {
10711     case TYPE_ALU:
10712       gcc_assert (operands[2] == const1_rtx);
10713       return "add{<imodesuffix>}\t%0, %0";
10715     default:
10716       if (operands[2] == const1_rtx
10717           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10718         return "sal{<imodesuffix>}\t%0";
10719       else
10720         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10721     }
10723   [(set (attr "type")
10724      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10725                       (match_operand 0 "register_operand"))
10726                  (match_operand 2 "const1_operand"))
10727               (const_string "alu")
10728            ]
10729            (const_string "ishift")))
10730    (set (attr "length_immediate")
10731      (if_then_else
10732        (ior (eq_attr "type" "alu")
10733             (and (eq_attr "type" "ishift")
10734                  (and (match_operand 2 "const1_operand")
10735                       (ior (match_test "TARGET_SHIFT1")
10736                            (match_test "optimize_function_for_size_p (cfun)")))))
10737        (const_string "0")
10738        (const_string "*")))
10739    (set_attr "mode" "<MODE>")])
10741 (define_insn "*ashlsi3_cmp_zext"
10742   [(set (reg FLAGS_REG)
10743         (compare
10744           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10745                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10746           (const_int 0)))
10747    (set (match_operand:DI 0 "register_operand" "=r")
10748         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10749   "TARGET_64BIT
10750    && (optimize_function_for_size_p (cfun)
10751        || !TARGET_PARTIAL_FLAG_REG_STALL
10752        || (operands[2] == const1_rtx
10753            && (TARGET_SHIFT1
10754                || TARGET_DOUBLE_WITH_ADD)))
10755    && ix86_match_ccmode (insn, CCGOCmode)
10756    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10758   switch (get_attr_type (insn))
10759     {
10760     case TYPE_ALU:
10761       gcc_assert (operands[2] == const1_rtx);
10762       return "add{l}\t%k0, %k0";
10764     default:
10765       if (operands[2] == const1_rtx
10766           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10767         return "sal{l}\t%k0";
10768       else
10769         return "sal{l}\t{%2, %k0|%k0, %2}";
10770     }
10772   [(set (attr "type")
10773      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10774                  (match_operand 2 "const1_operand"))
10775               (const_string "alu")
10776            ]
10777            (const_string "ishift")))
10778    (set (attr "length_immediate")
10779      (if_then_else
10780        (ior (eq_attr "type" "alu")
10781             (and (eq_attr "type" "ishift")
10782                  (and (match_operand 2 "const1_operand")
10783                       (ior (match_test "TARGET_SHIFT1")
10784                            (match_test "optimize_function_for_size_p (cfun)")))))
10785        (const_string "0")
10786        (const_string "*")))
10787    (set_attr "mode" "SI")])
10789 (define_insn "*ashl<mode>3_cconly"
10790   [(set (reg FLAGS_REG)
10791         (compare
10792           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10793                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10794           (const_int 0)))
10795    (clobber (match_scratch:SWI 0 "=<r>"))]
10796   "(optimize_function_for_size_p (cfun)
10797     || !TARGET_PARTIAL_FLAG_REG_STALL
10798     || (operands[2] == const1_rtx
10799         && (TARGET_SHIFT1
10800             || TARGET_DOUBLE_WITH_ADD)))
10801    && ix86_match_ccmode (insn, CCGOCmode)"
10803   switch (get_attr_type (insn))
10804     {
10805     case TYPE_ALU:
10806       gcc_assert (operands[2] == const1_rtx);
10807       return "add{<imodesuffix>}\t%0, %0";
10809     default:
10810       if (operands[2] == const1_rtx
10811           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10812         return "sal{<imodesuffix>}\t%0";
10813       else
10814         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10815     }
10817   [(set (attr "type")
10818      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10819                       (match_operand 0 "register_operand"))
10820                  (match_operand 2 "const1_operand"))
10821               (const_string "alu")
10822            ]
10823            (const_string "ishift")))
10824    (set (attr "length_immediate")
10825      (if_then_else
10826        (ior (eq_attr "type" "alu")
10827             (and (eq_attr "type" "ishift")
10828                  (and (match_operand 2 "const1_operand")
10829                       (ior (match_test "TARGET_SHIFT1")
10830                            (match_test "optimize_function_for_size_p (cfun)")))))
10831        (const_string "0")
10832        (const_string "*")))
10833    (set_attr "mode" "<MODE>")])
10835 ;; See comment above `ashl<mode>3' about how this works.
10837 (define_expand "<shift_insn><mode>3"
10838   [(set (match_operand:SDWIM 0 "<shift_operand>")
10839         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10840                            (match_operand:QI 2 "nonmemory_operand")))]
10841   ""
10842   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10844 ;; Avoid useless masking of count operand.
10845 (define_insn_and_split "*<shift_insn><mode>3_mask"
10846   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10847         (any_shiftrt:SWI48
10848           (match_operand:SWI48 1 "nonimmediate_operand")
10849           (subreg:QI
10850             (and:SI
10851               (match_operand:SI 2 "register_operand")
10852               (match_operand:SI 3 "const_int_operand")) 0)))
10853    (clobber (reg:CC FLAGS_REG))]
10854   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10855    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10856       == GET_MODE_BITSIZE (<MODE>mode)-1
10857    && can_create_pseudo_p ()"
10858   "#"
10859   "&& 1"
10860   [(parallel
10861      [(set (match_dup 0)
10862            (any_shiftrt:SWI48 (match_dup 1)
10863                               (match_dup 2)))
10864       (clobber (reg:CC FLAGS_REG))])]
10865   "operands[2] = gen_lowpart (QImode, operands[2]);")
10867 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10868   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10869         (any_shiftrt:SWI48
10870           (match_operand:SWI48 1 "nonimmediate_operand")
10871           (and:QI
10872             (match_operand:QI 2 "register_operand")
10873             (match_operand:QI 3 "const_int_operand"))))
10874    (clobber (reg:CC FLAGS_REG))]
10875   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10876    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10877       == GET_MODE_BITSIZE (<MODE>mode)-1
10878    && can_create_pseudo_p ()"
10879   "#"
10880   "&& 1"
10881   [(parallel
10882      [(set (match_dup 0)
10883            (any_shiftrt:SWI48 (match_dup 1)
10884                               (match_dup 2)))
10885       (clobber (reg:CC FLAGS_REG))])])
10887 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10888   [(set (match_operand:DWI 0 "register_operand" "=&r")
10889         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10890                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10891    (clobber (reg:CC FLAGS_REG))]
10892   ""
10893   "#"
10894   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10895   [(const_int 0)]
10896   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10897   [(set_attr "type" "multi")])
10899 ;; By default we don't ask for a scratch register, because when DWImode
10900 ;; values are manipulated, registers are already at a premium.  But if
10901 ;; we have one handy, we won't turn it away.
10903 (define_peephole2
10904   [(match_scratch:DWIH 3 "r")
10905    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10906                    (any_shiftrt:<DWI>
10907                      (match_operand:<DWI> 1 "register_operand")
10908                      (match_operand:QI 2 "nonmemory_operand")))
10909               (clobber (reg:CC FLAGS_REG))])
10910    (match_dup 3)]
10911   "TARGET_CMOVE"
10912   [(const_int 0)]
10913   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10915 (define_insn "x86_64_shrd"
10916   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10917         (ior:DI (lshiftrt:DI (match_dup 0)
10918                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10919                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10920                   (minus:QI (const_int 64) (match_dup 2)))))
10921    (clobber (reg:CC FLAGS_REG))]
10922   "TARGET_64BIT"
10923   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10924   [(set_attr "type" "ishift")
10925    (set_attr "prefix_0f" "1")
10926    (set_attr "mode" "DI")
10927    (set_attr "athlon_decode" "vector")
10928    (set_attr "amdfam10_decode" "vector")
10929    (set_attr "bdver1_decode" "vector")])
10931 (define_insn "x86_shrd"
10932   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10933         (ior:SI (lshiftrt:SI (match_dup 0)
10934                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10935                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10936                   (minus:QI (const_int 32) (match_dup 2)))))
10937    (clobber (reg:CC FLAGS_REG))]
10938   ""
10939   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10940   [(set_attr "type" "ishift")
10941    (set_attr "prefix_0f" "1")
10942    (set_attr "mode" "SI")
10943    (set_attr "pent_pair" "np")
10944    (set_attr "athlon_decode" "vector")
10945    (set_attr "amdfam10_decode" "vector")
10946    (set_attr "bdver1_decode" "vector")])
10948 (define_insn "ashrdi3_cvt"
10949   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10950         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10951                      (match_operand:QI 2 "const_int_operand")))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "TARGET_64BIT && INTVAL (operands[2]) == 63
10954    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10955    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10956   "@
10957    {cqto|cqo}
10958    sar{q}\t{%2, %0|%0, %2}"
10959   [(set_attr "type" "imovx,ishift")
10960    (set_attr "prefix_0f" "0,*")
10961    (set_attr "length_immediate" "0,*")
10962    (set_attr "modrm" "0,1")
10963    (set_attr "mode" "DI")])
10965 (define_insn "*ashrsi3_cvt_zext"
10966   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10967         (zero_extend:DI
10968           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10969                        (match_operand:QI 2 "const_int_operand"))))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "TARGET_64BIT && INTVAL (operands[2]) == 31
10972    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10973    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10974   "@
10975    {cltd|cdq}
10976    sar{l}\t{%2, %k0|%k0, %2}"
10977   [(set_attr "type" "imovx,ishift")
10978    (set_attr "prefix_0f" "0,*")
10979    (set_attr "length_immediate" "0,*")
10980    (set_attr "modrm" "0,1")
10981    (set_attr "mode" "SI")])
10983 (define_insn "ashrsi3_cvt"
10984   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10985         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10986                      (match_operand:QI 2 "const_int_operand")))
10987    (clobber (reg:CC FLAGS_REG))]
10988   "INTVAL (operands[2]) == 31
10989    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10990    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10991   "@
10992    {cltd|cdq}
10993    sar{l}\t{%2, %0|%0, %2}"
10994   [(set_attr "type" "imovx,ishift")
10995    (set_attr "prefix_0f" "0,*")
10996    (set_attr "length_immediate" "0,*")
10997    (set_attr "modrm" "0,1")
10998    (set_attr "mode" "SI")])
11000 (define_expand "x86_shift<mode>_adj_3"
11001   [(use (match_operand:SWI48 0 "register_operand"))
11002    (use (match_operand:SWI48 1 "register_operand"))
11003    (use (match_operand:QI 2 "register_operand"))]
11004   ""
11006   rtx_code_label *label = gen_label_rtx ();
11007   rtx tmp;
11009   emit_insn (gen_testqi_ccz_1 (operands[2],
11010                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11012   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11013   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11014   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11015                               gen_rtx_LABEL_REF (VOIDmode, label),
11016                               pc_rtx);
11017   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11018   JUMP_LABEL (tmp) = label;
11020   emit_move_insn (operands[0], operands[1]);
11021   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11022                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11023   emit_label (label);
11024   LABEL_NUSES (label) = 1;
11026   DONE;
11029 (define_insn "*bmi2_<shift_insn><mode>3_1"
11030   [(set (match_operand:SWI48 0 "register_operand" "=r")
11031         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11032                            (match_operand:SWI48 2 "register_operand" "r")))]
11033   "TARGET_BMI2"
11034   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11035   [(set_attr "type" "ishiftx")
11036    (set_attr "mode" "<MODE>")])
11038 (define_insn "*<shift_insn><mode>3_1"
11039   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11040         (any_shiftrt:SWI48
11041           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11042           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11043    (clobber (reg:CC FLAGS_REG))]
11044   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11046   switch (get_attr_type (insn))
11047     {
11048     case TYPE_ISHIFTX:
11049       return "#";
11051     default:
11052       if (operands[2] == const1_rtx
11053           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11054         return "<shift>{<imodesuffix>}\t%0";
11055       else
11056         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11057     }
11059   [(set_attr "isa" "*,bmi2")
11060    (set_attr "type" "ishift,ishiftx")
11061    (set (attr "length_immediate")
11062      (if_then_else
11063        (and (match_operand 2 "const1_operand")
11064             (ior (match_test "TARGET_SHIFT1")
11065                  (match_test "optimize_function_for_size_p (cfun)")))
11066        (const_string "0")
11067        (const_string "*")))
11068    (set_attr "mode" "<MODE>")])
11070 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11071 (define_split
11072   [(set (match_operand:SWI48 0 "register_operand")
11073         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11074                            (match_operand:QI 2 "register_operand")))
11075    (clobber (reg:CC FLAGS_REG))]
11076   "TARGET_BMI2 && reload_completed"
11077   [(set (match_dup 0)
11078         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11079   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11081 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11082   [(set (match_operand:DI 0 "register_operand" "=r")
11083         (zero_extend:DI
11084           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11085                           (match_operand:SI 2 "register_operand" "r"))))]
11086   "TARGET_64BIT && TARGET_BMI2"
11087   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11088   [(set_attr "type" "ishiftx")
11089    (set_attr "mode" "SI")])
11091 (define_insn "*<shift_insn>si3_1_zext"
11092   [(set (match_operand:DI 0 "register_operand" "=r,r")
11093         (zero_extend:DI
11094           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11095                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11099   switch (get_attr_type (insn))
11100     {
11101     case TYPE_ISHIFTX:
11102       return "#";
11104     default:
11105       if (operands[2] == const1_rtx
11106           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11107         return "<shift>{l}\t%k0";
11108       else
11109         return "<shift>{l}\t{%2, %k0|%k0, %2}";
11110     }
11112   [(set_attr "isa" "*,bmi2")
11113    (set_attr "type" "ishift,ishiftx")
11114    (set (attr "length_immediate")
11115      (if_then_else
11116        (and (match_operand 2 "const1_operand")
11117             (ior (match_test "TARGET_SHIFT1")
11118                  (match_test "optimize_function_for_size_p (cfun)")))
11119        (const_string "0")
11120        (const_string "*")))
11121    (set_attr "mode" "SI")])
11123 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11124 (define_split
11125   [(set (match_operand:DI 0 "register_operand")
11126         (zero_extend:DI
11127           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11128                           (match_operand:QI 2 "register_operand"))))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11131   [(set (match_dup 0)
11132         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11133   "operands[2] = gen_lowpart (SImode, operands[2]);")
11135 (define_insn "*<shift_insn><mode>3_1"
11136   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11137         (any_shiftrt:SWI12
11138           (match_operand:SWI12 1 "nonimmediate_operand" "0")
11139           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11140    (clobber (reg:CC FLAGS_REG))]
11141   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11143   if (operands[2] == const1_rtx
11144       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11145     return "<shift>{<imodesuffix>}\t%0";
11146   else
11147     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11149   [(set_attr "type" "ishift")
11150    (set (attr "length_immediate")
11151      (if_then_else
11152        (and (match_operand 2 "const1_operand")
11153             (ior (match_test "TARGET_SHIFT1")
11154                  (match_test "optimize_function_for_size_p (cfun)")))
11155        (const_string "0")
11156        (const_string "*")))
11157    (set_attr "mode" "<MODE>")])
11159 (define_insn "*<shift_insn>qi3_1_slp"
11160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11161         (any_shiftrt:QI (match_dup 0)
11162                         (match_operand:QI 1 "nonmemory_operand" "cI")))
11163    (clobber (reg:CC FLAGS_REG))]
11164   "(optimize_function_for_size_p (cfun)
11165     || !TARGET_PARTIAL_REG_STALL
11166     || (operands[1] == const1_rtx
11167         && TARGET_SHIFT1))"
11169   if (operands[1] == const1_rtx
11170       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11171     return "<shift>{b}\t%0";
11172   else
11173     return "<shift>{b}\t{%1, %0|%0, %1}";
11175   [(set_attr "type" "ishift1")
11176    (set (attr "length_immediate")
11177      (if_then_else
11178        (and (match_operand 1 "const1_operand")
11179             (ior (match_test "TARGET_SHIFT1")
11180                  (match_test "optimize_function_for_size_p (cfun)")))
11181        (const_string "0")
11182        (const_string "*")))
11183    (set_attr "mode" "QI")])
11185 ;; This pattern can't accept a variable shift count, since shifts by
11186 ;; zero don't affect the flags.  We assume that shifts by constant
11187 ;; zero are optimized away.
11188 (define_insn "*<shift_insn><mode>3_cmp"
11189   [(set (reg FLAGS_REG)
11190         (compare
11191           (any_shiftrt:SWI
11192             (match_operand:SWI 1 "nonimmediate_operand" "0")
11193             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11194           (const_int 0)))
11195    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11196         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11197   "(optimize_function_for_size_p (cfun)
11198     || !TARGET_PARTIAL_FLAG_REG_STALL
11199     || (operands[2] == const1_rtx
11200         && TARGET_SHIFT1))
11201    && ix86_match_ccmode (insn, CCGOCmode)
11202    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11204   if (operands[2] == const1_rtx
11205       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11206     return "<shift>{<imodesuffix>}\t%0";
11207   else
11208     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11210   [(set_attr "type" "ishift")
11211    (set (attr "length_immediate")
11212      (if_then_else
11213        (and (match_operand 2 "const1_operand")
11214             (ior (match_test "TARGET_SHIFT1")
11215                  (match_test "optimize_function_for_size_p (cfun)")))
11216        (const_string "0")
11217        (const_string "*")))
11218    (set_attr "mode" "<MODE>")])
11220 (define_insn "*<shift_insn>si3_cmp_zext"
11221   [(set (reg FLAGS_REG)
11222         (compare
11223           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11224                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11225           (const_int 0)))
11226    (set (match_operand:DI 0 "register_operand" "=r")
11227         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11228   "TARGET_64BIT
11229    && (optimize_function_for_size_p (cfun)
11230        || !TARGET_PARTIAL_FLAG_REG_STALL
11231        || (operands[2] == const1_rtx
11232            && TARGET_SHIFT1))
11233    && ix86_match_ccmode (insn, CCGOCmode)
11234    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11236   if (operands[2] == const1_rtx
11237       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11238     return "<shift>{l}\t%k0";
11239   else
11240     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11242   [(set_attr "type" "ishift")
11243    (set (attr "length_immediate")
11244      (if_then_else
11245        (and (match_operand 2 "const1_operand")
11246             (ior (match_test "TARGET_SHIFT1")
11247                  (match_test "optimize_function_for_size_p (cfun)")))
11248        (const_string "0")
11249        (const_string "*")))
11250    (set_attr "mode" "SI")])
11252 (define_insn "*<shift_insn><mode>3_cconly"
11253   [(set (reg FLAGS_REG)
11254         (compare
11255           (any_shiftrt:SWI
11256             (match_operand:SWI 1 "register_operand" "0")
11257             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11258           (const_int 0)))
11259    (clobber (match_scratch:SWI 0 "=<r>"))]
11260   "(optimize_function_for_size_p (cfun)
11261     || !TARGET_PARTIAL_FLAG_REG_STALL
11262     || (operands[2] == const1_rtx
11263         && TARGET_SHIFT1))
11264    && ix86_match_ccmode (insn, CCGOCmode)"
11266   if (operands[2] == const1_rtx
11267       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11268     return "<shift>{<imodesuffix>}\t%0";
11269   else
11270     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11272   [(set_attr "type" "ishift")
11273    (set (attr "length_immediate")
11274      (if_then_else
11275        (and (match_operand 2 "const1_operand")
11276             (ior (match_test "TARGET_SHIFT1")
11277                  (match_test "optimize_function_for_size_p (cfun)")))
11278        (const_string "0")
11279        (const_string "*")))
11280    (set_attr "mode" "<MODE>")])
11282 ;; Rotate instructions
11284 (define_expand "<rotate_insn>ti3"
11285   [(set (match_operand:TI 0 "register_operand")
11286         (any_rotate:TI (match_operand:TI 1 "register_operand")
11287                        (match_operand:QI 2 "nonmemory_operand")))]
11288   "TARGET_64BIT"
11290   if (const_1_to_63_operand (operands[2], VOIDmode))
11291     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11292                 (operands[0], operands[1], operands[2]));
11293   else
11294     FAIL;
11296   DONE;
11299 (define_expand "<rotate_insn>di3"
11300   [(set (match_operand:DI 0 "shiftdi_operand")
11301         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11302                        (match_operand:QI 2 "nonmemory_operand")))]
11303  ""
11305   if (TARGET_64BIT)
11306     ix86_expand_binary_operator (<CODE>, DImode, operands);
11307   else if (const_1_to_31_operand (operands[2], VOIDmode))
11308     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11309                 (operands[0], operands[1], operands[2]));
11310   else
11311     FAIL;
11313   DONE;
11316 (define_expand "<rotate_insn><mode>3"
11317   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11318         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11319                             (match_operand:QI 2 "nonmemory_operand")))]
11320   ""
11321   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11323 ;; Avoid useless masking of count operand.
11324 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11325   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11326         (any_rotate:SWI48
11327           (match_operand:SWI48 1 "nonimmediate_operand")
11328           (subreg:QI
11329             (and:SI
11330               (match_operand:SI 2 "register_operand")
11331               (match_operand:SI 3 "const_int_operand")) 0)))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11334    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11335       == GET_MODE_BITSIZE (<MODE>mode)-1
11336    && can_create_pseudo_p ()"
11337   "#"
11338   "&& 1"
11339   [(parallel
11340      [(set (match_dup 0)
11341            (any_rotate:SWI48 (match_dup 1)
11342                              (match_dup 2)))
11343       (clobber (reg:CC FLAGS_REG))])]
11344   "operands[2] = gen_lowpart (QImode, operands[2]);")
11346 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11347   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11348         (any_rotate:SWI48
11349           (match_operand:SWI48 1 "nonimmediate_operand")
11350           (and:QI
11351             (match_operand:QI 2 "register_operand")
11352             (match_operand:QI 3 "const_int_operand"))))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11355    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11356       == GET_MODE_BITSIZE (<MODE>mode)-1
11357    && can_create_pseudo_p ()"
11358   "#"
11359   "&& 1"
11360   [(parallel
11361      [(set (match_dup 0)
11362            (any_rotate:SWI48 (match_dup 1)
11363                              (match_dup 2)))
11364       (clobber (reg:CC FLAGS_REG))])])
11366 ;; Implement rotation using two double-precision
11367 ;; shift instructions and a scratch register.
11369 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11370  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11371        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11372                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11373   (clobber (reg:CC FLAGS_REG))
11374   (clobber (match_scratch:DWIH 3 "=&r"))]
11375  ""
11376  "#"
11377  "reload_completed"
11378  [(set (match_dup 3) (match_dup 4))
11379   (parallel
11380    [(set (match_dup 4)
11381          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11382                    (lshiftrt:DWIH (match_dup 5)
11383                                   (minus:QI (match_dup 6) (match_dup 2)))))
11384     (clobber (reg:CC FLAGS_REG))])
11385   (parallel
11386    [(set (match_dup 5)
11387          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11388                    (lshiftrt:DWIH (match_dup 3)
11389                                   (minus:QI (match_dup 6) (match_dup 2)))))
11390     (clobber (reg:CC FLAGS_REG))])]
11392   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11394   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11397 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11398  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11399        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11400                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11401   (clobber (reg:CC FLAGS_REG))
11402   (clobber (match_scratch:DWIH 3 "=&r"))]
11403  ""
11404  "#"
11405  "reload_completed"
11406  [(set (match_dup 3) (match_dup 4))
11407   (parallel
11408    [(set (match_dup 4)
11409          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11410                    (ashift:DWIH (match_dup 5)
11411                                 (minus:QI (match_dup 6) (match_dup 2)))))
11412     (clobber (reg:CC FLAGS_REG))])
11413   (parallel
11414    [(set (match_dup 5)
11415          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11416                    (ashift:DWIH (match_dup 3)
11417                                 (minus:QI (match_dup 6) (match_dup 2)))))
11418     (clobber (reg:CC FLAGS_REG))])]
11420   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11422   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11425 (define_mode_attr rorx_immediate_operand
11426         [(SI "const_0_to_31_operand")
11427          (DI "const_0_to_63_operand")])
11429 (define_insn "*bmi2_rorx<mode>3_1"
11430   [(set (match_operand:SWI48 0 "register_operand" "=r")
11431         (rotatert:SWI48
11432           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11433           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11434   "TARGET_BMI2"
11435   "rorx\t{%2, %1, %0|%0, %1, %2}"
11436   [(set_attr "type" "rotatex")
11437    (set_attr "mode" "<MODE>")])
11439 (define_insn "*<rotate_insn><mode>3_1"
11440   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11441         (any_rotate:SWI48
11442           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11443           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11444    (clobber (reg:CC FLAGS_REG))]
11445   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11447   switch (get_attr_type (insn))
11448     {
11449     case TYPE_ROTATEX:
11450       return "#";
11452     default:
11453       if (operands[2] == const1_rtx
11454           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11455         return "<rotate>{<imodesuffix>}\t%0";
11456       else
11457         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11458     }
11460   [(set_attr "isa" "*,bmi2")
11461    (set_attr "type" "rotate,rotatex")
11462    (set (attr "length_immediate")
11463      (if_then_else
11464        (and (eq_attr "type" "rotate")
11465             (and (match_operand 2 "const1_operand")
11466                  (ior (match_test "TARGET_SHIFT1")
11467                       (match_test "optimize_function_for_size_p (cfun)"))))
11468        (const_string "0")
11469        (const_string "*")))
11470    (set_attr "mode" "<MODE>")])
11472 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11473 (define_split
11474   [(set (match_operand:SWI48 0 "register_operand")
11475         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11476                       (match_operand:QI 2 "const_int_operand")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "TARGET_BMI2 && reload_completed"
11479   [(set (match_dup 0)
11480         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11482   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11484   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11487 (define_split
11488   [(set (match_operand:SWI48 0 "register_operand")
11489         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11490                         (match_operand:QI 2 "const_int_operand")))
11491    (clobber (reg:CC FLAGS_REG))]
11492   "TARGET_BMI2 && reload_completed"
11493   [(set (match_dup 0)
11494         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11496 (define_insn "*bmi2_rorxsi3_1_zext"
11497   [(set (match_operand:DI 0 "register_operand" "=r")
11498         (zero_extend:DI
11499           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11500                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11501   "TARGET_64BIT && TARGET_BMI2"
11502   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11503   [(set_attr "type" "rotatex")
11504    (set_attr "mode" "SI")])
11506 (define_insn "*<rotate_insn>si3_1_zext"
11507   [(set (match_operand:DI 0 "register_operand" "=r,r")
11508         (zero_extend:DI
11509           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11510                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11514   switch (get_attr_type (insn))
11515     {
11516     case TYPE_ROTATEX:
11517       return "#";
11519     default:
11520       if (operands[2] == const1_rtx
11521           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11522         return "<rotate>{l}\t%k0";
11523       else
11524         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11525     }
11527   [(set_attr "isa" "*,bmi2")
11528    (set_attr "type" "rotate,rotatex")
11529    (set (attr "length_immediate")
11530      (if_then_else
11531        (and (eq_attr "type" "rotate")
11532             (and (match_operand 2 "const1_operand")
11533                  (ior (match_test "TARGET_SHIFT1")
11534                       (match_test "optimize_function_for_size_p (cfun)"))))
11535        (const_string "0")
11536        (const_string "*")))
11537    (set_attr "mode" "SI")])
11539 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11540 (define_split
11541   [(set (match_operand:DI 0 "register_operand")
11542         (zero_extend:DI
11543           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11544                      (match_operand:QI 2 "const_int_operand"))))
11545    (clobber (reg:CC FLAGS_REG))]
11546   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11547   [(set (match_dup 0)
11548         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11550   int bitsize = GET_MODE_BITSIZE (SImode);
11552   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11555 (define_split
11556   [(set (match_operand:DI 0 "register_operand")
11557         (zero_extend:DI
11558           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11559                        (match_operand:QI 2 "const_int_operand"))))
11560    (clobber (reg:CC FLAGS_REG))]
11561   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11562   [(set (match_dup 0)
11563         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11565 (define_insn "*<rotate_insn><mode>3_1"
11566   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11567         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11568                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11569    (clobber (reg:CC FLAGS_REG))]
11570   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11572   if (operands[2] == const1_rtx
11573       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11574     return "<rotate>{<imodesuffix>}\t%0";
11575   else
11576     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11578   [(set_attr "type" "rotate")
11579    (set (attr "length_immediate")
11580      (if_then_else
11581        (and (match_operand 2 "const1_operand")
11582             (ior (match_test "TARGET_SHIFT1")
11583                  (match_test "optimize_function_for_size_p (cfun)")))
11584        (const_string "0")
11585        (const_string "*")))
11586    (set_attr "mode" "<MODE>")])
11588 (define_insn "*<rotate_insn>qi3_1_slp"
11589   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11590         (any_rotate:QI (match_dup 0)
11591                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11592    (clobber (reg:CC FLAGS_REG))]
11593   "(optimize_function_for_size_p (cfun)
11594     || !TARGET_PARTIAL_REG_STALL
11595     || (operands[1] == const1_rtx
11596         && TARGET_SHIFT1))"
11598   if (operands[1] == const1_rtx
11599       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11600     return "<rotate>{b}\t%0";
11601   else
11602     return "<rotate>{b}\t{%1, %0|%0, %1}";
11604   [(set_attr "type" "rotate1")
11605    (set (attr "length_immediate")
11606      (if_then_else
11607        (and (match_operand 1 "const1_operand")
11608             (ior (match_test "TARGET_SHIFT1")
11609                  (match_test "optimize_function_for_size_p (cfun)")))
11610        (const_string "0")
11611        (const_string "*")))
11612    (set_attr "mode" "QI")])
11614 (define_split
11615  [(set (match_operand:HI 0 "register_operand")
11616        (any_rotate:HI (match_dup 0) (const_int 8)))
11617   (clobber (reg:CC FLAGS_REG))]
11618  "reload_completed
11619   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11620  [(parallel [(set (strict_low_part (match_dup 0))
11621                   (bswap:HI (match_dup 0)))
11622              (clobber (reg:CC FLAGS_REG))])])
11624 ;; Bit set / bit test instructions
11626 ;; %%% bts, btr, btc
11628 ;; These instructions are *slow* when applied to memory.
11630 (define_code_attr btsc [(ior "bts") (xor "btc")])
11632 (define_insn "*<btsc><mode>"
11633   [(set (match_operand:SWI48 0 "register_operand" "=r")
11634         (any_or:SWI48
11635           (ashift:SWI48 (const_int 1)
11636                         (match_operand:QI 2 "register_operand" "r"))
11637           (match_operand:SWI48 1 "register_operand" "0")))
11638    (clobber (reg:CC FLAGS_REG))]
11639   "TARGET_USE_BT"
11640   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11641   [(set_attr "type" "alu1")
11642    (set_attr "prefix_0f" "1")
11643    (set_attr "znver1_decode" "double")
11644    (set_attr "mode" "<MODE>")])
11646 ;; Avoid useless masking of count operand.
11647 (define_insn_and_split "*<btsc><mode>_mask"
11648   [(set (match_operand:SWI48 0 "register_operand")
11649         (any_or:SWI48
11650           (ashift:SWI48
11651             (const_int 1)
11652             (subreg:QI
11653               (and:SI
11654                 (match_operand:SI 1 "register_operand")
11655                 (match_operand:SI 2 "const_int_operand")) 0))
11656           (match_operand:SWI48 3 "register_operand")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "TARGET_USE_BT
11659    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11660       == GET_MODE_BITSIZE (<MODE>mode)-1
11661    && can_create_pseudo_p ()"
11662   "#"
11663   "&& 1"
11664   [(parallel
11665      [(set (match_dup 0)
11666            (any_or:SWI48
11667              (ashift:SWI48 (const_int 1)
11668                            (match_dup 1))
11669              (match_dup 3)))
11670       (clobber (reg:CC FLAGS_REG))])]
11671   "operands[1] = gen_lowpart (QImode, operands[1]);")
11673 (define_insn_and_split "*<btsc><mode>_mask_1"
11674   [(set (match_operand:SWI48 0 "register_operand")
11675         (any_or:SWI48
11676           (ashift:SWI48
11677             (const_int 1)
11678             (and:QI
11679               (match_operand:QI 1 "register_operand")
11680               (match_operand:QI 2 "const_int_operand")))
11681           (match_operand:SWI48 3 "register_operand")))
11682    (clobber (reg:CC FLAGS_REG))]
11683   "TARGET_USE_BT
11684    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11685       == GET_MODE_BITSIZE (<MODE>mode)-1
11686    && can_create_pseudo_p ()"
11687   "#"
11688   "&& 1"
11689   [(parallel
11690      [(set (match_dup 0)
11691            (any_or:SWI48
11692              (ashift:SWI48 (const_int 1)
11693                            (match_dup 1))
11694              (match_dup 3)))
11695       (clobber (reg:CC FLAGS_REG))])])
11697 (define_insn "*btr<mode>"
11698   [(set (match_operand:SWI48 0 "register_operand" "=r")
11699         (and:SWI48
11700           (rotate:SWI48 (const_int -2)
11701                         (match_operand:QI 2 "register_operand" "r"))
11702         (match_operand:SWI48 1 "register_operand" "0")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "TARGET_USE_BT"
11705   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11706   [(set_attr "type" "alu1")
11707    (set_attr "prefix_0f" "1")
11708    (set_attr "znver1_decode" "double")
11709    (set_attr "mode" "<MODE>")])
11711 ;; Avoid useless masking of count operand.
11712 (define_insn_and_split "*btr<mode>_mask"
11713   [(set (match_operand:SWI48 0 "register_operand")
11714         (and:SWI48
11715           (rotate:SWI48
11716             (const_int -2)
11717             (subreg:QI
11718               (and:SI
11719                 (match_operand:SI 1 "register_operand")
11720                 (match_operand:SI 2 "const_int_operand")) 0))
11721           (match_operand:SWI48 3 "register_operand")))
11722    (clobber (reg:CC FLAGS_REG))]
11723   "TARGET_USE_BT
11724    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11725       == GET_MODE_BITSIZE (<MODE>mode)-1
11726    && can_create_pseudo_p ()"
11727   "#"
11728   "&& 1"
11729   [(parallel
11730      [(set (match_dup 0)
11731            (and:SWI48
11732              (rotate:SWI48 (const_int -2)
11733                            (match_dup 1))
11734              (match_dup 3)))
11735       (clobber (reg:CC FLAGS_REG))])]
11736   "operands[1] = gen_lowpart (QImode, operands[1]);")
11738 (define_insn_and_split "*btr<mode>_mask_1"
11739   [(set (match_operand:SWI48 0 "register_operand")
11740         (and:SWI48
11741           (rotate:SWI48
11742             (const_int -2)
11743             (and:QI
11744               (match_operand:QI 1 "register_operand")
11745               (match_operand:QI 2 "const_int_operand")))
11746           (match_operand:SWI48 3 "register_operand")))
11747    (clobber (reg:CC FLAGS_REG))]
11748   "TARGET_USE_BT
11749    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11750       == GET_MODE_BITSIZE (<MODE>mode)-1
11751    && can_create_pseudo_p ()"
11752   "#"
11753   "&& 1"
11754   [(parallel
11755      [(set (match_dup 0)
11756            (and:SWI48
11757              (rotate:SWI48 (const_int -2)
11758                            (match_dup 1))
11759              (match_dup 3)))
11760       (clobber (reg:CC FLAGS_REG))])])
11762 ;; These instructions are never faster than the corresponding
11763 ;; and/ior/xor operations when using immediate operand, so with
11764 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11765 ;; relevant immediates within the instruction itself, so operating
11766 ;; on bits in the high 32-bits of a register becomes easier.
11768 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11769 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11770 ;; negdf respectively, so they can never be disabled entirely.
11772 (define_insn "*btsq_imm"
11773   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11774                          (const_int 1)
11775                          (match_operand 1 "const_0_to_63_operand" "J"))
11776         (const_int 1))
11777    (clobber (reg:CC FLAGS_REG))]
11778   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11779   "bts{q}\t{%1, %0|%0, %1}"
11780   [(set_attr "type" "alu1")
11781    (set_attr "prefix_0f" "1")
11782    (set_attr "znver1_decode" "double")
11783    (set_attr "mode" "DI")])
11785 (define_insn "*btrq_imm"
11786   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11787                          (const_int 1)
11788                          (match_operand 1 "const_0_to_63_operand" "J"))
11789         (const_int 0))
11790    (clobber (reg:CC FLAGS_REG))]
11791   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11792   "btr{q}\t{%1, %0|%0, %1}"
11793   [(set_attr "type" "alu1")
11794    (set_attr "prefix_0f" "1")
11795    (set_attr "znver1_decode" "double")
11796    (set_attr "mode" "DI")])
11798 (define_insn "*btcq_imm"
11799   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11800                          (const_int 1)
11801                          (match_operand 1 "const_0_to_63_operand" "J"))
11802         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11803    (clobber (reg:CC FLAGS_REG))]
11804   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11805   "btc{q}\t{%1, %0|%0, %1}"
11806   [(set_attr "type" "alu1")
11807    (set_attr "prefix_0f" "1")
11808    (set_attr "znver1_decode" "double")
11809    (set_attr "mode" "DI")])
11811 ;; Allow Nocona to avoid these instructions if a register is available.
11813 (define_peephole2
11814   [(match_scratch:DI 2 "r")
11815    (parallel [(set (zero_extract:DI
11816                      (match_operand:DI 0 "nonimmediate_operand")
11817                      (const_int 1)
11818                      (match_operand 1 "const_0_to_63_operand"))
11819                    (const_int 1))
11820               (clobber (reg:CC FLAGS_REG))])]
11821   "TARGET_64BIT && !TARGET_USE_BT"
11822   [(parallel [(set (match_dup 0)
11823                    (ior:DI (match_dup 0) (match_dup 3)))
11824               (clobber (reg:CC FLAGS_REG))])]
11826   int i = INTVAL (operands[1]);
11828   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11830   if (!x86_64_immediate_operand (operands[3], DImode))
11831     {
11832       emit_move_insn (operands[2], operands[3]);
11833       operands[3] = operands[2];
11834     }
11837 (define_peephole2
11838   [(match_scratch:DI 2 "r")
11839    (parallel [(set (zero_extract:DI
11840                      (match_operand:DI 0 "nonimmediate_operand")
11841                      (const_int 1)
11842                      (match_operand 1 "const_0_to_63_operand"))
11843                    (const_int 0))
11844               (clobber (reg:CC FLAGS_REG))])]
11845   "TARGET_64BIT && !TARGET_USE_BT"
11846   [(parallel [(set (match_dup 0)
11847                    (and:DI (match_dup 0) (match_dup 3)))
11848               (clobber (reg:CC FLAGS_REG))])]
11850   int i = INTVAL (operands[1]);
11852   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11854   if (!x86_64_immediate_operand (operands[3], DImode))
11855     {
11856       emit_move_insn (operands[2], operands[3]);
11857       operands[3] = operands[2];
11858     }
11861 (define_peephole2
11862   [(match_scratch:DI 2 "r")
11863    (parallel [(set (zero_extract:DI
11864                      (match_operand:DI 0 "nonimmediate_operand")
11865                      (const_int 1)
11866                      (match_operand 1 "const_0_to_63_operand"))
11867               (not:DI (zero_extract:DI
11868                         (match_dup 0) (const_int 1) (match_dup 1))))
11869               (clobber (reg:CC FLAGS_REG))])]
11870   "TARGET_64BIT && !TARGET_USE_BT"
11871   [(parallel [(set (match_dup 0)
11872                    (xor:DI (match_dup 0) (match_dup 3)))
11873               (clobber (reg:CC FLAGS_REG))])]
11875   int i = INTVAL (operands[1]);
11877   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11879   if (!x86_64_immediate_operand (operands[3], DImode))
11880     {
11881       emit_move_insn (operands[2], operands[3]);
11882       operands[3] = operands[2];
11883     }
11886 ;; %%% bt
11888 (define_insn "*bt<mode>"
11889   [(set (reg:CCC FLAGS_REG)
11890         (compare:CCC
11891           (zero_extract:SWI48
11892             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11893             (const_int 1)
11894             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11895           (const_int 0)))]
11896   ""
11898   switch (get_attr_mode (insn))
11899     {
11900     case MODE_SI:
11901       return "bt{l}\t{%1, %k0|%k0, %1}";
11903     case MODE_DI:
11904       return "bt{q}\t{%q1, %0|%0, %q1}";
11906     default:
11907       gcc_unreachable ();
11908     }
11910   [(set_attr "type" "alu1")
11911    (set_attr "prefix_0f" "1")
11912    (set (attr "mode")
11913         (if_then_else
11914           (and (match_test "CONST_INT_P (operands[1])")
11915                (match_test "INTVAL (operands[1]) < 32"))
11916           (const_string "SI")
11917           (const_string "<MODE>")))])
11919 (define_insn_and_split "*jcc_bt<mode>"
11920   [(set (pc)
11921         (if_then_else (match_operator 0 "bt_comparison_operator"
11922                         [(zero_extract:SWI48
11923                            (match_operand:SWI48 1 "nonimmediate_operand")
11924                            (const_int 1)
11925                            (match_operand:SI 2 "nonmemory_operand"))
11926                          (const_int 0)])
11927                       (label_ref (match_operand 3))
11928                       (pc)))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11931    && (CONST_INT_P (operands[2])
11932        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11933           && INTVAL (operands[2])
11934                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11935        : !memory_operand (operands[1], <MODE>mode))
11936    && can_create_pseudo_p ()"
11937   "#"
11938   "&& 1"
11939   [(set (reg:CCC FLAGS_REG)
11940         (compare:CCC
11941           (zero_extract:SWI48
11942             (match_dup 1)
11943             (const_int 1)
11944             (match_dup 2))
11945           (const_int 0)))
11946    (set (pc)
11947         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11948                       (label_ref (match_dup 3))
11949                       (pc)))]
11951   operands[0] = shallow_copy_rtx (operands[0]);
11952   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11955 (define_insn_and_split "*jcc_bt<mode>_1"
11956   [(set (pc)
11957         (if_then_else (match_operator 0 "bt_comparison_operator"
11958                         [(zero_extract:SWI48
11959                            (match_operand:SWI48 1 "register_operand")
11960                            (const_int 1)
11961                            (zero_extend:SI
11962                              (match_operand:QI 2 "register_operand")))
11963                          (const_int 0)])
11964                       (label_ref (match_operand 3))
11965                       (pc)))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11968    && can_create_pseudo_p ()"
11969   "#"
11970   "&& 1"
11971   [(set (reg:CCC FLAGS_REG)
11972         (compare:CCC
11973           (zero_extract:SWI48
11974             (match_dup 1)
11975             (const_int 1)
11976             (match_dup 2))
11977           (const_int 0)))
11978    (set (pc)
11979         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11980                       (label_ref (match_dup 3))
11981                       (pc)))]
11983   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11984   operands[0] = shallow_copy_rtx (operands[0]);
11985   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11988 ;; Avoid useless masking of bit offset operand.
11989 (define_insn_and_split "*jcc_bt<mode>_mask"
11990   [(set (pc)
11991         (if_then_else (match_operator 0 "bt_comparison_operator"
11992                         [(zero_extract:SWI48
11993                            (match_operand:SWI48 1 "register_operand")
11994                            (const_int 1)
11995                            (and:SI
11996                              (match_operand:SI 2 "register_operand")
11997                              (match_operand 3 "const_int_operand")))])
11998                       (label_ref (match_operand 4))
11999                       (pc)))
12000    (clobber (reg:CC FLAGS_REG))]
12001   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12002    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12003       == GET_MODE_BITSIZE (<MODE>mode)-1
12004    && can_create_pseudo_p ()"
12005   "#"
12006   "&& 1"
12007   [(set (reg:CCC FLAGS_REG)
12008         (compare:CCC
12009           (zero_extract:SWI48
12010             (match_dup 1)
12011             (const_int 1)
12012             (match_dup 2))
12013           (const_int 0)))
12014    (set (pc)
12015         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12016                       (label_ref (match_dup 4))
12017                       (pc)))]
12019   operands[0] = shallow_copy_rtx (operands[0]);
12020   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12023 ;; Store-flag instructions.
12025 ;; For all sCOND expanders, also expand the compare or test insn that
12026 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12028 (define_insn_and_split "*setcc_di_1"
12029   [(set (match_operand:DI 0 "register_operand" "=q")
12030         (match_operator:DI 1 "ix86_comparison_operator"
12031           [(reg FLAGS_REG) (const_int 0)]))]
12032   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12033   "#"
12034   "&& reload_completed"
12035   [(set (match_dup 2) (match_dup 1))
12036    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12038   operands[1] = shallow_copy_rtx (operands[1]);
12039   PUT_MODE (operands[1], QImode);
12040   operands[2] = gen_lowpart (QImode, operands[0]);
12043 (define_insn_and_split "*setcc_si_1_and"
12044   [(set (match_operand:SI 0 "register_operand" "=q")
12045         (match_operator:SI 1 "ix86_comparison_operator"
12046           [(reg FLAGS_REG) (const_int 0)]))
12047    (clobber (reg:CC FLAGS_REG))]
12048   "!TARGET_PARTIAL_REG_STALL
12049    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12050   "#"
12051   "&& reload_completed"
12052   [(set (match_dup 2) (match_dup 1))
12053    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12054               (clobber (reg:CC FLAGS_REG))])]
12056   operands[1] = shallow_copy_rtx (operands[1]);
12057   PUT_MODE (operands[1], QImode);
12058   operands[2] = gen_lowpart (QImode, operands[0]);
12061 (define_insn_and_split "*setcc_si_1_movzbl"
12062   [(set (match_operand:SI 0 "register_operand" "=q")
12063         (match_operator:SI 1 "ix86_comparison_operator"
12064           [(reg FLAGS_REG) (const_int 0)]))]
12065   "!TARGET_PARTIAL_REG_STALL
12066    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12067   "#"
12068   "&& reload_completed"
12069   [(set (match_dup 2) (match_dup 1))
12070    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12072   operands[1] = shallow_copy_rtx (operands[1]);
12073   PUT_MODE (operands[1], QImode);
12074   operands[2] = gen_lowpart (QImode, operands[0]);
12077 (define_insn "*setcc_qi"
12078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12079         (match_operator:QI 1 "ix86_comparison_operator"
12080           [(reg FLAGS_REG) (const_int 0)]))]
12081   ""
12082   "set%C1\t%0"
12083   [(set_attr "type" "setcc")
12084    (set_attr "mode" "QI")])
12086 (define_insn "*setcc_qi_slp"
12087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12088         (match_operator:QI 1 "ix86_comparison_operator"
12089           [(reg FLAGS_REG) (const_int 0)]))]
12090   ""
12091   "set%C1\t%0"
12092   [(set_attr "type" "setcc")
12093    (set_attr "mode" "QI")])
12095 ;; In general it is not safe to assume too much about CCmode registers,
12096 ;; so simplify-rtx stops when it sees a second one.  Under certain
12097 ;; conditions this is safe on x86, so help combine not create
12099 ;;      seta    %al
12100 ;;      testb   %al, %al
12101 ;;      sete    %al
12103 (define_split
12104   [(set (match_operand:QI 0 "nonimmediate_operand")
12105         (ne:QI (match_operator 1 "ix86_comparison_operator"
12106                  [(reg FLAGS_REG) (const_int 0)])
12107             (const_int 0)))]
12108   ""
12109   [(set (match_dup 0) (match_dup 1))]
12111   operands[1] = shallow_copy_rtx (operands[1]);
12112   PUT_MODE (operands[1], QImode);
12115 (define_split
12116   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12117         (ne:QI (match_operator 1 "ix86_comparison_operator"
12118                  [(reg FLAGS_REG) (const_int 0)])
12119             (const_int 0)))]
12120   ""
12121   [(set (match_dup 0) (match_dup 1))]
12123   operands[1] = shallow_copy_rtx (operands[1]);
12124   PUT_MODE (operands[1], QImode);
12127 (define_split
12128   [(set (match_operand:QI 0 "nonimmediate_operand")
12129         (eq:QI (match_operator 1 "ix86_comparison_operator"
12130                  [(reg FLAGS_REG) (const_int 0)])
12131             (const_int 0)))]
12132   ""
12133   [(set (match_dup 0) (match_dup 1))]
12135   operands[1] = shallow_copy_rtx (operands[1]);
12136   PUT_MODE (operands[1], QImode);
12137   PUT_CODE (operands[1],
12138             ix86_reverse_condition (GET_CODE (operands[1]),
12139                                     GET_MODE (XEXP (operands[1], 0))));
12141   /* Make sure that (a) the CCmode we have for the flags is strong
12142      enough for the reversed compare or (b) we have a valid FP compare.  */
12143   if (! ix86_comparison_operator (operands[1], VOIDmode))
12144     FAIL;
12147 (define_split
12148   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12149         (eq:QI (match_operator 1 "ix86_comparison_operator"
12150                  [(reg FLAGS_REG) (const_int 0)])
12151             (const_int 0)))]
12152   ""
12153   [(set (match_dup 0) (match_dup 1))]
12155   operands[1] = shallow_copy_rtx (operands[1]);
12156   PUT_MODE (operands[1], QImode);
12157   PUT_CODE (operands[1],
12158             ix86_reverse_condition (GET_CODE (operands[1]),
12159                                     GET_MODE (XEXP (operands[1], 0))));
12161   /* Make sure that (a) the CCmode we have for the flags is strong
12162      enough for the reversed compare or (b) we have a valid FP compare.  */
12163   if (! ix86_comparison_operator (operands[1], VOIDmode))
12164     FAIL;
12167 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12168 ;; subsequent logical operations are used to imitate conditional moves.
12169 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12170 ;; it directly.
12172 (define_insn "setcc_<mode>_sse"
12173   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12174         (match_operator:MODEF 3 "sse_comparison_operator"
12175           [(match_operand:MODEF 1 "register_operand" "0,x")
12176            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12177   "SSE_FLOAT_MODE_P (<MODE>mode)"
12178   "@
12179    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12180    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12181   [(set_attr "isa" "noavx,avx")
12182    (set_attr "type" "ssecmp")
12183    (set_attr "length_immediate" "1")
12184    (set_attr "prefix" "orig,vex")
12185    (set_attr "mode" "<MODE>")])
12187 ;; Basic conditional jump instructions.
12188 ;; We ignore the overflow flag for signed branch instructions.
12190 (define_insn "*jcc"
12191   [(set (pc)
12192         (if_then_else (match_operator 1 "ix86_comparison_operator"
12193                                       [(reg FLAGS_REG) (const_int 0)])
12194                       (label_ref (match_operand 0))
12195                       (pc)))]
12196   ""
12197   "%!%+j%C1\t%l0"
12198   [(set_attr "type" "ibr")
12199    (set_attr "modrm" "0")
12200    (set (attr "length")
12201         (if_then_else
12202           (and (ge (minus (match_dup 0) (pc))
12203                    (const_int -126))
12204                (lt (minus (match_dup 0) (pc))
12205                    (const_int 128)))
12206           (const_int 2)
12207           (const_int 6)))
12208    (set_attr "maybe_prefix_bnd" "1")])
12210 ;; In general it is not safe to assume too much about CCmode registers,
12211 ;; so simplify-rtx stops when it sees a second one.  Under certain
12212 ;; conditions this is safe on x86, so help combine not create
12214 ;;      seta    %al
12215 ;;      testb   %al, %al
12216 ;;      je      Lfoo
12218 (define_split
12219   [(set (pc)
12220         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12221                                       [(reg FLAGS_REG) (const_int 0)])
12222                           (const_int 0))
12223                       (label_ref (match_operand 1))
12224                       (pc)))]
12225   ""
12226   [(set (pc)
12227         (if_then_else (match_dup 0)
12228                       (label_ref (match_dup 1))
12229                       (pc)))]
12231   operands[0] = shallow_copy_rtx (operands[0]);
12232   PUT_MODE (operands[0], VOIDmode);
12235 (define_split
12236   [(set (pc)
12237         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12238                                       [(reg FLAGS_REG) (const_int 0)])
12239                           (const_int 0))
12240                       (label_ref (match_operand 1))
12241                       (pc)))]
12242   ""
12243   [(set (pc)
12244         (if_then_else (match_dup 0)
12245                       (label_ref (match_dup 1))
12246                       (pc)))]
12248   operands[0] = shallow_copy_rtx (operands[0]);
12249   PUT_MODE (operands[0], VOIDmode);
12250   PUT_CODE (operands[0],
12251             ix86_reverse_condition (GET_CODE (operands[0]),
12252                                     GET_MODE (XEXP (operands[0], 0))));
12254   /* Make sure that (a) the CCmode we have for the flags is strong
12255      enough for the reversed compare or (b) we have a valid FP compare.  */
12256   if (! ix86_comparison_operator (operands[0], VOIDmode))
12257     FAIL;
12260 ;; Unconditional and other jump instructions
12262 (define_insn "jump"
12263   [(set (pc)
12264         (label_ref (match_operand 0)))]
12265   ""
12266   "%!jmp\t%l0"
12267   [(set_attr "type" "ibr")
12268    (set_attr "modrm" "0")
12269    (set (attr "length")
12270         (if_then_else
12271           (and (ge (minus (match_dup 0) (pc))
12272                    (const_int -126))
12273                (lt (minus (match_dup 0) (pc))
12274                    (const_int 128)))
12275           (const_int 2)
12276           (const_int 5)))
12277    (set_attr "maybe_prefix_bnd" "1")])
12279 (define_expand "indirect_jump"
12280   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12281   ""
12283   if (TARGET_X32)
12284     operands[0] = convert_memory_address (word_mode, operands[0]);
12287 (define_insn "*indirect_jump"
12288   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12289   ""
12290   "%!jmp\t%A0"
12291   [(set_attr "type" "ibr")
12292    (set_attr "length_immediate" "0")
12293    (set_attr "maybe_prefix_bnd" "1")])
12295 (define_expand "tablejump"
12296   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12297               (use (label_ref (match_operand 1)))])]
12298   ""
12300   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12301      relative.  Convert the relative address to an absolute address.  */
12302   if (flag_pic)
12303     {
12304       rtx op0, op1;
12305       enum rtx_code code;
12307       /* We can't use @GOTOFF for text labels on VxWorks;
12308          see gotoff_operand.  */
12309       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12310         {
12311           code = PLUS;
12312           op0 = operands[0];
12313           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12314         }
12315       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12316         {
12317           code = PLUS;
12318           op0 = operands[0];
12319           op1 = pic_offset_table_rtx;
12320         }
12321       else
12322         {
12323           code = MINUS;
12324           op0 = pic_offset_table_rtx;
12325           op1 = operands[0];
12326         }
12328       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12329                                          OPTAB_DIRECT);
12330     }
12332   if (TARGET_X32)
12333     operands[0] = convert_memory_address (word_mode, operands[0]);
12336 (define_insn "*tablejump_1"
12337   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12338    (use (label_ref (match_operand 1)))]
12339   ""
12340   "%!jmp\t%A0"
12341   [(set_attr "type" "ibr")
12342    (set_attr "length_immediate" "0")
12343    (set_attr "maybe_prefix_bnd" "1")])
12345 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12347 (define_peephole2
12348   [(set (reg FLAGS_REG) (match_operand 0))
12349    (set (match_operand:QI 1 "register_operand")
12350         (match_operator:QI 2 "ix86_comparison_operator"
12351           [(reg FLAGS_REG) (const_int 0)]))
12352    (set (match_operand 3 "any_QIreg_operand")
12353         (zero_extend (match_dup 1)))]
12354   "(peep2_reg_dead_p (3, operands[1])
12355     || operands_match_p (operands[1], operands[3]))
12356    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12357    && peep2_regno_dead_p (0, FLAGS_REG)"
12358   [(set (match_dup 4) (match_dup 0))
12359    (set (strict_low_part (match_dup 5))
12360         (match_dup 2))]
12362   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12363   operands[5] = gen_lowpart (QImode, operands[3]);
12364   ix86_expand_clear (operands[3]);
12367 (define_peephole2
12368   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12369               (match_operand 4)])
12370    (set (match_operand:QI 1 "register_operand")
12371         (match_operator:QI 2 "ix86_comparison_operator"
12372           [(reg FLAGS_REG) (const_int 0)]))
12373    (set (match_operand 3 "any_QIreg_operand")
12374         (zero_extend (match_dup 1)))]
12375   "(peep2_reg_dead_p (3, operands[1])
12376     || operands_match_p (operands[1], operands[3]))
12377    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12378    && ! reg_set_p (operands[3], operands[4])
12379    && peep2_regno_dead_p (0, FLAGS_REG)"
12380   [(parallel [(set (match_dup 5) (match_dup 0))
12381               (match_dup 4)])
12382    (set (strict_low_part (match_dup 6))
12383         (match_dup 2))]
12385   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12386   operands[6] = gen_lowpart (QImode, operands[3]);
12387   ix86_expand_clear (operands[3]);
12390 (define_peephole2
12391   [(set (reg FLAGS_REG) (match_operand 0))
12392    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12393               (match_operand 5)])
12394    (set (match_operand:QI 2 "register_operand")
12395         (match_operator:QI 3 "ix86_comparison_operator"
12396           [(reg FLAGS_REG) (const_int 0)]))
12397    (set (match_operand 4 "any_QIreg_operand")
12398         (zero_extend (match_dup 2)))]
12399   "(peep2_reg_dead_p (4, operands[2])
12400     || operands_match_p (operands[2], operands[4]))
12401    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12402    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12403    && ! reg_set_p (operands[4], operands[5])
12404    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12405    && peep2_regno_dead_p (0, FLAGS_REG)"
12406   [(set (match_dup 6) (match_dup 0))
12407    (parallel [(set (match_dup 7) (match_dup 1))
12408               (match_dup 5)])
12409    (set (strict_low_part (match_dup 8))
12410         (match_dup 3))]
12412   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12413   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12414   operands[8] = gen_lowpart (QImode, operands[4]);
12415   ix86_expand_clear (operands[4]);
12418 ;; Similar, but match zero extend with andsi3.
12420 (define_peephole2
12421   [(set (reg FLAGS_REG) (match_operand 0))
12422    (set (match_operand:QI 1 "register_operand")
12423         (match_operator:QI 2 "ix86_comparison_operator"
12424           [(reg FLAGS_REG) (const_int 0)]))
12425    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12426                    (and:SI (match_dup 3) (const_int 255)))
12427               (clobber (reg:CC FLAGS_REG))])]
12428   "REGNO (operands[1]) == REGNO (operands[3])
12429    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12430    && peep2_regno_dead_p (0, FLAGS_REG)"
12431   [(set (match_dup 4) (match_dup 0))
12432    (set (strict_low_part (match_dup 5))
12433         (match_dup 2))]
12435   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12436   operands[5] = gen_lowpart (QImode, operands[3]);
12437   ix86_expand_clear (operands[3]);
12440 (define_peephole2
12441   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12442               (match_operand 4)])
12443    (set (match_operand:QI 1 "register_operand")
12444         (match_operator:QI 2 "ix86_comparison_operator"
12445           [(reg FLAGS_REG) (const_int 0)]))
12446    (parallel [(set (match_operand 3 "any_QIreg_operand")
12447                    (zero_extend (match_dup 1)))
12448               (clobber (reg:CC FLAGS_REG))])]
12449   "(peep2_reg_dead_p (3, operands[1])
12450     || operands_match_p (operands[1], operands[3]))
12451    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12452    && ! reg_set_p (operands[3], operands[4])
12453    && peep2_regno_dead_p (0, FLAGS_REG)"
12454   [(parallel [(set (match_dup 5) (match_dup 0))
12455               (match_dup 4)])
12456    (set (strict_low_part (match_dup 6))
12457         (match_dup 2))]
12459   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12460   operands[6] = gen_lowpart (QImode, operands[3]);
12461   ix86_expand_clear (operands[3]);
12464 (define_peephole2
12465   [(set (reg FLAGS_REG) (match_operand 0))
12466    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12467               (match_operand 5)])
12468    (set (match_operand:QI 2 "register_operand")
12469         (match_operator:QI 3 "ix86_comparison_operator"
12470           [(reg FLAGS_REG) (const_int 0)]))
12471    (parallel [(set (match_operand 4 "any_QIreg_operand")
12472                    (zero_extend (match_dup 2)))
12473               (clobber (reg:CC FLAGS_REG))])]
12474   "(peep2_reg_dead_p (4, operands[2])
12475     || operands_match_p (operands[2], operands[4]))
12476    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12477    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12478    && ! reg_set_p (operands[4], operands[5])
12479    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12480    && peep2_regno_dead_p (0, FLAGS_REG)"
12481   [(set (match_dup 6) (match_dup 0))
12482    (parallel [(set (match_dup 7) (match_dup 1))
12483               (match_dup 5)])
12484    (set (strict_low_part (match_dup 8))
12485         (match_dup 3))]
12487   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12488   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12489   operands[8] = gen_lowpart (QImode, operands[4]);
12490   ix86_expand_clear (operands[4]);
12493 ;; Call instructions.
12495 ;; The predicates normally associated with named expanders are not properly
12496 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12497 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12499 ;; P6 processors will jump to the address after the decrement when %esp
12500 ;; is used as a call operand, so they will execute return address as a code.
12501 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12503 ;; Register constraint for call instruction.
12504 (define_mode_attr c [(SI "l") (DI "r")])
12506 ;; Call subroutine returning no value.
12508 (define_expand "call"
12509   [(call (match_operand:QI 0)
12510          (match_operand 1))
12511    (use (match_operand 2))]
12512   ""
12514   ix86_expand_call (NULL, operands[0], operands[1],
12515                     operands[2], NULL, false);
12516   DONE;
12519 (define_expand "sibcall"
12520   [(call (match_operand:QI 0)
12521          (match_operand 1))
12522    (use (match_operand 2))]
12523   ""
12525   ix86_expand_call (NULL, operands[0], operands[1],
12526                     operands[2], NULL, true);
12527   DONE;
12530 (define_insn "*call"
12531   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12532          (match_operand 1))]
12533   "!SIBLING_CALL_P (insn)"
12534   "* return ix86_output_call_insn (insn, operands[0]);"
12535   [(set_attr "type" "call")])
12537 ;; This covers both call and sibcall since only GOT slot is allowed.
12538 (define_insn "*call_got_x32"
12539   [(call (mem:QI (zero_extend:DI
12540                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12541          (match_operand 1))]
12542   "TARGET_X32"
12544   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12545   return ix86_output_call_insn (insn, fnaddr);
12547   [(set_attr "type" "call")])
12549 ;; Since sibcall never returns, we can only use call-clobbered register
12550 ;; as GOT base.
12551 (define_insn "*sibcall_GOT_32"
12552   [(call (mem:QI
12553            (mem:SI (plus:SI
12554                      (match_operand:SI 0 "register_no_elim_operand" "U")
12555                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12556          (match_operand 2))]
12557   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12559   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12560   fnaddr = gen_const_mem (SImode, fnaddr);
12561   return ix86_output_call_insn (insn, fnaddr);
12563   [(set_attr "type" "call")])
12565 (define_insn "*sibcall"
12566   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12567          (match_operand 1))]
12568   "SIBLING_CALL_P (insn)"
12569   "* return ix86_output_call_insn (insn, operands[0]);"
12570   [(set_attr "type" "call")])
12572 (define_insn "*sibcall_memory"
12573   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12574          (match_operand 1))
12575    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12576   "!TARGET_X32"
12577   "* return ix86_output_call_insn (insn, operands[0]);"
12578   [(set_attr "type" "call")])
12580 (define_peephole2
12581   [(set (match_operand:W 0 "register_operand")
12582         (match_operand:W 1 "memory_operand"))
12583    (call (mem:QI (match_dup 0))
12584          (match_operand 3))]
12585   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12586    && !reg_mentioned_p (operands[0],
12587                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12588   [(parallel [(call (mem:QI (match_dup 1))
12589                     (match_dup 3))
12590               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12592 (define_peephole2
12593   [(set (match_operand:W 0 "register_operand")
12594         (match_operand:W 1 "memory_operand"))
12595    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12596    (call (mem:QI (match_dup 0))
12597          (match_operand 3))]
12598   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12599    && !reg_mentioned_p (operands[0],
12600                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12601   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12602    (parallel [(call (mem:QI (match_dup 1))
12603                     (match_dup 3))
12604               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12606 (define_expand "call_pop"
12607   [(parallel [(call (match_operand:QI 0)
12608                     (match_operand:SI 1))
12609               (set (reg:SI SP_REG)
12610                    (plus:SI (reg:SI SP_REG)
12611                             (match_operand:SI 3)))])]
12612   "!TARGET_64BIT"
12614   ix86_expand_call (NULL, operands[0], operands[1],
12615                     operands[2], operands[3], false);
12616   DONE;
12619 (define_insn "*call_pop"
12620   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12621          (match_operand 1))
12622    (set (reg:SI SP_REG)
12623         (plus:SI (reg:SI SP_REG)
12624                  (match_operand:SI 2 "immediate_operand" "i")))]
12625   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12626   "* return ix86_output_call_insn (insn, operands[0]);"
12627   [(set_attr "type" "call")])
12629 (define_insn "*sibcall_pop"
12630   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12631          (match_operand 1))
12632    (set (reg:SI SP_REG)
12633         (plus:SI (reg:SI SP_REG)
12634                  (match_operand:SI 2 "immediate_operand" "i")))]
12635   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12636   "* return ix86_output_call_insn (insn, operands[0]);"
12637   [(set_attr "type" "call")])
12639 (define_insn "*sibcall_pop_memory"
12640   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12641          (match_operand 1))
12642    (set (reg:SI SP_REG)
12643         (plus:SI (reg:SI SP_REG)
12644                  (match_operand:SI 2 "immediate_operand" "i")))
12645    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12646   "!TARGET_64BIT"
12647   "* return ix86_output_call_insn (insn, operands[0]);"
12648   [(set_attr "type" "call")])
12650 (define_peephole2
12651   [(set (match_operand:SI 0 "register_operand")
12652         (match_operand:SI 1 "memory_operand"))
12653    (parallel [(call (mem:QI (match_dup 0))
12654                     (match_operand 3))
12655               (set (reg:SI SP_REG)
12656                    (plus:SI (reg:SI SP_REG)
12657                             (match_operand:SI 4 "immediate_operand")))])]
12658   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12659    && !reg_mentioned_p (operands[0],
12660                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12661   [(parallel [(call (mem:QI (match_dup 1))
12662                     (match_dup 3))
12663               (set (reg:SI SP_REG)
12664                    (plus:SI (reg:SI SP_REG)
12665                             (match_dup 4)))
12666               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12668 (define_peephole2
12669   [(set (match_operand:SI 0 "register_operand")
12670         (match_operand:SI 1 "memory_operand"))
12671    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12672    (parallel [(call (mem:QI (match_dup 0))
12673                     (match_operand 3))
12674               (set (reg:SI SP_REG)
12675                    (plus:SI (reg:SI SP_REG)
12676                             (match_operand:SI 4 "immediate_operand")))])]
12677   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12678    && !reg_mentioned_p (operands[0],
12679                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12680   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12681    (parallel [(call (mem:QI (match_dup 1))
12682                     (match_dup 3))
12683               (set (reg:SI SP_REG)
12684                    (plus:SI (reg:SI SP_REG)
12685                             (match_dup 4)))
12686               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12688 ;; Combining simple memory jump instruction
12690 (define_peephole2
12691   [(set (match_operand:W 0 "register_operand")
12692         (match_operand:W 1 "memory_operand"))
12693    (set (pc) (match_dup 0))]
12694   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12695   [(set (pc) (match_dup 1))])
12697 ;; Call subroutine, returning value in operand 0
12699 (define_expand "call_value"
12700   [(set (match_operand 0)
12701         (call (match_operand:QI 1)
12702               (match_operand 2)))
12703    (use (match_operand 3))]
12704   ""
12706   ix86_expand_call (operands[0], operands[1], operands[2],
12707                     operands[3], NULL, false);
12708   DONE;
12711 (define_expand "sibcall_value"
12712   [(set (match_operand 0)
12713         (call (match_operand:QI 1)
12714               (match_operand 2)))
12715    (use (match_operand 3))]
12716   ""
12718   ix86_expand_call (operands[0], operands[1], operands[2],
12719                     operands[3], NULL, true);
12720   DONE;
12723 (define_insn "*call_value"
12724   [(set (match_operand 0)
12725         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12726               (match_operand 2)))]
12727   "!SIBLING_CALL_P (insn)"
12728   "* return ix86_output_call_insn (insn, operands[1]);"
12729   [(set_attr "type" "callv")])
12731 ;; This covers both call and sibcall since only GOT slot is allowed.
12732 (define_insn "*call_value_got_x32"
12733   [(set (match_operand 0)
12734         (call (mem:QI
12735                 (zero_extend:DI
12736                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12737               (match_operand 2)))]
12738   "TARGET_X32"
12740   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12741   return ix86_output_call_insn (insn, fnaddr);
12743   [(set_attr "type" "callv")])
12745 ;; Since sibcall never returns, we can only use call-clobbered register
12746 ;; as GOT base.
12747 (define_insn "*sibcall_value_GOT_32"
12748   [(set (match_operand 0)
12749         (call (mem:QI
12750                 (mem:SI (plus:SI
12751                           (match_operand:SI 1 "register_no_elim_operand" "U")
12752                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12753          (match_operand 3)))]
12754   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12756   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12757   fnaddr = gen_const_mem (SImode, fnaddr);
12758   return ix86_output_call_insn (insn, fnaddr);
12760   [(set_attr "type" "callv")])
12762 (define_insn "*sibcall_value"
12763   [(set (match_operand 0)
12764         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12765               (match_operand 2)))]
12766   "SIBLING_CALL_P (insn)"
12767   "* return ix86_output_call_insn (insn, operands[1]);"
12768   [(set_attr "type" "callv")])
12770 (define_insn "*sibcall_value_memory"
12771   [(set (match_operand 0)
12772         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12773               (match_operand 2)))
12774    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12775   "!TARGET_X32"
12776   "* return ix86_output_call_insn (insn, operands[1]);"
12777   [(set_attr "type" "callv")])
12779 (define_peephole2
12780   [(set (match_operand:W 0 "register_operand")
12781         (match_operand:W 1 "memory_operand"))
12782    (set (match_operand 2)
12783    (call (mem:QI (match_dup 0))
12784                  (match_operand 3)))]
12785   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12786    && !reg_mentioned_p (operands[0],
12787                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12788   [(parallel [(set (match_dup 2)
12789                    (call (mem:QI (match_dup 1))
12790                          (match_dup 3)))
12791               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12793 (define_peephole2
12794   [(set (match_operand:W 0 "register_operand")
12795         (match_operand:W 1 "memory_operand"))
12796    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12797    (set (match_operand 2)
12798         (call (mem:QI (match_dup 0))
12799               (match_operand 3)))]
12800   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12801    && !reg_mentioned_p (operands[0],
12802                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12803   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12804    (parallel [(set (match_dup 2)
12805                    (call (mem:QI (match_dup 1))
12806                          (match_dup 3)))
12807               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12809 (define_expand "call_value_pop"
12810   [(parallel [(set (match_operand 0)
12811                    (call (match_operand:QI 1)
12812                          (match_operand:SI 2)))
12813               (set (reg:SI SP_REG)
12814                    (plus:SI (reg:SI SP_REG)
12815                             (match_operand:SI 4)))])]
12816   "!TARGET_64BIT"
12818   ix86_expand_call (operands[0], operands[1], operands[2],
12819                     operands[3], operands[4], false);
12820   DONE;
12823 (define_insn "*call_value_pop"
12824   [(set (match_operand 0)
12825         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12826               (match_operand 2)))
12827    (set (reg:SI SP_REG)
12828         (plus:SI (reg:SI SP_REG)
12829                  (match_operand:SI 3 "immediate_operand" "i")))]
12830   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12831   "* return ix86_output_call_insn (insn, operands[1]);"
12832   [(set_attr "type" "callv")])
12834 (define_insn "*sibcall_value_pop"
12835   [(set (match_operand 0)
12836         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12837               (match_operand 2)))
12838    (set (reg:SI SP_REG)
12839         (plus:SI (reg:SI SP_REG)
12840                  (match_operand:SI 3 "immediate_operand" "i")))]
12841   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12842   "* return ix86_output_call_insn (insn, operands[1]);"
12843   [(set_attr "type" "callv")])
12845 (define_insn "*sibcall_value_pop_memory"
12846   [(set (match_operand 0)
12847         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12848               (match_operand 2)))
12849    (set (reg:SI SP_REG)
12850         (plus:SI (reg:SI SP_REG)
12851                  (match_operand:SI 3 "immediate_operand" "i")))
12852    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12853   "!TARGET_64BIT"
12854   "* return ix86_output_call_insn (insn, operands[1]);"
12855   [(set_attr "type" "callv")])
12857 (define_peephole2
12858   [(set (match_operand:SI 0 "register_operand")
12859         (match_operand:SI 1 "memory_operand"))
12860    (parallel [(set (match_operand 2)
12861                    (call (mem:QI (match_dup 0))
12862                          (match_operand 3)))
12863               (set (reg:SI SP_REG)
12864                    (plus:SI (reg:SI SP_REG)
12865                             (match_operand:SI 4 "immediate_operand")))])]
12866   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12867    && !reg_mentioned_p (operands[0],
12868                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12869   [(parallel [(set (match_dup 2)
12870                    (call (mem:QI (match_dup 1))
12871                          (match_dup 3)))
12872               (set (reg:SI SP_REG)
12873                    (plus:SI (reg:SI SP_REG)
12874                             (match_dup 4)))
12875               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12877 (define_peephole2
12878   [(set (match_operand:SI 0 "register_operand")
12879         (match_operand:SI 1 "memory_operand"))
12880    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12881    (parallel [(set (match_operand 2)
12882                    (call (mem:QI (match_dup 0))
12883                          (match_operand 3)))
12884               (set (reg:SI SP_REG)
12885                    (plus:SI (reg:SI SP_REG)
12886                             (match_operand:SI 4 "immediate_operand")))])]
12887   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12888    && !reg_mentioned_p (operands[0],
12889                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12890   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12891    (parallel [(set (match_dup 2)
12892                    (call (mem:QI (match_dup 1))
12893                          (match_dup 3)))
12894               (set (reg:SI SP_REG)
12895                    (plus:SI (reg:SI SP_REG)
12896                             (match_dup 4)))
12897               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12899 ;; Call subroutine returning any type.
12901 (define_expand "untyped_call"
12902   [(parallel [(call (match_operand 0)
12903                     (const_int 0))
12904               (match_operand 1)
12905               (match_operand 2)])]
12906   ""
12908   int i;
12910   /* In order to give reg-stack an easier job in validating two
12911      coprocessor registers as containing a possible return value,
12912      simply pretend the untyped call returns a complex long double
12913      value. 
12915      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12916      and should have the default ABI.  */
12918   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12919                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12920                     operands[0], const0_rtx,
12921                     GEN_INT ((TARGET_64BIT
12922                               ? (ix86_abi == SYSV_ABI
12923                                  ? X86_64_SSE_REGPARM_MAX
12924                                  : X86_64_MS_SSE_REGPARM_MAX)
12925                               : X86_32_SSE_REGPARM_MAX)
12926                              - 1),
12927                     NULL, false);
12929   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12930     {
12931       rtx set = XVECEXP (operands[2], 0, i);
12932       emit_move_insn (SET_DEST (set), SET_SRC (set));
12933     }
12935   /* The optimizer does not know that the call sets the function value
12936      registers we stored in the result block.  We avoid problems by
12937      claiming that all hard registers are used and clobbered at this
12938      point.  */
12939   emit_insn (gen_blockage ());
12941   DONE;
12944 ;; Prologue and epilogue instructions
12946 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12947 ;; all of memory.  This blocks insns from being moved across this point.
12949 (define_insn "blockage"
12950   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12951   ""
12952   ""
12953   [(set_attr "length" "0")])
12955 ;; Do not schedule instructions accessing memory across this point.
12957 (define_expand "memory_blockage"
12958   [(set (match_dup 0)
12959         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12960   ""
12962   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12963   MEM_VOLATILE_P (operands[0]) = 1;
12966 (define_insn "*memory_blockage"
12967   [(set (match_operand:BLK 0)
12968         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12969   ""
12970   ""
12971   [(set_attr "length" "0")])
12973 ;; As USE insns aren't meaningful after reload, this is used instead
12974 ;; to prevent deleting instructions setting registers for PIC code
12975 (define_insn "prologue_use"
12976   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12977   ""
12978   ""
12979   [(set_attr "length" "0")])
12981 ;; Insn emitted into the body of a function to return from a function.
12982 ;; This is only done if the function's epilogue is known to be simple.
12983 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12985 (define_expand "return"
12986   [(simple_return)]
12987   "ix86_can_use_return_insn_p ()"
12989   if (crtl->args.pops_args)
12990     {
12991       rtx popc = GEN_INT (crtl->args.pops_args);
12992       emit_jump_insn (gen_simple_return_pop_internal (popc));
12993       DONE;
12994     }
12997 ;; We need to disable this for TARGET_SEH, as otherwise
12998 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12999 ;; the maximum size of prologue in unwind information.
13000 ;; Also disallow shrink-wrapping if using stack slot to pass the
13001 ;; static chain pointer - the first instruction has to be pushl %esi
13002 ;; and it can't be moved around, as we use alternate entry points
13003 ;; in that case.
13005 (define_expand "simple_return"
13006   [(simple_return)]
13007   "!TARGET_SEH && !ix86_static_chain_on_stack"
13009   if (crtl->args.pops_args)
13010     {
13011       rtx popc = GEN_INT (crtl->args.pops_args);
13012       emit_jump_insn (gen_simple_return_pop_internal (popc));
13013       DONE;
13014     }
13017 (define_insn "simple_return_internal"
13018   [(simple_return)]
13019   "reload_completed"
13020   "%!ret"
13021   [(set_attr "length" "1")
13022    (set_attr "atom_unit" "jeu")
13023    (set_attr "length_immediate" "0")
13024    (set_attr "modrm" "0")
13025    (set_attr "maybe_prefix_bnd" "1")])
13027 (define_insn "interrupt_return"
13028   [(simple_return)
13029    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13030   "reload_completed"
13032   return TARGET_64BIT ? "iretq" : "iret";
13035 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13036 ;; instruction Athlon and K8 have.
13038 (define_insn "simple_return_internal_long"
13039   [(simple_return)
13040    (unspec [(const_int 0)] UNSPEC_REP)]
13041   "reload_completed"
13043   if (ix86_bnd_prefixed_insn_p (insn))
13044     return "%!ret";
13046   return "rep%; ret";
13048   [(set_attr "length" "2")
13049    (set_attr "atom_unit" "jeu")
13050    (set_attr "length_immediate" "0")
13051    (set_attr "prefix_rep" "1")
13052    (set_attr "modrm" "0")])
13054 (define_insn "simple_return_pop_internal"
13055   [(simple_return)
13056    (use (match_operand:SI 0 "const_int_operand"))]
13057   "reload_completed"
13058   "%!ret\t%0"
13059   [(set_attr "length" "3")
13060    (set_attr "atom_unit" "jeu")
13061    (set_attr "length_immediate" "2")
13062    (set_attr "modrm" "0")
13063    (set_attr "maybe_prefix_bnd" "1")])
13065 (define_insn "simple_return_indirect_internal"
13066   [(simple_return)
13067    (use (match_operand:SI 0 "register_operand" "r"))]
13068   "reload_completed"
13069   "%!jmp\t%A0"
13070   [(set_attr "type" "ibr")
13071    (set_attr "length_immediate" "0")
13072    (set_attr "maybe_prefix_bnd" "1")])
13074 (define_insn "nop"
13075   [(const_int 0)]
13076   ""
13077   "nop"
13078   [(set_attr "length" "1")
13079    (set_attr "length_immediate" "0")
13080    (set_attr "modrm" "0")])
13082 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
13083 (define_insn "nops"
13084   [(unspec_volatile [(match_operand 0 "const_int_operand")]
13085                     UNSPECV_NOPS)]
13086   "reload_completed"
13088   int num = INTVAL (operands[0]);
13090   gcc_assert (IN_RANGE (num, 1, 8));
13092   while (num--)
13093     fputs ("\tnop\n", asm_out_file);
13095   return "";
13097   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13098    (set_attr "length_immediate" "0")
13099    (set_attr "modrm" "0")])
13101 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13102 ;; branch prediction penalty for the third jump in a 16-byte
13103 ;; block on K8.
13105 (define_insn "pad"
13106   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13107   ""
13109 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13110   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13111 #else
13112   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13113      The align insn is used to avoid 3 jump instructions in the row to improve
13114      branch prediction and the benefits hardly outweigh the cost of extra 8
13115      nops on the average inserted by full alignment pseudo operation.  */
13116 #endif
13117   return "";
13119   [(set_attr "length" "16")])
13121 (define_expand "prologue"
13122   [(const_int 0)]
13123   ""
13124   "ix86_expand_prologue (); DONE;")
13126 (define_expand "set_got"
13127   [(parallel
13128      [(set (match_operand:SI 0 "register_operand")
13129            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13130       (clobber (reg:CC FLAGS_REG))])]
13131   "!TARGET_64BIT"
13133   if (flag_pic && !TARGET_VXWORKS_RTP)
13134     ix86_pc_thunk_call_expanded = true;
13137 (define_insn "*set_got"
13138   [(set (match_operand:SI 0 "register_operand" "=r")
13139         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13140    (clobber (reg:CC FLAGS_REG))]
13141   "!TARGET_64BIT"
13142   "* return output_set_got (operands[0], NULL_RTX);"
13143   [(set_attr "type" "multi")
13144    (set_attr "length" "12")])
13146 (define_expand "set_got_labelled"
13147   [(parallel
13148      [(set (match_operand:SI 0 "register_operand")
13149            (unspec:SI [(label_ref (match_operand 1))]
13150                       UNSPEC_SET_GOT))
13151       (clobber (reg:CC FLAGS_REG))])]
13152   "!TARGET_64BIT"
13154   if (flag_pic && !TARGET_VXWORKS_RTP)
13155     ix86_pc_thunk_call_expanded = true;
13158 (define_insn "*set_got_labelled"
13159   [(set (match_operand:SI 0 "register_operand" "=r")
13160         (unspec:SI [(label_ref (match_operand 1))]
13161          UNSPEC_SET_GOT))
13162    (clobber (reg:CC FLAGS_REG))]
13163   "!TARGET_64BIT"
13164   "* return output_set_got (operands[0], operands[1]);"
13165   [(set_attr "type" "multi")
13166    (set_attr "length" "12")])
13168 (define_insn "set_got_rex64"
13169   [(set (match_operand:DI 0 "register_operand" "=r")
13170         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13171   "TARGET_64BIT"
13172   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13173   [(set_attr "type" "lea")
13174    (set_attr "length_address" "4")
13175    (set_attr "modrm_class" "unknown")
13176    (set_attr "mode" "DI")])
13178 (define_insn "set_rip_rex64"
13179   [(set (match_operand:DI 0 "register_operand" "=r")
13180         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13181   "TARGET_64BIT"
13182   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13183   [(set_attr "type" "lea")
13184    (set_attr "length_address" "4")
13185    (set_attr "mode" "DI")])
13187 (define_insn "set_got_offset_rex64"
13188   [(set (match_operand:DI 0 "register_operand" "=r")
13189         (unspec:DI
13190           [(label_ref (match_operand 1))]
13191           UNSPEC_SET_GOT_OFFSET))]
13192   "TARGET_LP64"
13193   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13194   [(set_attr "type" "imov")
13195    (set_attr "length_immediate" "0")
13196    (set_attr "length_address" "8")
13197    (set_attr "mode" "DI")])
13199 (define_expand "epilogue"
13200   [(const_int 0)]
13201   ""
13202   "ix86_expand_epilogue (1); DONE;")
13204 (define_expand "sibcall_epilogue"
13205   [(const_int 0)]
13206   ""
13207   "ix86_expand_epilogue (0); DONE;")
13209 (define_expand "eh_return"
13210   [(use (match_operand 0 "register_operand"))]
13211   ""
13213   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13215   /* Tricky bit: we write the address of the handler to which we will
13216      be returning into someone else's stack frame, one word below the
13217      stack address we wish to restore.  */
13218   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13219   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13220   tmp = gen_rtx_MEM (Pmode, tmp);
13221   emit_move_insn (tmp, ra);
13223   emit_jump_insn (gen_eh_return_internal ());
13224   emit_barrier ();
13225   DONE;
13228 (define_insn_and_split "eh_return_internal"
13229   [(eh_return)]
13230   ""
13231   "#"
13232   "epilogue_completed"
13233   [(const_int 0)]
13234   "ix86_expand_epilogue (2); DONE;")
13236 (define_insn "leave"
13237   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13238    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13239    (clobber (mem:BLK (scratch)))]
13240   "!TARGET_64BIT"
13241   "leave"
13242   [(set_attr "type" "leave")])
13244 (define_insn "leave_rex64"
13245   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13246    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13247    (clobber (mem:BLK (scratch)))]
13248   "TARGET_64BIT"
13249   "leave"
13250   [(set_attr "type" "leave")])
13252 ;; Handle -fsplit-stack.
13254 (define_expand "split_stack_prologue"
13255   [(const_int 0)]
13256   ""
13258   ix86_expand_split_stack_prologue ();
13259   DONE;
13262 ;; In order to support the call/return predictor, we use a return
13263 ;; instruction which the middle-end doesn't see.
13264 (define_insn "split_stack_return"
13265   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13266                      UNSPECV_SPLIT_STACK_RETURN)]
13267   ""
13269   if (operands[0] == const0_rtx)
13270     return "ret";
13271   else
13272     return "ret\t%0";
13274   [(set_attr "atom_unit" "jeu")
13275    (set_attr "modrm" "0")
13276    (set (attr "length")
13277         (if_then_else (match_operand:SI 0 "const0_operand")
13278                       (const_int 1)
13279                       (const_int 3)))
13280    (set (attr "length_immediate")
13281         (if_then_else (match_operand:SI 0 "const0_operand")
13282                       (const_int 0)
13283                       (const_int 2)))])
13285 ;; If there are operand 0 bytes available on the stack, jump to
13286 ;; operand 1.
13288 (define_expand "split_stack_space_check"
13289   [(set (pc) (if_then_else
13290               (ltu (minus (reg SP_REG)
13291                           (match_operand 0 "register_operand"))
13292                    (match_dup 2))
13293               (label_ref (match_operand 1))
13294               (pc)))]
13295   ""
13297   rtx reg = gen_reg_rtx (Pmode);
13299   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13301   operands[2] = ix86_split_stack_guard ();
13302   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13304   DONE;
13307 ;; Bit manipulation instructions.
13309 (define_expand "ffs<mode>2"
13310   [(set (match_dup 2) (const_int -1))
13311    (parallel [(set (match_dup 3) (match_dup 4))
13312               (set (match_operand:SWI48 0 "register_operand")
13313                    (ctz:SWI48
13314                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13315    (set (match_dup 0) (if_then_else:SWI48
13316                         (eq (match_dup 3) (const_int 0))
13317                         (match_dup 2)
13318                         (match_dup 0)))
13319    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13320               (clobber (reg:CC FLAGS_REG))])]
13321   ""
13323   machine_mode flags_mode;
13325   if (<MODE>mode == SImode && !TARGET_CMOVE)
13326     {
13327       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13328       DONE;
13329     }
13331   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13333   operands[2] = gen_reg_rtx (<MODE>mode);
13334   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13335   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13338 (define_insn_and_split "ffssi2_no_cmove"
13339   [(set (match_operand:SI 0 "register_operand" "=r")
13340         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13341    (clobber (match_scratch:SI 2 "=&q"))
13342    (clobber (reg:CC FLAGS_REG))]
13343   "!TARGET_CMOVE"
13344   "#"
13345   "&& reload_completed"
13346   [(parallel [(set (match_dup 4) (match_dup 5))
13347               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13348    (set (strict_low_part (match_dup 3))
13349         (eq:QI (match_dup 4) (const_int 0)))
13350    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13351               (clobber (reg:CC FLAGS_REG))])
13352    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13353               (clobber (reg:CC FLAGS_REG))])
13354    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13355               (clobber (reg:CC FLAGS_REG))])]
13357   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13359   operands[3] = gen_lowpart (QImode, operands[2]);
13360   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13361   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13363   ix86_expand_clear (operands[2]);
13366 (define_insn_and_split "*tzcnt<mode>_1"
13367   [(set (reg:CCC FLAGS_REG)
13368         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13369                      (const_int 0)))
13370    (set (match_operand:SWI48 0 "register_operand" "=r")
13371         (ctz:SWI48 (match_dup 1)))]
13372   "TARGET_BMI"
13373   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13374   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13375    && optimize_function_for_speed_p (cfun)
13376    && !reg_mentioned_p (operands[0], operands[1])"
13377   [(parallel
13378     [(set (reg:CCC FLAGS_REG)
13379           (compare:CCC (match_dup 1) (const_int 0)))
13380      (set (match_dup 0)
13381           (ctz:SWI48 (match_dup 1)))
13382      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13383   "ix86_expand_clear (operands[0]);"
13384   [(set_attr "type" "alu1")
13385    (set_attr "prefix_0f" "1")
13386    (set_attr "prefix_rep" "1")
13387    (set_attr "btver2_decode" "double")
13388    (set_attr "mode" "<MODE>")])
13390 ; False dependency happens when destination is only updated by tzcnt,
13391 ; lzcnt or popcnt.  There is no false dependency when destination is
13392 ; also used in source.
13393 (define_insn "*tzcnt<mode>_1_falsedep"
13394   [(set (reg:CCC FLAGS_REG)
13395         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13396                      (const_int 0)))
13397    (set (match_operand:SWI48 0 "register_operand" "=r")
13398         (ctz:SWI48 (match_dup 1)))
13399    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13400            UNSPEC_INSN_FALSE_DEP)]
13401   "TARGET_BMI"
13402   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13403   [(set_attr "type" "alu1")
13404    (set_attr "prefix_0f" "1")
13405    (set_attr "prefix_rep" "1")
13406    (set_attr "btver2_decode" "double")
13407    (set_attr "mode" "<MODE>")])
13409 (define_insn "*bsf<mode>_1"
13410   [(set (reg:CCZ FLAGS_REG)
13411         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13412                      (const_int 0)))
13413    (set (match_operand:SWI48 0 "register_operand" "=r")
13414         (ctz:SWI48 (match_dup 1)))]
13415   ""
13416   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13417   [(set_attr "type" "alu1")
13418    (set_attr "prefix_0f" "1")
13419    (set_attr "btver2_decode" "double")
13420    (set_attr "znver1_decode" "vector")
13421    (set_attr "mode" "<MODE>")])
13423 (define_insn_and_split "ctz<mode>2"
13424   [(set (match_operand:SWI48 0 "register_operand" "=r")
13425         (ctz:SWI48
13426           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13427    (clobber (reg:CC FLAGS_REG))]
13428   ""
13430   if (TARGET_BMI)
13431     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13432   else if (optimize_function_for_size_p (cfun))
13433     ;
13434   else if (TARGET_GENERIC)
13435     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13436     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13438   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13440   "(TARGET_BMI || TARGET_GENERIC)
13441    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13442    && optimize_function_for_speed_p (cfun)
13443    && !reg_mentioned_p (operands[0], operands[1])"
13444   [(parallel
13445     [(set (match_dup 0)
13446           (ctz:SWI48 (match_dup 1)))
13447      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13448      (clobber (reg:CC FLAGS_REG))])]
13449   "ix86_expand_clear (operands[0]);"
13450   [(set_attr "type" "alu1")
13451    (set_attr "prefix_0f" "1")
13452    (set (attr "prefix_rep")
13453      (if_then_else
13454        (ior (match_test "TARGET_BMI")
13455             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13456                  (match_test "TARGET_GENERIC")))
13457        (const_string "1")
13458        (const_string "0")))
13459    (set_attr "mode" "<MODE>")])
13461 ; False dependency happens when destination is only updated by tzcnt,
13462 ; lzcnt or popcnt.  There is no false dependency when destination is
13463 ; also used in source.
13464 (define_insn "*ctz<mode>2_falsedep"
13465   [(set (match_operand:SWI48 0 "register_operand" "=r")
13466         (ctz:SWI48
13467           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13468    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13469            UNSPEC_INSN_FALSE_DEP)
13470    (clobber (reg:CC FLAGS_REG))]
13471   ""
13473   if (TARGET_BMI)
13474     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13475   else if (TARGET_GENERIC)
13476     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13477     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13478   else
13479     gcc_unreachable ();
13481   [(set_attr "type" "alu1")
13482    (set_attr "prefix_0f" "1")
13483    (set_attr "prefix_rep" "1")
13484    (set_attr "mode" "<MODE>")])
13486 (define_insn "bsr_rex64"
13487   [(set (match_operand:DI 0 "register_operand" "=r")
13488         (minus:DI (const_int 63)
13489                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "TARGET_64BIT"
13492   "bsr{q}\t{%1, %0|%0, %1}"
13493   [(set_attr "type" "alu1")
13494    (set_attr "prefix_0f" "1")
13495    (set_attr "znver1_decode" "vector")
13496    (set_attr "mode" "DI")])
13498 (define_insn "bsr"
13499   [(set (match_operand:SI 0 "register_operand" "=r")
13500         (minus:SI (const_int 31)
13501                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13502    (clobber (reg:CC FLAGS_REG))]
13503   ""
13504   "bsr{l}\t{%1, %0|%0, %1}"
13505   [(set_attr "type" "alu1")
13506    (set_attr "prefix_0f" "1")
13507    (set_attr "znver1_decode" "vector")
13508    (set_attr "mode" "SI")])
13510 (define_insn "*bsrhi"
13511   [(set (match_operand:HI 0 "register_operand" "=r")
13512         (minus:HI (const_int 15)
13513                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13514    (clobber (reg:CC FLAGS_REG))]
13515   ""
13516   "bsr{w}\t{%1, %0|%0, %1}"
13517   [(set_attr "type" "alu1")
13518    (set_attr "prefix_0f" "1")
13519    (set_attr "znver1_decode" "vector")
13520    (set_attr "mode" "HI")])
13522 (define_expand "clz<mode>2"
13523   [(parallel
13524      [(set (match_operand:SWI48 0 "register_operand")
13525            (minus:SWI48
13526              (match_dup 2)
13527              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13528       (clobber (reg:CC FLAGS_REG))])
13529    (parallel
13530      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13531       (clobber (reg:CC FLAGS_REG))])]
13532   ""
13534   if (TARGET_LZCNT)
13535     {
13536       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13537       DONE;
13538     }
13539   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13542 (define_insn_and_split "clz<mode>2_lzcnt"
13543   [(set (match_operand:SWI48 0 "register_operand" "=r")
13544         (clz:SWI48
13545           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13546    (clobber (reg:CC FLAGS_REG))]
13547   "TARGET_LZCNT"
13548   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13549   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13550    && optimize_function_for_speed_p (cfun)
13551    && !reg_mentioned_p (operands[0], operands[1])"
13552   [(parallel
13553     [(set (match_dup 0)
13554           (clz:SWI48 (match_dup 1)))
13555      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13556      (clobber (reg:CC FLAGS_REG))])]
13557   "ix86_expand_clear (operands[0]);"
13558   [(set_attr "prefix_rep" "1")
13559    (set_attr "type" "bitmanip")
13560    (set_attr "mode" "<MODE>")])
13562 ; False dependency happens when destination is only updated by tzcnt,
13563 ; lzcnt or popcnt.  There is no false dependency when destination is
13564 ; also used in source.
13565 (define_insn "*clz<mode>2_lzcnt_falsedep"
13566   [(set (match_operand:SWI48 0 "register_operand" "=r")
13567         (clz:SWI48
13568           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13569    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13570            UNSPEC_INSN_FALSE_DEP)
13571    (clobber (reg:CC FLAGS_REG))]
13572   "TARGET_LZCNT"
13573   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13574   [(set_attr "prefix_rep" "1")
13575    (set_attr "type" "bitmanip")
13576    (set_attr "mode" "<MODE>")])
13578 (define_int_iterator LT_ZCNT
13579         [(UNSPEC_TZCNT "TARGET_BMI")
13580          (UNSPEC_LZCNT "TARGET_LZCNT")])
13582 (define_int_attr lt_zcnt
13583         [(UNSPEC_TZCNT "tzcnt")
13584          (UNSPEC_LZCNT "lzcnt")])
13586 (define_int_attr lt_zcnt_type
13587         [(UNSPEC_TZCNT "alu1")
13588          (UNSPEC_LZCNT "bitmanip")])
13590 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13591 ;; provides operand size as output when source operand is zero. 
13593 (define_insn_and_split "<lt_zcnt>_<mode>"
13594   [(set (match_operand:SWI48 0 "register_operand" "=r")
13595         (unspec:SWI48
13596           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13597    (clobber (reg:CC FLAGS_REG))]
13598   ""
13599   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13600   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13601    && optimize_function_for_speed_p (cfun)
13602    && !reg_mentioned_p (operands[0], operands[1])"
13603   [(parallel
13604     [(set (match_dup 0)
13605           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13606      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13607      (clobber (reg:CC FLAGS_REG))])]
13608   "ix86_expand_clear (operands[0]);"
13609   [(set_attr "type" "<lt_zcnt_type>")
13610    (set_attr "prefix_0f" "1")
13611    (set_attr "prefix_rep" "1")
13612    (set_attr "mode" "<MODE>")])
13614 ; False dependency happens when destination is only updated by tzcnt,
13615 ; lzcnt or popcnt.  There is no false dependency when destination is
13616 ; also used in source.
13617 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13618   [(set (match_operand:SWI48 0 "register_operand" "=r")
13619         (unspec:SWI48
13620           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13621    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13622            UNSPEC_INSN_FALSE_DEP)
13623    (clobber (reg:CC FLAGS_REG))]
13624   ""
13625   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13626   [(set_attr "type" "<lt_zcnt_type>")
13627    (set_attr "prefix_0f" "1")
13628    (set_attr "prefix_rep" "1")
13629    (set_attr "mode" "<MODE>")])
13631 (define_insn "<lt_zcnt>_hi"
13632   [(set (match_operand:HI 0 "register_operand" "=r")
13633         (unspec:HI
13634           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13635    (clobber (reg:CC FLAGS_REG))]
13636   ""
13637   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13638   [(set_attr "type" "<lt_zcnt_type>")
13639    (set_attr "prefix_0f" "1")
13640    (set_attr "prefix_rep" "1")
13641    (set_attr "mode" "HI")])
13643 ;; BMI instructions.
13645 (define_insn "bmi_bextr_<mode>"
13646   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13647         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13648                        (match_operand:SWI48 2 "register_operand" "r,r")]
13649                       UNSPEC_BEXTR))
13650    (clobber (reg:CC FLAGS_REG))]
13651   "TARGET_BMI"
13652   "bextr\t{%2, %1, %0|%0, %1, %2}"
13653   [(set_attr "type" "bitmanip")
13654    (set_attr "btver2_decode" "direct, double")
13655    (set_attr "mode" "<MODE>")])
13657 (define_insn "*bmi_bextr_<mode>_ccz"
13658   [(set (reg:CCZ FLAGS_REG)
13659         (compare:CCZ
13660           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13661                          (match_operand:SWI48 2 "register_operand" "r,r")]
13662                         UNSPEC_BEXTR)
13663           (const_int 0)))
13664    (clobber (match_scratch:SWI48 0 "=r,r"))]
13665   "TARGET_BMI"
13666   "bextr\t{%2, %1, %0|%0, %1, %2}"
13667   [(set_attr "type" "bitmanip")
13668    (set_attr "btver2_decode" "direct, double")
13669    (set_attr "mode" "<MODE>")])
13671 (define_insn "*bmi_blsi_<mode>"
13672   [(set (match_operand:SWI48 0 "register_operand" "=r")
13673         (and:SWI48
13674           (neg:SWI48
13675             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13676           (match_dup 1)))
13677    (clobber (reg:CC FLAGS_REG))]
13678   "TARGET_BMI"
13679   "blsi\t{%1, %0|%0, %1}"
13680   [(set_attr "type" "bitmanip")
13681    (set_attr "btver2_decode" "double")
13682    (set_attr "mode" "<MODE>")])
13684 (define_insn "*bmi_blsmsk_<mode>"
13685   [(set (match_operand:SWI48 0 "register_operand" "=r")
13686         (xor:SWI48
13687           (plus:SWI48
13688             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13689             (const_int -1))
13690           (match_dup 1)))
13691    (clobber (reg:CC FLAGS_REG))]
13692   "TARGET_BMI"
13693   "blsmsk\t{%1, %0|%0, %1}"
13694   [(set_attr "type" "bitmanip")
13695    (set_attr "btver2_decode" "double")
13696    (set_attr "mode" "<MODE>")])
13698 (define_insn "*bmi_blsr_<mode>"
13699   [(set (match_operand:SWI48 0 "register_operand" "=r")
13700         (and:SWI48
13701           (plus:SWI48
13702             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13703             (const_int -1))
13704           (match_dup 1)))
13705    (clobber (reg:CC FLAGS_REG))]
13706    "TARGET_BMI"
13707    "blsr\t{%1, %0|%0, %1}"
13708   [(set_attr "type" "bitmanip")
13709    (set_attr "btver2_decode" "double")
13710    (set_attr "mode" "<MODE>")])
13712 ;; BMI2 instructions.
13713 (define_expand "bmi2_bzhi_<mode>3"
13714   [(parallel
13715     [(set (match_operand:SWI48 0 "register_operand")
13716           (zero_extract:SWI48
13717             (match_operand:SWI48 1 "nonimmediate_operand")
13718             (umin:SWI48
13719               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13720                          (const_int 255))
13721               (match_dup 3))
13722             (const_int 0)))
13723      (clobber (reg:CC FLAGS_REG))])]
13724   "TARGET_BMI2"
13725   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13727 (define_insn "*bmi2_bzhi_<mode>3"
13728   [(set (match_operand:SWI48 0 "register_operand" "=r")
13729         (zero_extract:SWI48
13730           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13731           (umin:SWI48
13732             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13733                        (const_int 255))
13734             (match_operand:SWI48 3 "const_int_operand" "n"))
13735           (const_int 0)))
13736    (clobber (reg:CC FLAGS_REG))]
13737   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13738   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13739   [(set_attr "type" "bitmanip")
13740    (set_attr "prefix" "vex")
13741    (set_attr "mode" "<MODE>")])
13743 (define_insn "*bmi2_bzhi_<mode>3_1"
13744   [(set (match_operand:SWI48 0 "register_operand" "=r")
13745         (zero_extract:SWI48
13746           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13747           (umin:SWI48
13748             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13749             (match_operand:SWI48 3 "const_int_operand" "n"))
13750           (const_int 0)))
13751    (clobber (reg:CC FLAGS_REG))]
13752   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13753   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13754   [(set_attr "type" "bitmanip")
13755    (set_attr "prefix" "vex")
13756    (set_attr "mode" "<MODE>")])
13758 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13759   [(set (reg:CCZ FLAGS_REG)
13760         (compare:CCZ
13761           (zero_extract:SWI48
13762             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13763             (umin:SWI48
13764               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13765               (match_operand:SWI48 3 "const_int_operand" "n"))
13766             (const_int 0))
13767         (const_int 0)))
13768    (clobber (match_scratch:SWI48 0 "=r"))]
13769   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13770   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13771   [(set_attr "type" "bitmanip")
13772    (set_attr "prefix" "vex")
13773    (set_attr "mode" "<MODE>")])
13775 (define_insn "bmi2_pdep_<mode>3"
13776   [(set (match_operand:SWI48 0 "register_operand" "=r")
13777         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13778                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13779                        UNSPEC_PDEP))]
13780   "TARGET_BMI2"
13781   "pdep\t{%2, %1, %0|%0, %1, %2}"
13782   [(set_attr "type" "bitmanip")
13783    (set_attr "prefix" "vex")
13784    (set_attr "mode" "<MODE>")])
13786 (define_insn "bmi2_pext_<mode>3"
13787   [(set (match_operand:SWI48 0 "register_operand" "=r")
13788         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13789                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13790                        UNSPEC_PEXT))]
13791   "TARGET_BMI2"
13792   "pext\t{%2, %1, %0|%0, %1, %2}"
13793   [(set_attr "type" "bitmanip")
13794    (set_attr "prefix" "vex")
13795    (set_attr "mode" "<MODE>")])
13797 ;; TBM instructions.
13798 (define_insn "tbm_bextri_<mode>"
13799   [(set (match_operand:SWI48 0 "register_operand" "=r")
13800         (zero_extract:SWI48
13801           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13802           (match_operand 2 "const_0_to_255_operand" "N")
13803           (match_operand 3 "const_0_to_255_operand" "N")))
13804    (clobber (reg:CC FLAGS_REG))]
13805    "TARGET_TBM"
13807   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13808   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13810   [(set_attr "type" "bitmanip")
13811    (set_attr "mode" "<MODE>")])
13813 (define_insn "*tbm_blcfill_<mode>"
13814   [(set (match_operand:SWI48 0 "register_operand" "=r")
13815         (and:SWI48
13816           (plus:SWI48
13817             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13818             (const_int 1))
13819           (match_dup 1)))
13820    (clobber (reg:CC FLAGS_REG))]
13821    "TARGET_TBM"
13822    "blcfill\t{%1, %0|%0, %1}"
13823   [(set_attr "type" "bitmanip")
13824    (set_attr "mode" "<MODE>")])
13826 (define_insn "*tbm_blci_<mode>"
13827   [(set (match_operand:SWI48 0 "register_operand" "=r")
13828         (ior:SWI48
13829           (not:SWI48
13830             (plus:SWI48
13831               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13832               (const_int 1)))
13833           (match_dup 1)))
13834    (clobber (reg:CC FLAGS_REG))]
13835    "TARGET_TBM"
13836    "blci\t{%1, %0|%0, %1}"
13837   [(set_attr "type" "bitmanip")
13838    (set_attr "mode" "<MODE>")])
13840 (define_insn "*tbm_blcic_<mode>"
13841   [(set (match_operand:SWI48 0 "register_operand" "=r")
13842         (and:SWI48
13843           (plus:SWI48
13844             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13845             (const_int 1))
13846           (not:SWI48
13847             (match_dup 1))))
13848    (clobber (reg:CC FLAGS_REG))]
13849    "TARGET_TBM"
13850    "blcic\t{%1, %0|%0, %1}"
13851   [(set_attr "type" "bitmanip")
13852    (set_attr "mode" "<MODE>")])
13854 (define_insn "*tbm_blcmsk_<mode>"
13855   [(set (match_operand:SWI48 0 "register_operand" "=r")
13856         (xor:SWI48
13857           (plus:SWI48
13858             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13859             (const_int 1))
13860           (match_dup 1)))
13861    (clobber (reg:CC FLAGS_REG))]
13862    "TARGET_TBM"
13863    "blcmsk\t{%1, %0|%0, %1}"
13864   [(set_attr "type" "bitmanip")
13865    (set_attr "mode" "<MODE>")])
13867 (define_insn "*tbm_blcs_<mode>"
13868   [(set (match_operand:SWI48 0 "register_operand" "=r")
13869         (ior:SWI48
13870           (plus:SWI48
13871             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13872             (const_int 1))
13873           (match_dup 1)))
13874    (clobber (reg:CC FLAGS_REG))]
13875    "TARGET_TBM"
13876    "blcs\t{%1, %0|%0, %1}"
13877   [(set_attr "type" "bitmanip")
13878    (set_attr "mode" "<MODE>")])
13880 (define_insn "*tbm_blsfill_<mode>"
13881   [(set (match_operand:SWI48 0 "register_operand" "=r")
13882         (ior:SWI48
13883           (plus:SWI48
13884             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13885             (const_int -1))
13886           (match_dup 1)))
13887    (clobber (reg:CC FLAGS_REG))]
13888    "TARGET_TBM"
13889    "blsfill\t{%1, %0|%0, %1}"
13890   [(set_attr "type" "bitmanip")
13891    (set_attr "mode" "<MODE>")])
13893 (define_insn "*tbm_blsic_<mode>"
13894   [(set (match_operand:SWI48 0 "register_operand" "=r")
13895         (ior:SWI48
13896           (plus:SWI48
13897             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13898             (const_int -1))
13899           (not:SWI48
13900             (match_dup 1))))
13901    (clobber (reg:CC FLAGS_REG))]
13902    "TARGET_TBM"
13903    "blsic\t{%1, %0|%0, %1}"
13904   [(set_attr "type" "bitmanip")
13905    (set_attr "mode" "<MODE>")])
13907 (define_insn "*tbm_t1mskc_<mode>"
13908   [(set (match_operand:SWI48 0 "register_operand" "=r")
13909         (ior:SWI48
13910           (plus:SWI48
13911             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13912             (const_int 1))
13913           (not:SWI48
13914             (match_dup 1))))
13915    (clobber (reg:CC FLAGS_REG))]
13916    "TARGET_TBM"
13917    "t1mskc\t{%1, %0|%0, %1}"
13918   [(set_attr "type" "bitmanip")
13919    (set_attr "mode" "<MODE>")])
13921 (define_insn "*tbm_tzmsk_<mode>"
13922   [(set (match_operand:SWI48 0 "register_operand" "=r")
13923         (and:SWI48
13924           (plus:SWI48
13925             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13926             (const_int -1))
13927           (not:SWI48
13928             (match_dup 1))))
13929    (clobber (reg:CC FLAGS_REG))]
13930    "TARGET_TBM"
13931    "tzmsk\t{%1, %0|%0, %1}"
13932   [(set_attr "type" "bitmanip")
13933    (set_attr "mode" "<MODE>")])
13935 (define_insn_and_split "popcount<mode>2"
13936   [(set (match_operand:SWI48 0 "register_operand" "=r")
13937         (popcount:SWI48
13938           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "TARGET_POPCNT"
13942 #if TARGET_MACHO
13943   return "popcnt\t{%1, %0|%0, %1}";
13944 #else
13945   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13946 #endif
13948   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13949    && optimize_function_for_speed_p (cfun)
13950    && !reg_mentioned_p (operands[0], operands[1])"
13951   [(parallel
13952     [(set (match_dup 0)
13953           (popcount:SWI48 (match_dup 1)))
13954      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13955      (clobber (reg:CC FLAGS_REG))])]
13956   "ix86_expand_clear (operands[0]);"
13957   [(set_attr "prefix_rep" "1")
13958    (set_attr "type" "bitmanip")
13959    (set_attr "mode" "<MODE>")])
13961 ; False dependency happens when destination is only updated by tzcnt,
13962 ; lzcnt or popcnt.  There is no false dependency when destination is
13963 ; also used in source.
13964 (define_insn "*popcount<mode>2_falsedep"
13965   [(set (match_operand:SWI48 0 "register_operand" "=r")
13966         (popcount:SWI48
13967           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13968    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13969            UNSPEC_INSN_FALSE_DEP)
13970    (clobber (reg:CC FLAGS_REG))]
13971   "TARGET_POPCNT"
13973 #if TARGET_MACHO
13974   return "popcnt\t{%1, %0|%0, %1}";
13975 #else
13976   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13977 #endif
13979   [(set_attr "prefix_rep" "1")
13980    (set_attr "type" "bitmanip")
13981    (set_attr "mode" "<MODE>")])
13983 (define_insn_and_split "*popcounthi2_1"
13984   [(set (match_operand:SI 0 "register_operand")
13985         (popcount:SI
13986           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13987    (clobber (reg:CC FLAGS_REG))]
13988   "TARGET_POPCNT
13989    && can_create_pseudo_p ()"
13990   "#"
13991   "&& 1"
13992   [(const_int 0)]
13994   rtx tmp = gen_reg_rtx (HImode);
13996   emit_insn (gen_popcounthi2 (tmp, operands[1]));
13997   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13998   DONE;
14001 (define_insn "popcounthi2"
14002   [(set (match_operand:HI 0 "register_operand" "=r")
14003         (popcount:HI
14004           (match_operand:HI 1 "nonimmediate_operand" "rm")))
14005    (clobber (reg:CC FLAGS_REG))]
14006   "TARGET_POPCNT"
14008 #if TARGET_MACHO
14009   return "popcnt\t{%1, %0|%0, %1}";
14010 #else
14011   return "popcnt{w}\t{%1, %0|%0, %1}";
14012 #endif
14014   [(set_attr "prefix_rep" "1")
14015    (set_attr "type" "bitmanip")
14016    (set_attr "mode" "HI")])
14018 (define_expand "bswapdi2"
14019   [(set (match_operand:DI 0 "register_operand")
14020         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14021   "TARGET_64BIT"
14023   if (!TARGET_MOVBE)
14024     operands[1] = force_reg (DImode, operands[1]);
14027 (define_expand "bswapsi2"
14028   [(set (match_operand:SI 0 "register_operand")
14029         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14030   ""
14032   if (TARGET_MOVBE)
14033     ;
14034   else if (TARGET_BSWAP)
14035     operands[1] = force_reg (SImode, operands[1]);
14036   else
14037     {
14038       rtx x = operands[0];
14040       emit_move_insn (x, operands[1]);
14041       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14042       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14043       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14044       DONE;
14045     }
14048 (define_insn "*bswap<mode>2_movbe"
14049   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14050         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14051   "TARGET_MOVBE
14052    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14053   "@
14054     bswap\t%0
14055     movbe\t{%1, %0|%0, %1}
14056     movbe\t{%1, %0|%0, %1}"
14057   [(set_attr "type" "bitmanip,imov,imov")
14058    (set_attr "modrm" "0,1,1")
14059    (set_attr "prefix_0f" "*,1,1")
14060    (set_attr "prefix_extra" "*,1,1")
14061    (set_attr "mode" "<MODE>")])
14063 (define_insn "*bswap<mode>2"
14064   [(set (match_operand:SWI48 0 "register_operand" "=r")
14065         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14066   "TARGET_BSWAP"
14067   "bswap\t%0"
14068   [(set_attr "type" "bitmanip")
14069    (set_attr "modrm" "0")
14070    (set_attr "mode" "<MODE>")])
14072 (define_insn "*bswaphi_lowpart_1"
14073   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14074         (bswap:HI (match_dup 0)))
14075    (clobber (reg:CC FLAGS_REG))]
14076   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14077   "@
14078     xchg{b}\t{%h0, %b0|%b0, %h0}
14079     rol{w}\t{$8, %0|%0, 8}"
14080   [(set_attr "length" "2,4")
14081    (set_attr "mode" "QI,HI")])
14083 (define_insn "bswaphi_lowpart"
14084   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14085         (bswap:HI (match_dup 0)))
14086    (clobber (reg:CC FLAGS_REG))]
14087   ""
14088   "rol{w}\t{$8, %0|%0, 8}"
14089   [(set_attr "length" "4")
14090    (set_attr "mode" "HI")])
14092 (define_expand "paritydi2"
14093   [(set (match_operand:DI 0 "register_operand")
14094         (parity:DI (match_operand:DI 1 "register_operand")))]
14095   "! TARGET_POPCNT"
14097   rtx scratch = gen_reg_rtx (QImode);
14099   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14100                                 NULL_RTX, operands[1]));
14102   ix86_expand_setcc (scratch, ORDERED,
14103                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14105   if (TARGET_64BIT)
14106     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14107   else
14108     {
14109       rtx tmp = gen_reg_rtx (SImode);
14111       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14112       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14113     }
14114   DONE;
14117 (define_expand "paritysi2"
14118   [(set (match_operand:SI 0 "register_operand")
14119         (parity:SI (match_operand:SI 1 "register_operand")))]
14120   "! TARGET_POPCNT"
14122   rtx scratch = gen_reg_rtx (QImode);
14124   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14126   ix86_expand_setcc (scratch, ORDERED,
14127                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14129   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14130   DONE;
14133 (define_insn_and_split "paritydi2_cmp"
14134   [(set (reg:CC FLAGS_REG)
14135         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14136                    UNSPEC_PARITY))
14137    (clobber (match_scratch:DI 0 "=r"))
14138    (clobber (match_scratch:SI 1 "=&r"))
14139    (clobber (match_scratch:HI 2 "=Q"))]
14140   "! TARGET_POPCNT"
14141   "#"
14142   "&& reload_completed"
14143   [(parallel
14144      [(set (match_dup 1)
14145            (xor:SI (match_dup 1) (match_dup 4)))
14146       (clobber (reg:CC FLAGS_REG))])
14147    (parallel
14148      [(set (reg:CC FLAGS_REG)
14149            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14150       (clobber (match_dup 1))
14151       (clobber (match_dup 2))])]
14153   operands[4] = gen_lowpart (SImode, operands[3]);
14155   if (TARGET_64BIT)
14156     {
14157       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14158       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14159     }
14160   else
14161     operands[1] = gen_highpart (SImode, operands[3]);
14164 (define_insn_and_split "paritysi2_cmp"
14165   [(set (reg:CC FLAGS_REG)
14166         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14167                    UNSPEC_PARITY))
14168    (clobber (match_scratch:SI 0 "=r"))
14169    (clobber (match_scratch:HI 1 "=&Q"))]
14170   "! TARGET_POPCNT"
14171   "#"
14172   "&& reload_completed"
14173   [(parallel
14174      [(set (match_dup 1)
14175            (xor:HI (match_dup 1) (match_dup 3)))
14176       (clobber (reg:CC FLAGS_REG))])
14177    (parallel
14178      [(set (reg:CC FLAGS_REG)
14179            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14180       (clobber (match_dup 1))])]
14182   operands[3] = gen_lowpart (HImode, operands[2]);
14184   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14185   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14188 (define_insn "*parityhi2_cmp"
14189   [(set (reg:CC FLAGS_REG)
14190         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14191                    UNSPEC_PARITY))
14192    (clobber (match_scratch:HI 0 "=Q"))]
14193   "! TARGET_POPCNT"
14194   "xor{b}\t{%h0, %b0|%b0, %h0}"
14195   [(set_attr "length" "2")
14196    (set_attr "mode" "HI")])
14199 ;; Thread-local storage patterns for ELF.
14201 ;; Note that these code sequences must appear exactly as shown
14202 ;; in order to allow linker relaxation.
14204 (define_insn "*tls_global_dynamic_32_gnu"
14205   [(set (match_operand:SI 0 "register_operand" "=a")
14206         (unspec:SI
14207          [(match_operand:SI 1 "register_operand" "Yb")
14208           (match_operand 2 "tls_symbolic_operand")
14209           (match_operand 3 "constant_call_address_operand" "Bz")
14210           (reg:SI SP_REG)]
14211          UNSPEC_TLS_GD))
14212    (clobber (match_scratch:SI 4 "=d"))
14213    (clobber (match_scratch:SI 5 "=c"))
14214    (clobber (reg:CC FLAGS_REG))]
14215   "!TARGET_64BIT && TARGET_GNU_TLS"
14217   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14218     output_asm_insn
14219       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14220   else
14221     output_asm_insn
14222       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14223   if (TARGET_SUN_TLS)
14224 #ifdef HAVE_AS_IX86_TLSGDPLT
14225     return "call\t%a2@tlsgdplt";
14226 #else
14227     return "call\t%p3@plt";
14228 #endif
14229   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14230     return "call\t%P3";
14231   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14233   [(set_attr "type" "multi")
14234    (set_attr "length" "12")])
14236 (define_expand "tls_global_dynamic_32"
14237   [(parallel
14238     [(set (match_operand:SI 0 "register_operand")
14239           (unspec:SI [(match_operand:SI 2 "register_operand")
14240                       (match_operand 1 "tls_symbolic_operand")
14241                       (match_operand 3 "constant_call_address_operand")
14242                       (reg:SI SP_REG)]
14243                      UNSPEC_TLS_GD))
14244      (clobber (match_scratch:SI 4))
14245      (clobber (match_scratch:SI 5))
14246      (clobber (reg:CC FLAGS_REG))])]
14247   ""
14248   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14250 (define_insn "*tls_global_dynamic_64_<mode>"
14251   [(set (match_operand:P 0 "register_operand" "=a")
14252         (call:P
14253          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14254          (match_operand 3)))
14255    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14256               (reg:P SP_REG)]
14257              UNSPEC_TLS_GD)]
14258   "TARGET_64BIT"
14260   if (!TARGET_X32)
14261     fputs (ASM_BYTE "0x66\n", asm_out_file);
14262   output_asm_insn
14263     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14264   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14265     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14266   else
14267     fputs (ASM_BYTE "0x66\n", asm_out_file);
14268   fputs ("\trex64\n", asm_out_file);
14269   if (TARGET_SUN_TLS)
14270     return "call\t%p2@plt";
14271   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14272     return "call\t%P2";
14273   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14275   [(set_attr "type" "multi")
14276    (set (attr "length")
14277         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14279 (define_insn "*tls_global_dynamic_64_largepic"
14280   [(set (match_operand:DI 0 "register_operand" "=a")
14281         (call:DI
14282          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14283                           (match_operand:DI 3 "immediate_operand" "i")))
14284          (match_operand 4)))
14285    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14286                (reg:DI SP_REG)]
14287               UNSPEC_TLS_GD)]
14288   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14289    && GET_CODE (operands[3]) == CONST
14290    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14291    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14293   output_asm_insn
14294     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14295   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14296   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14297   return "call\t{*%%rax|rax}";
14299   [(set_attr "type" "multi")
14300    (set_attr "length" "22")])
14302 (define_expand "tls_global_dynamic_64_<mode>"
14303   [(parallel
14304     [(set (match_operand:P 0 "register_operand")
14305           (call:P
14306            (mem:QI (match_operand 2))
14307            (const_int 0)))
14308      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14309                 (reg:P SP_REG)]
14310                UNSPEC_TLS_GD)])]
14311   "TARGET_64BIT"
14312   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14314 (define_insn "*tls_local_dynamic_base_32_gnu"
14315   [(set (match_operand:SI 0 "register_operand" "=a")
14316         (unspec:SI
14317          [(match_operand:SI 1 "register_operand" "Yb")
14318           (match_operand 2 "constant_call_address_operand" "Bz")
14319           (reg:SI SP_REG)]
14320          UNSPEC_TLS_LD_BASE))
14321    (clobber (match_scratch:SI 3 "=d"))
14322    (clobber (match_scratch:SI 4 "=c"))
14323    (clobber (reg:CC FLAGS_REG))]
14324   "!TARGET_64BIT && TARGET_GNU_TLS"
14326   output_asm_insn
14327     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14328   if (TARGET_SUN_TLS)
14329     {
14330       if (HAVE_AS_IX86_TLSLDMPLT)
14331         return "call\t%&@tlsldmplt";
14332       else
14333         return "call\t%p2@plt";
14334     }
14335   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14336     return "call\t%P2";
14337   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14339   [(set_attr "type" "multi")
14340    (set_attr "length" "11")])
14342 (define_expand "tls_local_dynamic_base_32"
14343   [(parallel
14344      [(set (match_operand:SI 0 "register_operand")
14345            (unspec:SI
14346             [(match_operand:SI 1 "register_operand")
14347              (match_operand 2 "constant_call_address_operand")
14348              (reg:SI SP_REG)]
14349             UNSPEC_TLS_LD_BASE))
14350       (clobber (match_scratch:SI 3))
14351       (clobber (match_scratch:SI 4))
14352       (clobber (reg:CC FLAGS_REG))])]
14353   ""
14354   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14356 (define_insn "*tls_local_dynamic_base_64_<mode>"
14357   [(set (match_operand:P 0 "register_operand" "=a")
14358         (call:P
14359          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14360          (match_operand 2)))
14361    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14362   "TARGET_64BIT"
14364   output_asm_insn
14365     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14366   if (TARGET_SUN_TLS)
14367     return "call\t%p1@plt";
14368   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14369     return "call\t%P1";
14370   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14372   [(set_attr "type" "multi")
14373    (set_attr "length" "12")])
14375 (define_insn "*tls_local_dynamic_base_64_largepic"
14376   [(set (match_operand:DI 0 "register_operand" "=a")
14377         (call:DI
14378          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14379                           (match_operand:DI 2 "immediate_operand" "i")))
14380          (match_operand 3)))
14381    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14382   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14383    && GET_CODE (operands[2]) == CONST
14384    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14385    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14387   output_asm_insn
14388     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14389   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14390   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14391   return "call\t{*%%rax|rax}";
14393   [(set_attr "type" "multi")
14394    (set_attr "length" "22")])
14396 (define_expand "tls_local_dynamic_base_64_<mode>"
14397   [(parallel
14398      [(set (match_operand:P 0 "register_operand")
14399            (call:P
14400             (mem:QI (match_operand 1))
14401             (const_int 0)))
14402       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14403   "TARGET_64BIT"
14404   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14406 ;; Local dynamic of a single variable is a lose.  Show combine how
14407 ;; to convert that back to global dynamic.
14409 (define_insn_and_split "*tls_local_dynamic_32_once"
14410   [(set (match_operand:SI 0 "register_operand" "=a")
14411         (plus:SI
14412          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14413                      (match_operand 2 "constant_call_address_operand" "Bz")
14414                      (reg:SI SP_REG)]
14415                     UNSPEC_TLS_LD_BASE)
14416          (const:SI (unspec:SI
14417                     [(match_operand 3 "tls_symbolic_operand")]
14418                     UNSPEC_DTPOFF))))
14419    (clobber (match_scratch:SI 4 "=d"))
14420    (clobber (match_scratch:SI 5 "=c"))
14421    (clobber (reg:CC FLAGS_REG))]
14422   ""
14423   "#"
14424   ""
14425   [(parallel
14426      [(set (match_dup 0)
14427            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14428                        (reg:SI SP_REG)]
14429                       UNSPEC_TLS_GD))
14430       (clobber (match_dup 4))
14431       (clobber (match_dup 5))
14432       (clobber (reg:CC FLAGS_REG))])])
14434 ;; Load and add the thread base pointer from %<tp_seg>:0.
14435 (define_insn_and_split "*load_tp_<mode>"
14436   [(set (match_operand:PTR 0 "register_operand" "=r")
14437         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14438   ""
14439   "#"
14440   ""
14441   [(set (match_dup 0)
14442         (match_dup 1))]
14444   addr_space_t as = DEFAULT_TLS_SEG_REG;
14446   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14447   set_mem_addr_space (operands[1], as);
14450 (define_insn_and_split "*load_tp_x32_zext"
14451   [(set (match_operand:DI 0 "register_operand" "=r")
14452         (zero_extend:DI
14453           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14454   "TARGET_X32"
14455   "#"
14456   ""
14457   [(set (match_dup 0)
14458         (zero_extend:DI (match_dup 1)))]
14460   addr_space_t as = DEFAULT_TLS_SEG_REG;
14462   operands[1] = gen_const_mem (SImode, const0_rtx);
14463   set_mem_addr_space (operands[1], as);
14466 (define_insn_and_split "*add_tp_<mode>"
14467   [(set (match_operand:PTR 0 "register_operand" "=r")
14468         (plus:PTR
14469           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14470           (match_operand:PTR 1 "register_operand" "0")))
14471    (clobber (reg:CC FLAGS_REG))]
14472   ""
14473   "#"
14474   ""
14475   [(parallel
14476      [(set (match_dup 0)
14477            (plus:PTR (match_dup 1) (match_dup 2)))
14478       (clobber (reg:CC FLAGS_REG))])]
14480   addr_space_t as = DEFAULT_TLS_SEG_REG;
14482   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14483   set_mem_addr_space (operands[2], as);
14486 (define_insn_and_split "*add_tp_x32_zext"
14487   [(set (match_operand:DI 0 "register_operand" "=r")
14488         (zero_extend:DI
14489           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14490                    (match_operand:SI 1 "register_operand" "0"))))
14491    (clobber (reg:CC FLAGS_REG))]
14492   "TARGET_X32"
14493   "#"
14494   ""
14495   [(parallel
14496      [(set (match_dup 0)
14497            (zero_extend:DI
14498              (plus:SI (match_dup 1) (match_dup 2))))
14499       (clobber (reg:CC FLAGS_REG))])]
14501   addr_space_t as = DEFAULT_TLS_SEG_REG;
14503   operands[2] = gen_const_mem (SImode, const0_rtx);
14504   set_mem_addr_space (operands[2], as);
14507 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14508 ;; %rax as destination of the initial executable code sequence.
14509 (define_insn "tls_initial_exec_64_sun"
14510   [(set (match_operand:DI 0 "register_operand" "=a")
14511         (unspec:DI
14512          [(match_operand 1 "tls_symbolic_operand")]
14513          UNSPEC_TLS_IE_SUN))
14514    (clobber (reg:CC FLAGS_REG))]
14515   "TARGET_64BIT && TARGET_SUN_TLS"
14517   output_asm_insn
14518     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14519   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14521   [(set_attr "type" "multi")])
14523 ;; GNU2 TLS patterns can be split.
14525 (define_expand "tls_dynamic_gnu2_32"
14526   [(set (match_dup 3)
14527         (plus:SI (match_operand:SI 2 "register_operand")
14528                  (const:SI
14529                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14530                              UNSPEC_TLSDESC))))
14531    (parallel
14532     [(set (match_operand:SI 0 "register_operand")
14533           (unspec:SI [(match_dup 1) (match_dup 3)
14534                       (match_dup 2) (reg:SI SP_REG)]
14535                       UNSPEC_TLSDESC))
14536      (clobber (reg:CC FLAGS_REG))])]
14537   "!TARGET_64BIT && TARGET_GNU2_TLS"
14539   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14540   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14543 (define_insn "*tls_dynamic_gnu2_lea_32"
14544   [(set (match_operand:SI 0 "register_operand" "=r")
14545         (plus:SI (match_operand:SI 1 "register_operand" "b")
14546                  (const:SI
14547                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14548                               UNSPEC_TLSDESC))))]
14549   "!TARGET_64BIT && TARGET_GNU2_TLS"
14550   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14551   [(set_attr "type" "lea")
14552    (set_attr "mode" "SI")
14553    (set_attr "length" "6")
14554    (set_attr "length_address" "4")])
14556 (define_insn "*tls_dynamic_gnu2_call_32"
14557   [(set (match_operand:SI 0 "register_operand" "=a")
14558         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14559                     (match_operand:SI 2 "register_operand" "0")
14560                     ;; we have to make sure %ebx still points to the GOT
14561                     (match_operand:SI 3 "register_operand" "b")
14562                     (reg:SI SP_REG)]
14563                    UNSPEC_TLSDESC))
14564    (clobber (reg:CC FLAGS_REG))]
14565   "!TARGET_64BIT && TARGET_GNU2_TLS"
14566   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14567   [(set_attr "type" "call")
14568    (set_attr "length" "2")
14569    (set_attr "length_address" "0")])
14571 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14572   [(set (match_operand:SI 0 "register_operand" "=&a")
14573         (plus:SI
14574          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14575                      (match_operand:SI 4)
14576                      (match_operand:SI 2 "register_operand" "b")
14577                      (reg:SI SP_REG)]
14578                     UNSPEC_TLSDESC)
14579          (const:SI (unspec:SI
14580                     [(match_operand 1 "tls_symbolic_operand")]
14581                     UNSPEC_DTPOFF))))
14582    (clobber (reg:CC FLAGS_REG))]
14583   "!TARGET_64BIT && TARGET_GNU2_TLS"
14584   "#"
14585   ""
14586   [(set (match_dup 0) (match_dup 5))]
14588   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14589   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14592 (define_expand "tls_dynamic_gnu2_64"
14593   [(set (match_dup 2)
14594         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14595                    UNSPEC_TLSDESC))
14596    (parallel
14597     [(set (match_operand:DI 0 "register_operand")
14598           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14599                      UNSPEC_TLSDESC))
14600      (clobber (reg:CC FLAGS_REG))])]
14601   "TARGET_64BIT && TARGET_GNU2_TLS"
14603   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14604   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14607 (define_insn "*tls_dynamic_gnu2_lea_64"
14608   [(set (match_operand:DI 0 "register_operand" "=r")
14609         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14610                    UNSPEC_TLSDESC))]
14611   "TARGET_64BIT && TARGET_GNU2_TLS"
14612   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14613   [(set_attr "type" "lea")
14614    (set_attr "mode" "DI")
14615    (set_attr "length" "7")
14616    (set_attr "length_address" "4")])
14618 (define_insn "*tls_dynamic_gnu2_call_64"
14619   [(set (match_operand:DI 0 "register_operand" "=a")
14620         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14621                     (match_operand:DI 2 "register_operand" "0")
14622                     (reg:DI SP_REG)]
14623                    UNSPEC_TLSDESC))
14624    (clobber (reg:CC FLAGS_REG))]
14625   "TARGET_64BIT && TARGET_GNU2_TLS"
14626   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14627   [(set_attr "type" "call")
14628    (set_attr "length" "2")
14629    (set_attr "length_address" "0")])
14631 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14632   [(set (match_operand:DI 0 "register_operand" "=&a")
14633         (plus:DI
14634          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14635                      (match_operand:DI 3)
14636                      (reg:DI SP_REG)]
14637                     UNSPEC_TLSDESC)
14638          (const:DI (unspec:DI
14639                     [(match_operand 1 "tls_symbolic_operand")]
14640                     UNSPEC_DTPOFF))))
14641    (clobber (reg:CC FLAGS_REG))]
14642   "TARGET_64BIT && TARGET_GNU2_TLS"
14643   "#"
14644   ""
14645   [(set (match_dup 0) (match_dup 4))]
14647   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14648   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14651 (define_split
14652   [(match_operand 0 "tls_address_pattern")]
14653   "TARGET_TLS_DIRECT_SEG_REFS"
14654   [(match_dup 0)]
14655   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14658 ;; These patterns match the binary 387 instructions for addM3, subM3,
14659 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14660 ;; SFmode.  The first is the normal insn, the second the same insn but
14661 ;; with one operand a conversion, and the third the same insn but with
14662 ;; the other operand a conversion.  The conversion may be SFmode or
14663 ;; SImode if the target mode DFmode, but only SImode if the target mode
14664 ;; is SFmode.
14666 ;; Gcc is slightly more smart about handling normal two address instructions
14667 ;; so use special patterns for add and mull.
14669 (define_insn "*fop_<mode>_comm"
14670   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14671         (match_operator:MODEF 3 "binary_fp_operator"
14672           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14673            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14674   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14676    && COMMUTATIVE_ARITH_P (operands[3])
14677    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14678   "* return output_387_binary_op (insn, operands);"
14679   [(set (attr "type")
14680         (if_then_else (eq_attr "alternative" "1,2")
14681            (if_then_else (match_operand:MODEF 3 "mult_operator")
14682               (const_string "ssemul")
14683               (const_string "sseadd"))
14684            (if_then_else (match_operand:MODEF 3 "mult_operator")
14685               (const_string "fmul")
14686               (const_string "fop"))))
14687    (set_attr "isa" "*,noavx,avx")
14688    (set_attr "prefix" "orig,orig,vex")
14689    (set_attr "mode" "<MODE>")
14690    (set (attr "enabled")
14691      (if_then_else
14692        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14693        (if_then_else
14694          (eq_attr "alternative" "0")
14695          (symbol_ref "TARGET_MIX_SSE_I387
14696                       && X87_ENABLE_ARITH (<MODE>mode)")
14697          (const_string "*"))
14698        (if_then_else
14699          (eq_attr "alternative" "0")
14700          (symbol_ref "true")
14701          (symbol_ref "false"))))])
14703 (define_insn "*rcpsf2_sse"
14704   [(set (match_operand:SF 0 "register_operand" "=x")
14705         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14706                    UNSPEC_RCP))]
14707   "TARGET_SSE && TARGET_SSE_MATH"
14708   "%vrcpss\t{%1, %d0|%d0, %1}"
14709   [(set_attr "type" "sse")
14710    (set_attr "atom_sse_attr" "rcp")
14711    (set_attr "btver2_sse_attr" "rcp")
14712    (set_attr "prefix" "maybe_vex")
14713    (set_attr "mode" "SF")])
14715 (define_insn "*fop_<mode>_1"
14716   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14717         (match_operator:MODEF 3 "binary_fp_operator"
14718           [(match_operand:MODEF 1
14719              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14720            (match_operand:MODEF 2
14721              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14722   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14723     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14724    && !COMMUTATIVE_ARITH_P (operands[3])
14725    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14726   "* return output_387_binary_op (insn, operands);"
14727   [(set (attr "type")
14728         (if_then_else (eq_attr "alternative" "2,3")
14729            (if_then_else (match_operand:MODEF 3 "div_operator")
14730               (const_string "ssediv")
14731               (const_string "sseadd"))
14732            (if_then_else (match_operand:MODEF 3 "div_operator")
14733               (const_string "fdiv")
14734               (const_string "fop"))))
14735    (set_attr "isa" "*,*,noavx,avx")
14736    (set_attr "prefix" "orig,orig,orig,vex")
14737    (set_attr "mode" "<MODE>")
14738    (set (attr "enabled")
14739      (if_then_else
14740        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14741        (if_then_else
14742          (eq_attr "alternative" "0,1")
14743          (symbol_ref "TARGET_MIX_SSE_I387
14744                       && X87_ENABLE_ARITH (<MODE>mode)")
14745          (const_string "*"))
14746        (if_then_else
14747          (eq_attr "alternative" "0,1")
14748          (symbol_ref "true")
14749          (symbol_ref "false"))))])
14751 ;; ??? Add SSE splitters for these!
14752 (define_insn "*fop_<MODEF:mode>_2_i387"
14753   [(set (match_operand:MODEF 0 "register_operand" "=f")
14754         (match_operator:MODEF 3 "binary_fp_operator"
14755           [(float:MODEF
14756              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14757            (match_operand:MODEF 2 "register_operand" "0")]))]
14758   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14759    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14760    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14761        || optimize_function_for_size_p (cfun))"
14762   "* return output_387_binary_op (insn, operands);"
14763   [(set (attr "type")
14764         (cond [(match_operand:MODEF 3 "mult_operator")
14765                  (const_string "fmul")
14766                (match_operand:MODEF 3 "div_operator")
14767                  (const_string "fdiv")
14768               ]
14769               (const_string "fop")))
14770    (set_attr "fp_int_src" "true")
14771    (set_attr "mode" "<SWI24:MODE>")])
14773 (define_insn "*fop_<MODEF:mode>_3_i387"
14774   [(set (match_operand:MODEF 0 "register_operand" "=f")
14775         (match_operator:MODEF 3 "binary_fp_operator"
14776           [(match_operand:MODEF 1 "register_operand" "0")
14777            (float:MODEF
14778              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14779   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14780    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14781    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14782        || optimize_function_for_size_p (cfun))"
14783   "* return output_387_binary_op (insn, operands);"
14784   [(set (attr "type")
14785         (cond [(match_operand:MODEF 3 "mult_operator")
14786                  (const_string "fmul")
14787                (match_operand:MODEF 3 "div_operator")
14788                  (const_string "fdiv")
14789               ]
14790               (const_string "fop")))
14791    (set_attr "fp_int_src" "true")
14792    (set_attr "mode" "<MODE>")])
14794 (define_insn "*fop_df_4_i387"
14795   [(set (match_operand:DF 0 "register_operand" "=f,f")
14796         (match_operator:DF 3 "binary_fp_operator"
14797            [(float_extend:DF
14798              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14799             (match_operand:DF 2 "register_operand" "0,f")]))]
14800   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14801    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14802   "* return output_387_binary_op (insn, operands);"
14803   [(set (attr "type")
14804         (cond [(match_operand:DF 3 "mult_operator")
14805                  (const_string "fmul")
14806                (match_operand:DF 3 "div_operator")
14807                  (const_string "fdiv")
14808               ]
14809               (const_string "fop")))
14810    (set_attr "mode" "SF")])
14812 (define_insn "*fop_df_5_i387"
14813   [(set (match_operand:DF 0 "register_operand" "=f,f")
14814         (match_operator:DF 3 "binary_fp_operator"
14815           [(match_operand:DF 1 "register_operand" "0,f")
14816            (float_extend:DF
14817             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14818   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14819    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14820   "* return output_387_binary_op (insn, operands);"
14821   [(set (attr "type")
14822         (cond [(match_operand:DF 3 "mult_operator")
14823                  (const_string "fmul")
14824                (match_operand:DF 3 "div_operator")
14825                  (const_string "fdiv")
14826               ]
14827               (const_string "fop")))
14828    (set_attr "mode" "SF")])
14830 (define_insn "*fop_df_6_i387"
14831   [(set (match_operand:DF 0 "register_operand" "=f,f")
14832         (match_operator:DF 3 "binary_fp_operator"
14833           [(float_extend:DF
14834             (match_operand:SF 1 "register_operand" "0,f"))
14835            (float_extend:DF
14836             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14837   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14838    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14839   "* return output_387_binary_op (insn, operands);"
14840   [(set (attr "type")
14841         (cond [(match_operand:DF 3 "mult_operator")
14842                  (const_string "fmul")
14843                (match_operand:DF 3 "div_operator")
14844                  (const_string "fdiv")
14845               ]
14846               (const_string "fop")))
14847    (set_attr "mode" "SF")])
14849 (define_insn "*fop_xf_comm_i387"
14850   [(set (match_operand:XF 0 "register_operand" "=f")
14851         (match_operator:XF 3 "binary_fp_operator"
14852                         [(match_operand:XF 1 "register_operand" "%0")
14853                          (match_operand:XF 2 "register_operand" "f")]))]
14854   "TARGET_80387
14855    && COMMUTATIVE_ARITH_P (operands[3])"
14856   "* return output_387_binary_op (insn, operands);"
14857   [(set (attr "type")
14858         (if_then_else (match_operand:XF 3 "mult_operator")
14859            (const_string "fmul")
14860            (const_string "fop")))
14861    (set_attr "mode" "XF")])
14863 (define_insn "*fop_xf_1_i387"
14864   [(set (match_operand:XF 0 "register_operand" "=f,f")
14865         (match_operator:XF 3 "binary_fp_operator"
14866                         [(match_operand:XF 1 "register_operand" "0,f")
14867                          (match_operand:XF 2 "register_operand" "f,0")]))]
14868   "TARGET_80387
14869    && !COMMUTATIVE_ARITH_P (operands[3])"
14870   "* return output_387_binary_op (insn, operands);"
14871   [(set (attr "type")
14872         (if_then_else (match_operand:XF 3 "div_operator")
14873            (const_string "fdiv")
14874            (const_string "fop")))
14875    (set_attr "mode" "XF")])
14877 (define_insn "*fop_xf_2_i387"
14878   [(set (match_operand:XF 0 "register_operand" "=f")
14879         (match_operator:XF 3 "binary_fp_operator"
14880           [(float:XF
14881              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14882            (match_operand:XF 2 "register_operand" "0")]))]
14883   "TARGET_80387
14884    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14885   "* return output_387_binary_op (insn, operands);"
14886   [(set (attr "type")
14887         (cond [(match_operand:XF 3 "mult_operator")
14888                  (const_string "fmul")
14889                (match_operand:XF 3 "div_operator")
14890                  (const_string "fdiv")
14891               ]
14892               (const_string "fop")))
14893    (set_attr "fp_int_src" "true")
14894    (set_attr "mode" "<MODE>")])
14896 (define_insn "*fop_xf_3_i387"
14897   [(set (match_operand:XF 0 "register_operand" "=f")
14898         (match_operator:XF 3 "binary_fp_operator"
14899           [(match_operand:XF 1 "register_operand" "0")
14900            (float:XF
14901              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14902   "TARGET_80387
14903    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14904   "* return output_387_binary_op (insn, operands);"
14905   [(set (attr "type")
14906         (cond [(match_operand:XF 3 "mult_operator")
14907                  (const_string "fmul")
14908                (match_operand:XF 3 "div_operator")
14909                  (const_string "fdiv")
14910               ]
14911               (const_string "fop")))
14912    (set_attr "fp_int_src" "true")
14913    (set_attr "mode" "<MODE>")])
14915 (define_insn "*fop_xf_4_i387"
14916   [(set (match_operand:XF 0 "register_operand" "=f,f")
14917         (match_operator:XF 3 "binary_fp_operator"
14918            [(float_extend:XF
14919               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14920             (match_operand:XF 2 "register_operand" "0,f")]))]
14921   "TARGET_80387"
14922   "* return output_387_binary_op (insn, operands);"
14923   [(set (attr "type")
14924         (cond [(match_operand:XF 3 "mult_operator")
14925                  (const_string "fmul")
14926                (match_operand:XF 3 "div_operator")
14927                  (const_string "fdiv")
14928               ]
14929               (const_string "fop")))
14930    (set_attr "mode" "<MODE>")])
14932 (define_insn "*fop_xf_5_i387"
14933   [(set (match_operand:XF 0 "register_operand" "=f,f")
14934         (match_operator:XF 3 "binary_fp_operator"
14935           [(match_operand:XF 1 "register_operand" "0,f")
14936            (float_extend:XF
14937              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14938   "TARGET_80387"
14939   "* return output_387_binary_op (insn, operands);"
14940   [(set (attr "type")
14941         (cond [(match_operand:XF 3 "mult_operator")
14942                  (const_string "fmul")
14943                (match_operand:XF 3 "div_operator")
14944                  (const_string "fdiv")
14945               ]
14946               (const_string "fop")))
14947    (set_attr "mode" "<MODE>")])
14949 (define_insn "*fop_xf_6_i387"
14950   [(set (match_operand:XF 0 "register_operand" "=f,f")
14951         (match_operator:XF 3 "binary_fp_operator"
14952           [(float_extend:XF
14953              (match_operand:MODEF 1 "register_operand" "0,f"))
14954            (float_extend:XF
14955              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14956   "TARGET_80387"
14957   "* return output_387_binary_op (insn, operands);"
14958   [(set (attr "type")
14959         (cond [(match_operand:XF 3 "mult_operator")
14960                  (const_string "fmul")
14961                (match_operand:XF 3 "div_operator")
14962                  (const_string "fdiv")
14963               ]
14964               (const_string "fop")))
14965    (set_attr "mode" "<MODE>")])
14967 ;; FPU special functions.
14969 ;; This pattern implements a no-op XFmode truncation for
14970 ;; all fancy i386 XFmode math functions.
14972 (define_insn "truncxf<mode>2_i387_noop_unspec"
14973   [(set (match_operand:MODEF 0 "register_operand" "=f")
14974         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14975         UNSPEC_TRUNC_NOOP))]
14976   "TARGET_USE_FANCY_MATH_387"
14977   "* return output_387_reg_move (insn, operands);"
14978   [(set_attr "type" "fmov")
14979    (set_attr "mode" "<MODE>")])
14981 (define_insn "sqrtxf2"
14982   [(set (match_operand:XF 0 "register_operand" "=f")
14983         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14984   "TARGET_USE_FANCY_MATH_387"
14985   "fsqrt"
14986   [(set_attr "type" "fpspc")
14987    (set_attr "mode" "XF")
14988    (set_attr "athlon_decode" "direct")
14989    (set_attr "amdfam10_decode" "direct")
14990    (set_attr "bdver1_decode" "direct")])
14992 (define_insn "sqrt_extend<mode>xf2_i387"
14993   [(set (match_operand:XF 0 "register_operand" "=f")
14994         (sqrt:XF
14995           (float_extend:XF
14996             (match_operand:MODEF 1 "register_operand" "0"))))]
14997   "TARGET_USE_FANCY_MATH_387"
14998   "fsqrt"
14999   [(set_attr "type" "fpspc")
15000    (set_attr "mode" "XF")
15001    (set_attr "athlon_decode" "direct")
15002    (set_attr "amdfam10_decode" "direct")
15003    (set_attr "bdver1_decode" "direct")])
15005 (define_insn "*rsqrtsf2_sse"
15006   [(set (match_operand:SF 0 "register_operand" "=x")
15007         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15008                    UNSPEC_RSQRT))]
15009   "TARGET_SSE && TARGET_SSE_MATH"
15010   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15011   [(set_attr "type" "sse")
15012    (set_attr "atom_sse_attr" "rcp")
15013    (set_attr "btver2_sse_attr" "rcp")
15014    (set_attr "prefix" "maybe_vex")
15015    (set_attr "mode" "SF")])
15017 (define_expand "rsqrtsf2"
15018   [(set (match_operand:SF 0 "register_operand")
15019         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15020                    UNSPEC_RSQRT))]
15021   "TARGET_SSE && TARGET_SSE_MATH"
15023   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15024   DONE;
15027 (define_insn "*sqrt<mode>2_sse"
15028   [(set (match_operand:MODEF 0 "register_operand" "=v")
15029         (sqrt:MODEF
15030           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15031   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15032   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15033   [(set_attr "type" "sse")
15034    (set_attr "atom_sse_attr" "sqrt")
15035    (set_attr "btver2_sse_attr" "sqrt")
15036    (set_attr "prefix" "maybe_vex")
15037    (set_attr "mode" "<MODE>")
15038    (set_attr "athlon_decode" "*")
15039    (set_attr "amdfam10_decode" "*")
15040    (set_attr "bdver1_decode" "*")])
15042 (define_expand "sqrt<mode>2"
15043   [(set (match_operand:MODEF 0 "register_operand")
15044         (sqrt:MODEF
15045           (match_operand:MODEF 1 "nonimmediate_operand")))]
15046   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15047    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15049   if (<MODE>mode == SFmode
15050       && TARGET_SSE && TARGET_SSE_MATH
15051       && TARGET_RECIP_SQRT
15052       && !optimize_function_for_size_p (cfun)
15053       && flag_finite_math_only && !flag_trapping_math
15054       && flag_unsafe_math_optimizations)
15055     {
15056       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15057       DONE;
15058     }
15060   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15061     {
15062       rtx op0 = gen_reg_rtx (XFmode);
15063       rtx op1 = force_reg (<MODE>mode, operands[1]);
15065       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15066       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15067       DONE;
15068    }
15071 (define_insn "fpremxf4_i387"
15072   [(set (match_operand:XF 0 "register_operand" "=f")
15073         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15074                     (match_operand:XF 3 "register_operand" "1")]
15075                    UNSPEC_FPREM_F))
15076    (set (match_operand:XF 1 "register_operand" "=u")
15077         (unspec:XF [(match_dup 2) (match_dup 3)]
15078                    UNSPEC_FPREM_U))
15079    (set (reg:CCFP FPSR_REG)
15080         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15081                      UNSPEC_C2_FLAG))]
15082   "TARGET_USE_FANCY_MATH_387
15083    && flag_finite_math_only"
15084   "fprem"
15085   [(set_attr "type" "fpspc")
15086    (set_attr "znver1_decode" "vector")
15087    (set_attr "mode" "XF")])
15089 (define_expand "fmodxf3"
15090   [(use (match_operand:XF 0 "register_operand"))
15091    (use (match_operand:XF 1 "general_operand"))
15092    (use (match_operand:XF 2 "general_operand"))]
15093   "TARGET_USE_FANCY_MATH_387
15094    && flag_finite_math_only"
15096   rtx_code_label *label = gen_label_rtx ();
15098   rtx op1 = gen_reg_rtx (XFmode);
15099   rtx op2 = gen_reg_rtx (XFmode);
15101   emit_move_insn (op2, operands[2]);
15102   emit_move_insn (op1, operands[1]);
15104   emit_label (label);
15105   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15106   ix86_emit_fp_unordered_jump (label);
15107   LABEL_NUSES (label) = 1;
15109   emit_move_insn (operands[0], op1);
15110   DONE;
15113 (define_expand "fmod<mode>3"
15114   [(use (match_operand:MODEF 0 "register_operand"))
15115    (use (match_operand:MODEF 1 "general_operand"))
15116    (use (match_operand:MODEF 2 "general_operand"))]
15117   "TARGET_USE_FANCY_MATH_387
15118    && flag_finite_math_only"
15120   rtx (*gen_truncxf) (rtx, rtx);
15122   rtx_code_label *label = gen_label_rtx ();
15124   rtx op1 = gen_reg_rtx (XFmode);
15125   rtx op2 = gen_reg_rtx (XFmode);
15127   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15128   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15130   emit_label (label);
15131   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15132   ix86_emit_fp_unordered_jump (label);
15133   LABEL_NUSES (label) = 1;
15135   /* Truncate the result properly for strict SSE math.  */
15136   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15137       && !TARGET_MIX_SSE_I387)
15138     gen_truncxf = gen_truncxf<mode>2;
15139   else
15140     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15142   emit_insn (gen_truncxf (operands[0], op1));
15143   DONE;
15146 (define_insn "fprem1xf4_i387"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15149                     (match_operand:XF 3 "register_operand" "1")]
15150                    UNSPEC_FPREM1_F))
15151    (set (match_operand:XF 1 "register_operand" "=u")
15152         (unspec:XF [(match_dup 2) (match_dup 3)]
15153                    UNSPEC_FPREM1_U))
15154    (set (reg:CCFP FPSR_REG)
15155         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15156                      UNSPEC_C2_FLAG))]
15157   "TARGET_USE_FANCY_MATH_387
15158    && flag_finite_math_only"
15159   "fprem1"
15160   [(set_attr "type" "fpspc")
15161    (set_attr "znver1_decode" "vector")
15162    (set_attr "mode" "XF")])
15164 (define_expand "remainderxf3"
15165   [(use (match_operand:XF 0 "register_operand"))
15166    (use (match_operand:XF 1 "general_operand"))
15167    (use (match_operand:XF 2 "general_operand"))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_finite_math_only"
15171   rtx_code_label *label = gen_label_rtx ();
15173   rtx op1 = gen_reg_rtx (XFmode);
15174   rtx op2 = gen_reg_rtx (XFmode);
15176   emit_move_insn (op2, operands[2]);
15177   emit_move_insn (op1, operands[1]);
15179   emit_label (label);
15180   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15181   ix86_emit_fp_unordered_jump (label);
15182   LABEL_NUSES (label) = 1;
15184   emit_move_insn (operands[0], op1);
15185   DONE;
15188 (define_expand "remainder<mode>3"
15189   [(use (match_operand:MODEF 0 "register_operand"))
15190    (use (match_operand:MODEF 1 "general_operand"))
15191    (use (match_operand:MODEF 2 "general_operand"))]
15192   "TARGET_USE_FANCY_MATH_387
15193    && flag_finite_math_only"
15195   rtx (*gen_truncxf) (rtx, rtx);
15197   rtx_code_label *label = gen_label_rtx ();
15199   rtx op1 = gen_reg_rtx (XFmode);
15200   rtx op2 = gen_reg_rtx (XFmode);
15202   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15203   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15205   emit_label (label);
15207   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15208   ix86_emit_fp_unordered_jump (label);
15209   LABEL_NUSES (label) = 1;
15211   /* Truncate the result properly for strict SSE math.  */
15212   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15213       && !TARGET_MIX_SSE_I387)
15214     gen_truncxf = gen_truncxf<mode>2;
15215   else
15216     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15218   emit_insn (gen_truncxf (operands[0], op1));
15219   DONE;
15222 (define_int_iterator SINCOS
15223         [UNSPEC_SIN
15224          UNSPEC_COS])
15226 (define_int_attr sincos
15227         [(UNSPEC_SIN "sin")
15228          (UNSPEC_COS "cos")])
15230 (define_insn "*<sincos>xf2_i387"
15231   [(set (match_operand:XF 0 "register_operand" "=f")
15232         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15233                    SINCOS))]
15234   "TARGET_USE_FANCY_MATH_387
15235    && flag_unsafe_math_optimizations"
15236   "f<sincos>"
15237   [(set_attr "type" "fpspc")
15238    (set_attr "znver1_decode" "vector")
15239    (set_attr "mode" "XF")])
15241 (define_insn "*<sincos>_extend<mode>xf2_i387"
15242   [(set (match_operand:XF 0 "register_operand" "=f")
15243         (unspec:XF [(float_extend:XF
15244                       (match_operand:MODEF 1 "register_operand" "0"))]
15245                    SINCOS))]
15246   "TARGET_USE_FANCY_MATH_387
15247    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15248        || TARGET_MIX_SSE_I387)
15249    && flag_unsafe_math_optimizations"
15250   "f<sincos>"
15251   [(set_attr "type" "fpspc")
15252    (set_attr "znver1_decode" "vector")
15253    (set_attr "mode" "XF")])
15255 ;; When sincos pattern is defined, sin and cos builtin functions will be
15256 ;; expanded to sincos pattern with one of its outputs left unused.
15257 ;; CSE pass will figure out if two sincos patterns can be combined,
15258 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15259 ;; depending on the unused output.
15261 (define_insn "sincosxf3"
15262   [(set (match_operand:XF 0 "register_operand" "=f")
15263         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15264                    UNSPEC_SINCOS_COS))
15265    (set (match_operand:XF 1 "register_operand" "=u")
15266         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15267   "TARGET_USE_FANCY_MATH_387
15268    && flag_unsafe_math_optimizations"
15269   "fsincos"
15270   [(set_attr "type" "fpspc")
15271    (set_attr "znver1_decode" "vector")
15272    (set_attr "mode" "XF")])
15274 (define_split
15275   [(set (match_operand:XF 0 "register_operand")
15276         (unspec:XF [(match_operand:XF 2 "register_operand")]
15277                    UNSPEC_SINCOS_COS))
15278    (set (match_operand:XF 1 "register_operand")
15279         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15280   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15281    && can_create_pseudo_p ()"
15282   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15284 (define_split
15285   [(set (match_operand:XF 0 "register_operand")
15286         (unspec:XF [(match_operand:XF 2 "register_operand")]
15287                    UNSPEC_SINCOS_COS))
15288    (set (match_operand:XF 1 "register_operand")
15289         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15290   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15291    && can_create_pseudo_p ()"
15292   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15294 (define_insn "sincos_extend<mode>xf3_i387"
15295   [(set (match_operand:XF 0 "register_operand" "=f")
15296         (unspec:XF [(float_extend:XF
15297                       (match_operand:MODEF 2 "register_operand" "0"))]
15298                    UNSPEC_SINCOS_COS))
15299    (set (match_operand:XF 1 "register_operand" "=u")
15300         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15301   "TARGET_USE_FANCY_MATH_387
15302    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15303        || TARGET_MIX_SSE_I387)
15304    && flag_unsafe_math_optimizations"
15305   "fsincos"
15306   [(set_attr "type" "fpspc")
15307    (set_attr "znver1_decode" "vector")
15308    (set_attr "mode" "XF")])
15310 (define_split
15311   [(set (match_operand:XF 0 "register_operand")
15312         (unspec:XF [(float_extend:XF
15313                       (match_operand:MODEF 2 "register_operand"))]
15314                    UNSPEC_SINCOS_COS))
15315    (set (match_operand:XF 1 "register_operand")
15316         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15317   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15318    && can_create_pseudo_p ()"
15319   [(set (match_dup 1)
15320         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15322 (define_split
15323   [(set (match_operand:XF 0 "register_operand")
15324         (unspec:XF [(float_extend:XF
15325                       (match_operand:MODEF 2 "register_operand"))]
15326                    UNSPEC_SINCOS_COS))
15327    (set (match_operand:XF 1 "register_operand")
15328         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15329   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15330    && can_create_pseudo_p ()"
15331   [(set (match_dup 0)
15332         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15334 (define_expand "sincos<mode>3"
15335   [(use (match_operand:MODEF 0 "register_operand"))
15336    (use (match_operand:MODEF 1 "register_operand"))
15337    (use (match_operand:MODEF 2 "register_operand"))]
15338   "TARGET_USE_FANCY_MATH_387
15339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15340        || TARGET_MIX_SSE_I387)
15341    && flag_unsafe_math_optimizations"
15343   rtx op0 = gen_reg_rtx (XFmode);
15344   rtx op1 = gen_reg_rtx (XFmode);
15346   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15347   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15348   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15349   DONE;
15352 (define_insn "fptanxf4_i387"
15353   [(set (match_operand:XF 0 "register_operand" "=f")
15354         (match_operand:XF 3 "const_double_operand" "F"))
15355    (set (match_operand:XF 1 "register_operand" "=u")
15356         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15357                    UNSPEC_TAN))]
15358   "TARGET_USE_FANCY_MATH_387
15359    && flag_unsafe_math_optimizations
15360    && standard_80387_constant_p (operands[3]) == 2"
15361   "fptan"
15362   [(set_attr "type" "fpspc")
15363    (set_attr "znver1_decode" "vector")
15364    (set_attr "mode" "XF")])
15366 (define_insn "fptan_extend<mode>xf4_i387"
15367   [(set (match_operand:MODEF 0 "register_operand" "=f")
15368         (match_operand:MODEF 3 "const_double_operand" "F"))
15369    (set (match_operand:XF 1 "register_operand" "=u")
15370         (unspec:XF [(float_extend:XF
15371                       (match_operand:MODEF 2 "register_operand" "0"))]
15372                    UNSPEC_TAN))]
15373   "TARGET_USE_FANCY_MATH_387
15374    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15375        || TARGET_MIX_SSE_I387)
15376    && flag_unsafe_math_optimizations
15377    && standard_80387_constant_p (operands[3]) == 2"
15378   "fptan"
15379   [(set_attr "type" "fpspc")
15380    (set_attr "znver1_decode" "vector")
15381    (set_attr "mode" "XF")])
15383 (define_expand "tanxf2"
15384   [(use (match_operand:XF 0 "register_operand"))
15385    (use (match_operand:XF 1 "register_operand"))]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations"
15389   rtx one = gen_reg_rtx (XFmode);
15390   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15392   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15393   DONE;
15396 (define_expand "tan<mode>2"
15397   [(use (match_operand:MODEF 0 "register_operand"))
15398    (use (match_operand:MODEF 1 "register_operand"))]
15399   "TARGET_USE_FANCY_MATH_387
15400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401        || TARGET_MIX_SSE_I387)
15402    && flag_unsafe_math_optimizations"
15404   rtx op0 = gen_reg_rtx (XFmode);
15406   rtx one = gen_reg_rtx (<MODE>mode);
15407   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15409   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15410                                              operands[1], op2));
15411   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15412   DONE;
15415 (define_insn "*fpatanxf3_i387"
15416   [(set (match_operand:XF 0 "register_operand" "=f")
15417         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15418                     (match_operand:XF 2 "register_operand" "u")]
15419                    UNSPEC_FPATAN))
15420    (clobber (match_scratch:XF 3 "=2"))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && flag_unsafe_math_optimizations"
15423   "fpatan"
15424   [(set_attr "type" "fpspc")
15425    (set_attr "znver1_decode" "vector")
15426    (set_attr "mode" "XF")])
15428 (define_insn "fpatan_extend<mode>xf3_i387"
15429   [(set (match_operand:XF 0 "register_operand" "=f")
15430         (unspec:XF [(float_extend:XF
15431                       (match_operand:MODEF 1 "register_operand" "0"))
15432                     (float_extend:XF
15433                       (match_operand:MODEF 2 "register_operand" "u"))]
15434                    UNSPEC_FPATAN))
15435    (clobber (match_scratch:XF 3 "=2"))]
15436   "TARGET_USE_FANCY_MATH_387
15437    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15438        || TARGET_MIX_SSE_I387)
15439    && flag_unsafe_math_optimizations"
15440   "fpatan"
15441   [(set_attr "type" "fpspc")
15442    (set_attr "znver1_decode" "vector")
15443    (set_attr "mode" "XF")])
15445 (define_expand "atan2xf3"
15446   [(parallel [(set (match_operand:XF 0 "register_operand")
15447                    (unspec:XF [(match_operand:XF 2 "register_operand")
15448                                (match_operand:XF 1 "register_operand")]
15449                               UNSPEC_FPATAN))
15450               (clobber (match_scratch:XF 3))])]
15451   "TARGET_USE_FANCY_MATH_387
15452    && flag_unsafe_math_optimizations")
15454 (define_expand "atan2<mode>3"
15455   [(use (match_operand:MODEF 0 "register_operand"))
15456    (use (match_operand:MODEF 1 "register_operand"))
15457    (use (match_operand:MODEF 2 "register_operand"))]
15458   "TARGET_USE_FANCY_MATH_387
15459    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15460        || TARGET_MIX_SSE_I387)
15461    && flag_unsafe_math_optimizations"
15463   rtx op0 = gen_reg_rtx (XFmode);
15465   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15466   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15467   DONE;
15470 (define_expand "atanxf2"
15471   [(parallel [(set (match_operand:XF 0 "register_operand")
15472                    (unspec:XF [(match_dup 2)
15473                                (match_operand:XF 1 "register_operand")]
15474                               UNSPEC_FPATAN))
15475               (clobber (match_scratch:XF 3))])]
15476   "TARGET_USE_FANCY_MATH_387
15477    && flag_unsafe_math_optimizations"
15479   operands[2] = gen_reg_rtx (XFmode);
15480   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15483 (define_expand "atan<mode>2"
15484   [(use (match_operand:MODEF 0 "register_operand"))
15485    (use (match_operand:MODEF 1 "register_operand"))]
15486   "TARGET_USE_FANCY_MATH_387
15487    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15488        || TARGET_MIX_SSE_I387)
15489    && flag_unsafe_math_optimizations"
15491   rtx op0 = gen_reg_rtx (XFmode);
15493   rtx op2 = gen_reg_rtx (<MODE>mode);
15494   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15496   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15497   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15498   DONE;
15501 (define_expand "asinxf2"
15502   [(set (match_dup 2)
15503         (mult:XF (match_operand:XF 1 "register_operand")
15504                  (match_dup 1)))
15505    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15506    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15507    (parallel [(set (match_operand:XF 0 "register_operand")
15508                    (unspec:XF [(match_dup 5) (match_dup 1)]
15509                               UNSPEC_FPATAN))
15510               (clobber (match_scratch:XF 6))])]
15511   "TARGET_USE_FANCY_MATH_387
15512    && flag_unsafe_math_optimizations"
15514   int i;
15516   for (i = 2; i < 6; i++)
15517     operands[i] = gen_reg_rtx (XFmode);
15519   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15522 (define_expand "asin<mode>2"
15523   [(use (match_operand:MODEF 0 "register_operand"))
15524    (use (match_operand:MODEF 1 "general_operand"))]
15525   "TARGET_USE_FANCY_MATH_387
15526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15527        || TARGET_MIX_SSE_I387)
15528    && flag_unsafe_math_optimizations"
15530   rtx op0 = gen_reg_rtx (XFmode);
15531   rtx op1 = gen_reg_rtx (XFmode);
15533   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15534   emit_insn (gen_asinxf2 (op0, op1));
15535   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15536   DONE;
15539 (define_expand "acosxf2"
15540   [(set (match_dup 2)
15541         (mult:XF (match_operand:XF 1 "register_operand")
15542                  (match_dup 1)))
15543    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15544    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15545    (parallel [(set (match_operand:XF 0 "register_operand")
15546                    (unspec:XF [(match_dup 1) (match_dup 5)]
15547                               UNSPEC_FPATAN))
15548               (clobber (match_scratch:XF 6))])]
15549   "TARGET_USE_FANCY_MATH_387
15550    && flag_unsafe_math_optimizations"
15552   int i;
15554   for (i = 2; i < 6; i++)
15555     operands[i] = gen_reg_rtx (XFmode);
15557   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15560 (define_expand "acos<mode>2"
15561   [(use (match_operand:MODEF 0 "register_operand"))
15562    (use (match_operand:MODEF 1 "general_operand"))]
15563   "TARGET_USE_FANCY_MATH_387
15564    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15565        || TARGET_MIX_SSE_I387)
15566    && flag_unsafe_math_optimizations"
15568   rtx op0 = gen_reg_rtx (XFmode);
15569   rtx op1 = gen_reg_rtx (XFmode);
15571   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15572   emit_insn (gen_acosxf2 (op0, op1));
15573   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15574   DONE;
15577 (define_insn "fyl2xxf3_i387"
15578   [(set (match_operand:XF 0 "register_operand" "=f")
15579         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15580                     (match_operand:XF 2 "register_operand" "u")]
15581                    UNSPEC_FYL2X))
15582    (clobber (match_scratch:XF 3 "=2"))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && flag_unsafe_math_optimizations"
15585   "fyl2x"
15586   [(set_attr "type" "fpspc")
15587    (set_attr "znver1_decode" "vector")
15588    (set_attr "mode" "XF")])
15590 (define_insn "fyl2x_extend<mode>xf3_i387"
15591   [(set (match_operand:XF 0 "register_operand" "=f")
15592         (unspec:XF [(float_extend:XF
15593                       (match_operand:MODEF 1 "register_operand" "0"))
15594                     (match_operand:XF 2 "register_operand" "u")]
15595                    UNSPEC_FYL2X))
15596    (clobber (match_scratch:XF 3 "=2"))]
15597   "TARGET_USE_FANCY_MATH_387
15598    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15599        || TARGET_MIX_SSE_I387)
15600    && flag_unsafe_math_optimizations"
15601   "fyl2x"
15602   [(set_attr "type" "fpspc")
15603    (set_attr "znver1_decode" "vector")
15604    (set_attr "mode" "XF")])
15606 (define_expand "logxf2"
15607   [(parallel [(set (match_operand:XF 0 "register_operand")
15608                    (unspec:XF [(match_operand:XF 1 "register_operand")
15609                                (match_dup 2)] UNSPEC_FYL2X))
15610               (clobber (match_scratch:XF 3))])]
15611   "TARGET_USE_FANCY_MATH_387
15612    && flag_unsafe_math_optimizations"
15614   operands[2] = gen_reg_rtx (XFmode);
15615   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15618 (define_expand "log<mode>2"
15619   [(use (match_operand:MODEF 0 "register_operand"))
15620    (use (match_operand:MODEF 1 "register_operand"))]
15621   "TARGET_USE_FANCY_MATH_387
15622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15623        || TARGET_MIX_SSE_I387)
15624    && flag_unsafe_math_optimizations"
15626   rtx op0 = gen_reg_rtx (XFmode);
15628   rtx op2 = gen_reg_rtx (XFmode);
15629   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15631   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15632   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15633   DONE;
15636 (define_expand "log10xf2"
15637   [(parallel [(set (match_operand:XF 0 "register_operand")
15638                    (unspec:XF [(match_operand:XF 1 "register_operand")
15639                                (match_dup 2)] UNSPEC_FYL2X))
15640               (clobber (match_scratch:XF 3))])]
15641   "TARGET_USE_FANCY_MATH_387
15642    && flag_unsafe_math_optimizations"
15644   operands[2] = gen_reg_rtx (XFmode);
15645   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15648 (define_expand "log10<mode>2"
15649   [(use (match_operand:MODEF 0 "register_operand"))
15650    (use (match_operand:MODEF 1 "register_operand"))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15653        || TARGET_MIX_SSE_I387)
15654    && flag_unsafe_math_optimizations"
15656   rtx op0 = gen_reg_rtx (XFmode);
15658   rtx op2 = gen_reg_rtx (XFmode);
15659   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15661   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15662   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15663   DONE;
15666 (define_expand "log2xf2"
15667   [(parallel [(set (match_operand:XF 0 "register_operand")
15668                    (unspec:XF [(match_operand:XF 1 "register_operand")
15669                                (match_dup 2)] UNSPEC_FYL2X))
15670               (clobber (match_scratch:XF 3))])]
15671   "TARGET_USE_FANCY_MATH_387
15672    && flag_unsafe_math_optimizations"
15674   operands[2] = gen_reg_rtx (XFmode);
15675   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15678 (define_expand "log2<mode>2"
15679   [(use (match_operand:MODEF 0 "register_operand"))
15680    (use (match_operand:MODEF 1 "register_operand"))]
15681   "TARGET_USE_FANCY_MATH_387
15682    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15683        || TARGET_MIX_SSE_I387)
15684    && flag_unsafe_math_optimizations"
15686   rtx op0 = gen_reg_rtx (XFmode);
15688   rtx op2 = gen_reg_rtx (XFmode);
15689   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15691   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15692   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15693   DONE;
15696 (define_insn "fyl2xp1xf3_i387"
15697   [(set (match_operand:XF 0 "register_operand" "=f")
15698         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15699                     (match_operand:XF 2 "register_operand" "u")]
15700                    UNSPEC_FYL2XP1))
15701    (clobber (match_scratch:XF 3 "=2"))]
15702   "TARGET_USE_FANCY_MATH_387
15703    && flag_unsafe_math_optimizations"
15704   "fyl2xp1"
15705   [(set_attr "type" "fpspc")
15706    (set_attr "znver1_decode" "vector")
15707    (set_attr "mode" "XF")])
15709 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15710   [(set (match_operand:XF 0 "register_operand" "=f")
15711         (unspec:XF [(float_extend:XF
15712                       (match_operand:MODEF 1 "register_operand" "0"))
15713                     (match_operand:XF 2 "register_operand" "u")]
15714                    UNSPEC_FYL2XP1))
15715    (clobber (match_scratch:XF 3 "=2"))]
15716   "TARGET_USE_FANCY_MATH_387
15717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15718        || TARGET_MIX_SSE_I387)
15719    && flag_unsafe_math_optimizations"
15720   "fyl2xp1"
15721   [(set_attr "type" "fpspc")
15722    (set_attr "znver1_decode" "vector")
15723    (set_attr "mode" "XF")])
15725 (define_expand "log1pxf2"
15726   [(use (match_operand:XF 0 "register_operand"))
15727    (use (match_operand:XF 1 "register_operand"))]
15728   "TARGET_USE_FANCY_MATH_387
15729    && flag_unsafe_math_optimizations"
15731   ix86_emit_i387_log1p (operands[0], operands[1]);
15732   DONE;
15735 (define_expand "log1p<mode>2"
15736   [(use (match_operand:MODEF 0 "register_operand"))
15737    (use (match_operand:MODEF 1 "register_operand"))]
15738   "TARGET_USE_FANCY_MATH_387
15739    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15740        || TARGET_MIX_SSE_I387)
15741    && flag_unsafe_math_optimizations"
15743   rtx op0;
15745   op0 = gen_reg_rtx (XFmode);
15747   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15749   ix86_emit_i387_log1p (op0, operands[1]);
15750   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15751   DONE;
15754 (define_insn "fxtractxf3_i387"
15755   [(set (match_operand:XF 0 "register_operand" "=f")
15756         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15757                    UNSPEC_XTRACT_FRACT))
15758    (set (match_operand:XF 1 "register_operand" "=u")
15759         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15760   "TARGET_USE_FANCY_MATH_387
15761    && flag_unsafe_math_optimizations"
15762   "fxtract"
15763   [(set_attr "type" "fpspc")
15764    (set_attr "znver1_decode" "vector")
15765    (set_attr "mode" "XF")])
15767 (define_insn "fxtract_extend<mode>xf3_i387"
15768   [(set (match_operand:XF 0 "register_operand" "=f")
15769         (unspec:XF [(float_extend:XF
15770                       (match_operand:MODEF 2 "register_operand" "0"))]
15771                    UNSPEC_XTRACT_FRACT))
15772    (set (match_operand:XF 1 "register_operand" "=u")
15773         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15774   "TARGET_USE_FANCY_MATH_387
15775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15776        || TARGET_MIX_SSE_I387)
15777    && flag_unsafe_math_optimizations"
15778   "fxtract"
15779   [(set_attr "type" "fpspc")
15780    (set_attr "znver1_decode" "vector")
15781    (set_attr "mode" "XF")])
15783 (define_expand "logbxf2"
15784   [(parallel [(set (match_dup 2)
15785                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15786                               UNSPEC_XTRACT_FRACT))
15787               (set (match_operand:XF 0 "register_operand")
15788                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15789   "TARGET_USE_FANCY_MATH_387
15790    && flag_unsafe_math_optimizations"
15791   "operands[2] = gen_reg_rtx (XFmode);")
15793 (define_expand "logb<mode>2"
15794   [(use (match_operand:MODEF 0 "register_operand"))
15795    (use (match_operand:MODEF 1 "register_operand"))]
15796   "TARGET_USE_FANCY_MATH_387
15797    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15798        || TARGET_MIX_SSE_I387)
15799    && flag_unsafe_math_optimizations"
15801   rtx op0 = gen_reg_rtx (XFmode);
15802   rtx op1 = gen_reg_rtx (XFmode);
15804   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15805   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15806   DONE;
15809 (define_expand "ilogbxf2"
15810   [(use (match_operand:SI 0 "register_operand"))
15811    (use (match_operand:XF 1 "register_operand"))]
15812   "TARGET_USE_FANCY_MATH_387
15813    && flag_unsafe_math_optimizations"
15815   rtx op0, op1;
15817   if (optimize_insn_for_size_p ())
15818     FAIL;
15820   op0 = gen_reg_rtx (XFmode);
15821   op1 = gen_reg_rtx (XFmode);
15823   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15824   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15825   DONE;
15828 (define_expand "ilogb<mode>2"
15829   [(use (match_operand:SI 0 "register_operand"))
15830    (use (match_operand:MODEF 1 "register_operand"))]
15831   "TARGET_USE_FANCY_MATH_387
15832    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15833        || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15836   rtx op0, op1;
15838   if (optimize_insn_for_size_p ())
15839     FAIL;
15841   op0 = gen_reg_rtx (XFmode);
15842   op1 = gen_reg_rtx (XFmode);
15844   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15845   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15846   DONE;
15849 (define_insn "*f2xm1xf2_i387"
15850   [(set (match_operand:XF 0 "register_operand" "=f")
15851         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15852                    UNSPEC_F2XM1))]
15853   "TARGET_USE_FANCY_MATH_387
15854    && flag_unsafe_math_optimizations"
15855   "f2xm1"
15856   [(set_attr "type" "fpspc")
15857    (set_attr "znver1_decode" "vector")
15858    (set_attr "mode" "XF")])
15860 (define_insn "fscalexf4_i387"
15861   [(set (match_operand:XF 0 "register_operand" "=f")
15862         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15863                     (match_operand:XF 3 "register_operand" "1")]
15864                    UNSPEC_FSCALE_FRACT))
15865    (set (match_operand:XF 1 "register_operand" "=u")
15866         (unspec:XF [(match_dup 2) (match_dup 3)]
15867                    UNSPEC_FSCALE_EXP))]
15868   "TARGET_USE_FANCY_MATH_387
15869    && flag_unsafe_math_optimizations"
15870   "fscale"
15871   [(set_attr "type" "fpspc")
15872    (set_attr "znver1_decode" "vector")
15873    (set_attr "mode" "XF")])
15875 (define_expand "expNcorexf3"
15876   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15877                                (match_operand:XF 2 "register_operand")))
15878    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15879    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15880    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15881    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15882    (parallel [(set (match_operand:XF 0 "register_operand")
15883                    (unspec:XF [(match_dup 8) (match_dup 4)]
15884                               UNSPEC_FSCALE_FRACT))
15885               (set (match_dup 9)
15886                    (unspec:XF [(match_dup 8) (match_dup 4)]
15887                               UNSPEC_FSCALE_EXP))])]
15888   "TARGET_USE_FANCY_MATH_387
15889    && flag_unsafe_math_optimizations"
15891   int i;
15893   for (i = 3; i < 10; i++)
15894     operands[i] = gen_reg_rtx (XFmode);
15896   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15899 (define_expand "expxf2"
15900   [(use (match_operand:XF 0 "register_operand"))
15901    (use (match_operand:XF 1 "register_operand"))]
15902   "TARGET_USE_FANCY_MATH_387
15903    && flag_unsafe_math_optimizations"
15905   rtx op2;
15907   op2 = gen_reg_rtx (XFmode);
15908   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15910   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15911   DONE;
15914 (define_expand "exp<mode>2"
15915   [(use (match_operand:MODEF 0 "register_operand"))
15916    (use (match_operand:MODEF 1 "general_operand"))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15919        || TARGET_MIX_SSE_I387)
15920    && flag_unsafe_math_optimizations"
15922   rtx op0, op1;
15924   op0 = gen_reg_rtx (XFmode);
15925   op1 = gen_reg_rtx (XFmode);
15927   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15928   emit_insn (gen_expxf2 (op0, op1));
15929   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15930   DONE;
15933 (define_expand "exp10xf2"
15934   [(use (match_operand:XF 0 "register_operand"))
15935    (use (match_operand:XF 1 "register_operand"))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15939   rtx op2;
15941   op2 = gen_reg_rtx (XFmode);
15942   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15944   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15945   DONE;
15948 (define_expand "exp10<mode>2"
15949   [(use (match_operand:MODEF 0 "register_operand"))
15950    (use (match_operand:MODEF 1 "general_operand"))]
15951   "TARGET_USE_FANCY_MATH_387
15952    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15953        || TARGET_MIX_SSE_I387)
15954    && flag_unsafe_math_optimizations"
15956   rtx op0, op1;
15958   op0 = gen_reg_rtx (XFmode);
15959   op1 = gen_reg_rtx (XFmode);
15961   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15962   emit_insn (gen_exp10xf2 (op0, op1));
15963   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15964   DONE;
15967 (define_expand "exp2xf2"
15968   [(use (match_operand:XF 0 "register_operand"))
15969    (use (match_operand:XF 1 "register_operand"))]
15970   "TARGET_USE_FANCY_MATH_387
15971    && flag_unsafe_math_optimizations"
15973   rtx op2;
15975   op2 = gen_reg_rtx (XFmode);
15976   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15978   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15979   DONE;
15982 (define_expand "exp2<mode>2"
15983   [(use (match_operand:MODEF 0 "register_operand"))
15984    (use (match_operand:MODEF 1 "general_operand"))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15987        || TARGET_MIX_SSE_I387)
15988    && flag_unsafe_math_optimizations"
15990   rtx op0, op1;
15992   op0 = gen_reg_rtx (XFmode);
15993   op1 = gen_reg_rtx (XFmode);
15995   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15996   emit_insn (gen_exp2xf2 (op0, op1));
15997   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15998   DONE;
16001 (define_expand "expm1xf2"
16002   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16003                                (match_dup 2)))
16004    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16005    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16006    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16007    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16008    (parallel [(set (match_dup 7)
16009                    (unspec:XF [(match_dup 6) (match_dup 4)]
16010                               UNSPEC_FSCALE_FRACT))
16011               (set (match_dup 8)
16012                    (unspec:XF [(match_dup 6) (match_dup 4)]
16013                               UNSPEC_FSCALE_EXP))])
16014    (parallel [(set (match_dup 10)
16015                    (unspec:XF [(match_dup 9) (match_dup 8)]
16016                               UNSPEC_FSCALE_FRACT))
16017               (set (match_dup 11)
16018                    (unspec:XF [(match_dup 9) (match_dup 8)]
16019                               UNSPEC_FSCALE_EXP))])
16020    (set (match_dup 12) (minus:XF (match_dup 10)
16021                                  (float_extend:XF (match_dup 13))))
16022    (set (match_operand:XF 0 "register_operand")
16023         (plus:XF (match_dup 12) (match_dup 7)))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && flag_unsafe_math_optimizations"
16027   int i;
16029   for (i = 2; i < 13; i++)
16030     operands[i] = gen_reg_rtx (XFmode);
16032   operands[13]
16033     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16035   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16038 (define_expand "expm1<mode>2"
16039   [(use (match_operand:MODEF 0 "register_operand"))
16040    (use (match_operand:MODEF 1 "general_operand"))]
16041   "TARGET_USE_FANCY_MATH_387
16042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16043        || TARGET_MIX_SSE_I387)
16044    && flag_unsafe_math_optimizations"
16046   rtx op0, op1;
16048   op0 = gen_reg_rtx (XFmode);
16049   op1 = gen_reg_rtx (XFmode);
16051   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16052   emit_insn (gen_expm1xf2 (op0, op1));
16053   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16054   DONE;
16057 (define_expand "ldexpxf3"
16058   [(match_operand:XF 0 "register_operand")
16059    (match_operand:XF 1 "register_operand")
16060    (match_operand:SI 2 "register_operand")]
16061   "TARGET_USE_FANCY_MATH_387
16062    && flag_unsafe_math_optimizations"
16064   rtx tmp1, tmp2;
16066   tmp1 = gen_reg_rtx (XFmode);
16067   tmp2 = gen_reg_rtx (XFmode);
16069   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16070   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16071                                  operands[1], tmp1));
16072   DONE;
16075 (define_expand "ldexp<mode>3"
16076   [(use (match_operand:MODEF 0 "register_operand"))
16077    (use (match_operand:MODEF 1 "general_operand"))
16078    (use (match_operand:SI 2 "register_operand"))]
16079   "TARGET_USE_FANCY_MATH_387
16080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081        || TARGET_MIX_SSE_I387)
16082    && flag_unsafe_math_optimizations"
16084   rtx op0, op1;
16086   op0 = gen_reg_rtx (XFmode);
16087   op1 = gen_reg_rtx (XFmode);
16089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16090   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16091   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16092   DONE;
16095 (define_expand "scalbxf3"
16096   [(parallel [(set (match_operand:XF 0 " register_operand")
16097                    (unspec:XF [(match_operand:XF 1 "register_operand")
16098                                (match_operand:XF 2 "register_operand")]
16099                               UNSPEC_FSCALE_FRACT))
16100               (set (match_dup 3)
16101                    (unspec:XF [(match_dup 1) (match_dup 2)]
16102                               UNSPEC_FSCALE_EXP))])]
16103   "TARGET_USE_FANCY_MATH_387
16104    && flag_unsafe_math_optimizations"
16106   operands[3] = gen_reg_rtx (XFmode);
16109 (define_expand "scalb<mode>3"
16110   [(use (match_operand:MODEF 0 "register_operand"))
16111    (use (match_operand:MODEF 1 "general_operand"))
16112    (use (match_operand:MODEF 2 "general_operand"))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115        || TARGET_MIX_SSE_I387)
16116    && flag_unsafe_math_optimizations"
16118   rtx op0, op1, op2;
16120   op0 = gen_reg_rtx (XFmode);
16121   op1 = gen_reg_rtx (XFmode);
16122   op2 = gen_reg_rtx (XFmode);
16124   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16125   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16126   emit_insn (gen_scalbxf3 (op0, op1, op2));
16127   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16128   DONE;
16131 (define_expand "significandxf2"
16132   [(parallel [(set (match_operand:XF 0 "register_operand")
16133                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16134                               UNSPEC_XTRACT_FRACT))
16135               (set (match_dup 2)
16136                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16137   "TARGET_USE_FANCY_MATH_387
16138    && flag_unsafe_math_optimizations"
16139   "operands[2] = gen_reg_rtx (XFmode);")
16141 (define_expand "significand<mode>2"
16142   [(use (match_operand:MODEF 0 "register_operand"))
16143    (use (match_operand:MODEF 1 "register_operand"))]
16144   "TARGET_USE_FANCY_MATH_387
16145    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16146        || TARGET_MIX_SSE_I387)
16147    && flag_unsafe_math_optimizations"
16149   rtx op0 = gen_reg_rtx (XFmode);
16150   rtx op1 = gen_reg_rtx (XFmode);
16152   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16153   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16154   DONE;
16158 (define_insn "sse4_1_round<mode>2"
16159   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16160         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16161                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16162                       UNSPEC_ROUND))]
16163   "TARGET_SSE4_1"
16164   "@
16165    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16166    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16167   [(set_attr "type" "ssecvt")
16168    (set_attr "prefix_extra" "1,*")
16169    (set_attr "length_immediate" "*,1")
16170    (set_attr "prefix" "maybe_vex,evex")
16171    (set_attr "isa" "noavx512f,avx512f")
16172    (set_attr "mode" "<MODE>")])
16174 (define_insn "rintxf2"
16175   [(set (match_operand:XF 0 "register_operand" "=f")
16176         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16177                    UNSPEC_FRNDINT))]
16178   "TARGET_USE_FANCY_MATH_387"
16179   "frndint"
16180   [(set_attr "type" "fpspc")
16181    (set_attr "znver1_decode" "vector")
16182    (set_attr "mode" "XF")])
16184 (define_insn "rint<mode>2_frndint"
16185   [(set (match_operand:MODEF 0 "register_operand" "=f")
16186         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16187                       UNSPEC_FRNDINT))]
16188   "TARGET_USE_FANCY_MATH_387"
16189   "frndint"
16190   [(set_attr "type" "fpspc")
16191    (set_attr "znver1_decode" "vector")
16192    (set_attr "mode" "<MODE>")])
16194 (define_expand "rint<mode>2"
16195   [(use (match_operand:MODEF 0 "register_operand"))
16196    (use (match_operand:MODEF 1 "register_operand"))]
16197   "(TARGET_USE_FANCY_MATH_387
16198     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16199         || TARGET_MIX_SSE_I387))
16200    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16202   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16203     {
16204       if (TARGET_SSE4_1)
16205         emit_insn (gen_sse4_1_round<mode>2
16206                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16207       else
16208         ix86_expand_rint (operands[0], operands[1]);
16209     }
16210   else
16211     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16212   DONE;
16215 (define_expand "round<mode>2"
16216   [(match_operand:X87MODEF 0 "register_operand")
16217    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16218   "(TARGET_USE_FANCY_MATH_387
16219     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16220         || TARGET_MIX_SSE_I387)
16221     && flag_unsafe_math_optimizations)
16222    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16223        && !flag_trapping_math && !flag_rounding_math)"
16225   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16226       && !flag_trapping_math && !flag_rounding_math)
16227     {
16228       if (TARGET_SSE4_1)
16229         {
16230           operands[1] = force_reg (<MODE>mode, operands[1]);
16231           ix86_expand_round_sse4 (operands[0], operands[1]);
16232         }
16233       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16234         ix86_expand_round (operands[0], operands[1]);
16235       else
16236         ix86_expand_rounddf_32 (operands[0], operands[1]);
16237     }
16238   else
16239     {
16240       operands[1] = force_reg (<MODE>mode, operands[1]);
16241       ix86_emit_i387_round (operands[0], operands[1]);
16242     }
16243   DONE;
16246 (define_insn_and_split "*fistdi2_1"
16247   [(set (match_operand:DI 0 "nonimmediate_operand")
16248         (unspec:DI [(match_operand:XF 1 "register_operand")]
16249                    UNSPEC_FIST))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && can_create_pseudo_p ()"
16252   "#"
16253   "&& 1"
16254   [(const_int 0)]
16256   if (memory_operand (operands[0], VOIDmode))
16257     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16258   else
16259     {
16260       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16261       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16262                                          operands[2]));
16263     }
16264   DONE;
16266   [(set_attr "type" "fpspc")
16267    (set_attr "mode" "DI")])
16269 (define_insn "fistdi2"
16270   [(set (match_operand:DI 0 "memory_operand" "=m")
16271         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16272                    UNSPEC_FIST))
16273    (clobber (match_scratch:XF 2 "=&1f"))]
16274   "TARGET_USE_FANCY_MATH_387"
16275   "* return output_fix_trunc (insn, operands, false);"
16276   [(set_attr "type" "fpspc")
16277    (set_attr "mode" "DI")])
16279 (define_insn "fistdi2_with_temp"
16280   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16281         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16282                    UNSPEC_FIST))
16283    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16284    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16285   "TARGET_USE_FANCY_MATH_387"
16286   "#"
16287   [(set_attr "type" "fpspc")
16288    (set_attr "mode" "DI")])
16290 (define_split
16291   [(set (match_operand:DI 0 "register_operand")
16292         (unspec:DI [(match_operand:XF 1 "register_operand")]
16293                    UNSPEC_FIST))
16294    (clobber (match_operand:DI 2 "memory_operand"))
16295    (clobber (match_scratch 3))]
16296   "reload_completed"
16297   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16298               (clobber (match_dup 3))])
16299    (set (match_dup 0) (match_dup 2))])
16301 (define_split
16302   [(set (match_operand:DI 0 "memory_operand")
16303         (unspec:DI [(match_operand:XF 1 "register_operand")]
16304                    UNSPEC_FIST))
16305    (clobber (match_operand:DI 2 "memory_operand"))
16306    (clobber (match_scratch 3))]
16307   "reload_completed"
16308   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16309               (clobber (match_dup 3))])])
16311 (define_insn_and_split "*fist<mode>2_1"
16312   [(set (match_operand:SWI24 0 "register_operand")
16313         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16314                       UNSPEC_FIST))]
16315   "TARGET_USE_FANCY_MATH_387
16316    && can_create_pseudo_p ()"
16317   "#"
16318   "&& 1"
16319   [(const_int 0)]
16321   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16322   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16323                                         operands[2]));
16324   DONE;
16326   [(set_attr "type" "fpspc")
16327    (set_attr "mode" "<MODE>")])
16329 (define_insn "fist<mode>2"
16330   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16331         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16332                       UNSPEC_FIST))]
16333   "TARGET_USE_FANCY_MATH_387"
16334   "* return output_fix_trunc (insn, operands, false);"
16335   [(set_attr "type" "fpspc")
16336    (set_attr "mode" "<MODE>")])
16338 (define_insn "fist<mode>2_with_temp"
16339   [(set (match_operand:SWI24 0 "register_operand" "=r")
16340         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16341                       UNSPEC_FIST))
16342    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16343   "TARGET_USE_FANCY_MATH_387"
16344   "#"
16345   [(set_attr "type" "fpspc")
16346    (set_attr "mode" "<MODE>")])
16348 (define_split
16349   [(set (match_operand:SWI24 0 "register_operand")
16350         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16351                       UNSPEC_FIST))
16352    (clobber (match_operand:SWI24 2 "memory_operand"))]
16353   "reload_completed"
16354   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16355    (set (match_dup 0) (match_dup 2))])
16357 (define_split
16358   [(set (match_operand:SWI24 0 "memory_operand")
16359         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16360                       UNSPEC_FIST))
16361    (clobber (match_operand:SWI24 2 "memory_operand"))]
16362   "reload_completed"
16363   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16365 (define_expand "lrintxf<mode>2"
16366   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16367      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16368                      UNSPEC_FIST))]
16369   "TARGET_USE_FANCY_MATH_387")
16371 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16372   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16373      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16374                    UNSPEC_FIX_NOTRUNC))]
16375   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16377 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16378   [(match_operand:SWI248x 0 "nonimmediate_operand")
16379    (match_operand:X87MODEF 1 "register_operand")]
16380   "(TARGET_USE_FANCY_MATH_387
16381     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16382         || TARGET_MIX_SSE_I387)
16383     && flag_unsafe_math_optimizations)
16384    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16385        && <SWI248x:MODE>mode != HImode 
16386        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16387        && !flag_trapping_math && !flag_rounding_math)"
16389   if (optimize_insn_for_size_p ())
16390     FAIL;
16392   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16393       && <SWI248x:MODE>mode != HImode
16394       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16395       && !flag_trapping_math && !flag_rounding_math)
16396     ix86_expand_lround (operands[0], operands[1]);
16397   else
16398     ix86_emit_i387_round (operands[0], operands[1]);
16399   DONE;
16402 (define_int_iterator FRNDINT_ROUNDING
16403         [UNSPEC_FRNDINT_FLOOR
16404          UNSPEC_FRNDINT_CEIL
16405          UNSPEC_FRNDINT_TRUNC])
16407 (define_int_iterator FIST_ROUNDING
16408         [UNSPEC_FIST_FLOOR
16409          UNSPEC_FIST_CEIL])
16411 ;; Base name for define_insn
16412 (define_int_attr rounding_insn
16413         [(UNSPEC_FRNDINT_FLOOR "floor")
16414          (UNSPEC_FRNDINT_CEIL "ceil")
16415          (UNSPEC_FRNDINT_TRUNC "btrunc")
16416          (UNSPEC_FIST_FLOOR "floor")
16417          (UNSPEC_FIST_CEIL "ceil")])
16419 (define_int_attr rounding
16420         [(UNSPEC_FRNDINT_FLOOR "floor")
16421          (UNSPEC_FRNDINT_CEIL "ceil")
16422          (UNSPEC_FRNDINT_TRUNC "trunc")
16423          (UNSPEC_FIST_FLOOR "floor")
16424          (UNSPEC_FIST_CEIL "ceil")])
16426 (define_int_attr ROUNDING
16427         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16428          (UNSPEC_FRNDINT_CEIL "CEIL")
16429          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16430          (UNSPEC_FIST_FLOOR "FLOOR")
16431          (UNSPEC_FIST_CEIL "CEIL")])
16433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16434 (define_insn_and_split "frndint<mode>2_<rounding>"
16435   [(set (match_operand:X87MODEF 0 "register_operand")
16436         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16437                    FRNDINT_ROUNDING))
16438    (clobber (reg:CC FLAGS_REG))]
16439   "TARGET_USE_FANCY_MATH_387
16440    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16441    && can_create_pseudo_p ()"
16442   "#"
16443   "&& 1"
16444   [(const_int 0)]
16446   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16448   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16449   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16451   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16452                                                  operands[2], operands[3]));
16453   DONE;
16455   [(set_attr "type" "frndint")
16456    (set_attr "i387_cw" "<rounding>")
16457    (set_attr "mode" "<MODE>")])
16459 (define_insn "frndint<mode>2_<rounding>_i387"
16460   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16461         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16462                          FRNDINT_ROUNDING))
16463    (use (match_operand:HI 2 "memory_operand" "m"))
16464    (use (match_operand:HI 3 "memory_operand" "m"))]
16465   "TARGET_USE_FANCY_MATH_387
16466    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16467   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16468   [(set_attr "type" "frndint")
16469    (set_attr "i387_cw" "<rounding>")
16470    (set_attr "mode" "<MODE>")])
16472 (define_expand "<rounding_insn>xf2"
16473   [(parallel [(set (match_operand:XF 0 "register_operand")
16474                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16475                               FRNDINT_ROUNDING))
16476               (clobber (reg:CC FLAGS_REG))])]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16480 (define_expand "<rounding_insn><mode>2"
16481   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16482                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16483                                  FRNDINT_ROUNDING))
16484               (clobber (reg:CC FLAGS_REG))])]
16485   "(TARGET_USE_FANCY_MATH_387
16486     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16487         || TARGET_MIX_SSE_I387)
16488     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16489    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16490        && (TARGET_SSE4_1 || !flag_trapping_math
16491            || flag_fp_int_builtin_inexact))"
16493   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16494       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16495     {
16496       if (TARGET_SSE4_1)
16497         emit_insn (gen_sse4_1_round<mode>2
16498                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16499                                                        | ROUND_NO_EXC)));
16500       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16501         {
16502           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16503             ix86_expand_floorceil (operands[0], operands[1], true);
16504           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16505             ix86_expand_floorceil (operands[0], operands[1], false);
16506           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16507             ix86_expand_trunc (operands[0], operands[1]);
16508           else
16509             gcc_unreachable ();
16510         }
16511       else
16512         {
16513           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16514             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16515           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16516             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16517           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16518             ix86_expand_truncdf_32 (operands[0], operands[1]);
16519           else
16520             gcc_unreachable ();
16521         }
16522     }
16523   else
16524     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16525   DONE;
16528 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16529 (define_insn_and_split "frndintxf2_mask_pm"
16530   [(set (match_operand:XF 0 "register_operand")
16531         (unspec:XF [(match_operand:XF 1 "register_operand")]
16532                    UNSPEC_FRNDINT_MASK_PM))
16533    (clobber (reg:CC FLAGS_REG))]
16534   "TARGET_USE_FANCY_MATH_387
16535    && flag_unsafe_math_optimizations
16536    && can_create_pseudo_p ()"
16537   "#"
16538   "&& 1"
16539   [(const_int 0)]
16541   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16543   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16544   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16546   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16547                                           operands[2], operands[3]));
16548   DONE;
16550   [(set_attr "type" "frndint")
16551    (set_attr "i387_cw" "mask_pm")
16552    (set_attr "mode" "XF")])
16554 (define_insn "frndintxf2_mask_pm_i387"
16555   [(set (match_operand:XF 0 "register_operand" "=f")
16556         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16557                    UNSPEC_FRNDINT_MASK_PM))
16558    (use (match_operand:HI 2 "memory_operand" "m"))
16559    (use (match_operand:HI 3 "memory_operand" "m"))]
16560   "TARGET_USE_FANCY_MATH_387
16561    && flag_unsafe_math_optimizations"
16562   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16563   [(set_attr "type" "frndint")
16564    (set_attr "i387_cw" "mask_pm")
16565    (set_attr "mode" "XF")])
16567 (define_expand "nearbyintxf2"
16568   [(parallel [(set (match_operand:XF 0 "register_operand")
16569                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16570                               UNSPEC_FRNDINT_MASK_PM))
16571               (clobber (reg:CC FLAGS_REG))])]
16572   "TARGET_USE_FANCY_MATH_387
16573    && flag_unsafe_math_optimizations")
16575 (define_expand "nearbyint<mode>2"
16576   [(use (match_operand:MODEF 0 "register_operand"))
16577    (use (match_operand:MODEF 1 "register_operand"))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580        || TARGET_MIX_SSE_I387)
16581    && flag_unsafe_math_optimizations"
16583   rtx op0 = gen_reg_rtx (XFmode);
16584   rtx op1 = gen_reg_rtx (XFmode);
16586   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16587   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16589   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16590   DONE;
16593 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16594 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16595   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16596         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16597                         FIST_ROUNDING))
16598    (clobber (reg:CC FLAGS_REG))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && flag_unsafe_math_optimizations
16601    && can_create_pseudo_p ()"
16602   "#"
16603   "&& 1"
16604   [(const_int 0)]
16606   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16608   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16609   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16610   if (memory_operand (operands[0], VOIDmode))
16611     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16612                                            operands[2], operands[3]));
16613   else
16614     {
16615       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16616       emit_insn (gen_fist<mode>2_<rounding>_with_temp
16617                   (operands[0], operands[1], operands[2],
16618                    operands[3], operands[4]));
16619     }
16620   DONE;
16622   [(set_attr "type" "fistp")
16623    (set_attr "i387_cw" "<rounding>")
16624    (set_attr "mode" "<MODE>")])
16626 (define_insn "fistdi2_<rounding>"
16627   [(set (match_operand:DI 0 "memory_operand" "=m")
16628         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16629                    FIST_ROUNDING))
16630    (use (match_operand:HI 2 "memory_operand" "m"))
16631    (use (match_operand:HI 3 "memory_operand" "m"))
16632    (clobber (match_scratch:XF 4 "=&1f"))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations"
16635   "* return output_fix_trunc (insn, operands, false);"
16636   [(set_attr "type" "fistp")
16637    (set_attr "i387_cw" "<rounding>")
16638    (set_attr "mode" "DI")])
16640 (define_insn "fistdi2_<rounding>_with_temp"
16641   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16642         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16643                    FIST_ROUNDING))
16644    (use (match_operand:HI 2 "memory_operand" "m,m"))
16645    (use (match_operand:HI 3 "memory_operand" "m,m"))
16646    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16647    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16648   "TARGET_USE_FANCY_MATH_387
16649    && flag_unsafe_math_optimizations"
16650   "#"
16651   [(set_attr "type" "fistp")
16652    (set_attr "i387_cw" "<rounding>")
16653    (set_attr "mode" "DI")])
16655 (define_split
16656   [(set (match_operand:DI 0 "register_operand")
16657         (unspec:DI [(match_operand:XF 1 "register_operand")]
16658                    FIST_ROUNDING))
16659    (use (match_operand:HI 2 "memory_operand"))
16660    (use (match_operand:HI 3 "memory_operand"))
16661    (clobber (match_operand:DI 4 "memory_operand"))
16662    (clobber (match_scratch 5))]
16663   "reload_completed"
16664   [(parallel [(set (match_dup 4)
16665                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16666               (use (match_dup 2))
16667               (use (match_dup 3))
16668               (clobber (match_dup 5))])
16669    (set (match_dup 0) (match_dup 4))])
16671 (define_split
16672   [(set (match_operand:DI 0 "memory_operand")
16673         (unspec:DI [(match_operand:XF 1 "register_operand")]
16674                    FIST_ROUNDING))
16675    (use (match_operand:HI 2 "memory_operand"))
16676    (use (match_operand:HI 3 "memory_operand"))
16677    (clobber (match_operand:DI 4 "memory_operand"))
16678    (clobber (match_scratch 5))]
16679   "reload_completed"
16680   [(parallel [(set (match_dup 0)
16681                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16682               (use (match_dup 2))
16683               (use (match_dup 3))
16684               (clobber (match_dup 5))])])
16686 (define_insn "fist<mode>2_<rounding>"
16687   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16688         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16689                       FIST_ROUNDING))
16690    (use (match_operand:HI 2 "memory_operand" "m"))
16691    (use (match_operand:HI 3 "memory_operand" "m"))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && flag_unsafe_math_optimizations"
16694   "* return output_fix_trunc (insn, operands, false);"
16695   [(set_attr "type" "fistp")
16696    (set_attr "i387_cw" "<rounding>")
16697    (set_attr "mode" "<MODE>")])
16699 (define_insn "fist<mode>2_<rounding>_with_temp"
16700   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16701         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16702                       FIST_ROUNDING))
16703    (use (match_operand:HI 2 "memory_operand" "m,m"))
16704    (use (match_operand:HI 3 "memory_operand" "m,m"))
16705    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16706   "TARGET_USE_FANCY_MATH_387
16707    && flag_unsafe_math_optimizations"
16708   "#"
16709   [(set_attr "type" "fistp")
16710    (set_attr "i387_cw" "<rounding>")
16711    (set_attr "mode" "<MODE>")])
16713 (define_split
16714   [(set (match_operand:SWI24 0 "register_operand")
16715         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16716                       FIST_ROUNDING))
16717    (use (match_operand:HI 2 "memory_operand"))
16718    (use (match_operand:HI 3 "memory_operand"))
16719    (clobber (match_operand:SWI24 4 "memory_operand"))]
16720   "reload_completed"
16721   [(parallel [(set (match_dup 4)
16722                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16723               (use (match_dup 2))
16724               (use (match_dup 3))])
16725    (set (match_dup 0) (match_dup 4))])
16727 (define_split
16728   [(set (match_operand:SWI24 0 "memory_operand")
16729         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16730                       FIST_ROUNDING))
16731    (use (match_operand:HI 2 "memory_operand"))
16732    (use (match_operand:HI 3 "memory_operand"))
16733    (clobber (match_operand:SWI24 4 "memory_operand"))]
16734   "reload_completed"
16735   [(parallel [(set (match_dup 0)
16736                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16737               (use (match_dup 2))
16738               (use (match_dup 3))])])
16740 (define_expand "l<rounding_insn>xf<mode>2"
16741   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16742                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16743                                    FIST_ROUNDING))
16744               (clobber (reg:CC FLAGS_REG))])]
16745   "TARGET_USE_FANCY_MATH_387
16746    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747    && flag_unsafe_math_optimizations")
16749 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16750   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16751                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16752                                  FIST_ROUNDING))
16753               (clobber (reg:CC FLAGS_REG))])]
16754   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16755    && !flag_trapping_math"
16757   if (TARGET_64BIT && optimize_insn_for_size_p ())
16758     FAIL;
16760   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16761     ix86_expand_lfloorceil (operands[0], operands[1], true);
16762   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16763     ix86_expand_lfloorceil (operands[0], operands[1], false);
16764   else
16765     gcc_unreachable ();
16767   DONE;
16770 (define_insn "fxam<mode>2_i387"
16771   [(set (match_operand:HI 0 "register_operand" "=a")
16772         (unspec:HI
16773           [(match_operand:X87MODEF 1 "register_operand" "f")]
16774           UNSPEC_FXAM))]
16775   "TARGET_USE_FANCY_MATH_387"
16776   "fxam\n\tfnstsw\t%0"
16777   [(set_attr "type" "multi")
16778    (set_attr "length" "4")
16779    (set_attr "unit" "i387")
16780    (set_attr "mode" "<MODE>")])
16782 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16783   [(set (match_operand:HI 0 "register_operand")
16784         (unspec:HI
16785           [(match_operand:MODEF 1 "memory_operand")]
16786           UNSPEC_FXAM_MEM))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && can_create_pseudo_p ()"
16789   "#"
16790   "&& 1"
16791   [(set (match_dup 2)(match_dup 1))
16792    (set (match_dup 0)
16793         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16795   operands[2] = gen_reg_rtx (<MODE>mode);
16797   MEM_VOLATILE_P (operands[1]) = 1;
16799   [(set_attr "type" "multi")
16800    (set_attr "unit" "i387")
16801    (set_attr "mode" "<MODE>")])
16803 (define_expand "isinfxf2"
16804   [(use (match_operand:SI 0 "register_operand"))
16805    (use (match_operand:XF 1 "register_operand"))]
16806   "TARGET_USE_FANCY_MATH_387
16807    && ix86_libc_has_function (function_c99_misc)"
16809   rtx mask = GEN_INT (0x45);
16810   rtx val = GEN_INT (0x05);
16812   rtx scratch = gen_reg_rtx (HImode);
16813   rtx res = gen_reg_rtx (QImode);
16815   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16817   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16818   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16819   ix86_expand_setcc (res, EQ,
16820                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16821   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16822   DONE;
16825 (define_expand "isinf<mode>2"
16826   [(use (match_operand:SI 0 "register_operand"))
16827    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16828   "TARGET_USE_FANCY_MATH_387
16829    && ix86_libc_has_function (function_c99_misc)
16830    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16832   rtx mask = GEN_INT (0x45);
16833   rtx val = GEN_INT (0x05);
16835   rtx scratch = gen_reg_rtx (HImode);
16836   rtx res = gen_reg_rtx (QImode);
16838   /* Remove excess precision by forcing value through memory. */
16839   if (memory_operand (operands[1], VOIDmode))
16840     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16841   else
16842     {
16843       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16845       emit_move_insn (temp, operands[1]);
16846       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16847     }
16849   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16850   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16851   ix86_expand_setcc (res, EQ,
16852                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16853   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16854   DONE;
16857 (define_expand "signbittf2"
16858   [(use (match_operand:SI 0 "register_operand"))
16859    (use (match_operand:TF 1 "register_operand"))]
16860   "TARGET_SSE"
16862   if (TARGET_SSE4_1)
16863     {
16864       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16865       rtx scratch = gen_reg_rtx (QImode);
16867       emit_insn (gen_ptesttf2 (operands[1], mask));
16868         ix86_expand_setcc (scratch, NE,
16869                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16871       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16872     }
16873   else
16874     {
16875       emit_insn (gen_sse_movmskps (operands[0],
16876                                    gen_lowpart (V4SFmode, operands[1])));
16877       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16878     }
16879   DONE;
16882 (define_expand "signbitxf2"
16883   [(use (match_operand:SI 0 "register_operand"))
16884    (use (match_operand:XF 1 "register_operand"))]
16885   "TARGET_USE_FANCY_MATH_387"
16887   rtx scratch = gen_reg_rtx (HImode);
16889   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16890   emit_insn (gen_andsi3 (operands[0],
16891              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16892   DONE;
16895 (define_insn "movmsk_df"
16896   [(set (match_operand:SI 0 "register_operand" "=r")
16897         (unspec:SI
16898           [(match_operand:DF 1 "register_operand" "x")]
16899           UNSPEC_MOVMSK))]
16900   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16901   "%vmovmskpd\t{%1, %0|%0, %1}"
16902   [(set_attr "type" "ssemov")
16903    (set_attr "prefix" "maybe_vex")
16904    (set_attr "mode" "DF")])
16906 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16907 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16908 (define_expand "signbitdf2"
16909   [(use (match_operand:SI 0 "register_operand"))
16910    (use (match_operand:DF 1 "register_operand"))]
16911   "TARGET_USE_FANCY_MATH_387
16912    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16914   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16915     {
16916       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16917       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16918     }
16919   else
16920     {
16921       rtx scratch = gen_reg_rtx (HImode);
16923       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16924       emit_insn (gen_andsi3 (operands[0],
16925                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16926     }
16927   DONE;
16930 (define_expand "signbitsf2"
16931   [(use (match_operand:SI 0 "register_operand"))
16932    (use (match_operand:SF 1 "register_operand"))]
16933   "TARGET_USE_FANCY_MATH_387
16934    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16936   rtx scratch = gen_reg_rtx (HImode);
16938   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16939   emit_insn (gen_andsi3 (operands[0],
16940              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16941   DONE;
16944 ;; Block operation instructions
16946 (define_insn "cld"
16947   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16948   ""
16949   "cld"
16950   [(set_attr "length" "1")
16951    (set_attr "length_immediate" "0")
16952    (set_attr "modrm" "0")])
16954 (define_expand "movmem<mode>"
16955   [(use (match_operand:BLK 0 "memory_operand"))
16956    (use (match_operand:BLK 1 "memory_operand"))
16957    (use (match_operand:SWI48 2 "nonmemory_operand"))
16958    (use (match_operand:SWI48 3 "const_int_operand"))
16959    (use (match_operand:SI 4 "const_int_operand"))
16960    (use (match_operand:SI 5 "const_int_operand"))
16961    (use (match_operand:SI 6 ""))
16962    (use (match_operand:SI 7 ""))
16963    (use (match_operand:SI 8 ""))]
16964   ""
16966  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16967                                 operands[2], NULL, operands[3],
16968                                 operands[4], operands[5],
16969                                 operands[6], operands[7],
16970                                 operands[8], false))
16971    DONE;
16972  else
16973    FAIL;
16976 ;; Most CPUs don't like single string operations
16977 ;; Handle this case here to simplify previous expander.
16979 (define_expand "strmov"
16980   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16981    (set (match_operand 1 "memory_operand") (match_dup 4))
16982    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16983               (clobber (reg:CC FLAGS_REG))])
16984    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16985               (clobber (reg:CC FLAGS_REG))])]
16986   ""
16988   /* Can't use this for non-default address spaces.  */
16989   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16990     FAIL;
16992   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16994   /* If .md ever supports :P for Pmode, these can be directly
16995      in the pattern above.  */
16996   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16997   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16999   /* Can't use this if the user has appropriated esi or edi.  */
17000   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17001       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17002     {
17003       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17004                                       operands[2], operands[3],
17005                                       operands[5], operands[6]));
17006       DONE;
17007     }
17009   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17012 (define_expand "strmov_singleop"
17013   [(parallel [(set (match_operand 1 "memory_operand")
17014                    (match_operand 3 "memory_operand"))
17015               (set (match_operand 0 "register_operand")
17016                    (match_operand 4))
17017               (set (match_operand 2 "register_operand")
17018                    (match_operand 5))])]
17019   ""
17021   if (TARGET_CLD)
17022     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17025 (define_insn "*strmovdi_rex_1"
17026   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17027         (mem:DI (match_operand:P 3 "register_operand" "1")))
17028    (set (match_operand:P 0 "register_operand" "=D")
17029         (plus:P (match_dup 2)
17030                 (const_int 8)))
17031    (set (match_operand:P 1 "register_operand" "=S")
17032         (plus:P (match_dup 3)
17033                 (const_int 8)))]
17034   "TARGET_64BIT
17035    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17036    && ix86_check_no_addr_space (insn)"
17037   "%^movsq"
17038   [(set_attr "type" "str")
17039    (set_attr "memory" "both")
17040    (set_attr "mode" "DI")])
17042 (define_insn "*strmovsi_1"
17043   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17044         (mem:SI (match_operand:P 3 "register_operand" "1")))
17045    (set (match_operand:P 0 "register_operand" "=D")
17046         (plus:P (match_dup 2)
17047                 (const_int 4)))
17048    (set (match_operand:P 1 "register_operand" "=S")
17049         (plus:P (match_dup 3)
17050                 (const_int 4)))]
17051   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17052    && ix86_check_no_addr_space (insn)"
17053   "%^movs{l|d}"
17054   [(set_attr "type" "str")
17055    (set_attr "memory" "both")
17056    (set_attr "mode" "SI")])
17058 (define_insn "*strmovhi_1"
17059   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17060         (mem:HI (match_operand:P 3 "register_operand" "1")))
17061    (set (match_operand:P 0 "register_operand" "=D")
17062         (plus:P (match_dup 2)
17063                 (const_int 2)))
17064    (set (match_operand:P 1 "register_operand" "=S")
17065         (plus:P (match_dup 3)
17066                 (const_int 2)))]
17067   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17068    && ix86_check_no_addr_space (insn)"
17069   "%^movsw"
17070   [(set_attr "type" "str")
17071    (set_attr "memory" "both")
17072    (set_attr "mode" "HI")])
17074 (define_insn "*strmovqi_1"
17075   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17076         (mem:QI (match_operand:P 3 "register_operand" "1")))
17077    (set (match_operand:P 0 "register_operand" "=D")
17078         (plus:P (match_dup 2)
17079                 (const_int 1)))
17080    (set (match_operand:P 1 "register_operand" "=S")
17081         (plus:P (match_dup 3)
17082                 (const_int 1)))]
17083   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17084    && ix86_check_no_addr_space (insn)"
17085   "%^movsb"
17086   [(set_attr "type" "str")
17087    (set_attr "memory" "both")
17088    (set (attr "prefix_rex")
17089         (if_then_else
17090           (match_test "<P:MODE>mode == DImode")
17091           (const_string "0")
17092           (const_string "*")))
17093    (set_attr "mode" "QI")])
17095 (define_expand "rep_mov"
17096   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17097               (set (match_operand 0 "register_operand")
17098                    (match_operand 5))
17099               (set (match_operand 2 "register_operand")
17100                    (match_operand 6))
17101               (set (match_operand 1 "memory_operand")
17102                    (match_operand 3 "memory_operand"))
17103               (use (match_dup 4))])]
17104   ""
17106   if (TARGET_CLD)
17107     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17110 (define_insn "*rep_movdi_rex64"
17111   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17112    (set (match_operand:P 0 "register_operand" "=D")
17113         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17114                           (const_int 3))
17115                 (match_operand:P 3 "register_operand" "0")))
17116    (set (match_operand:P 1 "register_operand" "=S")
17117         (plus:P (ashift:P (match_dup 5) (const_int 3))
17118                 (match_operand:P 4 "register_operand" "1")))
17119    (set (mem:BLK (match_dup 3))
17120         (mem:BLK (match_dup 4)))
17121    (use (match_dup 5))]
17122   "TARGET_64BIT
17123    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17124    && ix86_check_no_addr_space (insn)"
17125   "%^rep{%;} movsq"
17126   [(set_attr "type" "str")
17127    (set_attr "prefix_rep" "1")
17128    (set_attr "memory" "both")
17129    (set_attr "mode" "DI")])
17131 (define_insn "*rep_movsi"
17132   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17133    (set (match_operand:P 0 "register_operand" "=D")
17134         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17135                           (const_int 2))
17136                  (match_operand:P 3 "register_operand" "0")))
17137    (set (match_operand:P 1 "register_operand" "=S")
17138         (plus:P (ashift:P (match_dup 5) (const_int 2))
17139                 (match_operand:P 4 "register_operand" "1")))
17140    (set (mem:BLK (match_dup 3))
17141         (mem:BLK (match_dup 4)))
17142    (use (match_dup 5))]
17143   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17144    && ix86_check_no_addr_space (insn)"
17145   "%^rep{%;} movs{l|d}"
17146   [(set_attr "type" "str")
17147    (set_attr "prefix_rep" "1")
17148    (set_attr "memory" "both")
17149    (set_attr "mode" "SI")])
17151 (define_insn "*rep_movqi"
17152   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17153    (set (match_operand:P 0 "register_operand" "=D")
17154         (plus:P (match_operand:P 3 "register_operand" "0")
17155                 (match_operand:P 5 "register_operand" "2")))
17156    (set (match_operand:P 1 "register_operand" "=S")
17157         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17158    (set (mem:BLK (match_dup 3))
17159         (mem:BLK (match_dup 4)))
17160    (use (match_dup 5))]
17161   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17162    && ix86_check_no_addr_space (insn)"
17163   "%^rep{%;} movsb"
17164   [(set_attr "type" "str")
17165    (set_attr "prefix_rep" "1")
17166    (set_attr "memory" "both")
17167    (set_attr "mode" "QI")])
17169 (define_expand "setmem<mode>"
17170    [(use (match_operand:BLK 0 "memory_operand"))
17171     (use (match_operand:SWI48 1 "nonmemory_operand"))
17172     (use (match_operand:QI 2 "nonmemory_operand"))
17173     (use (match_operand 3 "const_int_operand"))
17174     (use (match_operand:SI 4 "const_int_operand"))
17175     (use (match_operand:SI 5 "const_int_operand"))
17176     (use (match_operand:SI 6 ""))
17177     (use (match_operand:SI 7 ""))
17178     (use (match_operand:SI 8 ""))]
17179   ""
17181  if (ix86_expand_set_or_movmem (operands[0], NULL,
17182                                 operands[1], operands[2],
17183                                 operands[3], operands[4],
17184                                 operands[5], operands[6],
17185                                 operands[7], operands[8], true))
17186    DONE;
17187  else
17188    FAIL;
17191 ;; Most CPUs don't like single string operations
17192 ;; Handle this case here to simplify previous expander.
17194 (define_expand "strset"
17195   [(set (match_operand 1 "memory_operand")
17196         (match_operand 2 "register_operand"))
17197    (parallel [(set (match_operand 0 "register_operand")
17198                    (match_dup 3))
17199               (clobber (reg:CC FLAGS_REG))])]
17200   ""
17202   /* Can't use this for non-default address spaces.  */
17203   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17204     FAIL;
17206   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17207     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17209   /* If .md ever supports :P for Pmode, this can be directly
17210      in the pattern above.  */
17211   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17212                               GEN_INT (GET_MODE_SIZE (GET_MODE
17213                                                       (operands[2]))));
17214   /* Can't use this if the user has appropriated eax or edi.  */
17215   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17216       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17217     {
17218       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17219                                       operands[3]));
17220       DONE;
17221     }
17224 (define_expand "strset_singleop"
17225   [(parallel [(set (match_operand 1 "memory_operand")
17226                    (match_operand 2 "register_operand"))
17227               (set (match_operand 0 "register_operand")
17228                    (match_operand 3))
17229               (unspec [(const_int 0)] UNSPEC_STOS)])]
17230   ""
17232   if (TARGET_CLD)
17233     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17236 (define_insn "*strsetdi_rex_1"
17237   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17238         (match_operand:DI 2 "register_operand" "a"))
17239    (set (match_operand:P 0 "register_operand" "=D")
17240         (plus:P (match_dup 1)
17241                 (const_int 8)))
17242    (unspec [(const_int 0)] UNSPEC_STOS)]
17243   "TARGET_64BIT
17244    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17245    && ix86_check_no_addr_space (insn)"
17246   "%^stosq"
17247   [(set_attr "type" "str")
17248    (set_attr "memory" "store")
17249    (set_attr "mode" "DI")])
17251 (define_insn "*strsetsi_1"
17252   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17253         (match_operand:SI 2 "register_operand" "a"))
17254    (set (match_operand:P 0 "register_operand" "=D")
17255         (plus:P (match_dup 1)
17256                 (const_int 4)))
17257    (unspec [(const_int 0)] UNSPEC_STOS)]
17258   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17259    && ix86_check_no_addr_space (insn)"
17260   "%^stos{l|d}"
17261   [(set_attr "type" "str")
17262    (set_attr "memory" "store")
17263    (set_attr "mode" "SI")])
17265 (define_insn "*strsethi_1"
17266   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17267         (match_operand:HI 2 "register_operand" "a"))
17268    (set (match_operand:P 0 "register_operand" "=D")
17269         (plus:P (match_dup 1)
17270                 (const_int 2)))
17271    (unspec [(const_int 0)] UNSPEC_STOS)]
17272   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17273    && ix86_check_no_addr_space (insn)"
17274   "%^stosw"
17275   [(set_attr "type" "str")
17276    (set_attr "memory" "store")
17277    (set_attr "mode" "HI")])
17279 (define_insn "*strsetqi_1"
17280   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17281         (match_operand:QI 2 "register_operand" "a"))
17282    (set (match_operand:P 0 "register_operand" "=D")
17283         (plus:P (match_dup 1)
17284                 (const_int 1)))
17285    (unspec [(const_int 0)] UNSPEC_STOS)]
17286   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17287    && ix86_check_no_addr_space (insn)"
17288   "%^stosb"
17289   [(set_attr "type" "str")
17290    (set_attr "memory" "store")
17291    (set (attr "prefix_rex")
17292         (if_then_else
17293           (match_test "<P:MODE>mode == DImode")
17294           (const_string "0")
17295           (const_string "*")))
17296    (set_attr "mode" "QI")])
17298 (define_expand "rep_stos"
17299   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17300               (set (match_operand 0 "register_operand")
17301                    (match_operand 4))
17302               (set (match_operand 2 "memory_operand") (const_int 0))
17303               (use (match_operand 3 "register_operand"))
17304               (use (match_dup 1))])]
17305   ""
17307   if (TARGET_CLD)
17308     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17311 (define_insn "*rep_stosdi_rex64"
17312   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17313    (set (match_operand:P 0 "register_operand" "=D")
17314         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17315                           (const_int 3))
17316                  (match_operand:P 3 "register_operand" "0")))
17317    (set (mem:BLK (match_dup 3))
17318         (const_int 0))
17319    (use (match_operand:DI 2 "register_operand" "a"))
17320    (use (match_dup 4))]
17321   "TARGET_64BIT
17322    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17323    && ix86_check_no_addr_space (insn)"
17324   "%^rep{%;} stosq"
17325   [(set_attr "type" "str")
17326    (set_attr "prefix_rep" "1")
17327    (set_attr "memory" "store")
17328    (set_attr "mode" "DI")])
17330 (define_insn "*rep_stossi"
17331   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17332    (set (match_operand:P 0 "register_operand" "=D")
17333         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17334                           (const_int 2))
17335                  (match_operand:P 3 "register_operand" "0")))
17336    (set (mem:BLK (match_dup 3))
17337         (const_int 0))
17338    (use (match_operand:SI 2 "register_operand" "a"))
17339    (use (match_dup 4))]
17340   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17341    && ix86_check_no_addr_space (insn)"
17342   "%^rep{%;} stos{l|d}"
17343   [(set_attr "type" "str")
17344    (set_attr "prefix_rep" "1")
17345    (set_attr "memory" "store")
17346    (set_attr "mode" "SI")])
17348 (define_insn "*rep_stosqi"
17349   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17350    (set (match_operand:P 0 "register_operand" "=D")
17351         (plus:P (match_operand:P 3 "register_operand" "0")
17352                 (match_operand:P 4 "register_operand" "1")))
17353    (set (mem:BLK (match_dup 3))
17354         (const_int 0))
17355    (use (match_operand:QI 2 "register_operand" "a"))
17356    (use (match_dup 4))]
17357   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17358    && ix86_check_no_addr_space (insn)"
17359   "%^rep{%;} stosb"
17360   [(set_attr "type" "str")
17361    (set_attr "prefix_rep" "1")
17362    (set_attr "memory" "store")
17363    (set (attr "prefix_rex")
17364         (if_then_else
17365           (match_test "<P:MODE>mode == DImode")
17366           (const_string "0")
17367           (const_string "*")))
17368    (set_attr "mode" "QI")])
17370 (define_expand "cmpstrnsi"
17371   [(set (match_operand:SI 0 "register_operand")
17372         (compare:SI (match_operand:BLK 1 "general_operand")
17373                     (match_operand:BLK 2 "general_operand")))
17374    (use (match_operand 3 "general_operand"))
17375    (use (match_operand 4 "immediate_operand"))]
17376   ""
17378   rtx addr1, addr2, out, outlow, count, countreg, align;
17380   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17381     FAIL;
17383   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17384   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17385     FAIL;
17387   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17388      will have rewritten the length arg to be the minimum of the const string
17389      length and the actual length arg.  If both strings are the same and
17390      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17391      will incorrectly base the results on chars past the 0 byte.  */
17392   tree t1 = MEM_EXPR (operands[1]);
17393   tree t2 = MEM_EXPR (operands[2]);
17394   if (!((t1 && TREE_CODE (t1) == MEM_REF
17395          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17396          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17397       || (t2 && TREE_CODE (t2) == MEM_REF
17398           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17399           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17400     FAIL;
17402   out = operands[0];
17403   if (!REG_P (out))
17404     out = gen_reg_rtx (SImode);
17406   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17407   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17408   if (addr1 != XEXP (operands[1], 0))
17409     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17410   if (addr2 != XEXP (operands[2], 0))
17411     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17413   count = operands[3];
17414   countreg = ix86_zero_extend_to_Pmode (count);
17416   /* %%% Iff we are testing strict equality, we can use known alignment
17417      to good advantage.  This may be possible with combine, particularly
17418      once cc0 is dead.  */
17419   align = operands[4];
17421   if (CONST_INT_P (count))
17422     {
17423       if (INTVAL (count) == 0)
17424         {
17425           emit_move_insn (operands[0], const0_rtx);
17426           DONE;
17427         }
17428       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17429                                      operands[1], operands[2]));
17430     }
17431   else
17432     {
17433       rtx (*gen_cmp) (rtx, rtx);
17435       gen_cmp = (TARGET_64BIT
17436                  ? gen_cmpdi_1 : gen_cmpsi_1);
17438       emit_insn (gen_cmp (countreg, countreg));
17439       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17440                                   operands[1], operands[2]));
17441     }
17443   outlow = gen_lowpart (QImode, out);
17444   emit_insn (gen_cmpintqi (outlow));
17445   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17447   if (operands[0] != out)
17448     emit_move_insn (operands[0], out);
17450   DONE;
17453 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17455 (define_expand "cmpintqi"
17456   [(set (match_dup 1)
17457         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17458    (set (match_dup 2)
17459         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17460    (parallel [(set (match_operand:QI 0 "register_operand")
17461                    (minus:QI (match_dup 1)
17462                              (match_dup 2)))
17463               (clobber (reg:CC FLAGS_REG))])]
17464   ""
17466   operands[1] = gen_reg_rtx (QImode);
17467   operands[2] = gen_reg_rtx (QImode);
17470 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17471 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17473 (define_expand "cmpstrnqi_nz_1"
17474   [(parallel [(set (reg:CC FLAGS_REG)
17475                    (compare:CC (match_operand 4 "memory_operand")
17476                                (match_operand 5 "memory_operand")))
17477               (use (match_operand 2 "register_operand"))
17478               (use (match_operand:SI 3 "immediate_operand"))
17479               (clobber (match_operand 0 "register_operand"))
17480               (clobber (match_operand 1 "register_operand"))
17481               (clobber (match_dup 2))])]
17482   ""
17484   if (TARGET_CLD)
17485     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17488 (define_insn "*cmpstrnqi_nz_1"
17489   [(set (reg:CC FLAGS_REG)
17490         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17491                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17492    (use (match_operand:P 6 "register_operand" "2"))
17493    (use (match_operand:SI 3 "immediate_operand" "i"))
17494    (clobber (match_operand:P 0 "register_operand" "=S"))
17495    (clobber (match_operand:P 1 "register_operand" "=D"))
17496    (clobber (match_operand:P 2 "register_operand" "=c"))]
17497   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17498    && ix86_check_no_addr_space (insn)"
17499   "%^repz{%;} cmpsb"
17500   [(set_attr "type" "str")
17501    (set_attr "mode" "QI")
17502    (set (attr "prefix_rex")
17503         (if_then_else
17504           (match_test "<P:MODE>mode == DImode")
17505           (const_string "0")
17506           (const_string "*")))
17507    (set_attr "prefix_rep" "1")])
17509 ;; The same, but the count is not known to not be zero.
17511 (define_expand "cmpstrnqi_1"
17512   [(parallel [(set (reg:CC FLAGS_REG)
17513                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17514                                      (const_int 0))
17515                   (compare:CC (match_operand 4 "memory_operand")
17516                               (match_operand 5 "memory_operand"))
17517                   (const_int 0)))
17518               (use (match_operand:SI 3 "immediate_operand"))
17519               (use (reg:CC FLAGS_REG))
17520               (clobber (match_operand 0 "register_operand"))
17521               (clobber (match_operand 1 "register_operand"))
17522               (clobber (match_dup 2))])]
17523   ""
17525   if (TARGET_CLD)
17526     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17529 (define_insn "*cmpstrnqi_1"
17530   [(set (reg:CC FLAGS_REG)
17531         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17532                              (const_int 0))
17533           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17534                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17535           (const_int 0)))
17536    (use (match_operand:SI 3 "immediate_operand" "i"))
17537    (use (reg:CC FLAGS_REG))
17538    (clobber (match_operand:P 0 "register_operand" "=S"))
17539    (clobber (match_operand:P 1 "register_operand" "=D"))
17540    (clobber (match_operand:P 2 "register_operand" "=c"))]
17541   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17542    && ix86_check_no_addr_space (insn)"
17543   "%^repz{%;} cmpsb"
17544   [(set_attr "type" "str")
17545    (set_attr "mode" "QI")
17546    (set (attr "prefix_rex")
17547         (if_then_else
17548           (match_test "<P:MODE>mode == DImode")
17549           (const_string "0")
17550           (const_string "*")))
17551    (set_attr "prefix_rep" "1")])
17553 (define_expand "strlen<mode>"
17554   [(set (match_operand:P 0 "register_operand")
17555         (unspec:P [(match_operand:BLK 1 "general_operand")
17556                    (match_operand:QI 2 "immediate_operand")
17557                    (match_operand 3 "immediate_operand")]
17558                   UNSPEC_SCAS))]
17559   ""
17561  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17562    DONE;
17563  else
17564    FAIL;
17567 (define_expand "strlenqi_1"
17568   [(parallel [(set (match_operand 0 "register_operand")
17569                    (match_operand 2))
17570               (clobber (match_operand 1 "register_operand"))
17571               (clobber (reg:CC FLAGS_REG))])]
17572   ""
17574   if (TARGET_CLD)
17575     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17578 (define_insn "*strlenqi_1"
17579   [(set (match_operand:P 0 "register_operand" "=&c")
17580         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17581                    (match_operand:QI 2 "register_operand" "a")
17582                    (match_operand:P 3 "immediate_operand" "i")
17583                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17584    (clobber (match_operand:P 1 "register_operand" "=D"))
17585    (clobber (reg:CC FLAGS_REG))]
17586   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17587    && ix86_check_no_addr_space (insn)"
17588   "%^repnz{%;} scasb"
17589   [(set_attr "type" "str")
17590    (set_attr "mode" "QI")
17591    (set (attr "prefix_rex")
17592         (if_then_else
17593           (match_test "<P:MODE>mode == DImode")
17594           (const_string "0")
17595           (const_string "*")))
17596    (set_attr "prefix_rep" "1")])
17598 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17599 ;; handled in combine, but it is not currently up to the task.
17600 ;; When used for their truth value, the cmpstrn* expanders generate
17601 ;; code like this:
17603 ;;   repz cmpsb
17604 ;;   seta       %al
17605 ;;   setb       %dl
17606 ;;   cmpb       %al, %dl
17607 ;;   jcc        label
17609 ;; The intermediate three instructions are unnecessary.
17611 ;; This one handles cmpstrn*_nz_1...
17612 (define_peephole2
17613   [(parallel[
17614      (set (reg:CC FLAGS_REG)
17615           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17616                       (mem:BLK (match_operand 5 "register_operand"))))
17617      (use (match_operand 6 "register_operand"))
17618      (use (match_operand:SI 3 "immediate_operand"))
17619      (clobber (match_operand 0 "register_operand"))
17620      (clobber (match_operand 1 "register_operand"))
17621      (clobber (match_operand 2 "register_operand"))])
17622    (set (match_operand:QI 7 "register_operand")
17623         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17624    (set (match_operand:QI 8 "register_operand")
17625         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17626    (set (reg FLAGS_REG)
17627         (compare (match_dup 7) (match_dup 8)))
17628   ]
17629   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17630   [(parallel[
17631      (set (reg:CC FLAGS_REG)
17632           (compare:CC (mem:BLK (match_dup 4))
17633                       (mem:BLK (match_dup 5))))
17634      (use (match_dup 6))
17635      (use (match_dup 3))
17636      (clobber (match_dup 0))
17637      (clobber (match_dup 1))
17638      (clobber (match_dup 2))])])
17640 ;; ...and this one handles cmpstrn*_1.
17641 (define_peephole2
17642   [(parallel[
17643      (set (reg:CC FLAGS_REG)
17644           (if_then_else:CC (ne (match_operand 6 "register_operand")
17645                                (const_int 0))
17646             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17647                         (mem:BLK (match_operand 5 "register_operand")))
17648             (const_int 0)))
17649      (use (match_operand:SI 3 "immediate_operand"))
17650      (use (reg:CC FLAGS_REG))
17651      (clobber (match_operand 0 "register_operand"))
17652      (clobber (match_operand 1 "register_operand"))
17653      (clobber (match_operand 2 "register_operand"))])
17654    (set (match_operand:QI 7 "register_operand")
17655         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17656    (set (match_operand:QI 8 "register_operand")
17657         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17658    (set (reg FLAGS_REG)
17659         (compare (match_dup 7) (match_dup 8)))
17660   ]
17661   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17662   [(parallel[
17663      (set (reg:CC FLAGS_REG)
17664           (if_then_else:CC (ne (match_dup 6)
17665                                (const_int 0))
17666             (compare:CC (mem:BLK (match_dup 4))
17667                         (mem:BLK (match_dup 5)))
17668             (const_int 0)))
17669      (use (match_dup 3))
17670      (use (reg:CC FLAGS_REG))
17671      (clobber (match_dup 0))
17672      (clobber (match_dup 1))
17673      (clobber (match_dup 2))])])
17675 ;; Conditional move instructions.
17677 (define_expand "mov<mode>cc"
17678   [(set (match_operand:SWIM 0 "register_operand")
17679         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17680                            (match_operand:SWIM 2 "<general_operand>")
17681                            (match_operand:SWIM 3 "<general_operand>")))]
17682   ""
17683   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17685 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17686 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17687 ;; So just document what we're doing explicitly.
17689 (define_expand "x86_mov<mode>cc_0_m1"
17690   [(parallel
17691     [(set (match_operand:SWI48 0 "register_operand")
17692           (if_then_else:SWI48
17693             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17694              [(match_operand 1 "flags_reg_operand")
17695               (const_int 0)])
17696             (const_int -1)
17697             (const_int 0)))
17698      (clobber (reg:CC FLAGS_REG))])])
17700 (define_insn "*x86_mov<mode>cc_0_m1"
17701   [(set (match_operand:SWI48 0 "register_operand" "=r")
17702         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17703                              [(reg FLAGS_REG) (const_int 0)])
17704           (const_int -1)
17705           (const_int 0)))
17706    (clobber (reg:CC FLAGS_REG))]
17707   ""
17708   "sbb{<imodesuffix>}\t%0, %0"
17709   ; Since we don't have the proper number of operands for an alu insn,
17710   ; fill in all the blanks.
17711   [(set_attr "type" "alu")
17712    (set_attr "modrm_class" "op0")
17713    (set_attr "use_carry" "1")
17714    (set_attr "pent_pair" "pu")
17715    (set_attr "memory" "none")
17716    (set_attr "imm_disp" "false")
17717    (set_attr "mode" "<MODE>")
17718    (set_attr "length_immediate" "0")])
17720 (define_insn "*x86_mov<mode>cc_0_m1_se"
17721   [(set (match_operand:SWI48 0 "register_operand" "=r")
17722         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17723                              [(reg FLAGS_REG) (const_int 0)])
17724                             (const_int 1)
17725                             (const_int 0)))
17726    (clobber (reg:CC FLAGS_REG))]
17727   ""
17728   "sbb{<imodesuffix>}\t%0, %0"
17729   [(set_attr "type" "alu")
17730    (set_attr "modrm_class" "op0")
17731    (set_attr "use_carry" "1")
17732    (set_attr "pent_pair" "pu")
17733    (set_attr "memory" "none")
17734    (set_attr "imm_disp" "false")
17735    (set_attr "mode" "<MODE>")
17736    (set_attr "length_immediate" "0")])
17738 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17739   [(set (match_operand:SWI48 0 "register_operand" "=r")
17740         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17741                     [(reg FLAGS_REG) (const_int 0)])))
17742    (clobber (reg:CC FLAGS_REG))]
17743   ""
17744   "sbb{<imodesuffix>}\t%0, %0"
17745   [(set_attr "type" "alu")
17746    (set_attr "modrm_class" "op0")
17747    (set_attr "use_carry" "1")
17748    (set_attr "pent_pair" "pu")
17749    (set_attr "memory" "none")
17750    (set_attr "imm_disp" "false")
17751    (set_attr "mode" "<MODE>")
17752    (set_attr "length_immediate" "0")])
17754 (define_insn "*mov<mode>cc_noc"
17755   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17756         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17757                                [(reg FLAGS_REG) (const_int 0)])
17758           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17759           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17760   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17761   "@
17762    cmov%O2%C1\t{%2, %0|%0, %2}
17763    cmov%O2%c1\t{%3, %0|%0, %3}"
17764   [(set_attr "type" "icmov")
17765    (set_attr "mode" "<MODE>")])
17767 (define_insn "*movsicc_noc_zext"
17768   [(set (match_operand:DI 0 "register_operand" "=r,r")
17769         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17770                            [(reg FLAGS_REG) (const_int 0)])
17771           (zero_extend:DI
17772             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17773           (zero_extend:DI
17774             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17775   "TARGET_64BIT
17776    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17777   "@
17778    cmov%O2%C1\t{%2, %k0|%k0, %2}
17779    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17780   [(set_attr "type" "icmov")
17781    (set_attr "mode" "SI")])
17783 ;; Don't do conditional moves with memory inputs.  This splitter helps
17784 ;; register starved x86_32 by forcing inputs into registers before reload.
17785 (define_split
17786   [(set (match_operand:SWI248 0 "register_operand")
17787         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17788                                [(reg FLAGS_REG) (const_int 0)])
17789           (match_operand:SWI248 2 "nonimmediate_operand")
17790           (match_operand:SWI248 3 "nonimmediate_operand")))]
17791   "!TARGET_64BIT && TARGET_CMOVE
17792    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17793    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17794    && can_create_pseudo_p ()
17795    && optimize_insn_for_speed_p ()"
17796   [(set (match_dup 0)
17797         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17799   if (MEM_P (operands[2]))
17800     operands[2] = force_reg (<MODE>mode, operands[2]);
17801   if (MEM_P (operands[3]))
17802     operands[3] = force_reg (<MODE>mode, operands[3]);
17805 (define_insn "*movqicc_noc"
17806   [(set (match_operand:QI 0 "register_operand" "=r,r")
17807         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17808                            [(reg FLAGS_REG) (const_int 0)])
17809                       (match_operand:QI 2 "register_operand" "r,0")
17810                       (match_operand:QI 3 "register_operand" "0,r")))]
17811   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17812   "#"
17813   [(set_attr "type" "icmov")
17814    (set_attr "mode" "QI")])
17816 (define_split
17817   [(set (match_operand:SWI12 0 "register_operand")
17818         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17819                               [(reg FLAGS_REG) (const_int 0)])
17820                       (match_operand:SWI12 2 "register_operand")
17821                       (match_operand:SWI12 3 "register_operand")))]
17822   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17823    && reload_completed"
17824   [(set (match_dup 0)
17825         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17827   operands[0] = gen_lowpart (SImode, operands[0]);
17828   operands[2] = gen_lowpart (SImode, operands[2]);
17829   operands[3] = gen_lowpart (SImode, operands[3]);
17832 ;; Don't do conditional moves with memory inputs
17833 (define_peephole2
17834   [(match_scratch:SWI248 4 "r")
17835    (set (match_operand:SWI248 0 "register_operand")
17836         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17837                                [(reg FLAGS_REG) (const_int 0)])
17838           (match_operand:SWI248 2 "nonimmediate_operand")
17839           (match_operand:SWI248 3 "nonimmediate_operand")))]
17840   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17841    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17842    && optimize_insn_for_speed_p ()"
17843   [(set (match_dup 4) (match_dup 5))
17844    (set (match_dup 0)
17845         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17847   if (MEM_P (operands[2]))
17848     {
17849       operands[5] = operands[2];
17850       operands[2] = operands[4];
17851     }
17852   else if (MEM_P (operands[3]))
17853     {
17854       operands[5] = operands[3];
17855       operands[3] = operands[4];
17856     }
17857   else
17858     gcc_unreachable ();
17861 (define_peephole2
17862   [(match_scratch:SI 4 "r")
17863    (set (match_operand:DI 0 "register_operand")
17864         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17865                            [(reg FLAGS_REG) (const_int 0)])
17866           (zero_extend:DI
17867             (match_operand:SI 2 "nonimmediate_operand"))
17868           (zero_extend:DI
17869             (match_operand:SI 3 "nonimmediate_operand"))))]
17870   "TARGET_64BIT
17871    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17872    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17873    && optimize_insn_for_speed_p ()"
17874   [(set (match_dup 4) (match_dup 5))
17875    (set (match_dup 0)
17876         (if_then_else:DI (match_dup 1)
17877           (zero_extend:DI (match_dup 2))
17878           (zero_extend:DI (match_dup 3))))]
17880   if (MEM_P (operands[2]))
17881     {
17882       operands[5] = operands[2];
17883       operands[2] = operands[4];
17884     }
17885   else if (MEM_P (operands[3]))
17886     {
17887       operands[5] = operands[3];
17888       operands[3] = operands[4];
17889     }
17890   else
17891     gcc_unreachable ();
17894 (define_expand "mov<mode>cc"
17895   [(set (match_operand:X87MODEF 0 "register_operand")
17896         (if_then_else:X87MODEF
17897           (match_operand 1 "comparison_operator")
17898           (match_operand:X87MODEF 2 "register_operand")
17899           (match_operand:X87MODEF 3 "register_operand")))]
17900   "(TARGET_80387 && TARGET_CMOVE)
17901    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17902   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17904 (define_insn "*movxfcc_1"
17905   [(set (match_operand:XF 0 "register_operand" "=f,f")
17906         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17907                                 [(reg FLAGS_REG) (const_int 0)])
17908                       (match_operand:XF 2 "register_operand" "f,0")
17909                       (match_operand:XF 3 "register_operand" "0,f")))]
17910   "TARGET_80387 && TARGET_CMOVE"
17911   "@
17912    fcmov%F1\t{%2, %0|%0, %2}
17913    fcmov%f1\t{%3, %0|%0, %3}"
17914   [(set_attr "type" "fcmov")
17915    (set_attr "mode" "XF")])
17917 (define_insn "*movdfcc_1"
17918   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17919         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17920                                 [(reg FLAGS_REG) (const_int 0)])
17921                       (match_operand:DF 2 "nonimmediate_operand"
17922                                                "f ,0,rm,0 ,rm,0")
17923                       (match_operand:DF 3 "nonimmediate_operand"
17924                                                "0 ,f,0 ,rm,0, rm")))]
17925   "TARGET_80387 && TARGET_CMOVE
17926    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17927   "@
17928    fcmov%F1\t{%2, %0|%0, %2}
17929    fcmov%f1\t{%3, %0|%0, %3}
17930    #
17931    #
17932    cmov%O2%C1\t{%2, %0|%0, %2}
17933    cmov%O2%c1\t{%3, %0|%0, %3}"
17934   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17935    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17936    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17938 (define_split
17939   [(set (match_operand:DF 0 "general_reg_operand")
17940         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17941                                 [(reg FLAGS_REG) (const_int 0)])
17942                       (match_operand:DF 2 "nonimmediate_operand")
17943                       (match_operand:DF 3 "nonimmediate_operand")))]
17944   "!TARGET_64BIT && reload_completed"
17945   [(set (match_dup 2)
17946         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17947    (set (match_dup 3)
17948         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17950   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17951   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17954 (define_insn "*movsfcc_1_387"
17955   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17956         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17957                                 [(reg FLAGS_REG) (const_int 0)])
17958                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17959                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17960   "TARGET_80387 && TARGET_CMOVE
17961    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17962   "@
17963    fcmov%F1\t{%2, %0|%0, %2}
17964    fcmov%f1\t{%3, %0|%0, %3}
17965    cmov%O2%C1\t{%2, %0|%0, %2}
17966    cmov%O2%c1\t{%3, %0|%0, %3}"
17967   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17968    (set_attr "mode" "SF,SF,SI,SI")])
17970 ;; Don't do conditional moves with memory inputs.  This splitter helps
17971 ;; register starved x86_32 by forcing inputs into registers before reload.
17972 (define_split
17973   [(set (match_operand:MODEF 0 "register_operand")
17974         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17975                               [(reg FLAGS_REG) (const_int 0)])
17976           (match_operand:MODEF 2 "nonimmediate_operand")
17977           (match_operand:MODEF 3 "nonimmediate_operand")))]
17978   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17979    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17980    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17981    && can_create_pseudo_p ()
17982    && optimize_insn_for_speed_p ()"
17983   [(set (match_dup 0)
17984         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17986   if (MEM_P (operands[2]))
17987     operands[2] = force_reg (<MODE>mode, operands[2]);
17988   if (MEM_P (operands[3]))
17989     operands[3] = force_reg (<MODE>mode, operands[3]);
17992 ;; Don't do conditional moves with memory inputs
17993 (define_peephole2
17994   [(match_scratch:MODEF 4 "r")
17995    (set (match_operand:MODEF 0 "general_reg_operand")
17996         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17997                               [(reg FLAGS_REG) (const_int 0)])
17998           (match_operand:MODEF 2 "nonimmediate_operand")
17999           (match_operand:MODEF 3 "nonimmediate_operand")))]
18000   "(<MODE>mode != DFmode || TARGET_64BIT)
18001    && TARGET_80387 && TARGET_CMOVE
18002    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18003    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18004    && optimize_insn_for_speed_p ()"
18005   [(set (match_dup 4) (match_dup 5))
18006    (set (match_dup 0)
18007         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18009   if (MEM_P (operands[2]))
18010     {
18011       operands[5] = operands[2];
18012       operands[2] = operands[4];
18013     }
18014   else if (MEM_P (operands[3]))
18015     {
18016       operands[5] = operands[3];
18017       operands[3] = operands[4];
18018     }
18019   else
18020     gcc_unreachable ();
18023 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18024 ;; the scalar versions to have only XMM registers as operands.
18026 ;; XOP conditional move
18027 (define_insn "*xop_pcmov_<mode>"
18028   [(set (match_operand:MODEF 0 "register_operand" "=x")
18029         (if_then_else:MODEF
18030           (match_operand:MODEF 1 "register_operand" "x")
18031           (match_operand:MODEF 2 "register_operand" "x")
18032           (match_operand:MODEF 3 "register_operand" "x")))]
18033   "TARGET_XOP"
18034   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18035   [(set_attr "type" "sse4arg")])
18037 ;; These versions of the min/max patterns are intentionally ignorant of
18038 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18039 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18040 ;; are undefined in this condition, we're certain this is correct.
18042 (define_insn "<code><mode>3"
18043   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18044         (smaxmin:MODEF
18045           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18046           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18047   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18048   "@
18049    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18050    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18051   [(set_attr "isa" "noavx,avx")
18052    (set_attr "prefix" "orig,vex")
18053    (set_attr "type" "sseadd")
18054    (set_attr "mode" "<MODE>")])
18056 ;; These versions of the min/max patterns implement exactly the operations
18057 ;;   min = (op1 < op2 ? op1 : op2)
18058 ;;   max = (!(op1 < op2) ? op1 : op2)
18059 ;; Their operands are not commutative, and thus they may be used in the
18060 ;; presence of -0.0 and NaN.
18062 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18063   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18064         (unspec:MODEF
18065           [(match_operand:MODEF 1 "register_operand" "0,v")
18066            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18067           IEEE_MAXMIN))]
18068   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18069   "@
18070    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18071    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18072   [(set_attr "isa" "noavx,avx")
18073    (set_attr "prefix" "orig,maybe_evex")
18074    (set_attr "type" "sseadd")
18075    (set_attr "mode" "<MODE>")])
18077 ;; Make two stack loads independent:
18078 ;;   fld aa              fld aa
18079 ;;   fld %st(0)     ->   fld bb
18080 ;;   fmul bb             fmul %st(1), %st
18082 ;; Actually we only match the last two instructions for simplicity.
18084 (define_peephole2
18085   [(set (match_operand 0 "fp_register_operand")
18086         (match_operand 1 "fp_register_operand"))
18087    (set (match_dup 0)
18088         (match_operator 2 "binary_fp_operator"
18089            [(match_dup 0)
18090             (match_operand 3 "memory_operand")]))]
18091   "REGNO (operands[0]) != REGNO (operands[1])"
18092   [(set (match_dup 0) (match_dup 3))
18093    (set (match_dup 0)
18094         (match_op_dup 2
18095           [(match_dup 5) (match_dup 4)]))]
18097   operands[4] = operands[0];
18098   operands[5] = operands[1];
18100   /* The % modifier is not operational anymore in peephole2's, so we have to
18101      swap the operands manually in the case of addition and multiplication. */
18102   if (COMMUTATIVE_ARITH_P (operands[2]))
18103     std::swap (operands[4], operands[5]);
18106 (define_peephole2
18107   [(set (match_operand 0 "fp_register_operand")
18108         (match_operand 1 "fp_register_operand"))
18109    (set (match_dup 0)
18110         (match_operator 2 "binary_fp_operator"
18111            [(match_operand 3 "memory_operand")
18112             (match_dup 0)]))]
18113   "REGNO (operands[0]) != REGNO (operands[1])"
18114   [(set (match_dup 0) (match_dup 3))
18115    (set (match_dup 0)
18116         (match_op_dup 2
18117           [(match_dup 4) (match_dup 5)]))]
18119   operands[4] = operands[0];
18120   operands[5] = operands[1];
18122   /* The % modifier is not operational anymore in peephole2's, so we have to
18123      swap the operands manually in the case of addition and multiplication. */
18124   if (COMMUTATIVE_ARITH_P (operands[2]))
18125     std::swap (operands[4], operands[5]);
18128 ;; Conditional addition patterns
18129 (define_expand "add<mode>cc"
18130   [(match_operand:SWI 0 "register_operand")
18131    (match_operand 1 "ordered_comparison_operator")
18132    (match_operand:SWI 2 "register_operand")
18133    (match_operand:SWI 3 "const_int_operand")]
18134   ""
18135   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18137 ;; Misc patterns (?)
18139 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18140 ;; Otherwise there will be nothing to keep
18142 ;; [(set (reg ebp) (reg esp))]
18143 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18144 ;;  (clobber (eflags)]
18145 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18147 ;; in proper program order.
18149 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18150   [(set (match_operand:P 0 "register_operand" "=r,r")
18151         (plus:P (match_operand:P 1 "register_operand" "0,r")
18152                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18153    (clobber (reg:CC FLAGS_REG))
18154    (clobber (mem:BLK (scratch)))]
18155   ""
18157   switch (get_attr_type (insn))
18158     {
18159     case TYPE_IMOV:
18160       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18162     case TYPE_ALU:
18163       gcc_assert (rtx_equal_p (operands[0], operands[1]));
18164       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18165         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18167       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18169     default:
18170       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18171       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18172     }
18174   [(set (attr "type")
18175         (cond [(and (eq_attr "alternative" "0")
18176                     (not (match_test "TARGET_OPT_AGU")))
18177                  (const_string "alu")
18178                (match_operand:<MODE> 2 "const0_operand")
18179                  (const_string "imov")
18180               ]
18181               (const_string "lea")))
18182    (set (attr "length_immediate")
18183         (cond [(eq_attr "type" "imov")
18184                  (const_string "0")
18185                (and (eq_attr "type" "alu")
18186                     (match_operand 2 "const128_operand"))
18187                  (const_string "1")
18188               ]
18189               (const_string "*")))
18190    (set_attr "mode" "<MODE>")])
18192 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18193   [(set (match_operand:P 0 "register_operand" "=r")
18194         (minus:P (match_operand:P 1 "register_operand" "0")
18195                  (match_operand:P 2 "register_operand" "r")))
18196    (clobber (reg:CC FLAGS_REG))
18197    (clobber (mem:BLK (scratch)))]
18198   ""
18199   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18200   [(set_attr "type" "alu")
18201    (set_attr "mode" "<MODE>")])
18203 (define_insn "allocate_stack_worker_probe_<mode>"
18204   [(set (match_operand:P 0 "register_operand" "=a")
18205         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18206                             UNSPECV_STACK_PROBE))
18207    (clobber (reg:CC FLAGS_REG))]
18208   "ix86_target_stack_probe ()"
18209   "call\t___chkstk_ms"
18210   [(set_attr "type" "multi")
18211    (set_attr "length" "5")])
18213 (define_expand "allocate_stack"
18214   [(match_operand 0 "register_operand")
18215    (match_operand 1 "general_operand")]
18216   "ix86_target_stack_probe ()"
18218   rtx x;
18220 #ifndef CHECK_STACK_LIMIT
18221 #define CHECK_STACK_LIMIT 0
18222 #endif
18224   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18225       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18226     x = operands[1];
18227   else
18228     {
18229       rtx (*insn) (rtx, rtx);
18231       x = copy_to_mode_reg (Pmode, operands[1]);
18233       insn = (TARGET_64BIT
18234               ? gen_allocate_stack_worker_probe_di
18235               : gen_allocate_stack_worker_probe_si);
18237       emit_insn (insn (x, x));
18238     }
18240   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18241                            stack_pointer_rtx, 0, OPTAB_DIRECT);
18243   if (x != stack_pointer_rtx)
18244     emit_move_insn (stack_pointer_rtx, x);
18246   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18247   DONE;
18250 (define_expand "probe_stack"
18251   [(match_operand 0 "memory_operand")]
18252   ""
18254   rtx (*insn) (rtx, rtx)
18255     = (GET_MODE (operands[0]) == DImode
18256        ? gen_probe_stack_di : gen_probe_stack_si);
18258   emit_insn (insn (operands[0], const0_rtx));
18259   DONE;
18262 ;; Use OR for stack probes, this is shorter.
18263 (define_insn "probe_stack_<mode>"
18264   [(set (match_operand:W 0 "memory_operand" "=m")
18265         (unspec:W [(match_operand:W 1 "const0_operand")]
18266                   UNSPEC_PROBE_STACK))
18267    (clobber (reg:CC FLAGS_REG))]
18268   ""
18269   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18270   [(set_attr "type" "alu1")
18271    (set_attr "mode" "<MODE>")
18272    (set_attr "length_immediate" "1")])
18273   
18274 (define_insn "adjust_stack_and_probe<mode>"
18275   [(set (match_operand:P 0 "register_operand" "=r")
18276         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18277                             UNSPECV_PROBE_STACK_RANGE))
18278    (set (reg:P SP_REG)
18279         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18280    (clobber (reg:CC FLAGS_REG))
18281    (clobber (mem:BLK (scratch)))]
18282   ""
18283   "* return output_adjust_stack_and_probe (operands[0]);"
18284   [(set_attr "type" "multi")])
18286 (define_insn "probe_stack_range<mode>"
18287   [(set (match_operand:P 0 "register_operand" "=r")
18288         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18289                             (match_operand:P 2 "const_int_operand" "n")]
18290                             UNSPECV_PROBE_STACK_RANGE))
18291    (clobber (reg:CC FLAGS_REG))]
18292   ""
18293   "* return output_probe_stack_range (operands[0], operands[2]);"
18294   [(set_attr "type" "multi")])
18296 /* Additional processing for builtin_setjmp.  Store the shadow stack pointer
18297    as a forth element in jmpbuf.  */
18298 (define_expand "builtin_setjmp_setup"
18299   [(match_operand 0 "address_operand")]
18300   "TARGET_SHSTK"
18302   if (flag_cf_protection & CF_RETURN)
18303     {
18304       rtx mem, reg_ssp;
18306       mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18307                                                3 * GET_MODE_SIZE (Pmode)));
18308       reg_ssp = gen_reg_rtx (Pmode);
18309       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18310       emit_insn ((Pmode == SImode)
18311                   ? gen_rdsspsi (reg_ssp, reg_ssp)
18312                   : gen_rdsspdi (reg_ssp, reg_ssp));
18313       emit_move_insn (mem, reg_ssp);
18314     }
18315   DONE;
18318 (define_expand "builtin_setjmp_receiver"
18319   [(label_ref (match_operand 0))]
18320   "!TARGET_64BIT && flag_pic"
18322 #if TARGET_MACHO
18323   if (TARGET_MACHO)
18324     {
18325       rtx xops[3];
18326       rtx_code_label *label_rtx = gen_label_rtx ();
18327       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18328       xops[0] = xops[1] = pic_offset_table_rtx;
18329       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18330       ix86_expand_binary_operator (MINUS, SImode, xops);
18331     }
18332   else
18333 #endif
18334     emit_insn (gen_set_got (pic_offset_table_rtx));
18335   DONE;
18338 (define_expand "builtin_longjmp"
18339   [(match_operand 0 "address_operand")]
18340   "TARGET_SHSTK"
18342   rtx fp, lab, stack;
18343   rtx jump, label, reg_adj, reg_ssp, reg_minus, mem_buf, tmp, clob;
18344   machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
18346   /* Adjust the shadow stack pointer (ssp) to the value saved in the
18347      jmp_buf.  The saving was done in the builtin_setjmp_setup.  */
18348   if (flag_cf_protection & CF_RETURN)
18349     {
18350       /* Get current shadow stack pointer.  The code below will check if
18351          SHSTK feature is enabled.  If it's not enabled RDSSP instruction
18352          is a NOP.  */
18353       reg_ssp = gen_reg_rtx (Pmode);
18354       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18355       emit_insn ((Pmode == SImode)
18356                  ? gen_rdsspsi (reg_ssp, reg_ssp)
18357                  : gen_rdsspdi (reg_ssp, reg_ssp));
18358       mem_buf = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18359                                                    3 * GET_MODE_SIZE (Pmode))),
18361       /* Compare through substraction the saved and the current ssp to decide
18362          if ssp has to be adjusted.  */
18363       reg_minus = gen_reg_rtx (Pmode);
18364       tmp = gen_rtx_SET (reg_minus, gen_rtx_MINUS (Pmode, reg_ssp, mem_buf));
18365       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18366       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18367       emit_insn (tmp);
18369       /* Jump over adjustment code.  */
18370       label = gen_label_rtx ();
18371       tmp = gen_rtx_REG (CCmode, FLAGS_REG);
18372       tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
18373       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18374                                   gen_rtx_LABEL_REF (VOIDmode, label),
18375                                   pc_rtx);
18376       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18377       JUMP_LABEL (jump) = label;
18379       /* Adjust the ssp.  */
18380       reg_adj = gen_reg_rtx (Pmode);
18381       tmp = gen_rtx_SET (reg_adj,
18382                          gen_rtx_LSHIFTRT (Pmode, negate_rtx (Pmode, reg_minus),
18383                                            GEN_INT (3)));
18384       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18385       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18386       emit_insn (tmp);
18387       emit_insn ((Pmode == SImode)
18388                  ? gen_incsspsi (reg_adj)
18389                  : gen_incsspdi (reg_adj));
18391       emit_label (label);
18392       LABEL_NUSES (label) = 1;
18393     }
18395   /* This code is the same as in expand_buildin_longjmp.  */
18396   fp = gen_rtx_MEM (Pmode, operands[0]);
18397   lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18398                                            GET_MODE_SIZE (Pmode)));
18399   stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0],
18400                                                2 * GET_MODE_SIZE (Pmode)));
18401   lab = copy_to_reg (lab);
18403   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
18404   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
18406   emit_move_insn (hard_frame_pointer_rtx, fp);
18407   emit_stack_restore (SAVE_NONLOCAL, stack);
18409   emit_use (hard_frame_pointer_rtx);
18410   emit_use (stack_pointer_rtx);
18411   emit_indirect_jump (lab);
18415 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18416 ;; Do not split instructions with mask registers.
18417 (define_split
18418   [(set (match_operand 0 "general_reg_operand")
18419         (match_operator 3 "promotable_binary_operator"
18420            [(match_operand 1 "general_reg_operand")
18421             (match_operand 2 "aligned_operand")]))
18422    (clobber (reg:CC FLAGS_REG))]
18423   "! TARGET_PARTIAL_REG_STALL && reload_completed
18424    && ((GET_MODE (operands[0]) == HImode
18425         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18426             /* ??? next two lines just !satisfies_constraint_K (...) */
18427             || !CONST_INT_P (operands[2])
18428             || satisfies_constraint_K (operands[2])))
18429        || (GET_MODE (operands[0]) == QImode
18430            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18431   [(parallel [(set (match_dup 0)
18432                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18433               (clobber (reg:CC FLAGS_REG))])]
18435   operands[0] = gen_lowpart (SImode, operands[0]);
18436   operands[1] = gen_lowpart (SImode, operands[1]);
18437   if (GET_CODE (operands[3]) != ASHIFT)
18438     operands[2] = gen_lowpart (SImode, operands[2]);
18439   operands[3] = shallow_copy_rtx (operands[3]);
18440   PUT_MODE (operands[3], SImode);
18443 ; Promote the QImode tests, as i386 has encoding of the AND
18444 ; instruction with 32-bit sign-extended immediate and thus the
18445 ; instruction size is unchanged, except in the %eax case for
18446 ; which it is increased by one byte, hence the ! optimize_size.
18447 (define_split
18448   [(set (match_operand 0 "flags_reg_operand")
18449         (match_operator 2 "compare_operator"
18450           [(and (match_operand 3 "aligned_operand")
18451                 (match_operand 4 "const_int_operand"))
18452            (const_int 0)]))
18453    (set (match_operand 1 "register_operand")
18454         (and (match_dup 3) (match_dup 4)))]
18455   "! TARGET_PARTIAL_REG_STALL && reload_completed
18456    && optimize_insn_for_speed_p ()
18457    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18458        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18459    /* Ensure that the operand will remain sign-extended immediate.  */
18460    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18461   [(parallel [(set (match_dup 0)
18462                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18463                                     (const_int 0)]))
18464               (set (match_dup 1)
18465                    (and:SI (match_dup 3) (match_dup 4)))])]
18467   operands[4]
18468     = gen_int_mode (INTVAL (operands[4])
18469                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18470   operands[1] = gen_lowpart (SImode, operands[1]);
18471   operands[3] = gen_lowpart (SImode, operands[3]);
18474 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18475 ; the TEST instruction with 32-bit sign-extended immediate and thus
18476 ; the instruction size would at least double, which is not what we
18477 ; want even with ! optimize_size.
18478 (define_split
18479   [(set (match_operand 0 "flags_reg_operand")
18480         (match_operator 1 "compare_operator"
18481           [(and (match_operand:HI 2 "aligned_operand")
18482                 (match_operand:HI 3 "const_int_operand"))
18483            (const_int 0)]))]
18484   "! TARGET_PARTIAL_REG_STALL && reload_completed
18485    && ! TARGET_FAST_PREFIX
18486    && optimize_insn_for_speed_p ()
18487    /* Ensure that the operand will remain sign-extended immediate.  */
18488    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18489   [(set (match_dup 0)
18490         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18491                          (const_int 0)]))]
18493   operands[3]
18494     = gen_int_mode (INTVAL (operands[3])
18495                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18496   operands[2] = gen_lowpart (SImode, operands[2]);
18499 (define_split
18500   [(set (match_operand 0 "register_operand")
18501         (neg (match_operand 1 "register_operand")))
18502    (clobber (reg:CC FLAGS_REG))]
18503   "! TARGET_PARTIAL_REG_STALL && reload_completed
18504    && (GET_MODE (operands[0]) == HImode
18505        || (GET_MODE (operands[0]) == QImode
18506            && (TARGET_PROMOTE_QImode
18507                || optimize_insn_for_size_p ())))"
18508   [(parallel [(set (match_dup 0)
18509                    (neg:SI (match_dup 1)))
18510               (clobber (reg:CC FLAGS_REG))])]
18512   operands[0] = gen_lowpart (SImode, operands[0]);
18513   operands[1] = gen_lowpart (SImode, operands[1]);
18516 ;; Do not split instructions with mask regs.
18517 (define_split
18518   [(set (match_operand 0 "general_reg_operand")
18519         (not (match_operand 1 "general_reg_operand")))]
18520   "! TARGET_PARTIAL_REG_STALL && reload_completed
18521    && (GET_MODE (operands[0]) == HImode
18522        || (GET_MODE (operands[0]) == QImode
18523            && (TARGET_PROMOTE_QImode
18524                || optimize_insn_for_size_p ())))"
18525   [(set (match_dup 0)
18526         (not:SI (match_dup 1)))]
18528   operands[0] = gen_lowpart (SImode, operands[0]);
18529   operands[1] = gen_lowpart (SImode, operands[1]);
18532 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18533 ;; transform a complex memory operation into two memory to register operations.
18535 ;; Don't push memory operands
18536 (define_peephole2
18537   [(set (match_operand:SWI 0 "push_operand")
18538         (match_operand:SWI 1 "memory_operand"))
18539    (match_scratch:SWI 2 "<r>")]
18540   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18541    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18542   [(set (match_dup 2) (match_dup 1))
18543    (set (match_dup 0) (match_dup 2))])
18545 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18546 ;; SImode pushes.
18547 (define_peephole2
18548   [(set (match_operand:SF 0 "push_operand")
18549         (match_operand:SF 1 "memory_operand"))
18550    (match_scratch:SF 2 "r")]
18551   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18552    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18553   [(set (match_dup 2) (match_dup 1))
18554    (set (match_dup 0) (match_dup 2))])
18556 ;; Don't move an immediate directly to memory when the instruction
18557 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18558 (define_peephole2
18559   [(match_scratch:SWI124 1 "<r>")
18560    (set (match_operand:SWI124 0 "memory_operand")
18561         (const_int 0))]
18562   "optimize_insn_for_speed_p ()
18563    && ((<MODE>mode == HImode
18564        && TARGET_LCP_STALL)
18565        || (!TARGET_USE_MOV0
18566           && TARGET_SPLIT_LONG_MOVES
18567           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18568    && peep2_regno_dead_p (0, FLAGS_REG)"
18569   [(parallel [(set (match_dup 2) (const_int 0))
18570               (clobber (reg:CC FLAGS_REG))])
18571    (set (match_dup 0) (match_dup 1))]
18572   "operands[2] = gen_lowpart (SImode, operands[1]);")
18574 (define_peephole2
18575   [(match_scratch:SWI124 2 "<r>")
18576    (set (match_operand:SWI124 0 "memory_operand")
18577         (match_operand:SWI124 1 "immediate_operand"))]
18578   "optimize_insn_for_speed_p ()
18579    && ((<MODE>mode == HImode
18580        && TARGET_LCP_STALL)
18581        || (TARGET_SPLIT_LONG_MOVES
18582           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18583   [(set (match_dup 2) (match_dup 1))
18584    (set (match_dup 0) (match_dup 2))])
18586 ;; Don't compare memory with zero, load and use a test instead.
18587 (define_peephole2
18588   [(set (match_operand 0 "flags_reg_operand")
18589         (match_operator 1 "compare_operator"
18590           [(match_operand:SI 2 "memory_operand")
18591            (const_int 0)]))
18592    (match_scratch:SI 3 "r")]
18593   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18594   [(set (match_dup 3) (match_dup 2))
18595    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18597 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18598 ;; Don't split NOTs with a displacement operand, because resulting XOR
18599 ;; will not be pairable anyway.
18601 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18602 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18603 ;; so this split helps here as well.
18605 ;; Note: Can't do this as a regular split because we can't get proper
18606 ;; lifetime information then.
18608 (define_peephole2
18609   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18610         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18611   "optimize_insn_for_speed_p ()
18612    && ((TARGET_NOT_UNPAIRABLE
18613         && (!MEM_P (operands[0])
18614             || !memory_displacement_operand (operands[0], <MODE>mode)))
18615        || (TARGET_NOT_VECTORMODE
18616            && long_memory_operand (operands[0], <MODE>mode)))
18617    && peep2_regno_dead_p (0, FLAGS_REG)"
18618   [(parallel [(set (match_dup 0)
18619                    (xor:SWI124 (match_dup 1) (const_int -1)))
18620               (clobber (reg:CC FLAGS_REG))])])
18622 ;; Non pairable "test imm, reg" instructions can be translated to
18623 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18624 ;; byte opcode instead of two, have a short form for byte operands),
18625 ;; so do it for other CPUs as well.  Given that the value was dead,
18626 ;; this should not create any new dependencies.  Pass on the sub-word
18627 ;; versions if we're concerned about partial register stalls.
18629 (define_peephole2
18630   [(set (match_operand 0 "flags_reg_operand")
18631         (match_operator 1 "compare_operator"
18632           [(and:SI (match_operand:SI 2 "register_operand")
18633                    (match_operand:SI 3 "immediate_operand"))
18634            (const_int 0)]))]
18635   "ix86_match_ccmode (insn, CCNOmode)
18636    && (REGNO (operands[2]) != AX_REG
18637        || satisfies_constraint_K (operands[3]))
18638    && peep2_reg_dead_p (1, operands[2])"
18639   [(parallel
18640      [(set (match_dup 0)
18641            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18642                             (const_int 0)]))
18643       (set (match_dup 2)
18644            (and:SI (match_dup 2) (match_dup 3)))])])
18646 ;; We don't need to handle HImode case, because it will be promoted to SImode
18647 ;; on ! TARGET_PARTIAL_REG_STALL
18649 (define_peephole2
18650   [(set (match_operand 0 "flags_reg_operand")
18651         (match_operator 1 "compare_operator"
18652           [(and:QI (match_operand:QI 2 "register_operand")
18653                    (match_operand:QI 3 "immediate_operand"))
18654            (const_int 0)]))]
18655   "! TARGET_PARTIAL_REG_STALL
18656    && ix86_match_ccmode (insn, CCNOmode)
18657    && REGNO (operands[2]) != AX_REG
18658    && peep2_reg_dead_p (1, operands[2])"
18659   [(parallel
18660      [(set (match_dup 0)
18661            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18662                             (const_int 0)]))
18663       (set (match_dup 2)
18664            (and:QI (match_dup 2) (match_dup 3)))])])
18666 (define_peephole2
18667   [(set (match_operand 0 "flags_reg_operand")
18668         (match_operator 1 "compare_operator"
18669           [(and:QI
18670              (subreg:QI
18671                (zero_extract:SI (match_operand 2 "QIreg_operand")
18672                                 (const_int 8)
18673                                 (const_int 8)) 0)
18674              (match_operand 3 "const_int_operand"))
18675            (const_int 0)]))]
18676   "! TARGET_PARTIAL_REG_STALL
18677    && ix86_match_ccmode (insn, CCNOmode)
18678    && REGNO (operands[2]) != AX_REG
18679    && peep2_reg_dead_p (1, operands[2])"
18680   [(parallel
18681      [(set (match_dup 0)
18682            (match_op_dup 1
18683              [(and:QI
18684                 (subreg:QI
18685                   (zero_extract:SI (match_dup 2)
18686                                    (const_int 8)
18687                                    (const_int 8)) 0)
18688                 (match_dup 3))
18689               (const_int 0)]))
18690       (set (zero_extract:SI (match_dup 2)
18691                             (const_int 8)
18692                             (const_int 8))
18693            (subreg:SI
18694              (and:QI
18695                (subreg:QI
18696                  (zero_extract:SI (match_dup 2)
18697                                   (const_int 8)
18698                                   (const_int 8)) 0)
18699                (match_dup 3)) 0))])])
18701 ;; Don't do logical operations with memory inputs.
18702 (define_peephole2
18703   [(match_scratch:SWI 2 "<r>")
18704    (parallel [(set (match_operand:SWI 0 "register_operand")
18705                    (match_operator:SWI 3 "arith_or_logical_operator"
18706                      [(match_dup 0)
18707                       (match_operand:SWI 1 "memory_operand")]))
18708               (clobber (reg:CC FLAGS_REG))])]
18709   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18710   [(set (match_dup 2) (match_dup 1))
18711    (parallel [(set (match_dup 0)
18712                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18713               (clobber (reg:CC FLAGS_REG))])])
18715 (define_peephole2
18716   [(match_scratch:SWI 2 "<r>")
18717    (parallel [(set (match_operand:SWI 0 "register_operand")
18718                    (match_operator:SWI 3 "arith_or_logical_operator"
18719                      [(match_operand:SWI 1 "memory_operand")
18720                       (match_dup 0)]))
18721               (clobber (reg:CC FLAGS_REG))])]
18722   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18723   [(set (match_dup 2) (match_dup 1))
18724    (parallel [(set (match_dup 0)
18725                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18726               (clobber (reg:CC FLAGS_REG))])])
18728 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18729 ;; the memory address refers to the destination of the load!
18731 (define_peephole2
18732   [(set (match_operand:SWI 0 "general_reg_operand")
18733         (match_operand:SWI 1 "general_reg_operand"))
18734    (parallel [(set (match_dup 0)
18735                    (match_operator:SWI 3 "commutative_operator"
18736                      [(match_dup 0)
18737                       (match_operand:SWI 2 "memory_operand")]))
18738               (clobber (reg:CC FLAGS_REG))])]
18739   "REGNO (operands[0]) != REGNO (operands[1])
18740    && (<MODE>mode != QImode
18741        || any_QIreg_operand (operands[1], QImode))"
18742   [(set (match_dup 0) (match_dup 4))
18743    (parallel [(set (match_dup 0)
18744                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18745               (clobber (reg:CC FLAGS_REG))])]
18746   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18748 (define_peephole2
18749   [(set (match_operand 0 "mmx_reg_operand")
18750         (match_operand 1 "mmx_reg_operand"))
18751    (set (match_dup 0)
18752         (match_operator 3 "commutative_operator"
18753           [(match_dup 0)
18754            (match_operand 2 "memory_operand")]))]
18755   "REGNO (operands[0]) != REGNO (operands[1])"
18756   [(set (match_dup 0) (match_dup 2))
18757    (set (match_dup 0)
18758         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18760 (define_peephole2
18761   [(set (match_operand 0 "sse_reg_operand")
18762         (match_operand 1 "sse_reg_operand"))
18763    (set (match_dup 0)
18764         (match_operator 3 "commutative_operator"
18765           [(match_dup 0)
18766            (match_operand 2 "memory_operand")]))]
18767   "REGNO (operands[0]) != REGNO (operands[1])"
18768   [(set (match_dup 0) (match_dup 2))
18769    (set (match_dup 0)
18770         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18772 ; Don't do logical operations with memory outputs
18774 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18775 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18776 ; the same decoder scheduling characteristics as the original.
18778 (define_peephole2
18779   [(match_scratch:SWI 2 "<r>")
18780    (parallel [(set (match_operand:SWI 0 "memory_operand")
18781                    (match_operator:SWI 3 "arith_or_logical_operator"
18782                      [(match_dup 0)
18783                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18784               (clobber (reg:CC FLAGS_REG))])]
18785   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18786   [(set (match_dup 2) (match_dup 0))
18787    (parallel [(set (match_dup 2)
18788                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18789               (clobber (reg:CC FLAGS_REG))])
18790    (set (match_dup 0) (match_dup 2))])
18792 (define_peephole2
18793   [(match_scratch:SWI 2 "<r>")
18794    (parallel [(set (match_operand:SWI 0 "memory_operand")
18795                    (match_operator:SWI 3 "arith_or_logical_operator"
18796                      [(match_operand:SWI 1 "<nonmemory_operand>")
18797                       (match_dup 0)]))
18798               (clobber (reg:CC FLAGS_REG))])]
18799   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18800   [(set (match_dup 2) (match_dup 0))
18801    (parallel [(set (match_dup 2)
18802                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18803               (clobber (reg:CC FLAGS_REG))])
18804    (set (match_dup 0) (match_dup 2))])
18806 ;; Attempt to use arith or logical operations with memory outputs with
18807 ;; setting of flags.
18808 (define_peephole2
18809   [(set (match_operand:SWI 0 "register_operand")
18810         (match_operand:SWI 1 "memory_operand"))
18811    (parallel [(set (match_dup 0)
18812                    (match_operator:SWI 3 "plusminuslogic_operator"
18813                      [(match_dup 0)
18814                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18815               (clobber (reg:CC FLAGS_REG))])
18816    (set (match_dup 1) (match_dup 0))
18817    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18818   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18819    && peep2_reg_dead_p (4, operands[0])
18820    && !reg_overlap_mentioned_p (operands[0], operands[1])
18821    && !reg_overlap_mentioned_p (operands[0], operands[2])
18822    && (<MODE>mode != QImode
18823        || immediate_operand (operands[2], QImode)
18824        || any_QIreg_operand (operands[2], QImode))
18825    && ix86_match_ccmode (peep2_next_insn (3),
18826                          (GET_CODE (operands[3]) == PLUS
18827                           || GET_CODE (operands[3]) == MINUS)
18828                          ? CCGOCmode : CCNOmode)"
18829   [(parallel [(set (match_dup 4) (match_dup 6))
18830               (set (match_dup 1) (match_dup 5))])]
18832   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18833   operands[5]
18834     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18835                       copy_rtx (operands[1]),
18836                       operands[2]);
18837   operands[6]
18838     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18839                        copy_rtx (operands[5]),
18840                        const0_rtx);
18843 ;; Likewise for instances where we have a lea pattern.
18844 (define_peephole2
18845   [(set (match_operand:SWI 0 "register_operand")
18846         (match_operand:SWI 1 "memory_operand"))
18847    (set (match_operand:SWI 3 "register_operand")
18848         (plus:SWI (match_dup 0)
18849                   (match_operand:SWI 2 "<nonmemory_operand>")))
18850    (set (match_dup 1) (match_dup 3))
18851    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18852   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18853    && peep2_reg_dead_p (4, operands[3])
18854    && (rtx_equal_p (operands[0], operands[3])
18855        || peep2_reg_dead_p (2, operands[0]))
18856    && !reg_overlap_mentioned_p (operands[0], operands[1])
18857    && !reg_overlap_mentioned_p (operands[3], operands[1])
18858    && !reg_overlap_mentioned_p (operands[0], operands[2])
18859    && (<MODE>mode != QImode
18860        || immediate_operand (operands[2], QImode)
18861        || any_QIreg_operand (operands[2], QImode))
18862    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18863   [(parallel [(set (match_dup 4) (match_dup 6))
18864               (set (match_dup 1) (match_dup 5))])]
18866   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18867   operands[5]
18868     = gen_rtx_PLUS (<MODE>mode,
18869                     copy_rtx (operands[1]),
18870                     operands[2]);
18871   operands[6]
18872     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18873                        copy_rtx (operands[5]),
18874                        const0_rtx);
18877 (define_peephole2
18878   [(parallel [(set (match_operand:SWI 0 "register_operand")
18879                    (match_operator:SWI 2 "plusminuslogic_operator"
18880                      [(match_dup 0)
18881                       (match_operand:SWI 1 "memory_operand")]))
18882               (clobber (reg:CC FLAGS_REG))])
18883    (set (match_dup 1) (match_dup 0))
18884    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18885   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18886    && GET_CODE (operands[2]) != MINUS
18887    && peep2_reg_dead_p (3, operands[0])
18888    && !reg_overlap_mentioned_p (operands[0], operands[1])
18889    && ix86_match_ccmode (peep2_next_insn (2),
18890                          GET_CODE (operands[2]) == PLUS
18891                          ? CCGOCmode : CCNOmode)"
18892   [(parallel [(set (match_dup 3) (match_dup 5))
18893               (set (match_dup 1) (match_dup 4))])]
18895   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18896   operands[4]
18897     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18898                       copy_rtx (operands[1]),
18899                       operands[0]);
18900   operands[5]
18901     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18902                        copy_rtx (operands[4]),
18903                        const0_rtx);
18906 (define_peephole2
18907   [(set (match_operand:SWI12 0 "register_operand")
18908         (match_operand:SWI12 1 "memory_operand"))
18909    (parallel [(set (match_operand:SI 4 "register_operand")
18910                    (match_operator:SI 3 "plusminuslogic_operator"
18911                      [(match_dup 4)
18912                       (match_operand:SI 2 "nonmemory_operand")]))
18913               (clobber (reg:CC FLAGS_REG))])
18914    (set (match_dup 1) (match_dup 0))
18915    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18916   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18917    && REGNO (operands[0]) == REGNO (operands[4])
18918    && peep2_reg_dead_p (4, operands[0])
18919    && (<MODE>mode != QImode
18920        || immediate_operand (operands[2], SImode)
18921        || any_QIreg_operand (operands[2], SImode))
18922    && !reg_overlap_mentioned_p (operands[0], operands[1])
18923    && !reg_overlap_mentioned_p (operands[0], operands[2])
18924    && ix86_match_ccmode (peep2_next_insn (3),
18925                          (GET_CODE (operands[3]) == PLUS
18926                           || GET_CODE (operands[3]) == MINUS)
18927                          ? CCGOCmode : CCNOmode)"
18928   [(parallel [(set (match_dup 4) (match_dup 6))
18929               (set (match_dup 1) (match_dup 5))])]
18931   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18932   operands[5]
18933     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18934                       copy_rtx (operands[1]),
18935                       gen_lowpart (<MODE>mode, operands[2]));
18936   operands[6]
18937     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18938                        copy_rtx (operands[5]),
18939                        const0_rtx);
18942 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18943 (define_peephole2
18944   [(set (match_operand 0 "general_reg_operand")
18945         (match_operand 1 "const0_operand"))]
18946   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18947    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18948    && peep2_regno_dead_p (0, FLAGS_REG)"
18949   [(parallel [(set (match_dup 0) (const_int 0))
18950               (clobber (reg:CC FLAGS_REG))])]
18951   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18953 (define_peephole2
18954   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18955         (const_int 0))]
18956   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18957    && peep2_regno_dead_p (0, FLAGS_REG)"
18958   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18959               (clobber (reg:CC FLAGS_REG))])])
18961 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18962 (define_peephole2
18963   [(set (match_operand:SWI248 0 "general_reg_operand")
18964         (const_int -1))]
18965   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18966    && peep2_regno_dead_p (0, FLAGS_REG)"
18967   [(parallel [(set (match_dup 0) (const_int -1))
18968               (clobber (reg:CC FLAGS_REG))])]
18970   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18971     operands[0] = gen_lowpart (SImode, operands[0]);
18974 ;; Attempt to convert simple lea to add/shift.
18975 ;; These can be created by move expanders.
18976 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18977 ;; relevant lea instructions were already split.
18979 (define_peephole2
18980   [(set (match_operand:SWI48 0 "register_operand")
18981         (plus:SWI48 (match_dup 0)
18982                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18983   "!TARGET_OPT_AGU
18984    && peep2_regno_dead_p (0, FLAGS_REG)"
18985   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18986               (clobber (reg:CC FLAGS_REG))])])
18988 (define_peephole2
18989   [(set (match_operand:SWI48 0 "register_operand")
18990         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18991                     (match_dup 0)))]
18992   "!TARGET_OPT_AGU
18993    && peep2_regno_dead_p (0, FLAGS_REG)"
18994   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18995               (clobber (reg:CC FLAGS_REG))])])
18997 (define_peephole2
18998   [(set (match_operand:DI 0 "register_operand")
18999         (zero_extend:DI
19000           (plus:SI (match_operand:SI 1 "register_operand")
19001                    (match_operand:SI 2 "nonmemory_operand"))))]
19002   "TARGET_64BIT && !TARGET_OPT_AGU
19003    && REGNO (operands[0]) == REGNO (operands[1])
19004    && peep2_regno_dead_p (0, FLAGS_REG)"
19005   [(parallel [(set (match_dup 0)
19006                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19007               (clobber (reg:CC FLAGS_REG))])])
19009 (define_peephole2
19010   [(set (match_operand:DI 0 "register_operand")
19011         (zero_extend:DI
19012           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19013                    (match_operand:SI 2 "register_operand"))))]
19014   "TARGET_64BIT && !TARGET_OPT_AGU
19015    && REGNO (operands[0]) == REGNO (operands[2])
19016    && peep2_regno_dead_p (0, FLAGS_REG)"
19017   [(parallel [(set (match_dup 0)
19018                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19019               (clobber (reg:CC FLAGS_REG))])])
19021 (define_peephole2
19022   [(set (match_operand:SWI48 0 "register_operand")
19023         (mult:SWI48 (match_dup 0)
19024                     (match_operand:SWI48 1 "const_int_operand")))]
19025   "pow2p_hwi (INTVAL (operands[1]))
19026    && peep2_regno_dead_p (0, FLAGS_REG)"
19027   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19028               (clobber (reg:CC FLAGS_REG))])]
19029   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19031 (define_peephole2
19032   [(set (match_operand:DI 0 "register_operand")
19033         (zero_extend:DI
19034           (mult:SI (match_operand:SI 1 "register_operand")
19035                    (match_operand:SI 2 "const_int_operand"))))]
19036   "TARGET_64BIT
19037    && pow2p_hwi (INTVAL (operands[2]))
19038    && REGNO (operands[0]) == REGNO (operands[1])
19039    && peep2_regno_dead_p (0, FLAGS_REG)"
19040   [(parallel [(set (match_dup 0)
19041                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19042               (clobber (reg:CC FLAGS_REG))])]
19043   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19045 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19046 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19047 ;; On many CPUs it is also faster, since special hardware to avoid esp
19048 ;; dependencies is present.
19050 ;; While some of these conversions may be done using splitters, we use
19051 ;; peepholes in order to allow combine_stack_adjustments pass to see
19052 ;; nonobfuscated RTL.
19054 ;; Convert prologue esp subtractions to push.
19055 ;; We need register to push.  In order to keep verify_flow_info happy we have
19056 ;; two choices
19057 ;; - use scratch and clobber it in order to avoid dependencies
19058 ;; - use already live register
19059 ;; We can't use the second way right now, since there is no reliable way how to
19060 ;; verify that given register is live.  First choice will also most likely in
19061 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19062 ;; call clobbered registers are dead.  We may want to use base pointer as an
19063 ;; alternative when no register is available later.
19065 (define_peephole2
19066   [(match_scratch:W 1 "r")
19067    (parallel [(set (reg:P SP_REG)
19068                    (plus:P (reg:P SP_REG)
19069                            (match_operand:P 0 "const_int_operand")))
19070               (clobber (reg:CC FLAGS_REG))
19071               (clobber (mem:BLK (scratch)))])]
19072   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19073    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19074    && ix86_red_zone_size == 0"
19075   [(clobber (match_dup 1))
19076    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19077               (clobber (mem:BLK (scratch)))])])
19079 (define_peephole2
19080   [(match_scratch:W 1 "r")
19081    (parallel [(set (reg:P SP_REG)
19082                    (plus:P (reg:P SP_REG)
19083                            (match_operand:P 0 "const_int_operand")))
19084               (clobber (reg:CC FLAGS_REG))
19085               (clobber (mem:BLK (scratch)))])]
19086   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19087    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19088    && ix86_red_zone_size == 0"
19089   [(clobber (match_dup 1))
19090    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19091    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19092               (clobber (mem:BLK (scratch)))])])
19094 ;; Convert esp subtractions to push.
19095 (define_peephole2
19096   [(match_scratch:W 1 "r")
19097    (parallel [(set (reg:P SP_REG)
19098                    (plus:P (reg:P SP_REG)
19099                            (match_operand:P 0 "const_int_operand")))
19100               (clobber (reg:CC FLAGS_REG))])]
19101   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19102    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19103    && ix86_red_zone_size == 0"
19104   [(clobber (match_dup 1))
19105    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19107 (define_peephole2
19108   [(match_scratch:W 1 "r")
19109    (parallel [(set (reg:P SP_REG)
19110                    (plus:P (reg:P SP_REG)
19111                            (match_operand:P 0 "const_int_operand")))
19112               (clobber (reg:CC FLAGS_REG))])]
19113   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19114    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19115    && ix86_red_zone_size == 0"
19116   [(clobber (match_dup 1))
19117    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19118    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19120 ;; Convert epilogue deallocator to pop.
19121 (define_peephole2
19122   [(match_scratch:W 1 "r")
19123    (parallel [(set (reg:P SP_REG)
19124                    (plus:P (reg:P SP_REG)
19125                            (match_operand:P 0 "const_int_operand")))
19126               (clobber (reg:CC FLAGS_REG))
19127               (clobber (mem:BLK (scratch)))])]
19128   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19129    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19130   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19131               (clobber (mem:BLK (scratch)))])])
19133 ;; Two pops case is tricky, since pop causes dependency
19134 ;; on destination register.  We use two registers if available.
19135 (define_peephole2
19136   [(match_scratch:W 1 "r")
19137    (match_scratch:W 2 "r")
19138    (parallel [(set (reg:P SP_REG)
19139                    (plus:P (reg:P SP_REG)
19140                            (match_operand:P 0 "const_int_operand")))
19141               (clobber (reg:CC FLAGS_REG))
19142               (clobber (mem:BLK (scratch)))])]
19143   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19144    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19145   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19146               (clobber (mem:BLK (scratch)))])
19147    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19149 (define_peephole2
19150   [(match_scratch:W 1 "r")
19151    (parallel [(set (reg:P SP_REG)
19152                    (plus:P (reg:P SP_REG)
19153                            (match_operand:P 0 "const_int_operand")))
19154               (clobber (reg:CC FLAGS_REG))
19155               (clobber (mem:BLK (scratch)))])]
19156   "optimize_insn_for_size_p ()
19157    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19158   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19159               (clobber (mem:BLK (scratch)))])
19160    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19162 ;; Convert esp additions to pop.
19163 (define_peephole2
19164   [(match_scratch:W 1 "r")
19165    (parallel [(set (reg:P SP_REG)
19166                    (plus:P (reg:P SP_REG)
19167                            (match_operand:P 0 "const_int_operand")))
19168               (clobber (reg:CC FLAGS_REG))])]
19169   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19170   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19172 ;; Two pops case is tricky, since pop causes dependency
19173 ;; on destination register.  We use two registers if available.
19174 (define_peephole2
19175   [(match_scratch:W 1 "r")
19176    (match_scratch:W 2 "r")
19177    (parallel [(set (reg:P SP_REG)
19178                    (plus:P (reg:P SP_REG)
19179                            (match_operand:P 0 "const_int_operand")))
19180               (clobber (reg:CC FLAGS_REG))])]
19181   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19182   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19183    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19185 (define_peephole2
19186   [(match_scratch:W 1 "r")
19187    (parallel [(set (reg:P SP_REG)
19188                    (plus:P (reg:P SP_REG)
19189                            (match_operand:P 0 "const_int_operand")))
19190               (clobber (reg:CC FLAGS_REG))])]
19191   "optimize_insn_for_size_p ()
19192    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19193   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19194    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19196 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19197 ;; required and register dies.  Similarly for 128 to -128.
19198 (define_peephole2
19199   [(set (match_operand 0 "flags_reg_operand")
19200         (match_operator 1 "compare_operator"
19201           [(match_operand 2 "register_operand")
19202            (match_operand 3 "const_int_operand")]))]
19203   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19204      && incdec_operand (operands[3], GET_MODE (operands[3])))
19205     || (!TARGET_FUSE_CMP_AND_BRANCH
19206         && INTVAL (operands[3]) == 128))
19207    && ix86_match_ccmode (insn, CCGCmode)
19208    && peep2_reg_dead_p (1, operands[2])"
19209   [(parallel [(set (match_dup 0)
19210                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19211               (clobber (match_dup 2))])])
19213 ;; Convert imul by three, five and nine into lea
19214 (define_peephole2
19215   [(parallel
19216     [(set (match_operand:SWI48 0 "register_operand")
19217           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19218                       (match_operand:SWI48 2 "const359_operand")))
19219      (clobber (reg:CC FLAGS_REG))])]
19220   "!TARGET_PARTIAL_REG_STALL
19221    || <MODE>mode == SImode
19222    || optimize_function_for_size_p (cfun)"
19223   [(set (match_dup 0)
19224         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19225                     (match_dup 1)))]
19226   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19228 (define_peephole2
19229   [(parallel
19230     [(set (match_operand:SWI48 0 "register_operand")
19231           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19232                       (match_operand:SWI48 2 "const359_operand")))
19233      (clobber (reg:CC FLAGS_REG))])]
19234   "optimize_insn_for_speed_p ()
19235    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19236   [(set (match_dup 0) (match_dup 1))
19237    (set (match_dup 0)
19238         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19239                     (match_dup 0)))]
19240   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19242 ;; imul $32bit_imm, mem, reg is vector decoded, while
19243 ;; imul $32bit_imm, reg, reg is direct decoded.
19244 (define_peephole2
19245   [(match_scratch:SWI48 3 "r")
19246    (parallel [(set (match_operand:SWI48 0 "register_operand")
19247                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19248                                (match_operand:SWI48 2 "immediate_operand")))
19249               (clobber (reg:CC FLAGS_REG))])]
19250   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19251    && !satisfies_constraint_K (operands[2])"
19252   [(set (match_dup 3) (match_dup 1))
19253    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19254               (clobber (reg:CC FLAGS_REG))])])
19256 (define_peephole2
19257   [(match_scratch:SI 3 "r")
19258    (parallel [(set (match_operand:DI 0 "register_operand")
19259                    (zero_extend:DI
19260                      (mult:SI (match_operand:SI 1 "memory_operand")
19261                               (match_operand:SI 2 "immediate_operand"))))
19262               (clobber (reg:CC FLAGS_REG))])]
19263   "TARGET_64BIT
19264    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19265    && !satisfies_constraint_K (operands[2])"
19266   [(set (match_dup 3) (match_dup 1))
19267    (parallel [(set (match_dup 0)
19268                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19269               (clobber (reg:CC FLAGS_REG))])])
19271 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19272 ;; Convert it into imul reg, reg
19273 ;; It would be better to force assembler to encode instruction using long
19274 ;; immediate, but there is apparently no way to do so.
19275 (define_peephole2
19276   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19277                    (mult:SWI248
19278                     (match_operand:SWI248 1 "nonimmediate_operand")
19279                     (match_operand:SWI248 2 "const_int_operand")))
19280               (clobber (reg:CC FLAGS_REG))])
19281    (match_scratch:SWI248 3 "r")]
19282   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19283    && satisfies_constraint_K (operands[2])"
19284   [(set (match_dup 3) (match_dup 2))
19285    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19286               (clobber (reg:CC FLAGS_REG))])]
19288   if (!rtx_equal_p (operands[0], operands[1]))
19289     emit_move_insn (operands[0], operands[1]);
19292 ;; After splitting up read-modify operations, array accesses with memory
19293 ;; operands might end up in form:
19294 ;;  sall    $2, %eax
19295 ;;  movl    4(%esp), %edx
19296 ;;  addl    %edx, %eax
19297 ;; instead of pre-splitting:
19298 ;;  sall    $2, %eax
19299 ;;  addl    4(%esp), %eax
19300 ;; Turn it into:
19301 ;;  movl    4(%esp), %edx
19302 ;;  leal    (%edx,%eax,4), %eax
19304 (define_peephole2
19305   [(match_scratch:W 5 "r")
19306    (parallel [(set (match_operand 0 "register_operand")
19307                    (ashift (match_operand 1 "register_operand")
19308                            (match_operand 2 "const_int_operand")))
19309                (clobber (reg:CC FLAGS_REG))])
19310    (parallel [(set (match_operand 3 "register_operand")
19311                    (plus (match_dup 0)
19312                          (match_operand 4 "x86_64_general_operand")))
19313                    (clobber (reg:CC FLAGS_REG))])]
19314   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19315    /* Validate MODE for lea.  */
19316    && ((!TARGET_PARTIAL_REG_STALL
19317         && (GET_MODE (operands[0]) == QImode
19318             || GET_MODE (operands[0]) == HImode))
19319        || GET_MODE (operands[0]) == SImode
19320        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19321    && (rtx_equal_p (operands[0], operands[3])
19322        || peep2_reg_dead_p (2, operands[0]))
19323    /* We reorder load and the shift.  */
19324    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19325   [(set (match_dup 5) (match_dup 4))
19326    (set (match_dup 0) (match_dup 1))]
19328   machine_mode op1mode = GET_MODE (operands[1]);
19329   machine_mode mode = op1mode == DImode ? DImode : SImode;
19330   int scale = 1 << INTVAL (operands[2]);
19331   rtx index = gen_lowpart (word_mode, operands[1]);
19332   rtx base = gen_lowpart (word_mode, operands[5]);
19333   rtx dest = gen_lowpart (mode, operands[3]);
19335   operands[1] = gen_rtx_PLUS (word_mode, base,
19336                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19337   if (mode != word_mode)
19338     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19340   operands[5] = base;
19341   if (op1mode != word_mode)
19342     operands[5] = gen_lowpart (op1mode, operands[5]);
19344   operands[0] = dest;
19347 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19348 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19349 ;; caught for use by garbage collectors and the like.  Using an insn that
19350 ;; maps to SIGILL makes it more likely the program will rightfully die.
19351 ;; Keeping with tradition, "6" is in honor of #UD.
19352 (define_insn "trap"
19353   [(trap_if (const_int 1) (const_int 6))]
19354   ""
19356 #ifdef HAVE_AS_IX86_UD2
19357   return "ud2";
19358 #else
19359   return ASM_SHORT "0x0b0f";
19360 #endif
19362   [(set_attr "length" "2")])
19364 (define_insn "ud2"
19365   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19366   ""
19368 #ifdef HAVE_AS_IX86_UD2
19369   return "ud2";
19370 #else
19371   return ASM_SHORT "0x0b0f";
19372 #endif
19374   [(set_attr "length" "2")])
19376 (define_expand "prefetch"
19377   [(prefetch (match_operand 0 "address_operand")
19378              (match_operand:SI 1 "const_int_operand")
19379              (match_operand:SI 2 "const_int_operand"))]
19380   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19382   bool write = INTVAL (operands[1]) != 0;
19383   int locality = INTVAL (operands[2]);
19385   gcc_assert (IN_RANGE (locality, 0, 3));
19387   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19388      supported by SSE counterpart (non-SSE2 athlon machines) or the
19389      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19390      prefetch as it allows specifying of locality.  */
19392   if (write)
19393     {
19394       if (TARGET_PREFETCHWT1)
19395         operands[2] = GEN_INT (MAX (locality, 2)); 
19396       else if (TARGET_PRFCHW)
19397         operands[2] = GEN_INT (3);
19398       else if (TARGET_3DNOW && !TARGET_SSE2)
19399         operands[2] = GEN_INT (3);
19400       else if (TARGET_PREFETCH_SSE)
19401         operands[1] = const0_rtx;
19402       else
19403         {
19404           gcc_assert (TARGET_3DNOW);
19405           operands[2] = GEN_INT (3);
19406         }
19407     }
19408   else
19409     {
19410       if (TARGET_PREFETCH_SSE)
19411         ;
19412       else
19413         {
19414           gcc_assert (TARGET_3DNOW);
19415           operands[2] = GEN_INT (3);
19416         }
19417     }
19420 (define_insn "*prefetch_sse"
19421   [(prefetch (match_operand 0 "address_operand" "p")
19422              (const_int 0)
19423              (match_operand:SI 1 "const_int_operand"))]
19424   "TARGET_PREFETCH_SSE"
19426   static const char * const patterns[4] = {
19427    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19428   };
19430   int locality = INTVAL (operands[1]);
19431   gcc_assert (IN_RANGE (locality, 0, 3));
19433   return patterns[locality];
19435   [(set_attr "type" "sse")
19436    (set_attr "atom_sse_attr" "prefetch")
19437    (set (attr "length_address")
19438         (symbol_ref "memory_address_length (operands[0], false)"))
19439    (set_attr "memory" "none")])
19441 (define_insn "*prefetch_3dnow"
19442   [(prefetch (match_operand 0 "address_operand" "p")
19443              (match_operand:SI 1 "const_int_operand" "n")
19444              (const_int 3))]
19445   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19447   if (INTVAL (operands[1]) == 0)
19448     return "prefetch\t%a0";
19449   else
19450     return "prefetchw\t%a0";
19452   [(set_attr "type" "mmx")
19453    (set (attr "length_address")
19454         (symbol_ref "memory_address_length (operands[0], false)"))
19455    (set_attr "memory" "none")])
19457 (define_insn "*prefetch_prefetchwt1"
19458   [(prefetch (match_operand 0 "address_operand" "p")
19459              (const_int 1)
19460              (const_int 2))]
19461   "TARGET_PREFETCHWT1"
19462   "prefetchwt1\t%a0";
19463   [(set_attr "type" "sse")
19464    (set (attr "length_address")
19465         (symbol_ref "memory_address_length (operands[0], false)"))
19466    (set_attr "memory" "none")])
19468 (define_expand "stack_protect_set"
19469   [(match_operand 0 "memory_operand")
19470    (match_operand 1 "memory_operand")]
19471   "TARGET_SSP_TLS_GUARD"
19473   rtx (*insn)(rtx, rtx);
19475   insn = (TARGET_LP64
19476           ? gen_stack_protect_set_di
19477           : gen_stack_protect_set_si);
19479   emit_insn (insn (operands[0], operands[1]));
19480   DONE;
19483 (define_insn "stack_protect_set_<mode>"
19484   [(set (match_operand:PTR 0 "memory_operand" "=m")
19485         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19486                     UNSPEC_SP_SET))
19487    (set (match_scratch:PTR 2 "=&r") (const_int 0))
19488    (clobber (reg:CC FLAGS_REG))]
19489   "TARGET_SSP_TLS_GUARD"
19490   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19491   [(set_attr "type" "multi")])
19493 (define_expand "stack_protect_test"
19494   [(match_operand 0 "memory_operand")
19495    (match_operand 1 "memory_operand")
19496    (match_operand 2)]
19497   "TARGET_SSP_TLS_GUARD"
19499   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19501   rtx (*insn)(rtx, rtx, rtx);
19503   insn = (TARGET_LP64
19504           ? gen_stack_protect_test_di
19505           : gen_stack_protect_test_si);
19507   emit_insn (insn (flags, operands[0], operands[1]));
19509   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19510                                   flags, const0_rtx, operands[2]));
19511   DONE;
19514 (define_insn "stack_protect_test_<mode>"
19515   [(set (match_operand:CCZ 0 "flags_reg_operand")
19516         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19517                      (match_operand:PTR 2 "memory_operand" "m")]
19518                     UNSPEC_SP_TEST))
19519    (clobber (match_scratch:PTR 3 "=&r"))]
19520   "TARGET_SSP_TLS_GUARD"
19521   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19522   [(set_attr "type" "multi")])
19524 (define_insn "sse4_2_crc32<mode>"
19525   [(set (match_operand:SI 0 "register_operand" "=r")
19526         (unspec:SI
19527           [(match_operand:SI 1 "register_operand" "0")
19528            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19529           UNSPEC_CRC32))]
19530   "TARGET_SSE4_2 || TARGET_CRC32"
19531   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19532   [(set_attr "type" "sselog1")
19533    (set_attr "prefix_rep" "1")
19534    (set_attr "prefix_extra" "1")
19535    (set (attr "prefix_data16")
19536      (if_then_else (match_operand:HI 2)
19537        (const_string "1")
19538        (const_string "*")))
19539    (set (attr "prefix_rex")
19540      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19541        (const_string "1")
19542        (const_string "*")))
19543    (set_attr "mode" "SI")])
19545 (define_insn "sse4_2_crc32di"
19546   [(set (match_operand:DI 0 "register_operand" "=r")
19547         (unspec:DI
19548           [(match_operand:DI 1 "register_operand" "0")
19549            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19550           UNSPEC_CRC32))]
19551   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19552   "crc32{q}\t{%2, %0|%0, %2}"
19553   [(set_attr "type" "sselog1")
19554    (set_attr "prefix_rep" "1")
19555    (set_attr "prefix_extra" "1")
19556    (set_attr "mode" "DI")])
19558 (define_insn "rdpmc"
19559   [(set (match_operand:DI 0 "register_operand" "=A")
19560         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19561                             UNSPECV_RDPMC))]
19562   "!TARGET_64BIT"
19563   "rdpmc"
19564   [(set_attr "type" "other")
19565    (set_attr "length" "2")])
19567 (define_insn "rdpmc_rex64"
19568   [(set (match_operand:DI 0 "register_operand" "=a")
19569         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19570                             UNSPECV_RDPMC))
19571    (set (match_operand:DI 1 "register_operand" "=d")
19572         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19573   "TARGET_64BIT"
19574   "rdpmc"
19575   [(set_attr "type" "other")
19576    (set_attr "length" "2")])
19578 (define_insn "rdtsc"
19579   [(set (match_operand:DI 0 "register_operand" "=A")
19580         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19581   "!TARGET_64BIT"
19582   "rdtsc"
19583   [(set_attr "type" "other")
19584    (set_attr "length" "2")])
19586 (define_insn "rdtsc_rex64"
19587   [(set (match_operand:DI 0 "register_operand" "=a")
19588         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19589    (set (match_operand:DI 1 "register_operand" "=d")
19590         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19591   "TARGET_64BIT"
19592   "rdtsc"
19593   [(set_attr "type" "other")
19594    (set_attr "length" "2")])
19596 (define_insn "rdtscp"
19597   [(set (match_operand:DI 0 "register_operand" "=A")
19598         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19599    (set (match_operand:SI 1 "register_operand" "=c")
19600         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19601   "!TARGET_64BIT"
19602   "rdtscp"
19603   [(set_attr "type" "other")
19604    (set_attr "length" "3")])
19606 (define_insn "rdtscp_rex64"
19607   [(set (match_operand:DI 0 "register_operand" "=a")
19608         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19609    (set (match_operand:DI 1 "register_operand" "=d")
19610         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19611    (set (match_operand:SI 2 "register_operand" "=c")
19612         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19613   "TARGET_64BIT"
19614   "rdtscp"
19615   [(set_attr "type" "other")
19616    (set_attr "length" "3")])
19618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19620 ;; FXSR, XSAVE and XSAVEOPT instructions
19622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19624 (define_insn "fxsave"
19625   [(set (match_operand:BLK 0 "memory_operand" "=m")
19626         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19627   "TARGET_FXSR"
19628   "fxsave\t%0"
19629   [(set_attr "type" "other")
19630    (set_attr "memory" "store")
19631    (set (attr "length")
19632         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19634 (define_insn "fxsave64"
19635   [(set (match_operand:BLK 0 "memory_operand" "=m")
19636         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19637   "TARGET_64BIT && TARGET_FXSR"
19638   "fxsave64\t%0"
19639   [(set_attr "type" "other")
19640    (set_attr "memory" "store")
19641    (set (attr "length")
19642         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19644 (define_insn "fxrstor"
19645   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19646                     UNSPECV_FXRSTOR)]
19647   "TARGET_FXSR"
19648   "fxrstor\t%0"
19649   [(set_attr "type" "other")
19650    (set_attr "memory" "load")
19651    (set (attr "length")
19652         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19654 (define_insn "fxrstor64"
19655   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19656                     UNSPECV_FXRSTOR64)]
19657   "TARGET_64BIT && TARGET_FXSR"
19658   "fxrstor64\t%0"
19659   [(set_attr "type" "other")
19660    (set_attr "memory" "load")
19661    (set (attr "length")
19662         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19664 (define_int_iterator ANY_XSAVE
19665         [UNSPECV_XSAVE
19666          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19667          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19668          (UNSPECV_XSAVES "TARGET_XSAVES")])
19670 (define_int_iterator ANY_XSAVE64
19671         [UNSPECV_XSAVE64
19672          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19673          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19674          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19676 (define_int_attr xsave
19677         [(UNSPECV_XSAVE "xsave")
19678          (UNSPECV_XSAVE64 "xsave64")
19679          (UNSPECV_XSAVEOPT "xsaveopt")
19680          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19681          (UNSPECV_XSAVEC "xsavec")
19682          (UNSPECV_XSAVEC64 "xsavec64")
19683          (UNSPECV_XSAVES "xsaves")
19684          (UNSPECV_XSAVES64 "xsaves64")])
19686 (define_int_iterator ANY_XRSTOR
19687         [UNSPECV_XRSTOR
19688          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19690 (define_int_iterator ANY_XRSTOR64
19691         [UNSPECV_XRSTOR64
19692          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19694 (define_int_attr xrstor
19695         [(UNSPECV_XRSTOR "xrstor")
19696          (UNSPECV_XRSTOR64 "xrstor")
19697          (UNSPECV_XRSTORS "xrstors")
19698          (UNSPECV_XRSTORS64 "xrstors")])
19700 (define_insn "<xsave>"
19701   [(set (match_operand:BLK 0 "memory_operand" "=m")
19702         (unspec_volatile:BLK
19703          [(match_operand:DI 1 "register_operand" "A")]
19704          ANY_XSAVE))]
19705   "!TARGET_64BIT && TARGET_XSAVE"
19706   "<xsave>\t%0"
19707   [(set_attr "type" "other")
19708    (set_attr "memory" "store")
19709    (set (attr "length")
19710         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19712 (define_insn "<xsave>_rex64"
19713   [(set (match_operand:BLK 0 "memory_operand" "=m")
19714         (unspec_volatile:BLK
19715          [(match_operand:SI 1 "register_operand" "a")
19716           (match_operand:SI 2 "register_operand" "d")]
19717          ANY_XSAVE))]
19718   "TARGET_64BIT && TARGET_XSAVE"
19719   "<xsave>\t%0"
19720   [(set_attr "type" "other")
19721    (set_attr "memory" "store")
19722    (set (attr "length")
19723         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19725 (define_insn "<xsave>"
19726   [(set (match_operand:BLK 0 "memory_operand" "=m")
19727         (unspec_volatile:BLK
19728          [(match_operand:SI 1 "register_operand" "a")
19729           (match_operand:SI 2 "register_operand" "d")]
19730          ANY_XSAVE64))]
19731   "TARGET_64BIT && TARGET_XSAVE"
19732   "<xsave>\t%0"
19733   [(set_attr "type" "other")
19734    (set_attr "memory" "store")
19735    (set (attr "length")
19736         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19738 (define_insn "<xrstor>"
19739    [(unspec_volatile:BLK
19740      [(match_operand:BLK 0 "memory_operand" "m")
19741       (match_operand:DI 1 "register_operand" "A")]
19742      ANY_XRSTOR)]
19743   "!TARGET_64BIT && TARGET_XSAVE"
19744   "<xrstor>\t%0"
19745   [(set_attr "type" "other")
19746    (set_attr "memory" "load")
19747    (set (attr "length")
19748         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19750 (define_insn "<xrstor>_rex64"
19751    [(unspec_volatile:BLK
19752      [(match_operand:BLK 0 "memory_operand" "m")
19753       (match_operand:SI 1 "register_operand" "a")
19754       (match_operand:SI 2 "register_operand" "d")]
19755      ANY_XRSTOR)]
19756   "TARGET_64BIT && TARGET_XSAVE"
19757   "<xrstor>\t%0"
19758   [(set_attr "type" "other")
19759    (set_attr "memory" "load")
19760    (set (attr "length")
19761         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19763 (define_insn "<xrstor>64"
19764    [(unspec_volatile:BLK
19765      [(match_operand:BLK 0 "memory_operand" "m")
19766       (match_operand:SI 1 "register_operand" "a")
19767       (match_operand:SI 2 "register_operand" "d")]
19768      ANY_XRSTOR64)]
19769   "TARGET_64BIT && TARGET_XSAVE"
19770   "<xrstor>64\t%0"
19771   [(set_attr "type" "other")
19772    (set_attr "memory" "load")
19773    (set (attr "length")
19774         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19776 (define_insn "xsetbv"
19777   [(unspec_volatile:SI
19778          [(match_operand:SI 0 "register_operand" "c")
19779           (match_operand:DI 1 "register_operand" "A")]
19780          UNSPECV_XSETBV)]
19781   "!TARGET_64BIT && TARGET_XSAVE"
19782   "xsetbv"
19783   [(set_attr "type" "other")])
19785 (define_insn "xsetbv_rex64"
19786   [(unspec_volatile:SI
19787          [(match_operand:SI 0 "register_operand" "c")
19788           (match_operand:SI 1 "register_operand" "a")
19789           (match_operand:SI 2 "register_operand" "d")]
19790          UNSPECV_XSETBV)]
19791   "TARGET_64BIT && TARGET_XSAVE"
19792   "xsetbv"
19793   [(set_attr "type" "other")])
19795 (define_insn "xgetbv"
19796   [(set (match_operand:DI 0 "register_operand" "=A")
19797         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19798                             UNSPECV_XGETBV))]
19799   "!TARGET_64BIT && TARGET_XSAVE"
19800   "xgetbv"
19801   [(set_attr "type" "other")])
19803 (define_insn "xgetbv_rex64"
19804   [(set (match_operand:DI 0 "register_operand" "=a")
19805         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19806                             UNSPECV_XGETBV))
19807    (set (match_operand:DI 1 "register_operand" "=d")
19808         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19809   "TARGET_64BIT && TARGET_XSAVE"
19810   "xgetbv"
19811   [(set_attr "type" "other")])
19813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19815 ;; Floating-point instructions for atomic compound assignments
19817 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19819 ; Clobber all floating-point registers on environment save and restore
19820 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19821 (define_insn "fnstenv"
19822   [(set (match_operand:BLK 0 "memory_operand" "=m")
19823         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19824    (clobber (reg:HI FPCR_REG))
19825    (clobber (reg:XF ST0_REG))
19826    (clobber (reg:XF ST1_REG))
19827    (clobber (reg:XF ST2_REG))
19828    (clobber (reg:XF ST3_REG))
19829    (clobber (reg:XF ST4_REG))
19830    (clobber (reg:XF ST5_REG))
19831    (clobber (reg:XF ST6_REG))
19832    (clobber (reg:XF ST7_REG))]
19833   "TARGET_80387"
19834   "fnstenv\t%0"
19835   [(set_attr "type" "other")
19836    (set_attr "memory" "store")
19837    (set (attr "length")
19838         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19840 (define_insn "fldenv"
19841   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19842                     UNSPECV_FLDENV)
19843    (clobber (reg:CCFP FPSR_REG))
19844    (clobber (reg:HI FPCR_REG))
19845    (clobber (reg:XF ST0_REG))
19846    (clobber (reg:XF ST1_REG))
19847    (clobber (reg:XF ST2_REG))
19848    (clobber (reg:XF ST3_REG))
19849    (clobber (reg:XF ST4_REG))
19850    (clobber (reg:XF ST5_REG))
19851    (clobber (reg:XF ST6_REG))
19852    (clobber (reg:XF ST7_REG))]
19853   "TARGET_80387"
19854   "fldenv\t%0"
19855   [(set_attr "type" "other")
19856    (set_attr "memory" "load")
19857    (set (attr "length")
19858         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19860 (define_insn "fnstsw"
19861   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19862         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19863   "TARGET_80387"
19864   "fnstsw\t%0"
19865   [(set_attr "type" "other,other")
19866    (set_attr "memory" "none,store")
19867    (set (attr "length")
19868         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19870 (define_insn "fnclex"
19871   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19872   "TARGET_80387"
19873   "fnclex"
19874   [(set_attr "type" "other")
19875    (set_attr "memory" "none")
19876    (set_attr "length" "2")])
19878 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19880 ;; LWP instructions
19882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19884 (define_expand "lwp_llwpcb"
19885   [(unspec_volatile [(match_operand 0 "register_operand")]
19886                     UNSPECV_LLWP_INTRINSIC)]
19887   "TARGET_LWP")
19889 (define_insn "*lwp_llwpcb<mode>1"
19890   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19891                     UNSPECV_LLWP_INTRINSIC)]
19892   "TARGET_LWP"
19893   "llwpcb\t%0"
19894   [(set_attr "type" "lwp")
19895    (set_attr "mode" "<MODE>")
19896    (set_attr "length" "5")])
19898 (define_expand "lwp_slwpcb"
19899   [(set (match_operand 0 "register_operand")
19900         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19901   "TARGET_LWP"
19903   rtx (*insn)(rtx);
19905   insn = (Pmode == DImode
19906           ? gen_lwp_slwpcbdi
19907           : gen_lwp_slwpcbsi);
19909   emit_insn (insn (operands[0]));
19910   DONE;
19913 (define_insn "lwp_slwpcb<mode>"
19914   [(set (match_operand:P 0 "register_operand" "=r")
19915         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19916   "TARGET_LWP"
19917   "slwpcb\t%0"
19918   [(set_attr "type" "lwp")
19919    (set_attr "mode" "<MODE>")
19920    (set_attr "length" "5")])
19922 (define_expand "lwp_lwpval<mode>3"
19923   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19924                      (match_operand:SI 2 "nonimmediate_operand")
19925                      (match_operand:SI 3 "const_int_operand")]
19926                     UNSPECV_LWPVAL_INTRINSIC)]
19927   "TARGET_LWP"
19928   ;; Avoid unused variable warning.
19929   "(void) operands[0];")
19931 (define_insn "*lwp_lwpval<mode>3_1"
19932   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19933                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19934                      (match_operand:SI 2 "const_int_operand" "i")]
19935                     UNSPECV_LWPVAL_INTRINSIC)]
19936   "TARGET_LWP"
19937   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19938   [(set_attr "type" "lwp")
19939    (set_attr "mode" "<MODE>")
19940    (set (attr "length")
19941         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19943 (define_expand "lwp_lwpins<mode>3"
19944   [(set (reg:CCC FLAGS_REG)
19945         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19946                               (match_operand:SI 2 "nonimmediate_operand")
19947                               (match_operand:SI 3 "const_int_operand")]
19948                              UNSPECV_LWPINS_INTRINSIC))
19949    (set (match_operand:QI 0 "nonimmediate_operand")
19950         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19951   "TARGET_LWP")
19953 (define_insn "*lwp_lwpins<mode>3_1"
19954   [(set (reg:CCC FLAGS_REG)
19955         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19956                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19957                               (match_operand:SI 2 "const_int_operand" "i")]
19958                              UNSPECV_LWPINS_INTRINSIC))]
19959   "TARGET_LWP"
19960   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19961   [(set_attr "type" "lwp")
19962    (set_attr "mode" "<MODE>")
19963    (set (attr "length")
19964         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19966 (define_int_iterator RDFSGSBASE
19967         [UNSPECV_RDFSBASE
19968          UNSPECV_RDGSBASE])
19970 (define_int_iterator WRFSGSBASE
19971         [UNSPECV_WRFSBASE
19972          UNSPECV_WRGSBASE])
19974 (define_int_attr fsgs
19975         [(UNSPECV_RDFSBASE "fs")
19976          (UNSPECV_RDGSBASE "gs")
19977          (UNSPECV_WRFSBASE "fs")
19978          (UNSPECV_WRGSBASE "gs")])
19980 (define_insn "rd<fsgs>base<mode>"
19981   [(set (match_operand:SWI48 0 "register_operand" "=r")
19982         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19983   "TARGET_64BIT && TARGET_FSGSBASE"
19984   "rd<fsgs>base\t%0"
19985   [(set_attr "type" "other")
19986    (set_attr "prefix_extra" "2")])
19988 (define_insn "wr<fsgs>base<mode>"
19989   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19990                     WRFSGSBASE)]
19991   "TARGET_64BIT && TARGET_FSGSBASE"
19992   "wr<fsgs>base\t%0"
19993   [(set_attr "type" "other")
19994    (set_attr "prefix_extra" "2")])
19996 (define_insn "rdrand<mode>_1"
19997   [(set (match_operand:SWI248 0 "register_operand" "=r")
19998         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19999    (set (reg:CCC FLAGS_REG)
20000         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20001   "TARGET_RDRND"
20002   "rdrand\t%0"
20003   [(set_attr "type" "other")
20004    (set_attr "prefix_extra" "1")])
20006 (define_insn "rdseed<mode>_1"
20007   [(set (match_operand:SWI248 0 "register_operand" "=r")
20008         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20009    (set (reg:CCC FLAGS_REG)
20010         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20011   "TARGET_RDSEED"
20012   "rdseed\t%0"
20013   [(set_attr "type" "other")
20014    (set_attr "prefix_extra" "1")])
20016 (define_expand "pause"
20017   [(set (match_dup 0)
20018         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20019   ""
20021   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20022   MEM_VOLATILE_P (operands[0]) = 1;
20025 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20026 ;; They have the same encoding.
20027 (define_insn "*pause"
20028   [(set (match_operand:BLK 0)
20029         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20030   ""
20031   "rep%; nop"
20032   [(set_attr "length" "2")
20033    (set_attr "memory" "unknown")])
20035 ;; CET instructions
20036 (define_insn "rdssp<mode>"
20037   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20038         (unspec_volatile:SWI48x
20039           [(match_operand:SWI48x 1 "register_operand" "0")]
20040           UNSPECV_NOP_RDSSP))]
20041   "TARGET_SHSTK"
20042   "rdssp<mskmodesuffix>\t%0"
20043   [(set_attr "length" "4")
20044    (set_attr "type" "other")])
20046 (define_insn "incssp<mode>"
20047   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20048                    UNSPECV_INCSSP)]
20049   "TARGET_SHSTK"
20050   "incssp<mskmodesuffix>\t%0"
20051   [(set_attr "length" "4")
20052    (set_attr "type" "other")])
20054 (define_insn "saveprevssp"
20055   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20056   "TARGET_SHSTK"
20057   "saveprevssp"
20058   [(set_attr "length" "5")
20059    (set_attr "type" "other")])
20061 (define_insn "rstorssp"
20062   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20063                    UNSPECV_RSTORSSP)]
20064   "TARGET_SHSTK"
20065   "rstorssp\t%0"
20066   [(set_attr "length" "5")
20067    (set_attr "type" "other")])
20069 (define_insn "wrss<mode>"
20070   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20071                      (match_operand:SWI48x 1 "memory_operand" "m")]
20072                    UNSPECV_WRSS)]
20073   "TARGET_SHSTK"
20074   "wrss<mskmodesuffix>\t%0, %1"
20075   [(set_attr "length" "3")
20076    (set_attr "type" "other")])
20078 (define_insn "wruss<mode>"
20079   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20080                      (match_operand:SWI48x 1 "memory_operand" "m")]
20081                    UNSPECV_WRUSS)]
20082   "TARGET_SHSTK"
20083   "wruss<mskmodesuffix>\t%0, %1"
20084   [(set_attr "length" "4")
20085    (set_attr "type" "other")])
20087 (define_insn "setssbsy"
20088   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20089   "TARGET_SHSTK"
20090   "setssbsy"
20091   [(set_attr "length" "4")
20092    (set_attr "type" "other")])
20094 (define_insn "clrssbsy"
20095   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20096                    UNSPECV_CLRSSBSY)]
20097   "TARGET_SHSTK"
20098   "clrssbsy\t%0"
20099   [(set_attr "length" "4")
20100    (set_attr "type" "other")])
20102 (define_insn "nop_endbr"
20103   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20104   "TARGET_IBT"
20105   "*
20106 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20107   [(set_attr "length" "4")
20108    (set_attr "length_immediate" "0")
20109    (set_attr "modrm" "0")])
20111 ;; For RTM support
20112 (define_expand "xbegin"
20113   [(set (match_operand:SI 0 "register_operand")
20114         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20115   "TARGET_RTM"
20117   rtx_code_label *label = gen_label_rtx ();
20119   /* xbegin is emitted as jump_insn, so reload won't be able
20120      to reload its operand.  Force the value into AX hard register.  */
20121   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20122   emit_move_insn (ax_reg, constm1_rtx);
20124   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20126   emit_label (label);
20127   LABEL_NUSES (label) = 1;
20129   emit_move_insn (operands[0], ax_reg);
20131   DONE;
20134 (define_insn "xbegin_1"
20135   [(set (pc)
20136         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20137                           (const_int 0))
20138                       (label_ref (match_operand 1))
20139                       (pc)))
20140    (set (match_operand:SI 0 "register_operand" "+a")
20141         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20142   "TARGET_RTM"
20143   "xbegin\t%l1"
20144   [(set_attr "type" "other")
20145    (set_attr "length" "6")])
20147 (define_insn "xend"
20148   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20149   "TARGET_RTM"
20150   "xend"
20151   [(set_attr "type" "other")
20152    (set_attr "length" "3")])
20154 (define_insn "xabort"
20155   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20156                     UNSPECV_XABORT)]
20157   "TARGET_RTM"
20158   "xabort\t%0"
20159   [(set_attr "type" "other")
20160    (set_attr "length" "3")])
20162 (define_expand "xtest"
20163   [(set (match_operand:QI 0 "register_operand")
20164         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20165   "TARGET_RTM"
20167   emit_insn (gen_xtest_1 ());
20169   ix86_expand_setcc (operands[0], NE,
20170                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20171   DONE;
20174 (define_insn "xtest_1"
20175   [(set (reg:CCZ FLAGS_REG)
20176         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20177   "TARGET_RTM"
20178   "xtest"
20179   [(set_attr "type" "other")
20180    (set_attr "length" "3")])
20182 (define_insn "clwb"
20183   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20184                    UNSPECV_CLWB)]
20185   "TARGET_CLWB"
20186   "clwb\t%a0"
20187   [(set_attr "type" "sse")
20188    (set_attr "atom_sse_attr" "fence")
20189    (set_attr "memory" "unknown")])
20191 (define_insn "clflushopt"
20192   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20193                    UNSPECV_CLFLUSHOPT)]
20194   "TARGET_CLFLUSHOPT"
20195   "clflushopt\t%a0"
20196   [(set_attr "type" "sse")
20197    (set_attr "atom_sse_attr" "fence")
20198    (set_attr "memory" "unknown")])
20200 ;; MONITORX and MWAITX
20201 (define_insn "mwaitx"
20202   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20203                      (match_operand:SI 1 "register_operand" "a")
20204                      (match_operand:SI 2 "register_operand" "b")]
20205                    UNSPECV_MWAITX)]
20206   "TARGET_MWAITX"
20207 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20208 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20209 ;; we only need to set up 32bit registers.
20210   "mwaitx"
20211   [(set_attr "length" "3")])
20213 (define_insn "monitorx_<mode>"
20214   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20215                      (match_operand:SI 1 "register_operand" "c")
20216                      (match_operand:SI 2 "register_operand" "d")]
20217                    UNSPECV_MONITORX)]
20218   "TARGET_MWAITX"
20219 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20220 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20221 ;; zero extended to 64bit, we only need to set up 32bit registers.
20222   "%^monitorx"
20223   [(set (attr "length")
20224      (symbol_ref ("(Pmode != word_mode) + 3")))])
20226 ;; CLZERO
20227 (define_insn "clzero_<mode>"
20228   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20229                    UNSPECV_CLZERO)]
20230   "TARGET_CLZERO"
20231   "clzero"
20232   [(set_attr "length" "3")
20233   (set_attr "memory" "unknown")])
20235 ;; MPX instructions
20237 (define_expand "<mode>_mk"
20238   [(set (match_operand:BND 0 "register_operand")
20239         (unspec:BND
20240           [(mem:<bnd_ptr>
20241            (match_par_dup 3
20242              [(match_operand:<bnd_ptr> 1 "register_operand")
20243               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20244           UNSPEC_BNDMK))]
20245   "TARGET_MPX"
20247   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20248                                                   operands[2]),
20249                                 UNSPEC_BNDMK_ADDR);
20252 (define_insn "*<mode>_mk"
20253   [(set (match_operand:BND 0 "register_operand" "=w")
20254         (unspec:BND
20255           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20256              [(unspec:<bnd_ptr>
20257                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20258                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20259                 UNSPEC_BNDMK_ADDR)])]
20260           UNSPEC_BNDMK))]
20261   "TARGET_MPX"
20262   "bndmk\t{%3, %0|%0, %3}"
20263   [(set_attr "type" "mpxmk")])
20265 (define_expand "mov<mode>"
20266   [(set (match_operand:BND 0 "general_operand")
20267         (match_operand:BND 1 "general_operand"))]
20268   "TARGET_MPX"
20269   "ix86_expand_move (<MODE>mode, operands); DONE;")
20271 (define_insn "*mov<mode>_internal_mpx"
20272   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20273         (match_operand:BND 1 "general_operand" "wm,w"))]
20274   "TARGET_MPX"
20275   "bndmov\t{%1, %0|%0, %1}"
20276   [(set_attr "type" "mpxmov")])
20278 (define_expand "<mode>_<bndcheck>"
20279   [(parallel
20280      [(unspec
20281         [(match_operand:BND 0 "register_operand")
20282          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20283       (set (match_dup 2)
20284            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20285   "TARGET_MPX"
20287   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20288   MEM_VOLATILE_P (operands[2]) = 1;
20291 (define_insn "*<mode>_<bndcheck>"
20292   [(unspec
20293      [(match_operand:BND 0 "register_operand" "w")
20294       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20295    (set (match_operand:BLK 2 "bnd_mem_operator")
20296         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20297   "TARGET_MPX"
20298   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20299   [(set_attr "type" "mpxchk")])
20301 (define_expand "<mode>_ldx"
20302   [(parallel
20303      [(set (match_operand:BND 0 "register_operand")
20304            (unspec:BND
20305              [(mem:<bnd_ptr>
20306                 (match_par_dup 3
20307                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20308                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
20309              UNSPEC_BNDLDX))
20310       (use (mem:BLK (match_dup 1)))])]
20311   "TARGET_MPX"
20313   /* Avoid registers which cannot be used as index.  */
20314   if (!index_register_operand (operands[2], Pmode))
20315     operands[2] = copy_addr_to_reg (operands[2]);
20317   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20318                                                   operands[2]),
20319                                 UNSPEC_BNDLDX_ADDR);
20322 (define_insn "*<mode>_ldx"
20323   [(set (match_operand:BND 0 "register_operand" "=w")
20324         (unspec:BND
20325           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20326              [(unspec:<bnd_ptr>
20327                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20328                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20329                 UNSPEC_BNDLDX_ADDR)])]
20330           UNSPEC_BNDLDX))
20331    (use (mem:BLK (match_dup 1)))]
20332   "TARGET_MPX"
20333   "bndldx\t{%3, %0|%0, %3}"
20334   [(set_attr "type" "mpxld")])
20336 (define_expand "<mode>_stx"
20337   [(parallel
20338      [(unspec
20339         [(mem:<bnd_ptr>
20340            (match_par_dup 3
20341              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20342               (match_operand:<bnd_ptr> 1 "register_operand")]))
20343          (match_operand:BND 2 "register_operand")]
20344         UNSPEC_BNDSTX)
20345       (set (match_dup 4)
20346            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20347   "TARGET_MPX"
20349   /* Avoid registers which cannot be used as index.  */
20350   if (!index_register_operand (operands[1], Pmode))
20351     operands[1] = copy_addr_to_reg (operands[1]);
20353   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20354                                                   operands[1]),
20355                                 UNSPEC_BNDLDX_ADDR);
20356   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20357   MEM_VOLATILE_P (operands[4]) = 1;
20360 (define_insn "*<mode>_stx"
20361   [(unspec
20362      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20363         [(unspec:<bnd_ptr>
20364            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20365             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20366            UNSPEC_BNDLDX_ADDR)])
20367          (match_operand:BND 2 "register_operand" "w")]
20368         UNSPEC_BNDSTX)
20369    (set (match_operand:BLK 4 "bnd_mem_operator")
20370         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20371   "TARGET_MPX"
20372   "bndstx\t{%2, %3|%3, %2}"
20373   [(set_attr "type" "mpxst")])
20375 (define_insn "move_size_reloc_<mode>"
20376   [(set (match_operand:SWI48 0 "register_operand" "=r")
20377         (unspec:SWI48
20378           [(match_operand:SWI48 1 "symbol_operand")]
20379         UNSPEC_SIZEOF))]
20380   "TARGET_MPX"
20382   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20383     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20384   else
20385     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20387   [(set_attr "type" "imov")
20388    (set_attr "mode" "<MODE>")])
20390 ;; RDPKRU and WRPKRU
20392 (define_expand "rdpkru"
20393   [(parallel
20394      [(set (match_operand:SI 0 "register_operand")
20395            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20396       (set (match_dup 2) (const_int 0))])]
20397   "TARGET_PKU"
20399   operands[1] = force_reg (SImode, const0_rtx);
20400   operands[2] = gen_reg_rtx (SImode);
20403 (define_insn "*rdpkru"
20404   [(set (match_operand:SI 0 "register_operand" "=a")
20405         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20406                             UNSPECV_PKU))
20407    (set (match_operand:SI 1 "register_operand" "=d")
20408         (const_int 0))]
20409   "TARGET_PKU"
20410   "rdpkru"
20411   [(set_attr "type" "other")])
20413 (define_expand "wrpkru"
20414   [(unspec_volatile:SI
20415      [(match_operand:SI 0 "register_operand")
20416       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20417   "TARGET_PKU"
20419   operands[1] = force_reg (SImode, const0_rtx);
20420   operands[2] = force_reg (SImode, const0_rtx);
20423 (define_insn "*wrpkru"
20424   [(unspec_volatile:SI
20425      [(match_operand:SI 0 "register_operand" "a")
20426       (match_operand:SI 1 "register_operand" "d")
20427       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20428   "TARGET_PKU"
20429   "wrpkru"
20430   [(set_attr "type" "other")])
20432 (define_insn "rdpid"
20433   [(set (match_operand:SI 0 "register_operand" "=r")
20434         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20435   "TARGET_RDPID"
20436   "rdpid\t%0"
20437   [(set_attr "type" "other")])
20439 (include "mmx.md")
20440 (include "sse.md")
20441 (include "sync.md")