gcc/
[official-gcc.git] / gcc / config / i386 / i386.md
blob0959aef7a0d69325437d5250cd4c4fffd89f677f
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
115   UNSPEC_PEEPSIB
116   UNSPEC_INSN_FALSE_DEP
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For BMI support
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; For AVX512F support
186   UNSPEC_KMOV
188   UNSPEC_BNDMK
189   UNSPEC_BNDMK_ADDR
190   UNSPEC_BNDSTX
191   UNSPEC_BNDLDX
192   UNSPEC_BNDLDX_ADDR
193   UNSPEC_BNDCL
194   UNSPEC_BNDCU
195   UNSPEC_BNDCN
196   UNSPEC_MPX_FENCE
199 (define_c_enum "unspecv" [
200   UNSPECV_BLOCKAGE
201   UNSPECV_STACK_PROBE
202   UNSPECV_PROBE_STACK_RANGE
203   UNSPECV_ALIGN
204   UNSPECV_PROLOGUE_USE
205   UNSPECV_SPLIT_STACK_RETURN
206   UNSPECV_CLD
207   UNSPECV_NOPS
208   UNSPECV_RDTSC
209   UNSPECV_RDTSCP
210   UNSPECV_RDPMC
211   UNSPECV_LLWP_INTRINSIC
212   UNSPECV_SLWP_INTRINSIC
213   UNSPECV_LWPVAL_INTRINSIC
214   UNSPECV_LWPINS_INTRINSIC
215   UNSPECV_RDFSBASE
216   UNSPECV_RDGSBASE
217   UNSPECV_WRFSBASE
218   UNSPECV_WRGSBASE
219   UNSPECV_FXSAVE
220   UNSPECV_FXRSTOR
221   UNSPECV_FXSAVE64
222   UNSPECV_FXRSTOR64
223   UNSPECV_XSAVE
224   UNSPECV_XRSTOR
225   UNSPECV_XSAVE64
226   UNSPECV_XRSTOR64
227   UNSPECV_XSAVEOPT
228   UNSPECV_XSAVEOPT64
229   UNSPECV_XSAVES
230   UNSPECV_XRSTORS
231   UNSPECV_XSAVES64
232   UNSPECV_XRSTORS64
233   UNSPECV_XSAVEC
234   UNSPECV_XSAVEC64
236   ;; For atomic compound assignments.
237   UNSPECV_FNSTENV
238   UNSPECV_FLDENV
239   UNSPECV_FNSTSW
240   UNSPECV_FNCLEX
242   ;; For RDRAND support
243   UNSPECV_RDRAND
245   ;; For RDSEED support
246   UNSPECV_RDSEED
248   ;; For RTM support
249   UNSPECV_XBEGIN
250   UNSPECV_XEND
251   UNSPECV_XABORT
252   UNSPECV_XTEST
254   UNSPECV_NLGR
256   ;; For CLWB support
257   UNSPECV_CLWB
259   ;; For PCOMMIT support
260   UNSPECV_PCOMMIT
262   ;; For CLFLUSHOPT support
263   UNSPECV_CLFLUSHOPT
266 ;; Constants to represent rounding modes in the ROUND instruction
267 (define_constants
268   [(ROUND_FLOOR                 0x1)
269    (ROUND_CEIL                  0x2)
270    (ROUND_TRUNC                 0x3)
271    (ROUND_MXCSR                 0x4)
272    (ROUND_NO_EXC                0x8)
273   ])
275 ;; Constants to represent AVX512F embeded rounding
276 (define_constants
277   [(ROUND_NEAREST_INT                   0)
278    (ROUND_NEG_INF                       1)
279    (ROUND_POS_INF                       2)
280    (ROUND_ZERO                          3)
281    (NO_ROUND                            4)
282    (ROUND_SAE                           8)
283   ])
285 ;; Constants to represent pcomtrue/pcomfalse variants
286 (define_constants
287   [(PCOM_FALSE                  0)
288    (PCOM_TRUE                   1)
289    (COM_FALSE_S                 2)
290    (COM_FALSE_P                 3)
291    (COM_TRUE_S                  4)
292    (COM_TRUE_P                  5)
293   ])
295 ;; Constants used in the XOP pperm instruction
296 (define_constants
297   [(PPERM_SRC                   0x00)   /* copy source */
298    (PPERM_INVERT                0x20)   /* invert source */
299    (PPERM_REVERSE               0x40)   /* bit reverse source */
300    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
301    (PPERM_ZERO                  0x80)   /* all 0's */
302    (PPERM_ONES                  0xa0)   /* all 1's */
303    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
304    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
305    (PPERM_SRC1                  0x00)   /* use first source byte */
306    (PPERM_SRC2                  0x10)   /* use second source byte */
307    ])
309 ;; Registers by name.
310 (define_constants
311   [(AX_REG                       0)
312    (DX_REG                       1)
313    (CX_REG                       2)
314    (BX_REG                       3)
315    (SI_REG                       4)
316    (DI_REG                       5)
317    (BP_REG                       6)
318    (SP_REG                       7)
319    (ST0_REG                      8)
320    (ST1_REG                      9)
321    (ST2_REG                     10)
322    (ST3_REG                     11)
323    (ST4_REG                     12)
324    (ST5_REG                     13)
325    (ST6_REG                     14)
326    (ST7_REG                     15)
327    (ARGP_REG                    16)
328    (FLAGS_REG                   17)
329    (FPSR_REG                    18)
330    (FPCR_REG                    19)
331    (FRAME_REG                   20)
332    (XMM0_REG                    21)
333    (XMM1_REG                    22)
334    (XMM2_REG                    23)
335    (XMM3_REG                    24)
336    (XMM4_REG                    25)
337    (XMM5_REG                    26)
338    (XMM6_REG                    27)
339    (XMM7_REG                    28)
340    (MM0_REG                     29)
341    (MM1_REG                     30)
342    (MM2_REG                     31)
343    (MM3_REG                     32)
344    (MM4_REG                     33)
345    (MM5_REG                     34)
346    (MM6_REG                     35)
347    (MM7_REG                     36)
348    (R8_REG                      37)
349    (R9_REG                      38)
350    (R10_REG                     39)
351    (R11_REG                     40)
352    (R12_REG                     41)
353    (R13_REG                     42)
354    (R14_REG                     43)
355    (R15_REG                     44)
356    (XMM8_REG                    45)
357    (XMM9_REG                    46)
358    (XMM10_REG                   47)
359    (XMM11_REG                   48)
360    (XMM12_REG                   49)
361    (XMM13_REG                   50)
362    (XMM14_REG                   51)
363    (XMM15_REG                   52)
364    (XMM16_REG                   53)
365    (XMM17_REG                   54)
366    (XMM18_REG                   55)
367    (XMM19_REG                   56)
368    (XMM20_REG                   57)
369    (XMM21_REG                   58)
370    (XMM22_REG                   59)
371    (XMM23_REG                   60)
372    (XMM24_REG                   61)
373    (XMM25_REG                   62)
374    (XMM26_REG                   63)
375    (XMM27_REG                   64)
376    (XMM28_REG                   65)
377    (XMM29_REG                   66)
378    (XMM30_REG                   67)
379    (XMM31_REG                   68)
380    (MASK0_REG                   69)
381    (MASK1_REG                   70)
382    (MASK2_REG                   71)
383    (MASK3_REG                   72)
384    (MASK4_REG                   73)
385    (MASK5_REG                   74)
386    (MASK6_REG                   75)
387    (MASK7_REG                   76)
388    (BND0_REG                    77)
389    (BND1_REG                    78)
390    (BND2_REG                    79)
391    (BND3_REG                    80)
392    (FIRST_PSEUDO_REG            81)
393   ])
395 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
396 ;; from i386.c.
398 ;; In C guard expressions, put expressions which may be compile-time
399 ;; constants first.  This allows for better optimization.  For
400 ;; example, write "TARGET_64BIT && reload_completed", not
401 ;; "reload_completed && TARGET_64BIT".
404 ;; Processor type.
405 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
406                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
407                     btver2,knl"
408   (const (symbol_ref "ix86_schedule")))
410 ;; A basic instruction type.  Refinements due to arguments to be
411 ;; provided in other attributes.
412 (define_attr "type"
413   "other,multi,
414    alu,alu1,negnot,imov,imovx,lea,
415    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
416    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
417    push,pop,call,callv,leave,
418    str,bitmanip,
419    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
420    fxch,fistp,fisttp,frndint,
421    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
422    ssemul,sseimul,ssediv,sselog,sselog1,
423    sseishft,sseishft1,ssecmp,ssecomi,
424    ssecvt,ssecvt1,sseicvt,sseins,
425    sseshuf,sseshuf1,ssemuladd,sse4arg,
426    lwp,mskmov,msklog,
427    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
428    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
429   (const_string "other"))
431 ;; Main data type used by the insn
432 (define_attr "mode"
433   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
434   V2DF,V2SF,V1DF,V8DF"
435   (const_string "unknown"))
437 ;; The CPU unit operations uses.
438 (define_attr "unit" "integer,i387,sse,mmx,unknown"
439   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
440                           fxch,fistp,fisttp,frndint")
441            (const_string "i387")
442          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
443                           ssemul,sseimul,ssediv,sselog,sselog1,
444                           sseishft,sseishft1,ssecmp,ssecomi,
445                           ssecvt,ssecvt1,sseicvt,sseins,
446                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
447            (const_string "sse")
448          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
449            (const_string "mmx")
450          (eq_attr "type" "other")
451            (const_string "unknown")]
452          (const_string "integer")))
454 ;; The minimum required alignment of vector mode memory operands of the SSE
455 ;; (non-VEX/EVEX) instruction in bits, if it is different from
456 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
457 ;; multiple alternatives, this should be conservative maximum of those minimum
458 ;; required alignments.
459 (define_attr "ssememalign" "" (const_int 0))
461 ;; The (bounding maximum) length of an instruction immediate.
462 (define_attr "length_immediate" ""
463   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
464                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
465                           mpxld,mpxst")
466            (const_int 0)
467          (eq_attr "unit" "i387,sse,mmx")
468            (const_int 0)
469          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
470                           rotate,rotatex,rotate1,imul,icmp,push,pop")
471            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
472          (eq_attr "type" "imov,test")
473            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
474          (eq_attr "type" "call")
475            (if_then_else (match_operand 0 "constant_call_address_operand")
476              (const_int 4)
477              (const_int 0))
478          (eq_attr "type" "callv")
479            (if_then_else (match_operand 1 "constant_call_address_operand")
480              (const_int 4)
481              (const_int 0))
482          ;; We don't know the size before shorten_branches.  Expect
483          ;; the instruction to fit for better scheduling.
484          (eq_attr "type" "ibr")
485            (const_int 1)
486          ]
487          (symbol_ref "/* Update immediate_length and other attributes! */
488                       gcc_unreachable (),1")))
490 ;; The (bounding maximum) length of an instruction address.
491 (define_attr "length_address" ""
492   (cond [(eq_attr "type" "str,other,multi,fxch")
493            (const_int 0)
494          (and (eq_attr "type" "call")
495               (match_operand 0 "constant_call_address_operand"))
496              (const_int 0)
497          (and (eq_attr "type" "callv")
498               (match_operand 1 "constant_call_address_operand"))
499              (const_int 0)
500          ]
501          (symbol_ref "ix86_attr_length_address_default (insn)")))
503 ;; Set when length prefix is used.
504 (define_attr "prefix_data16" ""
505   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
506            (const_int 0)
507          (eq_attr "mode" "HI")
508            (const_int 1)
509          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
510            (const_int 1)
511         ]
512         (const_int 0)))
514 ;; Set when string REP prefix is used.
515 (define_attr "prefix_rep" ""
516   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
517            (const_int 0)
518          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
519            (const_int 1)
520          (and (eq_attr "type" "ibr,call,callv")
521               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
522            (const_int 1)
523         ]
524         (const_int 0)))
526 ;; Set when 0f opcode prefix is used.
527 (define_attr "prefix_0f" ""
528   (if_then_else
529     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
530                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
531          (eq_attr "unit" "sse,mmx"))
532     (const_int 1)
533     (const_int 0)))
535 ;; Set when REX opcode prefix is used.
536 (define_attr "prefix_rex" ""
537   (cond [(not (match_test "TARGET_64BIT"))
538            (const_int 0)
539          (and (eq_attr "mode" "DI")
540               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
541                    (eq_attr "unit" "!mmx")))
542            (const_int 1)
543          (and (eq_attr "mode" "QI")
544               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
545            (const_int 1)
546          (match_test "x86_extended_reg_mentioned_p (insn)")
547            (const_int 1)
548          (and (eq_attr "type" "imovx")
549               (match_operand:QI 1 "ext_QIreg_operand"))
550            (const_int 1)
551         ]
552         (const_int 0)))
554 ;; There are also additional prefixes in 3DNOW, SSSE3.
555 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
556 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
557 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
558 (define_attr "prefix_extra" ""
559   (cond [(eq_attr "type" "ssemuladd,sse4arg")
560            (const_int 2)
561          (eq_attr "type" "sseiadd1,ssecvt1")
562            (const_int 1)
563         ]
564         (const_int 0)))
566 ;; Prefix used: original, VEX or maybe VEX.
567 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
568   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
569            (const_string "vex")
570          (eq_attr "mode" "XI,V16SF,V8DF")
571            (const_string "evex")
572         ]
573         (const_string "orig")))
575 ;; VEX W bit is used.
576 (define_attr "prefix_vex_w" "" (const_int 0))
578 ;; The length of VEX prefix
579 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
580 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
581 ;; still prefix_0f 1, with prefix_extra 1.
582 (define_attr "length_vex" ""
583   (if_then_else (and (eq_attr "prefix_0f" "1")
584                      (eq_attr "prefix_extra" "0"))
585     (if_then_else (eq_attr "prefix_vex_w" "1")
586       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
587       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
588     (if_then_else (eq_attr "prefix_vex_w" "1")
589       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
590       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
592 ;; 4-bytes evex prefix and 1 byte opcode.
593 (define_attr "length_evex" "" (const_int 5))
595 ;; Set when modrm byte is used.
596 (define_attr "modrm" ""
597   (cond [(eq_attr "type" "str,leave")
598            (const_int 0)
599          (eq_attr "unit" "i387")
600            (const_int 0)
601          (and (eq_attr "type" "incdec")
602               (and (not (match_test "TARGET_64BIT"))
603                    (ior (match_operand:SI 1 "register_operand")
604                         (match_operand:HI 1 "register_operand"))))
605            (const_int 0)
606          (and (eq_attr "type" "push")
607               (not (match_operand 1 "memory_operand")))
608            (const_int 0)
609          (and (eq_attr "type" "pop")
610               (not (match_operand 0 "memory_operand")))
611            (const_int 0)
612          (and (eq_attr "type" "imov")
613               (and (not (eq_attr "mode" "DI"))
614                    (ior (and (match_operand 0 "register_operand")
615                              (match_operand 1 "immediate_operand"))
616                         (ior (and (match_operand 0 "ax_reg_operand")
617                                   (match_operand 1 "memory_displacement_only_operand"))
618                              (and (match_operand 0 "memory_displacement_only_operand")
619                                   (match_operand 1 "ax_reg_operand"))))))
620            (const_int 0)
621          (and (eq_attr "type" "call")
622               (match_operand 0 "constant_call_address_operand"))
623              (const_int 0)
624          (and (eq_attr "type" "callv")
625               (match_operand 1 "constant_call_address_operand"))
626              (const_int 0)
627          (and (eq_attr "type" "alu,alu1,icmp,test")
628               (match_operand 0 "ax_reg_operand"))
629              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
630          ]
631          (const_int 1)))
633 ;; When this attribute is set, calculate total insn length from
634 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
635 (define_attr "length_nobnd" "" (const_int 0))
637 ;; The (bounding maximum) length of an instruction in bytes.
638 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
639 ;; Later we may want to split them and compute proper length as for
640 ;; other insns.
641 (define_attr "length" ""
642   (cond [(eq_attr "length_nobnd" "!0")
643            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
644                  (attr "length_nobnd"))
645          (eq_attr "type" "other,multi,fistp,frndint")
646            (const_int 16)
647          (eq_attr "type" "fcmp")
648            (const_int 4)
649          (eq_attr "unit" "i387")
650            (plus (const_int 2)
651                  (plus (attr "prefix_data16")
652                        (attr "length_address")))
653          (ior (eq_attr "prefix" "evex")
654               (and (ior (eq_attr "prefix" "maybe_evex")
655                         (eq_attr "prefix" "maybe_vex"))
656                    (match_test "TARGET_AVX512F")))
657            (plus (attr "length_evex")
658                  (plus (attr "length_immediate")
659                        (plus (attr "modrm")
660                              (attr "length_address"))))
661          (ior (eq_attr "prefix" "vex")
662               (and (ior (eq_attr "prefix" "maybe_vex")
663                         (eq_attr "prefix" "maybe_evex"))
664                    (match_test "TARGET_AVX")))
665            (plus (attr "length_vex")
666                  (plus (attr "length_immediate")
667                        (plus (attr "modrm")
668                              (attr "length_address"))))]
669          (plus (plus (attr "modrm")
670                      (plus (attr "prefix_0f")
671                            (plus (attr "prefix_rex")
672                                  (plus (attr "prefix_extra")
673                                        (const_int 1)))))
674                (plus (attr "prefix_rep")
675                      (plus (attr "prefix_data16")
676                            (plus (attr "length_immediate")
677                                  (attr "length_address")))))))
679 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
680 ;; `store' if there is a simple memory reference therein, or `unknown'
681 ;; if the instruction is complex.
683 (define_attr "memory" "none,load,store,both,unknown"
684   (cond [(eq_attr "type" "other,multi,str,lwp")
685            (const_string "unknown")
686          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
687            (const_string "none")
688          (eq_attr "type" "fistp,leave")
689            (const_string "both")
690          (eq_attr "type" "frndint")
691            (const_string "load")
692          (eq_attr "type" "mpxld")
693            (const_string "load")
694          (eq_attr "type" "mpxst")
695            (const_string "store")
696          (eq_attr "type" "push")
697            (if_then_else (match_operand 1 "memory_operand")
698              (const_string "both")
699              (const_string "store"))
700          (eq_attr "type" "pop")
701            (if_then_else (match_operand 0 "memory_operand")
702              (const_string "both")
703              (const_string "load"))
704          (eq_attr "type" "setcc")
705            (if_then_else (match_operand 0 "memory_operand")
706              (const_string "store")
707              (const_string "none"))
708          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
709            (if_then_else (ior (match_operand 0 "memory_operand")
710                               (match_operand 1 "memory_operand"))
711              (const_string "load")
712              (const_string "none"))
713          (eq_attr "type" "ibr")
714            (if_then_else (match_operand 0 "memory_operand")
715              (const_string "load")
716              (const_string "none"))
717          (eq_attr "type" "call")
718            (if_then_else (match_operand 0 "constant_call_address_operand")
719              (const_string "none")
720              (const_string "load"))
721          (eq_attr "type" "callv")
722            (if_then_else (match_operand 1 "constant_call_address_operand")
723              (const_string "none")
724              (const_string "load"))
725          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
726               (match_operand 1 "memory_operand"))
727            (const_string "both")
728          (and (match_operand 0 "memory_operand")
729               (match_operand 1 "memory_operand"))
730            (const_string "both")
731          (match_operand 0 "memory_operand")
732            (const_string "store")
733          (match_operand 1 "memory_operand")
734            (const_string "load")
735          (and (eq_attr "type"
736                  "!alu1,negnot,ishift1,
737                    imov,imovx,icmp,test,bitmanip,
738                    fmov,fcmp,fsgn,
739                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
740                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
741                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
742               (match_operand 2 "memory_operand"))
743            (const_string "load")
744          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
745               (match_operand 3 "memory_operand"))
746            (const_string "load")
747         ]
748         (const_string "none")))
750 ;; Indicates if an instruction has both an immediate and a displacement.
752 (define_attr "imm_disp" "false,true,unknown"
753   (cond [(eq_attr "type" "other,multi")
754            (const_string "unknown")
755          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
756               (and (match_operand 0 "memory_displacement_operand")
757                    (match_operand 1 "immediate_operand")))
758            (const_string "true")
759          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
760               (and (match_operand 0 "memory_displacement_operand")
761                    (match_operand 2 "immediate_operand")))
762            (const_string "true")
763         ]
764         (const_string "false")))
766 ;; Indicates if an FP operation has an integer source.
768 (define_attr "fp_int_src" "false,true"
769   (const_string "false"))
771 ;; Defines rounding mode of an FP operation.
773 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
774   (const_string "any"))
776 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
777 (define_attr "use_carry" "0,1" (const_string "0"))
779 ;; Define attribute to indicate unaligned ssemov insns
780 (define_attr "movu" "0,1" (const_string "0"))
782 ;; Used to control the "enabled" attribute on a per-instruction basis.
783 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
784                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
785                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
786                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
787   (const_string "base"))
789 (define_attr "enabled" ""
790   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
791          (eq_attr "isa" "x64_sse4")
792            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
793          (eq_attr "isa" "x64_sse4_noavx")
794            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
795          (eq_attr "isa" "x64_avx")
796            (symbol_ref "TARGET_64BIT && TARGET_AVX")
797          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
798          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
799          (eq_attr "isa" "sse2_noavx")
800            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
801          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
802          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
803          (eq_attr "isa" "sse4_noavx")
804            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
805          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
806          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
807          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
808          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
809          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
810          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
811          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
812          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
813          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
814          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
815          (eq_attr "isa" "fma_avx512f")
816            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
817          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
818          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
819          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
820          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
821         ]
822         (const_int 1)))
824 (define_attr "preferred_for_size" "" (const_int 1))
825 (define_attr "preferred_for_speed" "" (const_int 1))
827 ;; Describe a user's asm statement.
828 (define_asm_attributes
829   [(set_attr "length" "128")
830    (set_attr "type" "multi")])
832 (define_code_iterator plusminus [plus minus])
834 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
836 (define_code_iterator multdiv [mult div])
838 ;; Base name for define_insn
839 (define_code_attr plusminus_insn
840   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
841    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
843 ;; Base name for insn mnemonic.
844 (define_code_attr plusminus_mnemonic
845   [(plus "add") (ss_plus "adds") (us_plus "addus")
846    (minus "sub") (ss_minus "subs") (us_minus "subus")])
847 (define_code_attr plusminus_carry_mnemonic
848   [(plus "adc") (minus "sbb")])
849 (define_code_attr multdiv_mnemonic
850   [(mult "mul") (div "div")])
852 ;; Mark commutative operators as such in constraints.
853 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
854                         (minus "") (ss_minus "") (us_minus "")])
856 ;; Mapping of max and min
857 (define_code_iterator maxmin [smax smin umax umin])
859 ;; Mapping of signed max and min
860 (define_code_iterator smaxmin [smax smin])
862 ;; Mapping of unsigned max and min
863 (define_code_iterator umaxmin [umax umin])
865 ;; Base name for integer and FP insn mnemonic
866 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
867                               (umax "maxu") (umin "minu")])
868 (define_code_attr maxmin_float [(smax "max") (smin "min")])
870 ;; Mapping of logic operators
871 (define_code_iterator any_logic [and ior xor])
872 (define_code_iterator any_or [ior xor])
873 (define_code_iterator fpint_logic [and xor])
875 ;; Base name for insn mnemonic.
876 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
878 ;; Mapping of logic-shift operators
879 (define_code_iterator any_lshift [ashift lshiftrt])
881 ;; Mapping of shift-right operators
882 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
884 ;; Mapping of all shift operators
885 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
887 ;; Base name for define_insn
888 (define_code_attr shift_insn
889   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
891 ;; Base name for insn mnemonic.
892 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
893 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
895 ;; Mapping of rotate operators
896 (define_code_iterator any_rotate [rotate rotatert])
898 ;; Base name for define_insn
899 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
901 ;; Base name for insn mnemonic.
902 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
904 ;; Mapping of abs neg operators
905 (define_code_iterator absneg [abs neg])
907 ;; Base name for x87 insn mnemonic.
908 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
910 ;; Used in signed and unsigned widening multiplications.
911 (define_code_iterator any_extend [sign_extend zero_extend])
913 ;; Prefix for insn menmonic.
914 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
916 ;; Prefix for define_insn
917 (define_code_attr u [(sign_extend "") (zero_extend "u")])
918 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
919 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
921 ;; Used in signed and unsigned truncations.
922 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
923 ;; Instruction suffix for truncations.
924 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
926 ;; Used in signed and unsigned fix.
927 (define_code_iterator any_fix [fix unsigned_fix])
928 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
930 ;; Used in signed and unsigned float.
931 (define_code_iterator any_float [float unsigned_float])
932 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
934 ;; All integer modes.
935 (define_mode_iterator SWI1248x [QI HI SI DI])
937 ;; All integer modes with AVX512BW.
938 (define_mode_iterator SWI1248_AVX512BW
939   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
941 ;; All integer modes without QImode.
942 (define_mode_iterator SWI248x [HI SI DI])
944 ;; All integer modes without QImode and HImode.
945 (define_mode_iterator SWI48x [SI DI])
947 ;; All integer modes without SImode and DImode.
948 (define_mode_iterator SWI12 [QI HI])
950 ;; All integer modes without DImode.
951 (define_mode_iterator SWI124 [QI HI SI])
953 ;; All integer modes without QImode and DImode.
954 (define_mode_iterator SWI24 [HI SI])
956 ;; Single word integer modes.
957 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
959 ;; Single word integer modes without QImode.
960 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
962 ;; Single word integer modes without QImode and HImode.
963 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
965 ;; All math-dependant single and double word integer modes.
966 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
967                              (HI "TARGET_HIMODE_MATH")
968                              SI DI (TI "TARGET_64BIT")])
970 ;; Math-dependant single word integer modes.
971 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
972                             (HI "TARGET_HIMODE_MATH")
973                             SI (DI "TARGET_64BIT")])
975 ;; Math-dependant integer modes without DImode.
976 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
977                                (HI "TARGET_HIMODE_MATH")
978                                SI])
980 ;; Math-dependant single word integer modes without QImode.
981 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
982                                SI (DI "TARGET_64BIT")])
984 ;; Double word integer modes.
985 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
986                            (TI "TARGET_64BIT")])
988 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
989 ;; compile time constant, it is faster to use <MODE_SIZE> than
990 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
991 ;; command line options just use GET_MODE_SIZE macro.
992 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
993                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
994                              (V16QI "16") (V32QI "32") (V64QI "64")
995                              (V8HI "16") (V16HI "32") (V32HI "64")
996                              (V4SI "16") (V8SI "32") (V16SI "64")
997                              (V2DI "16") (V4DI "32") (V8DI "64")
998                              (V1TI "16") (V2TI "32") (V4TI "64")
999                              (V2DF "16") (V4DF "32") (V8DF "64")
1000                              (V4SF "16") (V8SF "32") (V16SF "64")])
1002 ;; Double word integer modes as mode attribute.
1003 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1004 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1006 ;; Half mode for double word integer modes.
1007 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1008                             (DI "TARGET_64BIT")])
1010 ;; Bound modes.
1011 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1012                            (BND64 "TARGET_LP64")])
1014 ;; Pointer mode corresponding to bound mode.
1015 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1017 ;; MPX check types
1018 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1020 ;; Check name
1021 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1022                            (UNSPEC_BNDCU "cu")
1023                            (UNSPEC_BNDCN "cn")])
1025 ;; Instruction suffix for integer modes.
1026 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1028 ;; Instruction suffix for masks.
1029 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1031 ;; Pointer size prefix for integer modes (Intel asm dialect)
1032 (define_mode_attr iptrsize [(QI "BYTE")
1033                             (HI "WORD")
1034                             (SI "DWORD")
1035                             (DI "QWORD")])
1037 ;; Register class for integer modes.
1038 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1040 ;; Immediate operand constraint for integer modes.
1041 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1043 ;; General operand constraint for word modes.
1044 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1046 ;; Immediate operand constraint for double integer modes.
1047 (define_mode_attr di [(SI "nF") (DI "e")])
1049 ;; Immediate operand constraint for shifts.
1050 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1052 ;; General operand predicate for integer modes.
1053 (define_mode_attr general_operand
1054         [(QI "general_operand")
1055          (HI "general_operand")
1056          (SI "x86_64_general_operand")
1057          (DI "x86_64_general_operand")
1058          (TI "x86_64_general_operand")])
1060 ;; General sign extend operand predicate for integer modes,
1061 ;; which disallows VOIDmode operands and thus it is suitable
1062 ;; for use inside sign_extend.
1063 (define_mode_attr general_sext_operand
1064         [(QI "sext_operand")
1065          (HI "sext_operand")
1066          (SI "x86_64_sext_operand")
1067          (DI "x86_64_sext_operand")])
1069 ;; General sign/zero extend operand predicate for integer modes.
1070 (define_mode_attr general_szext_operand
1071         [(QI "general_operand")
1072          (HI "general_operand")
1073          (SI "x86_64_szext_general_operand")
1074          (DI "x86_64_szext_general_operand")])
1076 ;; Immediate operand predicate for integer modes.
1077 (define_mode_attr immediate_operand
1078         [(QI "immediate_operand")
1079          (HI "immediate_operand")
1080          (SI "x86_64_immediate_operand")
1081          (DI "x86_64_immediate_operand")])
1083 ;; Nonmemory operand predicate for integer modes.
1084 (define_mode_attr nonmemory_operand
1085         [(QI "nonmemory_operand")
1086          (HI "nonmemory_operand")
1087          (SI "x86_64_nonmemory_operand")
1088          (DI "x86_64_nonmemory_operand")])
1090 ;; Operand predicate for shifts.
1091 (define_mode_attr shift_operand
1092         [(QI "nonimmediate_operand")
1093          (HI "nonimmediate_operand")
1094          (SI "nonimmediate_operand")
1095          (DI "shiftdi_operand")
1096          (TI "register_operand")])
1098 ;; Operand predicate for shift argument.
1099 (define_mode_attr shift_immediate_operand
1100         [(QI "const_1_to_31_operand")
1101          (HI "const_1_to_31_operand")
1102          (SI "const_1_to_31_operand")
1103          (DI "const_1_to_63_operand")])
1105 ;; Input operand predicate for arithmetic left shifts.
1106 (define_mode_attr ashl_input_operand
1107         [(QI "nonimmediate_operand")
1108          (HI "nonimmediate_operand")
1109          (SI "nonimmediate_operand")
1110          (DI "ashldi_input_operand")
1111          (TI "reg_or_pm1_operand")])
1113 ;; SSE and x87 SFmode and DFmode floating point modes
1114 (define_mode_iterator MODEF [SF DF])
1116 ;; All x87 floating point modes
1117 (define_mode_iterator X87MODEF [SF DF XF])
1119 ;; SSE instruction suffix for various modes
1120 (define_mode_attr ssemodesuffix
1121   [(SF "ss") (DF "sd")
1122    (V16SF "ps") (V8DF "pd")
1123    (V8SF "ps") (V4DF "pd")
1124    (V4SF "ps") (V2DF "pd")
1125    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1126    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1127    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1129 ;; SSE vector suffix for floating point modes
1130 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1132 ;; SSE vector mode corresponding to a scalar mode
1133 (define_mode_attr ssevecmode
1134   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1135 (define_mode_attr ssevecmodelower
1136   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1138 ;; Instruction suffix for REX 64bit operators.
1139 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1141 ;; This mode iterator allows :P to be used for patterns that operate on
1142 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1143 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1145 ;; This mode iterator allows :W to be used for patterns that operate on
1146 ;; word_mode sized quantities.
1147 (define_mode_iterator W
1148   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1150 ;; This mode iterator allows :PTR to be used for patterns that operate on
1151 ;; ptr_mode sized quantities.
1152 (define_mode_iterator PTR
1153   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1155 ;; Scheduling descriptions
1157 (include "pentium.md")
1158 (include "ppro.md")
1159 (include "k6.md")
1160 (include "athlon.md")
1161 (include "bdver1.md")
1162 (include "bdver3.md")
1163 (include "btver2.md")
1164 (include "geode.md")
1165 (include "atom.md")
1166 (include "slm.md")
1167 (include "core2.md")
1170 ;; Operand and operator predicates and constraints
1172 (include "predicates.md")
1173 (include "constraints.md")
1176 ;; Compare and branch/compare and store instructions.
1178 (define_expand "cbranch<mode>4"
1179   [(set (reg:CC FLAGS_REG)
1180         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1181                     (match_operand:SDWIM 2 "<general_operand>")))
1182    (set (pc) (if_then_else
1183                (match_operator 0 "ordered_comparison_operator"
1184                 [(reg:CC FLAGS_REG) (const_int 0)])
1185                (label_ref (match_operand 3))
1186                (pc)))]
1187   ""
1189   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1190     operands[1] = force_reg (<MODE>mode, operands[1]);
1191   ix86_expand_branch (GET_CODE (operands[0]),
1192                       operands[1], operands[2], operands[3]);
1193   DONE;
1196 (define_expand "cstore<mode>4"
1197   [(set (reg:CC FLAGS_REG)
1198         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1199                     (match_operand:SWIM 3 "<general_operand>")))
1200    (set (match_operand:QI 0 "register_operand")
1201         (match_operator 1 "ordered_comparison_operator"
1202           [(reg:CC FLAGS_REG) (const_int 0)]))]
1203   ""
1205   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1206     operands[2] = force_reg (<MODE>mode, operands[2]);
1207   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208                      operands[2], operands[3]);
1209   DONE;
1212 (define_expand "cmp<mode>_1"
1213   [(set (reg:CC FLAGS_REG)
1214         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1215                     (match_operand:SWI48 1 "<general_operand>")))])
1217 (define_insn "*cmp<mode>_ccno_1"
1218   [(set (reg FLAGS_REG)
1219         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1220                  (match_operand:SWI 1 "const0_operand")))]
1221   "ix86_match_ccmode (insn, CCNOmode)"
1222   "@
1223    test{<imodesuffix>}\t%0, %0
1224    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1225   [(set_attr "type" "test,icmp")
1226    (set_attr "length_immediate" "0,1")
1227    (set_attr "mode" "<MODE>")])
1229 (define_insn "*cmp<mode>_1"
1230   [(set (reg FLAGS_REG)
1231         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1232                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1233   "ix86_match_ccmode (insn, CCmode)"
1234   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1235   [(set_attr "type" "icmp")
1236    (set_attr "mode" "<MODE>")])
1238 (define_insn "*cmp<mode>_minus_1"
1239   [(set (reg FLAGS_REG)
1240         (compare
1241           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1242                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1243           (const_int 0)))]
1244   "ix86_match_ccmode (insn, CCGOCmode)"
1245   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1246   [(set_attr "type" "icmp")
1247    (set_attr "mode" "<MODE>")])
1249 (define_insn "*cmpqi_ext_1"
1250   [(set (reg FLAGS_REG)
1251         (compare
1252           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1253           (subreg:QI
1254             (zero_extract:SI
1255               (match_operand 1 "ext_register_operand" "Q,Q")
1256               (const_int 8)
1257               (const_int 8)) 0)))]
1258   "ix86_match_ccmode (insn, CCmode)"
1259   "cmp{b}\t{%h1, %0|%0, %h1}"
1260   [(set_attr "isa" "*,nox64")
1261    (set_attr "type" "icmp")
1262    (set_attr "mode" "QI")])
1264 (define_insn "*cmpqi_ext_2"
1265   [(set (reg FLAGS_REG)
1266         (compare
1267           (subreg:QI
1268             (zero_extract:SI
1269               (match_operand 0 "ext_register_operand" "Q")
1270               (const_int 8)
1271               (const_int 8)) 0)
1272           (match_operand:QI 1 "const0_operand")))]
1273   "ix86_match_ccmode (insn, CCNOmode)"
1274   "test{b}\t%h0, %h0"
1275   [(set_attr "type" "test")
1276    (set_attr "length_immediate" "0")
1277    (set_attr "mode" "QI")])
1279 (define_expand "cmpqi_ext_3"
1280   [(set (reg:CC FLAGS_REG)
1281         (compare:CC
1282           (subreg:QI
1283             (zero_extract:SI
1284               (match_operand 0 "ext_register_operand")
1285               (const_int 8)
1286               (const_int 8)) 0)
1287           (match_operand:QI 1 "const_int_operand")))])
1289 (define_insn "*cmpqi_ext_3"
1290   [(set (reg FLAGS_REG)
1291         (compare
1292           (subreg:QI
1293             (zero_extract:SI
1294               (match_operand 0 "ext_register_operand" "Q,Q")
1295               (const_int 8)
1296               (const_int 8)) 0)
1297           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1298   "ix86_match_ccmode (insn, CCmode)"
1299   "cmp{b}\t{%1, %h0|%h0, %1}"
1300   [(set_attr "isa" "*,nox64")
1301    (set_attr "type" "icmp")
1302    (set_attr "modrm" "1")
1303    (set_attr "mode" "QI")])
1305 (define_insn "*cmpqi_ext_4"
1306   [(set (reg FLAGS_REG)
1307         (compare
1308           (subreg:QI
1309             (zero_extract:SI
1310               (match_operand 0 "ext_register_operand" "Q")
1311               (const_int 8)
1312               (const_int 8)) 0)
1313           (subreg:QI
1314             (zero_extract:SI
1315               (match_operand 1 "ext_register_operand" "Q")
1316               (const_int 8)
1317               (const_int 8)) 0)))]
1318   "ix86_match_ccmode (insn, CCmode)"
1319   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1320   [(set_attr "type" "icmp")
1321    (set_attr "mode" "QI")])
1323 ;; These implement float point compares.
1324 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1325 ;; which would allow mix and match FP modes on the compares.  Which is what
1326 ;; the old patterns did, but with many more of them.
1328 (define_expand "cbranchxf4"
1329   [(set (reg:CC FLAGS_REG)
1330         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1331                     (match_operand:XF 2 "nonmemory_operand")))
1332    (set (pc) (if_then_else
1333               (match_operator 0 "ix86_fp_comparison_operator"
1334                [(reg:CC FLAGS_REG)
1335                 (const_int 0)])
1336               (label_ref (match_operand 3))
1337               (pc)))]
1338   "TARGET_80387"
1340   ix86_expand_branch (GET_CODE (operands[0]),
1341                       operands[1], operands[2], operands[3]);
1342   DONE;
1345 (define_expand "cstorexf4"
1346   [(set (reg:CC FLAGS_REG)
1347         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1348                     (match_operand:XF 3 "nonmemory_operand")))
1349    (set (match_operand:QI 0 "register_operand")
1350               (match_operator 1 "ix86_fp_comparison_operator"
1351                [(reg:CC FLAGS_REG)
1352                 (const_int 0)]))]
1353   "TARGET_80387"
1355   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356                      operands[2], operands[3]);
1357   DONE;
1360 (define_expand "cbranch<mode>4"
1361   [(set (reg:CC FLAGS_REG)
1362         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1363                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1364    (set (pc) (if_then_else
1365               (match_operator 0 "ix86_fp_comparison_operator"
1366                [(reg:CC FLAGS_REG)
1367                 (const_int 0)])
1368               (label_ref (match_operand 3))
1369               (pc)))]
1370   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1372   ix86_expand_branch (GET_CODE (operands[0]),
1373                       operands[1], operands[2], operands[3]);
1374   DONE;
1377 (define_expand "cstore<mode>4"
1378   [(set (reg:CC FLAGS_REG)
1379         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1380                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1381    (set (match_operand:QI 0 "register_operand")
1382               (match_operator 1 "ix86_fp_comparison_operator"
1383                [(reg:CC FLAGS_REG)
1384                 (const_int 0)]))]
1385   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1387   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1388                      operands[2], operands[3]);
1389   DONE;
1392 (define_expand "cbranchcc4"
1393   [(set (pc) (if_then_else
1394               (match_operator 0 "comparison_operator"
1395                [(match_operand 1 "flags_reg_operand")
1396                 (match_operand 2 "const0_operand")])
1397               (label_ref (match_operand 3))
1398               (pc)))]
1399   ""
1401   ix86_expand_branch (GET_CODE (operands[0]),
1402                       operands[1], operands[2], operands[3]);
1403   DONE;
1406 (define_expand "cstorecc4"
1407   [(set (match_operand:QI 0 "register_operand")
1408               (match_operator 1 "comparison_operator"
1409                [(match_operand 2 "flags_reg_operand")
1410                 (match_operand 3 "const0_operand")]))]
1411   ""
1413   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1414                      operands[2], operands[3]);
1415   DONE;
1419 ;; FP compares, step 1:
1420 ;; Set the FP condition codes.
1422 ;; CCFPmode     compare with exceptions
1423 ;; CCFPUmode    compare with no exceptions
1425 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1426 ;; used to manage the reg stack popping would not be preserved.
1428 (define_insn "*cmp<mode>_0_i387"
1429   [(set (match_operand:HI 0 "register_operand" "=a")
1430         (unspec:HI
1431           [(compare:CCFP
1432              (match_operand:X87MODEF 1 "register_operand" "f")
1433              (match_operand:X87MODEF 2 "const0_operand"))]
1434         UNSPEC_FNSTSW))]
1435   "TARGET_80387"
1436   "* return output_fp_compare (insn, operands, false, false);"
1437   [(set_attr "type" "multi")
1438    (set_attr "unit" "i387")
1439    (set_attr "mode" "<MODE>")])
1441 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1442   [(set (reg:CCFP FLAGS_REG)
1443         (compare:CCFP
1444           (match_operand:X87MODEF 1 "register_operand" "f")
1445           (match_operand:X87MODEF 2 "const0_operand")))
1446    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1447   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1448   "#"
1449   "&& reload_completed"
1450   [(set (match_dup 0)
1451         (unspec:HI
1452           [(compare:CCFP (match_dup 1)(match_dup 2))]
1453         UNSPEC_FNSTSW))
1454    (set (reg:CC FLAGS_REG)
1455         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1456   ""
1457   [(set_attr "type" "multi")
1458    (set_attr "unit" "i387")
1459    (set_attr "mode" "<MODE>")])
1461 (define_insn "*cmpxf_i387"
1462   [(set (match_operand:HI 0 "register_operand" "=a")
1463         (unspec:HI
1464           [(compare:CCFP
1465              (match_operand:XF 1 "register_operand" "f")
1466              (match_operand:XF 2 "register_operand" "f"))]
1467           UNSPEC_FNSTSW))]
1468   "TARGET_80387"
1469   "* return output_fp_compare (insn, operands, false, false);"
1470   [(set_attr "type" "multi")
1471    (set_attr "unit" "i387")
1472    (set_attr "mode" "XF")])
1474 (define_insn_and_split "*cmpxf_cc_i387"
1475   [(set (reg:CCFP FLAGS_REG)
1476         (compare:CCFP
1477           (match_operand:XF 1 "register_operand" "f")
1478           (match_operand:XF 2 "register_operand" "f")))
1479    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1480   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1481   "#"
1482   "&& reload_completed"
1483   [(set (match_dup 0)
1484         (unspec:HI
1485           [(compare:CCFP (match_dup 1)(match_dup 2))]
1486         UNSPEC_FNSTSW))
1487    (set (reg:CC FLAGS_REG)
1488         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1489   ""
1490   [(set_attr "type" "multi")
1491    (set_attr "unit" "i387")
1492    (set_attr "mode" "XF")])
1494 (define_insn "*cmp<mode>_i387"
1495   [(set (match_operand:HI 0 "register_operand" "=a")
1496         (unspec:HI
1497           [(compare:CCFP
1498              (match_operand:MODEF 1 "register_operand" "f")
1499              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1500           UNSPEC_FNSTSW))]
1501   "TARGET_80387"
1502   "* return output_fp_compare (insn, operands, false, false);"
1503   [(set_attr "type" "multi")
1504    (set_attr "unit" "i387")
1505    (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmp<mode>_cc_i387"
1508   [(set (reg:CCFP FLAGS_REG)
1509         (compare:CCFP
1510           (match_operand:MODEF 1 "register_operand" "f")
1511           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1512    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1513   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1514   "#"
1515   "&& reload_completed"
1516   [(set (match_dup 0)
1517         (unspec:HI
1518           [(compare:CCFP (match_dup 1)(match_dup 2))]
1519         UNSPEC_FNSTSW))
1520    (set (reg:CC FLAGS_REG)
1521         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1522   ""
1523   [(set_attr "type" "multi")
1524    (set_attr "unit" "i387")
1525    (set_attr "mode" "<MODE>")])
1527 (define_insn "*cmpu<mode>_i387"
1528   [(set (match_operand:HI 0 "register_operand" "=a")
1529         (unspec:HI
1530           [(compare:CCFPU
1531              (match_operand:X87MODEF 1 "register_operand" "f")
1532              (match_operand:X87MODEF 2 "register_operand" "f"))]
1533           UNSPEC_FNSTSW))]
1534   "TARGET_80387"
1535   "* return output_fp_compare (insn, operands, false, true);"
1536   [(set_attr "type" "multi")
1537    (set_attr "unit" "i387")
1538    (set_attr "mode" "<MODE>")])
1540 (define_insn_and_split "*cmpu<mode>_cc_i387"
1541   [(set (reg:CCFPU FLAGS_REG)
1542         (compare:CCFPU
1543           (match_operand:X87MODEF 1 "register_operand" "f")
1544           (match_operand:X87MODEF 2 "register_operand" "f")))
1545    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1546   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1547   "#"
1548   "&& reload_completed"
1549   [(set (match_dup 0)
1550         (unspec:HI
1551           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1552         UNSPEC_FNSTSW))
1553    (set (reg:CC FLAGS_REG)
1554         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1555   ""
1556   [(set_attr "type" "multi")
1557    (set_attr "unit" "i387")
1558    (set_attr "mode" "<MODE>")])
1560 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1561   [(set (match_operand:HI 0 "register_operand" "=a")
1562         (unspec:HI
1563           [(compare:CCFP
1564              (match_operand:X87MODEF 1 "register_operand" "f")
1565              (match_operator:X87MODEF 3 "float_operator"
1566                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1567           UNSPEC_FNSTSW))]
1568   "TARGET_80387
1569    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1570        || optimize_function_for_size_p (cfun))"
1571   "* return output_fp_compare (insn, operands, false, false);"
1572   [(set_attr "type" "multi")
1573    (set_attr "unit" "i387")
1574    (set_attr "fp_int_src" "true")
1575    (set_attr "mode" "<SWI24:MODE>")])
1577 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1578   [(set (reg:CCFP FLAGS_REG)
1579         (compare:CCFP
1580           (match_operand:X87MODEF 1 "register_operand" "f")
1581           (match_operator:X87MODEF 3 "float_operator"
1582             [(match_operand:SWI24 2 "memory_operand" "m")])))
1583    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1584   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1585    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1586        || optimize_function_for_size_p (cfun))"
1587   "#"
1588   "&& reload_completed"
1589   [(set (match_dup 0)
1590         (unspec:HI
1591           [(compare:CCFP
1592              (match_dup 1)
1593              (match_op_dup 3 [(match_dup 2)]))]
1594         UNSPEC_FNSTSW))
1595    (set (reg:CC FLAGS_REG)
1596         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1597   ""
1598   [(set_attr "type" "multi")
1599    (set_attr "unit" "i387")
1600    (set_attr "fp_int_src" "true")
1601    (set_attr "mode" "<SWI24:MODE>")])
1603 ;; FP compares, step 2
1604 ;; Move the fpsw to ax.
1606 (define_insn "x86_fnstsw_1"
1607   [(set (match_operand:HI 0 "register_operand" "=a")
1608         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1609   "TARGET_80387"
1610   "fnstsw\t%0"
1611   [(set_attr "length" "2")
1612    (set_attr "mode" "SI")
1613    (set_attr "unit" "i387")])
1615 ;; FP compares, step 3
1616 ;; Get ax into flags, general case.
1618 (define_insn "x86_sahf_1"
1619   [(set (reg:CC FLAGS_REG)
1620         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1621                    UNSPEC_SAHF))]
1622   "TARGET_SAHF"
1624 #ifndef HAVE_AS_IX86_SAHF
1625   if (TARGET_64BIT)
1626     return ASM_BYTE "0x9e";
1627   else
1628 #endif
1629   return "sahf";
1631   [(set_attr "length" "1")
1632    (set_attr "athlon_decode" "vector")
1633    (set_attr "amdfam10_decode" "direct")
1634    (set_attr "bdver1_decode" "direct")
1635    (set_attr "mode" "SI")])
1637 ;; Pentium Pro can do steps 1 through 3 in one go.
1638 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1639 ;; (these i387 instructions set flags directly)
1641 (define_mode_iterator FPCMP [CCFP CCFPU])
1642 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1644 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1645   [(set (reg:FPCMP FLAGS_REG)
1646         (compare:FPCMP
1647           (match_operand:MODEF 0 "register_operand" "f,v")
1648           (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1649   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1650   "* return output_fp_compare (insn, operands, true,
1651                                <FPCMP:MODE>mode == CCFPUmode);"
1652   [(set_attr "type" "fcmp,ssecomi")
1653    (set_attr "prefix" "orig,maybe_vex")
1654    (set_attr "mode" "<MODEF:MODE>")
1655    (set_attr "prefix_rep" "*,0")
1656    (set (attr "prefix_data16")
1657         (cond [(eq_attr "alternative" "0")
1658                  (const_string "*")
1659                (eq_attr "mode" "DF")
1660                  (const_string "1")
1661               ]
1662               (const_string "0")))
1663    (set_attr "athlon_decode" "vector")
1664    (set_attr "amdfam10_decode" "direct")
1665    (set_attr "bdver1_decode" "double")
1666    (set (attr "enabled")
1667      (cond [(eq_attr "alternative" "0")
1668               (symbol_ref "TARGET_MIX_SSE_I387")
1669            ]
1670            (symbol_ref "true")))])
1672 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1673   [(set (reg:FPCMP FLAGS_REG)
1674         (compare:FPCMP
1675           (match_operand:X87MODEF 0 "register_operand" "f")
1676           (match_operand:X87MODEF 1 "register_operand" "f")))]
1677   "TARGET_80387 && TARGET_CMOVE
1678    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1679   "* return output_fp_compare (insn, operands, true,
1680                                <FPCMP:MODE>mode == CCFPUmode);"
1681   [(set_attr "type" "fcmp")
1682    (set_attr "mode" "<X87MODEF:MODE>")
1683    (set_attr "athlon_decode" "vector")
1684    (set_attr "amdfam10_decode" "direct")
1685    (set_attr "bdver1_decode" "double")])
1687 ;; Push/pop instructions.
1689 (define_insn "*push<mode>2"
1690   [(set (match_operand:DWI 0 "push_operand" "=<")
1691         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1692   ""
1693   "#"
1694   [(set_attr "type" "multi")
1695    (set_attr "mode" "<MODE>")])
1697 (define_split
1698   [(set (match_operand:TI 0 "push_operand")
1699         (match_operand:TI 1 "general_operand"))]
1700   "TARGET_64BIT && reload_completed
1701    && !SSE_REG_P (operands[1])"
1702   [(const_int 0)]
1703   "ix86_split_long_move (operands); DONE;")
1705 (define_insn "*pushdi2_rex64"
1706   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1707         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1708   "TARGET_64BIT"
1709   "@
1710    push{q}\t%1
1711    #"
1712   [(set_attr "type" "push,multi")
1713    (set_attr "mode" "DI")])
1715 ;; Convert impossible pushes of immediate to existing instructions.
1716 ;; First try to get scratch register and go through it.  In case this
1717 ;; fails, push sign extended lower part first and then overwrite
1718 ;; upper part by 32bit move.
1719 (define_peephole2
1720   [(match_scratch:DI 2 "r")
1721    (set (match_operand:DI 0 "push_operand")
1722         (match_operand:DI 1 "immediate_operand"))]
1723   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1724    && !x86_64_immediate_operand (operands[1], DImode)"
1725   [(set (match_dup 2) (match_dup 1))
1726    (set (match_dup 0) (match_dup 2))])
1728 ;; We need to define this as both peepholer and splitter for case
1729 ;; peephole2 pass is not run.
1730 ;; "&& 1" is needed to keep it from matching the previous pattern.
1731 (define_peephole2
1732   [(set (match_operand:DI 0 "push_operand")
1733         (match_operand:DI 1 "immediate_operand"))]
1734   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1735    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1736   [(set (match_dup 0) (match_dup 1))
1737    (set (match_dup 2) (match_dup 3))]
1739   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1741   operands[1] = gen_lowpart (DImode, operands[2]);
1742   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1743                                                    GEN_INT (4)));
1746 (define_split
1747   [(set (match_operand:DI 0 "push_operand")
1748         (match_operand:DI 1 "immediate_operand"))]
1749   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1750                     ? epilogue_completed : reload_completed)
1751    && !symbolic_operand (operands[1], DImode)
1752    && !x86_64_immediate_operand (operands[1], DImode)"
1753   [(set (match_dup 0) (match_dup 1))
1754    (set (match_dup 2) (match_dup 3))]
1756   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1758   operands[1] = gen_lowpart (DImode, operands[2]);
1759   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1760                                                    GEN_INT (4)));
1763 (define_split
1764   [(set (match_operand:DI 0 "push_operand")
1765         (match_operand:DI 1 "general_operand"))]
1766   "!TARGET_64BIT && reload_completed
1767    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1768   [(const_int 0)]
1769   "ix86_split_long_move (operands); DONE;")
1771 (define_insn "*pushsi2"
1772   [(set (match_operand:SI 0 "push_operand" "=<")
1773         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1774   "!TARGET_64BIT"
1775   "push{l}\t%1"
1776   [(set_attr "type" "push")
1777    (set_attr "mode" "SI")])
1779 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1780 ;; "push a byte/word".  But actually we use pushl, which has the effect
1781 ;; of rounding the amount pushed up to a word.
1783 ;; For TARGET_64BIT we always round up to 8 bytes.
1784 (define_insn "*push<mode>2_rex64"
1785   [(set (match_operand:SWI124 0 "push_operand" "=X")
1786         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1787   "TARGET_64BIT"
1788   "push{q}\t%q1"
1789   [(set_attr "type" "push")
1790    (set_attr "mode" "DI")])
1792 (define_insn "*push<mode>2"
1793   [(set (match_operand:SWI12 0 "push_operand" "=X")
1794         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1795   "!TARGET_64BIT"
1796   "push{l}\t%k1"
1797   [(set_attr "type" "push")
1798    (set_attr "mode" "SI")])
1800 (define_insn "*push<mode>2_prologue"
1801   [(set (match_operand:W 0 "push_operand" "=<")
1802         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1803    (clobber (mem:BLK (scratch)))]
1804   ""
1805   "push{<imodesuffix>}\t%1"
1806   [(set_attr "type" "push")
1807    (set_attr "mode" "<MODE>")])
1809 (define_insn "*pop<mode>1"
1810   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1811         (match_operand:W 1 "pop_operand" ">"))]
1812   ""
1813   "pop{<imodesuffix>}\t%0"
1814   [(set_attr "type" "pop")
1815    (set_attr "mode" "<MODE>")])
1817 (define_insn "*pop<mode>1_epilogue"
1818   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1819         (match_operand:W 1 "pop_operand" ">"))
1820    (clobber (mem:BLK (scratch)))]
1821   ""
1822   "pop{<imodesuffix>}\t%0"
1823   [(set_attr "type" "pop")
1824    (set_attr "mode" "<MODE>")])
1826 (define_insn "*pushfl<mode>2"
1827   [(set (match_operand:W 0 "push_operand" "=<")
1828         (match_operand:W 1 "flags_reg_operand"))]
1829   ""
1830   "pushf{<imodesuffix>}"
1831   [(set_attr "type" "push")
1832    (set_attr "mode" "<MODE>")])
1834 (define_insn "*popfl<mode>1"
1835   [(set (match_operand:W 0 "flags_reg_operand")
1836         (match_operand:W 1 "pop_operand" ">"))]
1837   ""
1838   "popf{<imodesuffix>}"
1839   [(set_attr "type" "pop")
1840    (set_attr "mode" "<MODE>")])
1843 ;; Move instructions.
1845 (define_expand "movxi"
1846   [(set (match_operand:XI 0 "nonimmediate_operand")
1847         (match_operand:XI 1 "general_operand"))]
1848   "TARGET_AVX512F"
1849   "ix86_expand_move (XImode, operands); DONE;")
1851 ;; Reload patterns to support multi-word load/store
1852 ;; with non-offsetable address.
1853 (define_expand "reload_noff_store"
1854   [(parallel [(match_operand 0 "memory_operand" "=m")
1855               (match_operand 1 "register_operand" "r")
1856               (match_operand:DI 2 "register_operand" "=&r")])]
1857   "TARGET_64BIT"
1859   rtx mem = operands[0];
1860   rtx addr = XEXP (mem, 0);
1862   emit_move_insn (operands[2], addr);
1863   mem = replace_equiv_address_nv (mem, operands[2]);
1865   emit_insn (gen_rtx_SET (mem, operands[1]));
1866   DONE;
1869 (define_expand "reload_noff_load"
1870   [(parallel [(match_operand 0 "register_operand" "=r")
1871               (match_operand 1 "memory_operand" "m")
1872               (match_operand:DI 2 "register_operand" "=r")])]
1873   "TARGET_64BIT"
1875   rtx mem = operands[1];
1876   rtx addr = XEXP (mem, 0);
1878   emit_move_insn (operands[2], addr);
1879   mem = replace_equiv_address_nv (mem, operands[2]);
1881   emit_insn (gen_rtx_SET (operands[0], mem));
1882   DONE;
1885 (define_expand "movoi"
1886   [(set (match_operand:OI 0 "nonimmediate_operand")
1887         (match_operand:OI 1 "general_operand"))]
1888   "TARGET_AVX"
1889   "ix86_expand_move (OImode, operands); DONE;")
1891 (define_expand "movti"
1892   [(set (match_operand:TI 0 "nonimmediate_operand")
1893         (match_operand:TI 1 "nonimmediate_operand"))]
1894   "TARGET_64BIT || TARGET_SSE"
1896   if (TARGET_64BIT)
1897     ix86_expand_move (TImode, operands);
1898   else
1899     ix86_expand_vector_move (TImode, operands);
1900   DONE;
1903 ;; This expands to what emit_move_complex would generate if we didn't
1904 ;; have a movti pattern.  Having this avoids problems with reload on
1905 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1906 ;; to have around all the time.
1907 (define_expand "movcdi"
1908   [(set (match_operand:CDI 0 "nonimmediate_operand")
1909         (match_operand:CDI 1 "general_operand"))]
1910   ""
1912   if (push_operand (operands[0], CDImode))
1913     emit_move_complex_push (CDImode, operands[0], operands[1]);
1914   else
1915     emit_move_complex_parts (operands[0], operands[1]);
1916   DONE;
1919 (define_expand "mov<mode>"
1920   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1921         (match_operand:SWI1248x 1 "general_operand"))]
1922   ""
1923   "ix86_expand_move (<MODE>mode, operands); DONE;")
1925 (define_insn "*mov<mode>_xor"
1926   [(set (match_operand:SWI48 0 "register_operand" "=r")
1927         (match_operand:SWI48 1 "const0_operand"))
1928    (clobber (reg:CC FLAGS_REG))]
1929   "reload_completed"
1930   "xor{l}\t%k0, %k0"
1931   [(set_attr "type" "alu1")
1932    (set_attr "mode" "SI")
1933    (set_attr "length_immediate" "0")])
1935 (define_insn "*mov<mode>_or"
1936   [(set (match_operand:SWI48 0 "register_operand" "=r")
1937         (match_operand:SWI48 1 "const_int_operand"))
1938    (clobber (reg:CC FLAGS_REG))]
1939   "reload_completed
1940    && operands[1] == constm1_rtx"
1941   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1942   [(set_attr "type" "alu1")
1943    (set_attr "mode" "<MODE>")
1944    (set_attr "length_immediate" "1")])
1946 (define_insn "*movxi_internal_avx512f"
1947   [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1948         (match_operand:XI 1 "vector_move_operand"  "C ,vm,v"))]
1949   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951   switch (which_alternative)
1952     {
1953     case 0:
1954       return standard_sse_constant_opcode (insn, operands[1]);
1955     case 1:
1956     case 2:
1957       if (misaligned_operand (operands[0], XImode)
1958           || misaligned_operand (operands[1], XImode))
1959         return "vmovdqu32\t{%1, %0|%0, %1}";
1960       else
1961         return "vmovdqa32\t{%1, %0|%0, %1}";
1962     default:
1963       gcc_unreachable ();
1964     }
1966   [(set_attr "type" "sselog1,ssemov,ssemov")
1967    (set_attr "prefix" "evex")
1968    (set_attr "mode" "XI")])
1970 (define_insn "*movoi_internal_avx"
1971   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1972         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1973   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1975   switch (get_attr_type (insn))
1976     {
1977     case TYPE_SSELOG1:
1978       return standard_sse_constant_opcode (insn, operands[1]);
1980     case TYPE_SSEMOV:
1981       if (misaligned_operand (operands[0], OImode)
1982           || misaligned_operand (operands[1], OImode))
1983         {
1984           if (get_attr_mode (insn) == MODE_V8SF)
1985             return "vmovups\t{%1, %0|%0, %1}";
1986           else if (get_attr_mode (insn) == MODE_XI)
1987             return "vmovdqu32\t{%1, %0|%0, %1}";
1988           else
1989             return "vmovdqu\t{%1, %0|%0, %1}";
1990         }
1991       else
1992         {
1993           if (get_attr_mode (insn) == MODE_V8SF)
1994             return "vmovaps\t{%1, %0|%0, %1}";
1995           else if (get_attr_mode (insn) == MODE_XI)
1996             return "vmovdqa32\t{%1, %0|%0, %1}";
1997           else
1998             return "vmovdqa\t{%1, %0|%0, %1}";
1999         }
2001     default:
2002       gcc_unreachable ();
2003     }
2005   [(set_attr "type" "sselog1,ssemov,ssemov")
2006    (set_attr "prefix" "vex")
2007    (set (attr "mode")
2008         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2009                     (match_operand 1 "ext_sse_reg_operand"))
2010                  (const_string "XI")
2011                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2012                  (const_string "V8SF")
2013                (and (eq_attr "alternative" "2")
2014                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2015                  (const_string "V8SF")
2016               ]
2017               (const_string "OI")))])
2019 (define_insn "*movti_internal"
2020   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2021         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2022   "(TARGET_64BIT || TARGET_SSE)
2023    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2025   switch (get_attr_type (insn))
2026     {
2027     case TYPE_MULTI:
2028       return "#";
2030     case TYPE_SSELOG1:
2031       return standard_sse_constant_opcode (insn, operands[1]);
2033     case TYPE_SSEMOV:
2034       /* TDmode values are passed as TImode on the stack.  Moving them
2035          to stack may result in unaligned memory access.  */
2036       if (misaligned_operand (operands[0], TImode)
2037           || misaligned_operand (operands[1], TImode))
2038         {
2039           if (get_attr_mode (insn) == MODE_V4SF)
2040             return "%vmovups\t{%1, %0|%0, %1}";
2041           else if (get_attr_mode (insn) == MODE_XI)
2042             return "vmovdqu32\t{%1, %0|%0, %1}";
2043           else
2044             return "%vmovdqu\t{%1, %0|%0, %1}";
2045         }
2046       else
2047         {
2048           if (get_attr_mode (insn) == MODE_V4SF)
2049             return "%vmovaps\t{%1, %0|%0, %1}";
2050           else if (get_attr_mode (insn) == MODE_XI)
2051             return "vmovdqa32\t{%1, %0|%0, %1}";
2052           else
2053             return "%vmovdqa\t{%1, %0|%0, %1}";
2054         }
2056     default:
2057       gcc_unreachable ();
2058     }
2060   [(set_attr "isa" "x64,x64,*,*,*")
2061    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2062    (set (attr "prefix")
2063      (if_then_else (eq_attr "type" "sselog1,ssemov")
2064        (const_string "maybe_vex")
2065        (const_string "orig")))
2066    (set (attr "mode")
2067         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2068                     (match_operand 1 "ext_sse_reg_operand"))
2069                  (const_string "XI")
2070                (eq_attr "alternative" "0,1")
2071                  (const_string "DI")
2072                (ior (not (match_test "TARGET_SSE2"))
2073                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2074                  (const_string "V4SF")
2075                (and (eq_attr "alternative" "4")
2076                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2077                  (const_string "V4SF")
2078                (match_test "TARGET_AVX")
2079                  (const_string "TI")
2080                (match_test "optimize_function_for_size_p (cfun)")
2081                  (const_string "V4SF")
2082                ]
2083                (const_string "TI")))])
2085 (define_split
2086   [(set (match_operand:TI 0 "nonimmediate_operand")
2087         (match_operand:TI 1 "general_operand"))]
2088   "reload_completed
2089    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2090   [(const_int 0)]
2091   "ix86_split_long_move (operands); DONE;")
2093 (define_insn "*movdi_internal"
2094   [(set (match_operand:DI 0 "nonimmediate_operand"
2095     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2096         (match_operand:DI 1 "general_operand"
2097     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2098   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2100   switch (get_attr_type (insn))
2101     {
2102     case TYPE_MSKMOV:
2103       return "kmovq\t{%1, %0|%0, %1}";
2105     case TYPE_MULTI:
2106       return "#";
2108     case TYPE_MMX:
2109       return "pxor\t%0, %0";
2111     case TYPE_MMXMOV:
2112       /* Handle broken assemblers that require movd instead of movq.  */
2113       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2114           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2115         return "movd\t{%1, %0|%0, %1}";
2116       return "movq\t{%1, %0|%0, %1}";
2118     case TYPE_SSELOG1:
2119       if (GENERAL_REG_P (operands[0]))
2120         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2122       return standard_sse_constant_opcode (insn, operands[1]);
2124     case TYPE_SSEMOV:
2125       switch (get_attr_mode (insn))
2126         {
2127         case MODE_DI:
2128           /* Handle broken assemblers that require movd instead of movq.  */
2129           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2130               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2131             return "%vmovd\t{%1, %0|%0, %1}";
2132           return "%vmovq\t{%1, %0|%0, %1}";
2133         case MODE_TI:
2134           return "%vmovdqa\t{%1, %0|%0, %1}";
2135         case MODE_XI:
2136           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2138         case MODE_V2SF:
2139           gcc_assert (!TARGET_AVX);
2140           return "movlps\t{%1, %0|%0, %1}";
2141         case MODE_V4SF:
2142           return "%vmovaps\t{%1, %0|%0, %1}";
2144         default:
2145           gcc_unreachable ();
2146         }
2148     case TYPE_SSECVT:
2149       if (SSE_REG_P (operands[0]))
2150         return "movq2dq\t{%1, %0|%0, %1}";
2151       else
2152         return "movdq2q\t{%1, %0|%0, %1}";
2154     case TYPE_LEA:
2155       return "lea{q}\t{%E1, %0|%0, %E1}";
2157     case TYPE_IMOV:
2158       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159       if (get_attr_mode (insn) == MODE_SI)
2160         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2161       else if (which_alternative == 4)
2162         return "movabs{q}\t{%1, %0|%0, %1}";
2163       else if (ix86_use_lea_for_mov (insn, operands))
2164         return "lea{q}\t{%E1, %0|%0, %E1}";
2165       else
2166         return "mov{q}\t{%1, %0|%0, %1}";
2168     default:
2169       gcc_unreachable ();
2170     }
2172   [(set (attr "isa")
2173      (cond [(eq_attr "alternative" "0,1")
2174               (const_string "nox64")
2175             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2176               (const_string "x64")
2177             (eq_attr "alternative" "17")
2178               (const_string "x64_sse4")
2179            ]
2180            (const_string "*")))
2181    (set (attr "type")
2182      (cond [(eq_attr "alternative" "0,1")
2183               (const_string "multi")
2184             (eq_attr "alternative" "6")
2185               (const_string "mmx")
2186             (eq_attr "alternative" "7,8,9,10,11")
2187               (const_string "mmxmov")
2188             (eq_attr "alternative" "12,17")
2189               (const_string "sselog1")
2190             (eq_attr "alternative" "13,14,15,16,18")
2191               (const_string "ssemov")
2192             (eq_attr "alternative" "19,20")
2193               (const_string "ssecvt")
2194             (eq_attr "alternative" "21,22,23,24")
2195               (const_string "mskmov")
2196             (and (match_operand 0 "register_operand")
2197                  (match_operand 1 "pic_32bit_operand"))
2198               (const_string "lea")
2199            ]
2200            (const_string "imov")))
2201    (set (attr "modrm")
2202      (if_then_else
2203        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2204          (const_string "0")
2205          (const_string "*")))
2206    (set (attr "length_immediate")
2207      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2208               (const_string "8")
2209             (eq_attr "alternative" "17")
2210               (const_string "1")
2211            ]
2212            (const_string "*")))
2213    (set (attr "prefix_rex")
2214      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2215        (const_string "1")
2216        (const_string "*")))
2217    (set (attr "prefix_extra")
2218      (if_then_else (eq_attr "alternative" "17")
2219        (const_string "1")
2220        (const_string "*")))
2221    (set (attr "prefix")
2222      (if_then_else (eq_attr "type" "sselog1,ssemov")
2223        (const_string "maybe_vex")
2224        (const_string "orig")))
2225    (set (attr "prefix_data16")
2226      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2227        (const_string "1")
2228        (const_string "*")))
2229    (set (attr "mode")
2230      (cond [(eq_attr "alternative" "2")
2231               (const_string "SI")
2232             (eq_attr "alternative" "12,13")
2233               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2234                           (match_operand 1 "ext_sse_reg_operand"))
2235                        (const_string "XI")
2236                      (ior (not (match_test "TARGET_SSE2"))
2237                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2238                        (const_string "V4SF")
2239                      (match_test "TARGET_AVX")
2240                        (const_string "TI")
2241                      (match_test "optimize_function_for_size_p (cfun)")
2242                        (const_string "V4SF")
2243                     ]
2244                     (const_string "TI"))
2246             (and (eq_attr "alternative" "14,15")
2247                  (not (match_test "TARGET_SSE2")))
2248               (const_string "V2SF")
2249             (eq_attr "alternative" "17")
2250               (const_string "TI")
2251            ]
2252            (const_string "DI")))])
2254 (define_split
2255   [(set (match_operand:DI 0 "nonimmediate_operand")
2256         (match_operand:DI 1 "general_operand"))]
2257   "!TARGET_64BIT && reload_completed
2258    && !(MMX_REG_P (operands[0])
2259         || SSE_REG_P (operands[0])
2260         || MASK_REG_P (operands[0]))
2261    && !(MMX_REG_P (operands[1])
2262         || SSE_REG_P (operands[1])
2263         || MASK_REG_P (operands[1]))"
2264   [(const_int 0)]
2265   "ix86_split_long_move (operands); DONE;")
2267 (define_insn "*movsi_internal"
2268   [(set (match_operand:SI 0 "nonimmediate_operand"
2269                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2270         (match_operand:SI 1 "general_operand"
2271                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2272   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2274   switch (get_attr_type (insn))
2275     {
2276     case TYPE_SSELOG1:
2277       if (GENERAL_REG_P (operands[0]))
2278         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2280       return standard_sse_constant_opcode (insn, operands[1]);
2282     case TYPE_MSKMOV:
2283       return "kmovd\t{%1, %0|%0, %1}";
2285     case TYPE_SSEMOV:
2286       switch (get_attr_mode (insn))
2287         {
2288         case MODE_SI:
2289           return "%vmovd\t{%1, %0|%0, %1}";
2290         case MODE_TI:
2291           return "%vmovdqa\t{%1, %0|%0, %1}";
2292         case MODE_XI:
2293           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2295         case MODE_V4SF:
2296           return "%vmovaps\t{%1, %0|%0, %1}";
2298         case MODE_SF:
2299           gcc_assert (!TARGET_AVX);
2300           return "movss\t{%1, %0|%0, %1}";
2302         default:
2303           gcc_unreachable ();
2304         }
2306     case TYPE_MMX:
2307       return "pxor\t%0, %0";
2309     case TYPE_MMXMOV:
2310       switch (get_attr_mode (insn))
2311         {
2312         case MODE_DI:
2313           return "movq\t{%1, %0|%0, %1}";
2314         case MODE_SI:
2315           return "movd\t{%1, %0|%0, %1}";
2317         default:
2318           gcc_unreachable ();
2319         }
2321     case TYPE_LEA:
2322       return "lea{l}\t{%E1, %0|%0, %E1}";
2324     case TYPE_IMOV:
2325       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2326       if (ix86_use_lea_for_mov (insn, operands))
2327         return "lea{l}\t{%E1, %0|%0, %E1}";
2328       else
2329         return "mov{l}\t{%1, %0|%0, %1}";
2331     default:
2332       gcc_unreachable ();
2333     }
2335   [(set (attr "isa")
2336      (if_then_else (eq_attr "alternative" "11")
2337        (const_string "sse4")
2338        (const_string "*")))
2339    (set (attr "type")
2340      (cond [(eq_attr "alternative" "2")
2341               (const_string "mmx")
2342             (eq_attr "alternative" "3,4,5")
2343               (const_string "mmxmov")
2344             (eq_attr "alternative" "6,11")
2345               (const_string "sselog1")
2346             (eq_attr "alternative" "7,8,9,10,12")
2347               (const_string "ssemov")
2348             (eq_attr "alternative" "13,14")
2349               (const_string "mskmov")
2350             (and (match_operand 0 "register_operand")
2351                  (match_operand 1 "pic_32bit_operand"))
2352               (const_string "lea")
2353            ]
2354            (const_string "imov")))
2355    (set (attr "length_immediate")
2356      (if_then_else (eq_attr "alternative" "11")
2357        (const_string "1")
2358        (const_string "*")))
2359    (set (attr "prefix_extra")
2360      (if_then_else (eq_attr "alternative" "11")
2361        (const_string "1")
2362        (const_string "*")))
2363    (set (attr "prefix")
2364      (if_then_else (eq_attr "type" "sselog1,ssemov")
2365        (const_string "maybe_vex")
2366        (const_string "orig")))
2367    (set (attr "prefix_data16")
2368      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2369        (const_string "1")
2370        (const_string "*")))
2371    (set (attr "mode")
2372      (cond [(eq_attr "alternative" "2,3")
2373               (const_string "DI")
2374             (eq_attr "alternative" "6,7")
2375               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2376                           (match_operand 1 "ext_sse_reg_operand"))
2377                        (const_string "XI")
2378                      (ior (not (match_test "TARGET_SSE2"))
2379                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2380                        (const_string "V4SF")
2381                      (match_test "TARGET_AVX")
2382                        (const_string "TI")
2383                      (match_test "optimize_function_for_size_p (cfun)")
2384                        (const_string "V4SF")
2385                     ]
2386                     (const_string "TI"))
2388             (and (eq_attr "alternative" "8,9")
2389                  (not (match_test "TARGET_SSE2")))
2390               (const_string "SF")
2391             (eq_attr "alternative" "11")
2392               (const_string "TI")
2393            ]
2394            (const_string "SI")))])
2396 (define_insn "kmovw"
2397   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2398         (unspec:HI
2399           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2400           UNSPEC_KMOV))]
2401   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2402   "@
2403    kmovw\t{%k1, %0|%0, %k1}
2404    kmovw\t{%1, %0|%0, %1}";
2405   [(set_attr "mode" "HI")
2406    (set_attr "type" "mskmov")
2407    (set_attr "prefix" "vex")])
2410 (define_insn "*movhi_internal"
2411   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2412         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2413   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415   switch (get_attr_type (insn))
2416     {
2417     case TYPE_IMOVX:
2418       /* movzwl is faster than movw on p2 due to partial word stalls,
2419          though not as fast as an aligned movl.  */
2420       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2422     case TYPE_MSKMOV:
2423       switch (which_alternative)
2424         {
2425         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2426         case 5: return "kmovw\t{%1, %0|%0, %1}";
2427         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2428         default: gcc_unreachable ();
2429         }
2431     default:
2432       if (get_attr_mode (insn) == MODE_SI)
2433         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2434       else
2435         return "mov{w}\t{%1, %0|%0, %1}";
2436     }
2438   [(set (attr "type")
2439      (cond [(eq_attr "alternative" "4,5,6")
2440               (const_string "mskmov")
2441             (match_test "optimize_function_for_size_p (cfun)")
2442               (const_string "imov")
2443             (and (eq_attr "alternative" "0")
2444                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2445                       (not (match_test "TARGET_HIMODE_MATH"))))
2446               (const_string "imov")
2447             (and (eq_attr "alternative" "1,2")
2448                  (match_operand:HI 1 "aligned_operand"))
2449               (const_string "imov")
2450             (and (match_test "TARGET_MOVX")
2451                  (eq_attr "alternative" "0,2"))
2452               (const_string "imovx")
2453            ]
2454            (const_string "imov")))
2455     (set (attr "prefix")
2456       (if_then_else (eq_attr "alternative" "4,5,6")
2457         (const_string "vex")
2458         (const_string "orig")))
2459     (set (attr "mode")
2460       (cond [(eq_attr "type" "imovx")
2461                (const_string "SI")
2462              (and (eq_attr "alternative" "1,2")
2463                   (match_operand:HI 1 "aligned_operand"))
2464                (const_string "SI")
2465              (and (eq_attr "alternative" "0")
2466                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2467                        (not (match_test "TARGET_HIMODE_MATH"))))
2468                (const_string "SI")
2469             ]
2470             (const_string "HI")))])
2472 ;; Situation is quite tricky about when to choose full sized (SImode) move
2473 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2474 ;; partial register dependency machines (such as AMD Athlon), where QImode
2475 ;; moves issue extra dependency and for partial register stalls machines
2476 ;; that don't use QImode patterns (and QImode move cause stall on the next
2477 ;; instruction).
2479 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2480 ;; register stall machines with, where we use QImode instructions, since
2481 ;; partial register stall can be caused there.  Then we use movzx.
2483 (define_insn "*movqi_internal"
2484   [(set (match_operand:QI 0 "nonimmediate_operand"
2485                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2486         (match_operand:QI 1 "general_operand"
2487                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2488   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2490   switch (get_attr_type (insn))
2491     {
2492     case TYPE_IMOVX:
2493       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2494       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2496     case TYPE_MSKMOV:
2497       switch (which_alternative)
2498         {
2499         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2500                                        : "kmovw\t{%k1, %0|%0, %k1}";
2501         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2502                                        : "kmovw\t{%1, %0|%0, %1}";
2503         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2504                                        : "kmovw\t{%1, %k0|%k0, %1}";
2505         case 10:
2506         case 11:
2507           gcc_assert (TARGET_AVX512DQ);
2508           return "kmovb\t{%1, %0|%0, %1}";
2509         default: gcc_unreachable ();
2510         }
2512     default:
2513       if (get_attr_mode (insn) == MODE_SI)
2514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2515       else
2516         return "mov{b}\t{%1, %0|%0, %1}";
2517     }
2519   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2520    (set (attr "type")
2521      (cond [(eq_attr "alternative" "7,8,9,10,11")
2522               (const_string "mskmov")
2523             (and (eq_attr "alternative" "5")
2524                  (not (match_operand:QI 1 "aligned_operand")))
2525               (const_string "imovx")
2526             (match_test "optimize_function_for_size_p (cfun)")
2527               (const_string "imov")
2528             (and (eq_attr "alternative" "3")
2529                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2530                       (not (match_test "TARGET_QIMODE_MATH"))))
2531               (const_string "imov")
2532             (eq_attr "alternative" "3,5")
2533               (const_string "imovx")
2534             (and (match_test "TARGET_MOVX")
2535                  (eq_attr "alternative" "2"))
2536               (const_string "imovx")
2537            ]
2538            (const_string "imov")))
2539    (set (attr "prefix")
2540      (if_then_else (eq_attr "alternative" "7,8,9")
2541        (const_string "vex")
2542        (const_string "orig")))
2543    (set (attr "mode")
2544       (cond [(eq_attr "alternative" "3,4,5")
2545                (const_string "SI")
2546              (eq_attr "alternative" "6")
2547                (const_string "QI")
2548              (eq_attr "type" "imovx")
2549                (const_string "SI")
2550              (and (eq_attr "type" "imov")
2551                   (and (eq_attr "alternative" "0,1")
2552                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2553                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2554                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2555                (const_string "SI")
2556              ;; Avoid partial register stalls when not using QImode arithmetic
2557              (and (eq_attr "type" "imov")
2558                   (and (eq_attr "alternative" "0,1")
2559                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2560                             (not (match_test "TARGET_QIMODE_MATH")))))
2561                (const_string "SI")
2562            ]
2563            (const_string "QI")))])
2565 ;; Stores and loads of ax to arbitrary constant address.
2566 ;; We fake an second form of instruction to force reload to load address
2567 ;; into register when rax is not available
2568 (define_insn "*movabs<mode>_1"
2569   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2570         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2571   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2572   "@
2573    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2574    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2575   [(set_attr "type" "imov")
2576    (set_attr "modrm" "0,*")
2577    (set_attr "length_address" "8,0")
2578    (set_attr "length_immediate" "0,*")
2579    (set_attr "memory" "store")
2580    (set_attr "mode" "<MODE>")])
2582 (define_insn "*movabs<mode>_2"
2583   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2584         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2585   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2586   "@
2587    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2588    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2589   [(set_attr "type" "imov")
2590    (set_attr "modrm" "0,*")
2591    (set_attr "length_address" "8,0")
2592    (set_attr "length_immediate" "0")
2593    (set_attr "memory" "load")
2594    (set_attr "mode" "<MODE>")])
2596 (define_insn "*swap<mode>"
2597   [(set (match_operand:SWI48 0 "register_operand" "+r")
2598         (match_operand:SWI48 1 "register_operand" "+r"))
2599    (set (match_dup 1)
2600         (match_dup 0))]
2601   ""
2602   "xchg{<imodesuffix>}\t%1, %0"
2603   [(set_attr "type" "imov")
2604    (set_attr "mode" "<MODE>")
2605    (set_attr "pent_pair" "np")
2606    (set_attr "athlon_decode" "vector")
2607    (set_attr "amdfam10_decode" "double")
2608    (set_attr "bdver1_decode" "double")])
2610 (define_insn "*swap<mode>_1"
2611   [(set (match_operand:SWI12 0 "register_operand" "+r")
2612         (match_operand:SWI12 1 "register_operand" "+r"))
2613    (set (match_dup 1)
2614         (match_dup 0))]
2615   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2616   "xchg{l}\t%k1, %k0"
2617   [(set_attr "type" "imov")
2618    (set_attr "mode" "SI")
2619    (set_attr "pent_pair" "np")
2620    (set_attr "athlon_decode" "vector")
2621    (set_attr "amdfam10_decode" "double")
2622    (set_attr "bdver1_decode" "double")])
2624 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2625 ;; is disabled for AMDFAM10
2626 (define_insn "*swap<mode>_2"
2627   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2628         (match_operand:SWI12 1 "register_operand" "+<r>"))
2629    (set (match_dup 1)
2630         (match_dup 0))]
2631   "TARGET_PARTIAL_REG_STALL"
2632   "xchg{<imodesuffix>}\t%1, %0"
2633   [(set_attr "type" "imov")
2634    (set_attr "mode" "<MODE>")
2635    (set_attr "pent_pair" "np")
2636    (set_attr "athlon_decode" "vector")])
2638 (define_expand "movstrict<mode>"
2639   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2640         (match_operand:SWI12 1 "general_operand"))]
2641   ""
2643   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2644     FAIL;
2645   if (GET_CODE (operands[0]) == SUBREG
2646       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2647     FAIL;
2648   /* Don't generate memory->memory moves, go through a register */
2649   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2650     operands[1] = force_reg (<MODE>mode, operands[1]);
2653 (define_insn "*movstrict<mode>_1"
2654   [(set (strict_low_part
2655           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2656         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2657   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2658    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2659   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2660   [(set_attr "type" "imov")
2661    (set_attr "mode" "<MODE>")])
2663 (define_insn "*movstrict<mode>_xor"
2664   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2665         (match_operand:SWI12 1 "const0_operand"))
2666    (clobber (reg:CC FLAGS_REG))]
2667   "reload_completed"
2668   "xor{<imodesuffix>}\t%0, %0"
2669   [(set_attr "type" "alu1")
2670    (set_attr "mode" "<MODE>")
2671    (set_attr "length_immediate" "0")])
2673 (define_insn "*mov<mode>_extv_1"
2674   [(set (match_operand:SWI24 0 "register_operand" "=R")
2675         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2676                             (const_int 8)
2677                             (const_int 8)))]
2678   ""
2679   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2680   [(set_attr "type" "imovx")
2681    (set_attr "mode" "SI")])
2683 (define_insn "*movqi_extv_1"
2684   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2685         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2686                          (const_int 8)
2687                          (const_int 8)))]
2688   ""
2690   switch (get_attr_type (insn))
2691     {
2692     case TYPE_IMOVX:
2693       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2694     default:
2695       return "mov{b}\t{%h1, %0|%0, %h1}";
2696     }
2698   [(set_attr "isa" "*,*,nox64")
2699    (set (attr "type")
2700      (if_then_else (and (match_operand:QI 0 "register_operand")
2701                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2702                              (match_test "TARGET_MOVX")))
2703         (const_string "imovx")
2704         (const_string "imov")))
2705    (set (attr "mode")
2706      (if_then_else (eq_attr "type" "imovx")
2707         (const_string "SI")
2708         (const_string "QI")))])
2710 (define_insn "*mov<mode>_extzv_1"
2711   [(set (match_operand:SWI48 0 "register_operand" "=R")
2712         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2713                             (const_int 8)
2714                             (const_int 8)))]
2715   ""
2716   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2717   [(set_attr "type" "imovx")
2718    (set_attr "mode" "SI")])
2720 (define_insn "*movqi_extzv_2"
2721   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2722         (subreg:QI
2723           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2724                            (const_int 8)
2725                            (const_int 8)) 0))]
2726   ""
2728   switch (get_attr_type (insn))
2729     {
2730     case TYPE_IMOVX:
2731       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2732     default:
2733       return "mov{b}\t{%h1, %0|%0, %h1}";
2734     }
2736   [(set_attr "isa" "*,*,nox64")
2737    (set (attr "type")
2738      (if_then_else (and (match_operand:QI 0 "register_operand")
2739                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2740                              (match_test "TARGET_MOVX")))
2741         (const_string "imovx")
2742         (const_string "imov")))
2743    (set (attr "mode")
2744      (if_then_else (eq_attr "type" "imovx")
2745         (const_string "SI")
2746         (const_string "QI")))])
2748 (define_insn "mov<mode>_insv_1"
2749   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2750                              (const_int 8)
2751                              (const_int 8))
2752         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2753   ""
2755   if (CONST_INT_P (operands[1]))
2756     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2757   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2759   [(set_attr "isa" "*,nox64")
2760    (set_attr "type" "imov")
2761    (set_attr "mode" "QI")])
2763 (define_insn "*movqi_insv_2"
2764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2765                          (const_int 8)
2766                          (const_int 8))
2767         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2768                      (const_int 8)))]
2769   ""
2770   "mov{b}\t{%h1, %h0|%h0, %h1}"
2771   [(set_attr "type" "imov")
2772    (set_attr "mode" "QI")])
2774 ;; Floating point push instructions.
2776 (define_insn "*pushtf"
2777   [(set (match_operand:TF 0 "push_operand" "=<,<")
2778         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2779   "TARGET_64BIT || TARGET_SSE"
2781   /* This insn should be already split before reg-stack.  */
2782   gcc_unreachable ();
2784   [(set_attr "isa" "*,x64")
2785    (set_attr "type" "multi")
2786    (set_attr "unit" "sse,*")
2787    (set_attr "mode" "TF,DI")])
2789 ;; %%% Kill this when call knows how to work this out.
2790 (define_split
2791   [(set (match_operand:TF 0 "push_operand")
2792         (match_operand:TF 1 "sse_reg_operand"))]
2793   "TARGET_SSE && reload_completed"
2794   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2795    (set (match_dup 0) (match_dup 1))]
2797   /* Preserve memory attributes. */
2798   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2801 (define_insn "*pushxf"
2802   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2803         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2804   ""
2806   /* This insn should be already split before reg-stack.  */
2807   gcc_unreachable ();
2809   [(set_attr "type" "multi")
2810    (set_attr "unit" "i387,*,*,*")
2811    (set (attr "mode")
2812         (cond [(eq_attr "alternative" "1,2,3")
2813                  (if_then_else (match_test "TARGET_64BIT")
2814                    (const_string "DI")
2815                    (const_string "SI"))
2816               ]
2817               (const_string "XF")))
2818    (set (attr "preferred_for_size")
2819      (cond [(eq_attr "alternative" "1")
2820               (symbol_ref "false")]
2821            (symbol_ref "true")))])
2823 ;; %%% Kill this when call knows how to work this out.
2824 (define_split
2825   [(set (match_operand:XF 0 "push_operand")
2826         (match_operand:XF 1 "fp_register_operand"))]
2827   "reload_completed"
2828   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2829    (set (match_dup 0) (match_dup 1))]
2831   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2832   /* Preserve memory attributes. */
2833   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2836 (define_insn "*pushdf"
2837   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2838         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2839   ""
2841   /* This insn should be already split before reg-stack.  */
2842   gcc_unreachable ();
2844   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2845    (set_attr "type" "multi")
2846    (set_attr "unit" "i387,*,*,*,*,sse")
2847    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2848    (set (attr "preferred_for_size")
2849      (cond [(eq_attr "alternative" "1")
2850               (symbol_ref "false")]
2851            (symbol_ref "true")))
2852    (set (attr "preferred_for_speed")
2853      (cond [(eq_attr "alternative" "1")
2854               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2855            (symbol_ref "true")))])
2856    
2857 ;; %%% Kill this when call knows how to work this out.
2858 (define_split
2859   [(set (match_operand:DF 0 "push_operand")
2860         (match_operand:DF 1 "any_fp_register_operand"))]
2861   "reload_completed"
2862   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2863    (set (match_dup 0) (match_dup 1))]
2865   /* Preserve memory attributes. */
2866   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2869 (define_insn "*pushsf_rex64"
2870   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2871         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2872   "TARGET_64BIT"
2874   /* Anything else should be already split before reg-stack.  */
2875   gcc_assert (which_alternative == 1);
2876   return "push{q}\t%q1";
2878   [(set_attr "type" "multi,push,multi")
2879    (set_attr "unit" "i387,*,*")
2880    (set_attr "mode" "SF,DI,SF")])
2882 (define_insn "*pushsf"
2883   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2884         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2885   "!TARGET_64BIT"
2887   /* Anything else should be already split before reg-stack.  */
2888   gcc_assert (which_alternative == 1);
2889   return "push{l}\t%1";
2891   [(set_attr "type" "multi,push,multi")
2892    (set_attr "unit" "i387,*,*")
2893    (set_attr "mode" "SF,SI,SF")])
2895 ;; %%% Kill this when call knows how to work this out.
2896 (define_split
2897   [(set (match_operand:SF 0 "push_operand")
2898         (match_operand:SF 1 "any_fp_register_operand"))]
2899   "reload_completed"
2900   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2901    (set (match_dup 0) (match_dup 1))]
2903   rtx op = XEXP (operands[0], 0);
2904   if (GET_CODE (op) == PRE_DEC)
2905     {
2906       gcc_assert (!TARGET_64BIT);
2907       op = GEN_INT (-4);
2908     }
2909   else
2910     {
2911       op = XEXP (XEXP (op, 1), 1);
2912       gcc_assert (CONST_INT_P (op));
2913     }
2914   operands[2] = op;
2915   /* Preserve memory attributes. */
2916   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2919 (define_split
2920   [(set (match_operand:SF 0 "push_operand")
2921         (match_operand:SF 1 "memory_operand"))]
2922   "reload_completed
2923    && (operands[2] = find_constant_src (insn))"
2924   [(set (match_dup 0) (match_dup 2))])
2926 (define_split
2927   [(set (match_operand 0 "push_operand")
2928         (match_operand 1 "general_operand"))]
2929   "reload_completed
2930    && (GET_MODE (operands[0]) == TFmode
2931        || GET_MODE (operands[0]) == XFmode
2932        || GET_MODE (operands[0]) == DFmode)
2933    && !ANY_FP_REG_P (operands[1])"
2934   [(const_int 0)]
2935   "ix86_split_long_move (operands); DONE;")
2937 ;; Floating point move instructions.
2939 (define_expand "movtf"
2940   [(set (match_operand:TF 0 "nonimmediate_operand")
2941         (match_operand:TF 1 "nonimmediate_operand"))]
2942   "TARGET_64BIT || TARGET_SSE"
2943   "ix86_expand_move (TFmode, operands); DONE;")
2945 (define_expand "mov<mode>"
2946   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2947         (match_operand:X87MODEF 1 "general_operand"))]
2948   ""
2949   "ix86_expand_move (<MODE>mode, operands); DONE;")
2951 (define_insn "*movtf_internal"
2952   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2953         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2954   "(TARGET_64BIT || TARGET_SSE)
2955    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2956    && (!can_create_pseudo_p ()
2957        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2958        || !CONST_DOUBLE_P (operands[1])
2959        || (optimize_function_for_size_p (cfun)
2960            && standard_sse_constant_p (operands[1])
2961            && !memory_operand (operands[0], TFmode))
2962        || (!TARGET_MEMORY_MISMATCH_STALL
2963            && memory_operand (operands[0], TFmode)))"
2965   switch (get_attr_type (insn))
2966     {
2967     case TYPE_SSELOG1:
2968       return standard_sse_constant_opcode (insn, operands[1]);
2970     case TYPE_SSEMOV:
2971       /* Handle misaligned load/store since we
2972          don't have movmisaligntf pattern. */
2973       if (misaligned_operand (operands[0], TFmode)
2974           || misaligned_operand (operands[1], TFmode))
2975         {
2976           if (get_attr_mode (insn) == MODE_V4SF)
2977             return "%vmovups\t{%1, %0|%0, %1}";
2978           else
2979             return "%vmovdqu\t{%1, %0|%0, %1}";
2980         }
2981       else
2982         {
2983           if (get_attr_mode (insn) == MODE_V4SF)
2984             return "%vmovaps\t{%1, %0|%0, %1}";
2985           else
2986             return "%vmovdqa\t{%1, %0|%0, %1}";
2987         }
2989     case TYPE_MULTI:
2990         return "#";
2992     default:
2993       gcc_unreachable ();
2994     }
2996   [(set_attr "isa" "*,*,*,x64,x64")
2997    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2998    (set (attr "prefix")
2999      (if_then_else (eq_attr "type" "sselog1,ssemov")
3000        (const_string "maybe_vex")
3001        (const_string "orig")))
3002    (set (attr "mode")
3003         (cond [(eq_attr "alternative" "3,4")
3004                  (const_string "DI")
3005                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3006                  (const_string "V4SF")
3007                (and (eq_attr "alternative" "2")
3008                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3009                  (const_string "V4SF")
3010                (match_test "TARGET_AVX")
3011                  (const_string "TI")
3012                (ior (not (match_test "TARGET_SSE2"))
3013                     (match_test "optimize_function_for_size_p (cfun)"))
3014                  (const_string "V4SF")
3015                ]
3016                (const_string "TI")))])
3018 ;; Possible store forwarding (partial memory) stall
3019 ;; in alternatives 4, 6, 7 and 8.
3020 (define_insn "*movxf_internal"
3021   [(set (match_operand:XF 0 "nonimmediate_operand"
3022          "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3023         (match_operand:XF 1 "general_operand"
3024          "fm,f,G,roF,r , *roF,*r,F ,C"))]
3025   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026    && (!can_create_pseudo_p ()
3027        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3028        || !CONST_DOUBLE_P (operands[1])
3029        || (optimize_function_for_size_p (cfun)
3030            && standard_80387_constant_p (operands[1]) > 0
3031            && !memory_operand (operands[0], XFmode))
3032        || (!TARGET_MEMORY_MISMATCH_STALL
3033            && memory_operand (operands[0], XFmode)))"
3035   switch (get_attr_type (insn))
3036     {
3037     case TYPE_FMOV:
3038       if (which_alternative == 2)
3039         return standard_80387_constant_opcode (operands[1]);
3040       return output_387_reg_move (insn, operands);
3042     case TYPE_MULTI:
3043       return "#";
3045     default:
3046       gcc_unreachable ();
3047     }
3049   [(set (attr "isa")
3050         (cond [(eq_attr "alternative" "7")
3051                  (const_string "nox64")
3052                (eq_attr "alternative" "8")
3053                  (const_string "x64")
3054               ]
3055               (const_string "*")))
3056    (set (attr "type")
3057         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3058                  (const_string "multi")
3059               ]
3060               (const_string "fmov")))
3061    (set (attr "mode")
3062         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3063                  (if_then_else (match_test "TARGET_64BIT")
3064                    (const_string "DI")
3065                    (const_string "SI"))
3066               ]
3067               (const_string "XF")))
3068    (set (attr "preferred_for_size")
3069      (cond [(eq_attr "alternative" "3,4")
3070               (symbol_ref "false")]
3071            (symbol_ref "true")))])
3072    
3073 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3074 (define_insn "*movdf_internal"
3075   [(set (match_operand:DF 0 "nonimmediate_operand"
3076     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3077         (match_operand:DF 1 "general_operand"
3078     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3079   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3080    && (!can_create_pseudo_p ()
3081        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3082        || !CONST_DOUBLE_P (operands[1])
3083        || (optimize_function_for_size_p (cfun)
3084            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3085                 && standard_80387_constant_p (operands[1]) > 0)
3086                || (TARGET_SSE2 && TARGET_SSE_MATH
3087                    && standard_sse_constant_p (operands[1])))
3088            && !memory_operand (operands[0], DFmode))
3089        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3090            && memory_operand (operands[0], DFmode)))"
3092   switch (get_attr_type (insn))
3093     {
3094     case TYPE_FMOV:
3095       if (which_alternative == 2)
3096         return standard_80387_constant_opcode (operands[1]);
3097       return output_387_reg_move (insn, operands);
3099     case TYPE_MULTI:
3100       return "#";
3102     case TYPE_IMOV:
3103       if (get_attr_mode (insn) == MODE_SI)
3104         return "mov{l}\t{%1, %k0|%k0, %1}";
3105       else if (which_alternative == 11)
3106         return "movabs{q}\t{%1, %0|%0, %1}";
3107       else
3108         return "mov{q}\t{%1, %0|%0, %1}";
3110     case TYPE_SSELOG1:
3111       return standard_sse_constant_opcode (insn, operands[1]);
3113     case TYPE_SSEMOV:
3114       switch (get_attr_mode (insn))
3115         {
3116         case MODE_DF:
3117           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3118             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3119           return "%vmovsd\t{%1, %0|%0, %1}";
3121         case MODE_V4SF:
3122           return "%vmovaps\t{%1, %0|%0, %1}";
3123         case MODE_V8DF:
3124           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3125         case MODE_V2DF:
3126           return "%vmovapd\t{%1, %0|%0, %1}";
3128         case MODE_V2SF:
3129           gcc_assert (!TARGET_AVX);
3130           return "movlps\t{%1, %0|%0, %1}";
3131         case MODE_V1DF:
3132           gcc_assert (!TARGET_AVX);
3133           return "movlpd\t{%1, %0|%0, %1}";
3135         case MODE_DI:
3136           /* Handle broken assemblers that require movd instead of movq.  */
3137           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3138               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3139             return "%vmovd\t{%1, %0|%0, %1}";
3140           return "%vmovq\t{%1, %0|%0, %1}";
3142         default:
3143           gcc_unreachable ();
3144         }
3146     default:
3147       gcc_unreachable ();
3148     }
3150   [(set (attr "isa")
3151         (cond [(eq_attr "alternative" "3,4,5,6,7")
3152                  (const_string "nox64")
3153                (eq_attr "alternative" "8,9,10,11,20,21")
3154                  (const_string "x64")
3155                (eq_attr "alternative" "12,13,14,15")
3156                  (const_string "sse2")
3157               ]
3158               (const_string "*")))
3159    (set (attr "type")
3160         (cond [(eq_attr "alternative" "0,1,2")
3161                  (const_string "fmov")
3162                (eq_attr "alternative" "3,4,5,6,7")
3163                  (const_string "multi")
3164                (eq_attr "alternative" "8,9,10,11")
3165                  (const_string "imov")
3166                (eq_attr "alternative" "12,16")
3167                  (const_string "sselog1")
3168               ]
3169               (const_string "ssemov")))
3170    (set (attr "modrm")
3171      (if_then_else (eq_attr "alternative" "11")
3172        (const_string "0")
3173        (const_string "*")))
3174    (set (attr "length_immediate")
3175      (if_then_else (eq_attr "alternative" "11")
3176        (const_string "8")
3177        (const_string "*")))
3178    (set (attr "prefix")
3179      (if_then_else (eq_attr "type" "sselog1,ssemov")
3180        (const_string "maybe_vex")
3181        (const_string "orig")))
3182    (set (attr "prefix_data16")
3183      (if_then_else
3184        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3185             (eq_attr "mode" "V1DF"))
3186        (const_string "1")
3187        (const_string "*")))
3188    (set (attr "mode")
3189         (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3190                  (const_string "SI")
3191                (eq_attr "alternative" "8,9,11,20,21")
3192                  (const_string "DI")
3194                /* xorps is one byte shorter for non-AVX targets.  */
3195                (eq_attr "alternative" "12,16")
3196                  (cond [(not (match_test "TARGET_SSE2"))
3197                           (const_string "V4SF")
3198                         (match_test "TARGET_AVX512F")
3199                           (const_string "XI")
3200                         (match_test "TARGET_AVX")
3201                           (const_string "V2DF")
3202                         (match_test "optimize_function_for_size_p (cfun)")
3203                           (const_string "V4SF")
3204                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3205                           (const_string "TI")
3206                        ]
3207                        (const_string "V2DF"))
3209                /* For architectures resolving dependencies on
3210                   whole SSE registers use movapd to break dependency
3211                   chains, otherwise use short move to avoid extra work.  */
3213                /* movaps is one byte shorter for non-AVX targets.  */
3214                (eq_attr "alternative" "13,17")
3215                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3216                              (match_operand 1 "ext_sse_reg_operand"))
3217                           (const_string "V8DF")
3218                         (ior (not (match_test "TARGET_SSE2"))
3219                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3220                           (const_string "V4SF")
3221                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3222                           (const_string "V2DF")
3223                         (match_test "TARGET_AVX")
3224                           (const_string "DF")
3225                         (match_test "optimize_function_for_size_p (cfun)")
3226                           (const_string "V4SF")
3227                        ]
3228                        (const_string "DF"))
3230                /* For architectures resolving dependencies on register
3231                   parts we may avoid extra work to zero out upper part
3232                   of register.  */
3233                (eq_attr "alternative" "14,18")
3234                  (cond [(not (match_test "TARGET_SSE2"))
3235                           (const_string "V2SF")
3236                         (match_test "TARGET_AVX")
3237                           (const_string "DF")
3238                         (match_test "TARGET_SSE_SPLIT_REGS")
3239                           (const_string "V1DF")
3240                        ]
3241                        (const_string "DF"))
3243                (and (eq_attr "alternative" "15,19")
3244                     (not (match_test "TARGET_SSE2")))
3245                  (const_string "V2SF")
3246               ]
3247               (const_string "DF")))
3248    (set (attr "preferred_for_size")
3249      (cond [(eq_attr "alternative" "3,4")
3250               (symbol_ref "false")]
3251            (symbol_ref "true")))
3252    (set (attr "preferred_for_speed")
3253      (cond [(eq_attr "alternative" "3,4")
3254               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3255            (symbol_ref "true")))])
3257 (define_insn "*movsf_internal"
3258   [(set (match_operand:SF 0 "nonimmediate_operand"
3259           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3260         (match_operand:SF 1 "general_operand"
3261           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3262   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3263    && (!can_create_pseudo_p ()
3264        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3265        || !CONST_DOUBLE_P (operands[1])
3266        || (optimize_function_for_size_p (cfun)
3267            && ((!TARGET_SSE_MATH
3268                 && standard_80387_constant_p (operands[1]) > 0)
3269                || (TARGET_SSE_MATH
3270                    && standard_sse_constant_p (operands[1]))))
3271        || memory_operand (operands[0], SFmode))"
3273   switch (get_attr_type (insn))
3274     {
3275     case TYPE_FMOV:
3276       if (which_alternative == 2)
3277         return standard_80387_constant_opcode (operands[1]);
3278       return output_387_reg_move (insn, operands);
3280     case TYPE_IMOV:
3281       return "mov{l}\t{%1, %0|%0, %1}";
3283     case TYPE_SSELOG1:
3284       return standard_sse_constant_opcode (insn, operands[1]);
3286     case TYPE_SSEMOV:
3287       switch (get_attr_mode (insn))
3288         {
3289         case MODE_SF:
3290           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3291             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3292           return "%vmovss\t{%1, %0|%0, %1}";
3294         case MODE_V16SF:
3295           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3296         case MODE_V4SF:
3297           return "%vmovaps\t{%1, %0|%0, %1}";
3299         case MODE_SI:
3300           return "%vmovd\t{%1, %0|%0, %1}";
3302         default:
3303           gcc_unreachable ();
3304         }
3306     case TYPE_MMXMOV:
3307       switch (get_attr_mode (insn))
3308         {
3309         case MODE_DI:
3310           return "movq\t{%1, %0|%0, %1}";
3311         case MODE_SI:
3312           return "movd\t{%1, %0|%0, %1}";
3314         default:
3315           gcc_unreachable ();
3316         }
3318     default:
3319       gcc_unreachable ();
3320     }
3322   [(set (attr "type")
3323         (cond [(eq_attr "alternative" "0,1,2")
3324                  (const_string "fmov")
3325                (eq_attr "alternative" "3,4")
3326                  (const_string "imov")
3327                (eq_attr "alternative" "5")
3328                  (const_string "sselog1")
3329                (eq_attr "alternative" "11,12,13,14,15")
3330                  (const_string "mmxmov")
3331               ]
3332               (const_string "ssemov")))
3333    (set (attr "prefix")
3334      (if_then_else (eq_attr "type" "sselog1,ssemov")
3335        (const_string "maybe_vex")
3336        (const_string "orig")))
3337    (set (attr "prefix_data16")
3338      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3339        (const_string "1")
3340        (const_string "*")))
3341    (set (attr "mode")
3342         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3343                  (const_string "SI")
3344                (eq_attr "alternative" "11")
3345                  (const_string "DI")
3346                (eq_attr "alternative" "5")
3347                  (cond [(not (match_test "TARGET_SSE2"))
3348                           (const_string "V4SF")
3349                         (match_test "TARGET_AVX512F")
3350                           (const_string "V16SF")
3351                         (match_test "TARGET_AVX")
3352                           (const_string "V4SF")
3353                         (match_test "optimize_function_for_size_p (cfun)")
3354                           (const_string "V4SF")
3355                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3356                           (const_string "TI")
3357                        ]
3358                        (const_string "V4SF"))
3360                /* For architectures resolving dependencies on
3361                   whole SSE registers use APS move to break dependency
3362                   chains, otherwise use short move to avoid extra work.
3364                   Do the same for architectures resolving dependencies on
3365                   the parts.  While in DF mode it is better to always handle
3366                   just register parts, the SF mode is different due to lack
3367                   of instructions to load just part of the register.  It is
3368                   better to maintain the whole registers in single format
3369                   to avoid problems on using packed logical operations.  */
3370                (eq_attr "alternative" "6")
3371                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3372                               (match_operand 1 "ext_sse_reg_operand"))
3373                           (const_string "V16SF")
3374                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3375                              (match_test "TARGET_SSE_SPLIT_REGS"))
3376                           (const_string "V4SF")
3377                        ]
3378                        (const_string "SF"))
3379               ]
3380               (const_string "SF")))])
3382 (define_split
3383   [(set (match_operand 0 "any_fp_register_operand")
3384         (match_operand 1 "memory_operand"))]
3385   "reload_completed
3386    && (GET_MODE (operands[0]) == TFmode
3387        || GET_MODE (operands[0]) == XFmode
3388        || GET_MODE (operands[0]) == DFmode
3389        || GET_MODE (operands[0]) == SFmode)
3390    && (operands[2] = find_constant_src (insn))"
3391   [(set (match_dup 0) (match_dup 2))]
3393   rtx c = operands[2];
3394   int r = REGNO (operands[0]);
3396   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3397       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3398     FAIL;
3401 (define_split
3402   [(set (match_operand 0 "any_fp_register_operand")
3403         (float_extend (match_operand 1 "memory_operand")))]
3404   "reload_completed
3405    && (GET_MODE (operands[0]) == TFmode
3406        || GET_MODE (operands[0]) == XFmode
3407        || GET_MODE (operands[0]) == DFmode)
3408    && (operands[2] = find_constant_src (insn))"
3409   [(set (match_dup 0) (match_dup 2))]
3411   rtx c = operands[2];
3412   int r = REGNO (operands[0]);
3414   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3415       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3416     FAIL;
3419 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3420 (define_split
3421   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3422         (match_operand:X87MODEF 1 "immediate_operand"))]
3423   "reload_completed
3424    && (standard_80387_constant_p (operands[1]) == 8
3425        || standard_80387_constant_p (operands[1]) == 9)"
3426   [(set (match_dup 0)(match_dup 1))
3427    (set (match_dup 0)
3428         (neg:X87MODEF (match_dup 0)))]
3430   REAL_VALUE_TYPE r;
3432   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3433   if (real_isnegzero (&r))
3434     operands[1] = CONST0_RTX (<MODE>mode);
3435   else
3436     operands[1] = CONST1_RTX (<MODE>mode);
3439 (define_split
3440   [(set (match_operand 0 "nonimmediate_operand")
3441         (match_operand 1 "general_operand"))]
3442   "reload_completed
3443    && (GET_MODE (operands[0]) == TFmode
3444        || GET_MODE (operands[0]) == XFmode
3445        || GET_MODE (operands[0]) == DFmode)
3446    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3447   [(const_int 0)]
3448   "ix86_split_long_move (operands); DONE;")
3450 (define_insn "swapxf"
3451   [(set (match_operand:XF 0 "register_operand" "+f")
3452         (match_operand:XF 1 "register_operand" "+f"))
3453    (set (match_dup 1)
3454         (match_dup 0))]
3455   "TARGET_80387"
3457   if (STACK_TOP_P (operands[0]))
3458     return "fxch\t%1";
3459   else
3460     return "fxch\t%0";
3462   [(set_attr "type" "fxch")
3463    (set_attr "mode" "XF")])
3465 (define_insn "*swap<mode>"
3466   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3467         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3468    (set (match_dup 1)
3469         (match_dup 0))]
3470   "TARGET_80387 || reload_completed"
3472   if (STACK_TOP_P (operands[0]))
3473     return "fxch\t%1";
3474   else
3475     return "fxch\t%0";
3477   [(set_attr "type" "fxch")
3478    (set_attr "mode" "<MODE>")])
3480 ;; Zero extension instructions
3482 (define_expand "zero_extendsidi2"
3483   [(set (match_operand:DI 0 "nonimmediate_operand")
3484         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3486 (define_insn "*zero_extendsidi2"
3487   [(set (match_operand:DI 0 "nonimmediate_operand"
3488                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3489         (zero_extend:DI
3490          (match_operand:SI 1 "x86_64_zext_operand"
3491                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3492   ""
3494   switch (get_attr_type (insn))
3495     {
3496     case TYPE_IMOVX:
3497       if (ix86_use_lea_for_mov (insn, operands))
3498         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3499       else
3500         return "mov{l}\t{%1, %k0|%k0, %1}";
3502     case TYPE_MULTI:
3503       return "#";
3505     case TYPE_MMXMOV:
3506       return "movd\t{%1, %0|%0, %1}";
3508     case TYPE_SSELOG1:
3509       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3511     case TYPE_SSEMOV:
3512       if (GENERAL_REG_P (operands[0]))
3513         return "%vmovd\t{%1, %k0|%k0, %1}";
3515       return "%vmovd\t{%1, %0|%0, %1}";
3517     default:
3518       gcc_unreachable ();
3519     }
3521   [(set (attr "isa")
3522      (cond [(eq_attr "alternative" "0,1,2")
3523               (const_string "nox64")
3524             (eq_attr "alternative" "3,7")
3525               (const_string "x64")
3526             (eq_attr "alternative" "8")
3527               (const_string "x64_sse4")
3528             (eq_attr "alternative" "10")
3529               (const_string "sse2")
3530            ]
3531            (const_string "*")))
3532    (set (attr "type")
3533      (cond [(eq_attr "alternative" "0,1,2,4")
3534               (const_string "multi")
3535             (eq_attr "alternative" "5,6")
3536               (const_string "mmxmov")
3537             (eq_attr "alternative" "7,9,10")
3538               (const_string "ssemov")
3539             (eq_attr "alternative" "8")
3540               (const_string "sselog1")
3541            ]
3542            (const_string "imovx")))
3543    (set (attr "prefix_extra")
3544      (if_then_else (eq_attr "alternative" "8")
3545        (const_string "1")
3546        (const_string "*")))
3547    (set (attr "length_immediate")
3548      (if_then_else (eq_attr "alternative" "8")
3549        (const_string "1")
3550        (const_string "*")))
3551    (set (attr "prefix")
3552      (if_then_else (eq_attr "type" "ssemov,sselog1")
3553        (const_string "maybe_vex")
3554        (const_string "orig")))
3555    (set (attr "prefix_0f")
3556      (if_then_else (eq_attr "type" "imovx")
3557        (const_string "0")
3558        (const_string "*")))
3559    (set (attr "mode")
3560      (cond [(eq_attr "alternative" "5,6")
3561               (const_string "DI")
3562             (eq_attr "alternative" "7,8,9")
3563               (const_string "TI")
3564            ]
3565            (const_string "SI")))])
3567 (define_split
3568   [(set (match_operand:DI 0 "memory_operand")
3569         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3570   "reload_completed"
3571   [(set (match_dup 4) (const_int 0))]
3572   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3574 (define_split
3575   [(set (match_operand:DI 0 "register_operand")
3576         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3577   "!TARGET_64BIT && reload_completed
3578    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3579    && true_regnum (operands[0]) == true_regnum (operands[1])"
3580   [(set (match_dup 4) (const_int 0))]
3581   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3583 (define_split
3584   [(set (match_operand:DI 0 "nonimmediate_operand")
3585         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3586   "!TARGET_64BIT && reload_completed
3587    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3588    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3589   [(set (match_dup 3) (match_dup 1))
3590    (set (match_dup 4) (const_int 0))]
3591   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3593 (define_insn "zero_extend<mode>di2"
3594   [(set (match_operand:DI 0 "register_operand" "=r")
3595         (zero_extend:DI
3596          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3597   "TARGET_64BIT"
3598   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3599   [(set_attr "type" "imovx")
3600    (set_attr "mode" "SI")])
3602 (define_expand "zero_extend<mode>si2"
3603   [(set (match_operand:SI 0 "register_operand")
3604         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3605   ""
3607   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3608     {
3609       operands[1] = force_reg (<MODE>mode, operands[1]);
3610       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3611       DONE;
3612     }
3615 (define_insn_and_split "zero_extend<mode>si2_and"
3616   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3617         (zero_extend:SI
3618           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3619    (clobber (reg:CC FLAGS_REG))]
3620   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3621   "#"
3622   "&& reload_completed"
3623   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3624               (clobber (reg:CC FLAGS_REG))])]
3626   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3627     {
3628       ix86_expand_clear (operands[0]);
3630       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3631       emit_insn (gen_movstrict<mode>
3632                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3633       DONE;
3634     }
3636   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3638   [(set_attr "type" "alu1")
3639    (set_attr "mode" "SI")])
3641 (define_insn "*zero_extend<mode>si2"
3642   [(set (match_operand:SI 0 "register_operand" "=r")
3643         (zero_extend:SI
3644           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3645   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3646   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3647   [(set_attr "type" "imovx")
3648    (set_attr "mode" "SI")])
3650 (define_expand "zero_extendqihi2"
3651   [(set (match_operand:HI 0 "register_operand")
3652         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3653   ""
3655   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3656     {
3657       operands[1] = force_reg (QImode, operands[1]);
3658       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3659       DONE;
3660     }
3663 (define_insn_and_split "zero_extendqihi2_and"
3664   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3665         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3666    (clobber (reg:CC FLAGS_REG))]
3667   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3668   "#"
3669   "&& reload_completed"
3670   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3671               (clobber (reg:CC FLAGS_REG))])]
3673   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3674     {
3675       ix86_expand_clear (operands[0]);
3677       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3678       emit_insn (gen_movstrictqi
3679                   (gen_lowpart (QImode, operands[0]), operands[1]));
3680       DONE;
3681     }
3683   operands[0] = gen_lowpart (SImode, operands[0]);
3685   [(set_attr "type" "alu1")
3686    (set_attr "mode" "SI")])
3688 ; zero extend to SImode to avoid partial register stalls
3689 (define_insn "*zero_extendqihi2"
3690   [(set (match_operand:HI 0 "register_operand" "=r")
3691         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3692   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3693   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3694   [(set_attr "type" "imovx")
3695    (set_attr "mode" "SI")])
3697 ;; Sign extension instructions
3699 (define_expand "extendsidi2"
3700   [(set (match_operand:DI 0 "register_operand")
3701         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3702   ""
3704   if (!TARGET_64BIT)
3705     {
3706       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3707       DONE;
3708     }
3711 (define_insn "*extendsidi2_rex64"
3712   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3713         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3714   "TARGET_64BIT"
3715   "@
3716    {cltq|cdqe}
3717    movs{lq|x}\t{%1, %0|%0, %1}"
3718   [(set_attr "type" "imovx")
3719    (set_attr "mode" "DI")
3720    (set_attr "prefix_0f" "0")
3721    (set_attr "modrm" "0,1")])
3723 (define_insn "extendsidi2_1"
3724   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3725         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3726    (clobber (reg:CC FLAGS_REG))
3727    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3728   "!TARGET_64BIT"
3729   "#")
3731 ;; Split the memory case.  If the source register doesn't die, it will stay
3732 ;; this way, if it does die, following peephole2s take care of it.
3733 (define_split
3734   [(set (match_operand:DI 0 "memory_operand")
3735         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3736    (clobber (reg:CC FLAGS_REG))
3737    (clobber (match_operand:SI 2 "register_operand"))]
3738   "reload_completed"
3739   [(const_int 0)]
3741   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3743   emit_move_insn (operands[3], operands[1]);
3745   /* Generate a cltd if possible and doing so it profitable.  */
3746   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3747       && true_regnum (operands[1]) == AX_REG
3748       && true_regnum (operands[2]) == DX_REG)
3749     {
3750       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3751     }
3752   else
3753     {
3754       emit_move_insn (operands[2], operands[1]);
3755       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3756     }
3757   emit_move_insn (operands[4], operands[2]);
3758   DONE;
3761 ;; Peepholes for the case where the source register does die, after
3762 ;; being split with the above splitter.
3763 (define_peephole2
3764   [(set (match_operand:SI 0 "memory_operand")
3765         (match_operand:SI 1 "register_operand"))
3766    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3767    (parallel [(set (match_dup 2)
3768                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3769                (clobber (reg:CC FLAGS_REG))])
3770    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3771   "REGNO (operands[1]) != REGNO (operands[2])
3772    && peep2_reg_dead_p (2, operands[1])
3773    && peep2_reg_dead_p (4, operands[2])
3774    && !reg_mentioned_p (operands[2], operands[3])"
3775   [(set (match_dup 0) (match_dup 1))
3776    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3777               (clobber (reg:CC FLAGS_REG))])
3778    (set (match_dup 3) (match_dup 1))])
3780 (define_peephole2
3781   [(set (match_operand:SI 0 "memory_operand")
3782         (match_operand:SI 1 "register_operand"))
3783    (parallel [(set (match_operand:SI 2 "register_operand")
3784                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3785                (clobber (reg:CC FLAGS_REG))])
3786    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3787   "/* cltd is shorter than sarl $31, %eax */
3788    !optimize_function_for_size_p (cfun)
3789    && true_regnum (operands[1]) == AX_REG
3790    && true_regnum (operands[2]) == DX_REG
3791    && peep2_reg_dead_p (2, operands[1])
3792    && peep2_reg_dead_p (3, operands[2])
3793    && !reg_mentioned_p (operands[2], operands[3])"
3794   [(set (match_dup 0) (match_dup 1))
3795    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3796               (clobber (reg:CC FLAGS_REG))])
3797    (set (match_dup 3) (match_dup 1))])
3799 ;; Extend to register case.  Optimize case where source and destination
3800 ;; registers match and cases where we can use cltd.
3801 (define_split
3802   [(set (match_operand:DI 0 "register_operand")
3803         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3804    (clobber (reg:CC FLAGS_REG))
3805    (clobber (match_scratch:SI 2))]
3806   "reload_completed"
3807   [(const_int 0)]
3809   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3811   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3812     emit_move_insn (operands[3], operands[1]);
3814   /* Generate a cltd if possible and doing so it profitable.  */
3815   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3816       && true_regnum (operands[3]) == AX_REG
3817       && true_regnum (operands[4]) == DX_REG)
3818     {
3819       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3820       DONE;
3821     }
3823   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3824     emit_move_insn (operands[4], operands[1]);
3826   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3827   DONE;
3830 (define_insn "extend<mode>di2"
3831   [(set (match_operand:DI 0 "register_operand" "=r")
3832         (sign_extend:DI
3833          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3834   "TARGET_64BIT"
3835   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3836   [(set_attr "type" "imovx")
3837    (set_attr "mode" "DI")])
3839 (define_insn "extendhisi2"
3840   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3842   ""
3844   switch (get_attr_prefix_0f (insn))
3845     {
3846     case 0:
3847       return "{cwtl|cwde}";
3848     default:
3849       return "movs{wl|x}\t{%1, %0|%0, %1}";
3850     }
3852   [(set_attr "type" "imovx")
3853    (set_attr "mode" "SI")
3854    (set (attr "prefix_0f")
3855      ;; movsx is short decodable while cwtl is vector decoded.
3856      (if_then_else (and (eq_attr "cpu" "!k6")
3857                         (eq_attr "alternative" "0"))
3858         (const_string "0")
3859         (const_string "1")))
3860    (set (attr "modrm")
3861      (if_then_else (eq_attr "prefix_0f" "0")
3862         (const_string "0")
3863         (const_string "1")))])
3865 (define_insn "*extendhisi2_zext"
3866   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3867         (zero_extend:DI
3868          (sign_extend:SI
3869           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3870   "TARGET_64BIT"
3872   switch (get_attr_prefix_0f (insn))
3873     {
3874     case 0:
3875       return "{cwtl|cwde}";
3876     default:
3877       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3878     }
3880   [(set_attr "type" "imovx")
3881    (set_attr "mode" "SI")
3882    (set (attr "prefix_0f")
3883      ;; movsx is short decodable while cwtl is vector decoded.
3884      (if_then_else (and (eq_attr "cpu" "!k6")
3885                         (eq_attr "alternative" "0"))
3886         (const_string "0")
3887         (const_string "1")))
3888    (set (attr "modrm")
3889      (if_then_else (eq_attr "prefix_0f" "0")
3890         (const_string "0")
3891         (const_string "1")))])
3893 (define_insn "extendqisi2"
3894   [(set (match_operand:SI 0 "register_operand" "=r")
3895         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3896   ""
3897   "movs{bl|x}\t{%1, %0|%0, %1}"
3898    [(set_attr "type" "imovx")
3899     (set_attr "mode" "SI")])
3901 (define_insn "*extendqisi2_zext"
3902   [(set (match_operand:DI 0 "register_operand" "=r")
3903         (zero_extend:DI
3904           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3905   "TARGET_64BIT"
3906   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3907    [(set_attr "type" "imovx")
3908     (set_attr "mode" "SI")])
3910 (define_insn "extendqihi2"
3911   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3912         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3913   ""
3915   switch (get_attr_prefix_0f (insn))
3916     {
3917     case 0:
3918       return "{cbtw|cbw}";
3919     default:
3920       return "movs{bw|x}\t{%1, %0|%0, %1}";
3921     }
3923   [(set_attr "type" "imovx")
3924    (set_attr "mode" "HI")
3925    (set (attr "prefix_0f")
3926      ;; movsx is short decodable while cwtl is vector decoded.
3927      (if_then_else (and (eq_attr "cpu" "!k6")
3928                         (eq_attr "alternative" "0"))
3929         (const_string "0")
3930         (const_string "1")))
3931    (set (attr "modrm")
3932      (if_then_else (eq_attr "prefix_0f" "0")
3933         (const_string "0")
3934         (const_string "1")))])
3936 ;; Conversions between float and double.
3938 ;; These are all no-ops in the model used for the 80387.
3939 ;; So just emit moves.
3941 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3942 (define_split
3943   [(set (match_operand:DF 0 "push_operand")
3944         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3945   "reload_completed"
3946   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3947    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3949 (define_split
3950   [(set (match_operand:XF 0 "push_operand")
3951         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3952   "reload_completed"
3953   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3954    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3955   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3957 (define_expand "extendsfdf2"
3958   [(set (match_operand:DF 0 "nonimmediate_operand")
3959         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3960   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3962   /* ??? Needed for compress_float_constant since all fp constants
3963      are TARGET_LEGITIMATE_CONSTANT_P.  */
3964   if (CONST_DOUBLE_P (operands[1]))
3965     {
3966       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3967           && standard_80387_constant_p (operands[1]) > 0)
3968         {
3969           operands[1] = simplify_const_unary_operation
3970             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3971           emit_move_insn_1 (operands[0], operands[1]);
3972           DONE;
3973         }
3974       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3975     }
3978 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3979    cvtss2sd:
3980       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3981       cvtps2pd xmm2,xmm1
3982    We do the conversion post reload to avoid producing of 128bit spills
3983    that might lead to ICE on 32bit target.  The sequence unlikely combine
3984    anyway.  */
3985 (define_split
3986   [(set (match_operand:DF 0 "register_operand")
3987         (float_extend:DF
3988           (match_operand:SF 1 "nonimmediate_operand")))]
3989   "TARGET_USE_VECTOR_FP_CONVERTS
3990    && optimize_insn_for_speed_p ()
3991    && reload_completed && SSE_REG_P (operands[0])
3992    && (!EXT_REX_SSE_REG_P (operands[0])
3993        || TARGET_AVX512VL)"
3994    [(set (match_dup 2)
3995          (float_extend:V2DF
3996            (vec_select:V2SF
3997              (match_dup 3)
3998              (parallel [(const_int 0) (const_int 1)]))))]
4000   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4001   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4002   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4003      Try to avoid move when unpacking can be done in source.  */
4004   if (REG_P (operands[1]))
4005     {
4006       /* If it is unsafe to overwrite upper half of source, we need
4007          to move to destination and unpack there.  */
4008       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4009            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4010           && true_regnum (operands[0]) != true_regnum (operands[1]))
4011         {
4012           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4013           emit_move_insn (tmp, operands[1]);
4014         }
4015       else
4016         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4017       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4018                                              operands[3]));
4019     }
4020   else
4021     emit_insn (gen_vec_setv4sf_0 (operands[3],
4022                                   CONST0_RTX (V4SFmode), operands[1]));
4025 ;; It's more profitable to split and then extend in the same register.
4026 (define_peephole2
4027   [(set (match_operand:DF 0 "register_operand")
4028         (float_extend:DF
4029           (match_operand:SF 1 "memory_operand")))]
4030   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4031    && optimize_insn_for_speed_p ()
4032    && SSE_REG_P (operands[0])"
4033   [(set (match_dup 2) (match_dup 1))
4034    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4035   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4037 (define_insn "*extendsfdf2_mixed"
4038   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4039         (float_extend:DF
4040           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4041   "TARGET_SSE2 && TARGET_SSE_MATH"
4043   switch (which_alternative)
4044     {
4045     case 0:
4046     case 1:
4047       return output_387_reg_move (insn, operands);
4049     case 2:
4050       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4052     default:
4053       gcc_unreachable ();
4054     }
4056   [(set_attr "type" "fmov,fmov,ssecvt")
4057    (set_attr "prefix" "orig,orig,maybe_vex")
4058    (set_attr "mode" "SF,XF,DF")
4059    (set (attr "enabled")
4060      (cond [(eq_attr "alternative" "0,1")
4061               (symbol_ref "TARGET_MIX_SSE_I387")
4062            ]
4063            (symbol_ref "true")))])
4065 (define_insn "*extendsfdf2_i387"
4066   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4067         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4068   "TARGET_80387"
4069   "* return output_387_reg_move (insn, operands);"
4070   [(set_attr "type" "fmov")
4071    (set_attr "mode" "SF,XF")])
4073 (define_expand "extend<mode>xf2"
4074   [(set (match_operand:XF 0 "nonimmediate_operand")
4075         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4076   "TARGET_80387"
4078   /* ??? Needed for compress_float_constant since all fp constants
4079      are TARGET_LEGITIMATE_CONSTANT_P.  */
4080   if (CONST_DOUBLE_P (operands[1]))
4081     {
4082       if (standard_80387_constant_p (operands[1]) > 0)
4083         {
4084           operands[1] = simplify_const_unary_operation
4085             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4086           emit_move_insn_1 (operands[0], operands[1]);
4087           DONE;
4088         }
4089       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4090     }
4093 (define_insn "*extend<mode>xf2_i387"
4094   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4095         (float_extend:XF
4096           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4097   "TARGET_80387"
4098   "* return output_387_reg_move (insn, operands);"
4099   [(set_attr "type" "fmov")
4100    (set_attr "mode" "<MODE>,XF")])
4102 ;; %%% This seems bad bad news.
4103 ;; This cannot output into an f-reg because there is no way to be sure
4104 ;; of truncating in that case.  Otherwise this is just like a simple move
4105 ;; insn.  So we pretend we can output to a reg in order to get better
4106 ;; register preferencing, but we really use a stack slot.
4108 ;; Conversion from DFmode to SFmode.
4110 (define_expand "truncdfsf2"
4111   [(set (match_operand:SF 0 "nonimmediate_operand")
4112         (float_truncate:SF
4113           (match_operand:DF 1 "nonimmediate_operand")))]
4114   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4116   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4117     ;
4118   else if (flag_unsafe_math_optimizations)
4119     ;
4120   else
4121     {
4122       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4123       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4124       DONE;
4125     }
4128 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4129    cvtsd2ss:
4130       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4131       cvtpd2ps xmm2,xmm1
4132    We do the conversion post reload to avoid producing of 128bit spills
4133    that might lead to ICE on 32bit target.  The sequence unlikely combine
4134    anyway.  */
4135 (define_split
4136   [(set (match_operand:SF 0 "register_operand")
4137         (float_truncate:SF
4138           (match_operand:DF 1 "nonimmediate_operand")))]
4139   "TARGET_USE_VECTOR_FP_CONVERTS
4140    && optimize_insn_for_speed_p ()
4141    && reload_completed && SSE_REG_P (operands[0])
4142    && (!EXT_REX_SSE_REG_P (operands[0])
4143        || TARGET_AVX512VL)"
4144    [(set (match_dup 2)
4145          (vec_concat:V4SF
4146            (float_truncate:V2SF
4147              (match_dup 4))
4148            (match_dup 3)))]
4150   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4151   operands[3] = CONST0_RTX (V2SFmode);
4152   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4153   /* Use movsd for loading from memory, unpcklpd for registers.
4154      Try to avoid move when unpacking can be done in source, or SSE3
4155      movddup is available.  */
4156   if (REG_P (operands[1]))
4157     {
4158       if (!TARGET_SSE3
4159           && true_regnum (operands[0]) != true_regnum (operands[1])
4160           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4161               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4162         {
4163           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4164           emit_move_insn (tmp, operands[1]);
4165           operands[1] = tmp;
4166         }
4167       else if (!TARGET_SSE3)
4168         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4169       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4170     }
4171   else
4172     emit_insn (gen_sse2_loadlpd (operands[4],
4173                                  CONST0_RTX (V2DFmode), operands[1]));
4176 ;; It's more profitable to split and then extend in the same register.
4177 (define_peephole2
4178   [(set (match_operand:SF 0 "register_operand")
4179         (float_truncate:SF
4180           (match_operand:DF 1 "memory_operand")))]
4181   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4182    && optimize_insn_for_speed_p ()
4183    && SSE_REG_P (operands[0])"
4184   [(set (match_dup 2) (match_dup 1))
4185    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4186   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4188 (define_expand "truncdfsf2_with_temp"
4189   [(parallel [(set (match_operand:SF 0)
4190                    (float_truncate:SF (match_operand:DF 1)))
4191               (clobber (match_operand:SF 2))])])
4193 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4194 ;; because nothing we do there is unsafe.
4195 (define_insn "*truncdfsf_fast_mixed"
4196   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4197         (float_truncate:SF
4198           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4199   "TARGET_SSE2 && TARGET_SSE_MATH"
4201   switch (which_alternative)
4202     {
4203     case 0:
4204       return output_387_reg_move (insn, operands);
4205     case 1:
4206       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4207     default:
4208       gcc_unreachable ();
4209     }
4211   [(set_attr "type" "fmov,ssecvt")
4212    (set_attr "prefix" "orig,maybe_vex")
4213    (set_attr "mode" "SF")
4214    (set (attr "enabled")
4215      (cond [(eq_attr "alternative" "0")
4216               (symbol_ref "TARGET_MIX_SSE_I387
4217                            && flag_unsafe_math_optimizations")
4218            ]
4219            (symbol_ref "true")))])
4221 (define_insn "*truncdfsf_fast_i387"
4222   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4223         (float_truncate:SF
4224           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4225   "TARGET_80387 && flag_unsafe_math_optimizations"
4226   "* return output_387_reg_move (insn, operands);"
4227   [(set_attr "type" "fmov")
4228    (set_attr "mode" "SF")])
4230 (define_insn "*truncdfsf_mixed"
4231   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4232         (float_truncate:SF
4233           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4234    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4235   "TARGET_MIX_SSE_I387"
4237   switch (which_alternative)
4238     {
4239     case 0:
4240       return output_387_reg_move (insn, operands);
4241     case 1:
4242       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4244     default:
4245       return "#";
4246     }
4248   [(set_attr "isa" "*,sse2,*,*,*")
4249    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4250    (set_attr "unit" "*,*,i387,i387,i387")
4251    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4252    (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_i387"
4255   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4256         (float_truncate:SF
4257           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4258    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4259   "TARGET_80387"
4261   switch (which_alternative)
4262     {
4263     case 0:
4264       return output_387_reg_move (insn, operands);
4266     default:
4267       return "#";
4268     }
4270   [(set_attr "type" "fmov,multi,multi,multi")
4271    (set_attr "unit" "*,i387,i387,i387")
4272    (set_attr "mode" "SF")])
4274 (define_insn "*truncdfsf2_i387_1"
4275   [(set (match_operand:SF 0 "memory_operand" "=m")
4276         (float_truncate:SF
4277           (match_operand:DF 1 "register_operand" "f")))]
4278   "TARGET_80387
4279    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4280    && !TARGET_MIX_SSE_I387"
4281   "* return output_387_reg_move (insn, operands);"
4282   [(set_attr "type" "fmov")
4283    (set_attr "mode" "SF")])
4285 (define_split
4286   [(set (match_operand:SF 0 "register_operand")
4287         (float_truncate:SF
4288          (match_operand:DF 1 "fp_register_operand")))
4289    (clobber (match_operand 2))]
4290   "reload_completed"
4291   [(set (match_dup 2) (match_dup 1))
4292    (set (match_dup 0) (match_dup 2))]
4293   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4295 ;; Conversion from XFmode to {SF,DF}mode
4297 (define_expand "truncxf<mode>2"
4298   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4299                    (float_truncate:MODEF
4300                      (match_operand:XF 1 "register_operand")))
4301               (clobber (match_dup 2))])]
4302   "TARGET_80387"
4304   if (flag_unsafe_math_optimizations)
4305     {
4306       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4307       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4308       if (reg != operands[0])
4309         emit_move_insn (operands[0], reg);
4310       DONE;
4311     }
4312   else
4313     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4316 (define_insn "*truncxfsf2_mixed"
4317   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4318         (float_truncate:SF
4319           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4320    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4321   "TARGET_80387"
4323   gcc_assert (!which_alternative);
4324   return output_387_reg_move (insn, operands);
4326   [(set_attr "type" "fmov,multi,multi,multi")
4327    (set_attr "unit" "*,i387,i387,i387")
4328    (set_attr "mode" "SF")])
4330 (define_insn "*truncxfdf2_mixed"
4331   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4332         (float_truncate:DF
4333           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4334    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4335   "TARGET_80387"
4337   gcc_assert (!which_alternative);
4338   return output_387_reg_move (insn, operands);
4340   [(set_attr "isa" "*,*,sse2,*")
4341    (set_attr "type" "fmov,multi,multi,multi")
4342    (set_attr "unit" "*,i387,i387,i387")
4343    (set_attr "mode" "DF")])
4345 (define_insn "truncxf<mode>2_i387_noop"
4346   [(set (match_operand:MODEF 0 "register_operand" "=f")
4347         (float_truncate:MODEF
4348           (match_operand:XF 1 "register_operand" "f")))]
4349   "TARGET_80387 && flag_unsafe_math_optimizations"
4350   "* return output_387_reg_move (insn, operands);"
4351   [(set_attr "type" "fmov")
4352    (set_attr "mode" "<MODE>")])
4354 (define_insn "*truncxf<mode>2_i387"
4355   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4356         (float_truncate:MODEF
4357           (match_operand:XF 1 "register_operand" "f")))]
4358   "TARGET_80387"
4359   "* return output_387_reg_move (insn, operands);"
4360   [(set_attr "type" "fmov")
4361    (set_attr "mode" "<MODE>")])
4363 (define_split
4364   [(set (match_operand:MODEF 0 "register_operand")
4365         (float_truncate:MODEF
4366           (match_operand:XF 1 "register_operand")))
4367    (clobber (match_operand:MODEF 2 "memory_operand"))]
4368   "TARGET_80387 && reload_completed"
4369   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4370    (set (match_dup 0) (match_dup 2))])
4372 (define_split
4373   [(set (match_operand:MODEF 0 "memory_operand")
4374         (float_truncate:MODEF
4375           (match_operand:XF 1 "register_operand")))
4376    (clobber (match_operand:MODEF 2 "memory_operand"))]
4377   "TARGET_80387"
4378   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4380 ;; Signed conversion to DImode.
4382 (define_expand "fix_truncxfdi2"
4383   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4384                    (fix:DI (match_operand:XF 1 "register_operand")))
4385               (clobber (reg:CC FLAGS_REG))])]
4386   "TARGET_80387"
4388   if (TARGET_FISTTP)
4389    {
4390      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4391      DONE;
4392    }
4395 (define_expand "fix_trunc<mode>di2"
4396   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4397                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4398               (clobber (reg:CC FLAGS_REG))])]
4399   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4401   if (TARGET_FISTTP
4402       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4403    {
4404      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4405      DONE;
4406    }
4407   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4408    {
4409      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4410      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4411      if (out != operands[0])
4412         emit_move_insn (operands[0], out);
4413      DONE;
4414    }
4417 ;; Signed conversion to SImode.
4419 (define_expand "fix_truncxfsi2"
4420   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4421                    (fix:SI (match_operand:XF 1 "register_operand")))
4422               (clobber (reg:CC FLAGS_REG))])]
4423   "TARGET_80387"
4425   if (TARGET_FISTTP)
4426    {
4427      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4428      DONE;
4429    }
4432 (define_expand "fix_trunc<mode>si2"
4433   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4434                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4435               (clobber (reg:CC FLAGS_REG))])]
4436   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4438   if (TARGET_FISTTP
4439       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4440    {
4441      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4442      DONE;
4443    }
4444   if (SSE_FLOAT_MODE_P (<MODE>mode))
4445    {
4446      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4447      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4448      if (out != operands[0])
4449         emit_move_insn (operands[0], out);
4450      DONE;
4451    }
4454 ;; Signed conversion to HImode.
4456 (define_expand "fix_trunc<mode>hi2"
4457   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4458                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4459               (clobber (reg:CC FLAGS_REG))])]
4460   "TARGET_80387
4461    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4463   if (TARGET_FISTTP)
4464    {
4465      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4466      DONE;
4467    }
4470 ;; Unsigned conversion to SImode.
4472 (define_expand "fixuns_trunc<mode>si2"
4473   [(parallel
4474     [(set (match_operand:SI 0 "register_operand")
4475           (unsigned_fix:SI
4476             (match_operand:MODEF 1 "nonimmediate_operand")))
4477      (use (match_dup 2))
4478      (clobber (match_scratch:<ssevecmode> 3))
4479      (clobber (match_scratch:<ssevecmode> 4))])]
4480   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4482   machine_mode mode = <MODE>mode;
4483   machine_mode vecmode = <ssevecmode>mode;
4484   REAL_VALUE_TYPE TWO31r;
4485   rtx two31;
4487   if (optimize_insn_for_size_p ())
4488     FAIL;
4490   real_ldexp (&TWO31r, &dconst1, 31);
4491   two31 = const_double_from_real_value (TWO31r, mode);
4492   two31 = ix86_build_const_vector (vecmode, true, two31);
4493   operands[2] = force_reg (vecmode, two31);
4496 (define_insn_and_split "*fixuns_trunc<mode>_1"
4497   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4498         (unsigned_fix:SI
4499           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4500    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4501    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4502    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4503   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4504    && optimize_function_for_speed_p (cfun)"
4505   "#"
4506   "&& reload_completed"
4507   [(const_int 0)]
4509   ix86_split_convert_uns_si_sse (operands);
4510   DONE;
4513 ;; Unsigned conversion to HImode.
4514 ;; Without these patterns, we'll try the unsigned SI conversion which
4515 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4517 (define_expand "fixuns_trunc<mode>hi2"
4518   [(set (match_dup 2)
4519         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4520    (set (match_operand:HI 0 "nonimmediate_operand")
4521         (subreg:HI (match_dup 2) 0))]
4522   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4523   "operands[2] = gen_reg_rtx (SImode);")
4525 ;; When SSE is available, it is always faster to use it!
4526 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4527   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4528         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4529   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4530    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4531   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4532   [(set_attr "type" "sseicvt")
4533    (set_attr "prefix" "maybe_vex")
4534    (set (attr "prefix_rex")
4535         (if_then_else
4536           (match_test "<SWI48:MODE>mode == DImode")
4537           (const_string "1")
4538           (const_string "*")))
4539    (set_attr "mode" "<MODEF:MODE>")
4540    (set_attr "athlon_decode" "double,vector")
4541    (set_attr "amdfam10_decode" "double,double")
4542    (set_attr "bdver1_decode" "double,double")])
4544 ;; Avoid vector decoded forms of the instruction.
4545 (define_peephole2
4546   [(match_scratch:MODEF 2 "x")
4547    (set (match_operand:SWI48 0 "register_operand")
4548         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4549   "TARGET_AVOID_VECTOR_DECODE
4550    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4551    && optimize_insn_for_speed_p ()"
4552   [(set (match_dup 2) (match_dup 1))
4553    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4555 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4556   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4557         (fix:SWI248x (match_operand 1 "register_operand")))]
4558   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4559    && TARGET_FISTTP
4560    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561          && (TARGET_64BIT || <MODE>mode != DImode))
4562         && TARGET_SSE_MATH)
4563    && can_create_pseudo_p ()"
4564   "#"
4565   "&& 1"
4566   [(const_int 0)]
4568   if (memory_operand (operands[0], VOIDmode))
4569     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4570   else
4571     {
4572       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4573       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4574                                                             operands[1],
4575                                                             operands[2]));
4576     }
4577   DONE;
4579   [(set_attr "type" "fisttp")
4580    (set_attr "mode" "<MODE>")])
4582 (define_insn "fix_trunc<mode>_i387_fisttp"
4583   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4584         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4585    (clobber (match_scratch:XF 2 "=&1f"))]
4586   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4587    && TARGET_FISTTP
4588    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4589          && (TARGET_64BIT || <MODE>mode != DImode))
4590         && TARGET_SSE_MATH)"
4591   "* return output_fix_trunc (insn, operands, true);"
4592   [(set_attr "type" "fisttp")
4593    (set_attr "mode" "<MODE>")])
4595 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4596   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4597         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4598    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4599    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4600   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601    && TARGET_FISTTP
4602    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4603         && (TARGET_64BIT || <MODE>mode != DImode))
4604         && TARGET_SSE_MATH)"
4605   "#"
4606   [(set_attr "type" "fisttp")
4607    (set_attr "mode" "<MODE>")])
4609 (define_split
4610   [(set (match_operand:SWI248x 0 "register_operand")
4611         (fix:SWI248x (match_operand 1 "register_operand")))
4612    (clobber (match_operand:SWI248x 2 "memory_operand"))
4613    (clobber (match_scratch 3))]
4614   "reload_completed"
4615   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4616               (clobber (match_dup 3))])
4617    (set (match_dup 0) (match_dup 2))])
4619 (define_split
4620   [(set (match_operand:SWI248x 0 "memory_operand")
4621         (fix:SWI248x (match_operand 1 "register_operand")))
4622    (clobber (match_operand:SWI248x 2 "memory_operand"))
4623    (clobber (match_scratch 3))]
4624   "reload_completed"
4625   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4626               (clobber (match_dup 3))])])
4628 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4629 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4630 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4631 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4632 ;; function in i386.c.
4633 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4634   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4635         (fix:SWI248x (match_operand 1 "register_operand")))
4636    (clobber (reg:CC FLAGS_REG))]
4637   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638    && !TARGET_FISTTP
4639    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4640          && (TARGET_64BIT || <MODE>mode != DImode))
4641    && can_create_pseudo_p ()"
4642   "#"
4643   "&& 1"
4644   [(const_int 0)]
4646   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4648   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4649   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4650   if (memory_operand (operands[0], VOIDmode))
4651     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4652                                          operands[2], operands[3]));
4653   else
4654     {
4655       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4656       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4657                                                      operands[2], operands[3],
4658                                                      operands[4]));
4659     }
4660   DONE;
4662   [(set_attr "type" "fistp")
4663    (set_attr "i387_cw" "trunc")
4664    (set_attr "mode" "<MODE>")])
4666 (define_insn "fix_truncdi_i387"
4667   [(set (match_operand:DI 0 "memory_operand" "=m")
4668         (fix:DI (match_operand 1 "register_operand" "f")))
4669    (use (match_operand:HI 2 "memory_operand" "m"))
4670    (use (match_operand:HI 3 "memory_operand" "m"))
4671    (clobber (match_scratch:XF 4 "=&1f"))]
4672   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673    && !TARGET_FISTTP
4674    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4675   "* return output_fix_trunc (insn, operands, false);"
4676   [(set_attr "type" "fistp")
4677    (set_attr "i387_cw" "trunc")
4678    (set_attr "mode" "DI")])
4680 (define_insn "fix_truncdi_i387_with_temp"
4681   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4682         (fix:DI (match_operand 1 "register_operand" "f,f")))
4683    (use (match_operand:HI 2 "memory_operand" "m,m"))
4684    (use (match_operand:HI 3 "memory_operand" "m,m"))
4685    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4686    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4687   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4688    && !TARGET_FISTTP
4689    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4690   "#"
4691   [(set_attr "type" "fistp")
4692    (set_attr "i387_cw" "trunc")
4693    (set_attr "mode" "DI")])
4695 (define_split
4696   [(set (match_operand:DI 0 "register_operand")
4697         (fix:DI (match_operand 1 "register_operand")))
4698    (use (match_operand:HI 2 "memory_operand"))
4699    (use (match_operand:HI 3 "memory_operand"))
4700    (clobber (match_operand:DI 4 "memory_operand"))
4701    (clobber (match_scratch 5))]
4702   "reload_completed"
4703   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4704               (use (match_dup 2))
4705               (use (match_dup 3))
4706               (clobber (match_dup 5))])
4707    (set (match_dup 0) (match_dup 4))])
4709 (define_split
4710   [(set (match_operand:DI 0 "memory_operand")
4711         (fix:DI (match_operand 1 "register_operand")))
4712    (use (match_operand:HI 2 "memory_operand"))
4713    (use (match_operand:HI 3 "memory_operand"))
4714    (clobber (match_operand:DI 4 "memory_operand"))
4715    (clobber (match_scratch 5))]
4716   "reload_completed"
4717   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4718               (use (match_dup 2))
4719               (use (match_dup 3))
4720               (clobber (match_dup 5))])])
4722 (define_insn "fix_trunc<mode>_i387"
4723   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4724         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4725    (use (match_operand:HI 2 "memory_operand" "m"))
4726    (use (match_operand:HI 3 "memory_operand" "m"))]
4727   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4728    && !TARGET_FISTTP
4729    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4730   "* return output_fix_trunc (insn, operands, false);"
4731   [(set_attr "type" "fistp")
4732    (set_attr "i387_cw" "trunc")
4733    (set_attr "mode" "<MODE>")])
4735 (define_insn "fix_trunc<mode>_i387_with_temp"
4736   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4737         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4738    (use (match_operand:HI 2 "memory_operand" "m,m"))
4739    (use (match_operand:HI 3 "memory_operand" "m,m"))
4740    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4741   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4742    && !TARGET_FISTTP
4743    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4744   "#"
4745   [(set_attr "type" "fistp")
4746    (set_attr "i387_cw" "trunc")
4747    (set_attr "mode" "<MODE>")])
4749 (define_split
4750   [(set (match_operand:SWI24 0 "register_operand")
4751         (fix:SWI24 (match_operand 1 "register_operand")))
4752    (use (match_operand:HI 2 "memory_operand"))
4753    (use (match_operand:HI 3 "memory_operand"))
4754    (clobber (match_operand:SWI24 4 "memory_operand"))]
4755   "reload_completed"
4756   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4757               (use (match_dup 2))
4758               (use (match_dup 3))])
4759    (set (match_dup 0) (match_dup 4))])
4761 (define_split
4762   [(set (match_operand:SWI24 0 "memory_operand")
4763         (fix:SWI24 (match_operand 1 "register_operand")))
4764    (use (match_operand:HI 2 "memory_operand"))
4765    (use (match_operand:HI 3 "memory_operand"))
4766    (clobber (match_operand:SWI24 4 "memory_operand"))]
4767   "reload_completed"
4768   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4769               (use (match_dup 2))
4770               (use (match_dup 3))])])
4772 (define_insn "x86_fnstcw_1"
4773   [(set (match_operand:HI 0 "memory_operand" "=m")
4774         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4775   "TARGET_80387"
4776   "fnstcw\t%0"
4777   [(set (attr "length")
4778         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4779    (set_attr "mode" "HI")
4780    (set_attr "unit" "i387")
4781    (set_attr "bdver1_decode" "vector")])
4783 (define_insn "x86_fldcw_1"
4784   [(set (reg:HI FPCR_REG)
4785         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4786   "TARGET_80387"
4787   "fldcw\t%0"
4788   [(set (attr "length")
4789         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4790    (set_attr "mode" "HI")
4791    (set_attr "unit" "i387")
4792    (set_attr "athlon_decode" "vector")
4793    (set_attr "amdfam10_decode" "vector")
4794    (set_attr "bdver1_decode" "vector")])
4796 ;; Conversion between fixed point and floating point.
4798 ;; Even though we only accept memory inputs, the backend _really_
4799 ;; wants to be able to do this between registers.  Thankfully, LRA
4800 ;; will fix this up for us during register allocation.
4802 (define_insn "floathi<mode>2"
4803   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4804         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4805   "TARGET_80387
4806    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4807        || TARGET_MIX_SSE_I387)"
4808   "fild%Z1\t%1"
4809   [(set_attr "type" "fmov")
4810    (set_attr "mode" "<MODE>")
4811    (set_attr "fp_int_src" "true")])
4813 (define_insn "float<SWI48x:mode>xf2"
4814   [(set (match_operand:XF 0 "register_operand" "=f")
4815         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4816   "TARGET_80387"
4817   "fild%Z1\t%1"
4818   [(set_attr "type" "fmov")
4819    (set_attr "mode" "XF")
4820    (set_attr "fp_int_src" "true")])
4822 (define_expand "float<SWI48:mode><MODEF:mode>2"
4823   [(set (match_operand:MODEF 0 "register_operand")
4824         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4825   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4827   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4828       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4829     {
4830       rtx reg = gen_reg_rtx (XFmode);
4831       rtx (*insn)(rtx, rtx);
4833       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4835       if (<MODEF:MODE>mode == SFmode)
4836         insn = gen_truncxfsf2;
4837       else if (<MODEF:MODE>mode == DFmode)
4838         insn = gen_truncxfdf2;
4839       else
4840         gcc_unreachable ();
4842       emit_insn (insn (operands[0], reg));
4843       DONE;
4844     }
4847 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
4848   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4849         (float:MODEF
4850           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4851   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4852   "@
4853    fild%Z1\t%1
4854    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4855    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4856   [(set_attr "type" "fmov,sseicvt,sseicvt")
4857    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4858    (set_attr "mode" "<MODEF:MODE>")
4859    (set (attr "prefix_rex")
4860      (if_then_else
4861        (and (eq_attr "prefix" "maybe_vex")
4862             (match_test "<SWI48:MODE>mode == DImode"))
4863        (const_string "1")
4864        (const_string "*")))
4865    (set_attr "unit" "i387,*,*")
4866    (set_attr "athlon_decode" "*,double,direct")
4867    (set_attr "amdfam10_decode" "*,vector,double")
4868    (set_attr "bdver1_decode" "*,double,direct")
4869    (set_attr "fp_int_src" "true")
4870    (set (attr "enabled")
4871      (cond [(eq_attr "alternative" "0")
4872               (symbol_ref "TARGET_MIX_SSE_I387
4873                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4874                                                 <SWI48:MODE>mode)")
4875            ]
4876            (symbol_ref "true")))
4877    (set (attr "preferred_for_speed")
4878      (cond [(eq_attr "alternative" "1")
4879               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4880            (symbol_ref "true")))])
4882 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4883   [(set (match_operand:MODEF 0 "register_operand" "=f")
4884         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4885   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4886   "fild%Z1\t%1"
4887   [(set_attr "type" "fmov")
4888    (set_attr "mode" "<MODEF:MODE>")
4889    (set_attr "fp_int_src" "true")])
4891 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4892 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4893 ;; alternative in sse2_loadld.
4894 (define_split
4895   [(set (match_operand:MODEF 0 "register_operand")
4896         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4897   "TARGET_SSE2 && TARGET_SSE_MATH
4898    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4899    && reload_completed && SSE_REG_P (operands[0])
4900    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4901    && (!EXT_REX_SSE_REG_P (operands[0])
4902        || TARGET_AVX512VL)"
4903   [(const_int 0)]
4905   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4906                                      <MODE>mode, 0);
4907   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4909   emit_insn (gen_sse2_loadld (operands[4],
4910                               CONST0_RTX (V4SImode), operands[1]));
4912   if (<ssevecmode>mode == V4SFmode)
4913     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4914   else
4915     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4916   DONE;
4919 ;; Avoid partial SSE register dependency stalls
4920 (define_split
4921   [(set (match_operand:MODEF 0 "register_operand")
4922         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4923   "TARGET_SSE2 && TARGET_SSE_MATH
4924    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4925    && optimize_function_for_speed_p (cfun)
4926    && reload_completed && SSE_REG_P (operands[0])
4927    && (!EXT_REX_SSE_REG_P (operands[0])
4928        || TARGET_AVX512VL)"
4929   [(const_int 0)]
4931   const machine_mode vmode = <MODEF:ssevecmode>mode;
4932   const machine_mode mode = <MODEF:MODE>mode;
4933   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4935   emit_move_insn (op0, CONST0_RTX (vmode));
4937   t = gen_rtx_FLOAT (mode, operands[1]);
4938   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4939   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4940   emit_insn (gen_rtx_SET (op0, t));
4941   DONE;
4944 ;; Break partial reg stall for cvtsd2ss.
4946 (define_peephole2
4947   [(set (match_operand:SF 0 "register_operand")
4948         (float_truncate:SF
4949           (match_operand:DF 1 "nonimmediate_operand")))]
4950   "TARGET_SSE2 && TARGET_SSE_MATH
4951    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4952    && optimize_function_for_speed_p (cfun)
4953    && SSE_REG_P (operands[0])
4954    && (!SSE_REG_P (operands[1])
4955        || REGNO (operands[0]) != REGNO (operands[1]))
4956    && (!EXT_REX_SSE_REG_P (operands[0])
4957        || TARGET_AVX512VL)"
4958   [(set (match_dup 0)
4959         (vec_merge:V4SF
4960           (vec_duplicate:V4SF
4961             (float_truncate:V2SF
4962               (match_dup 1)))
4963           (match_dup 0)
4964           (const_int 1)))]
4966   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4967                                      SFmode, 0);
4968   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4969                                      DFmode, 0);
4970   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4973 ;; Break partial reg stall for cvtss2sd.
4975 (define_peephole2
4976   [(set (match_operand:DF 0 "register_operand")
4977         (float_extend:DF
4978           (match_operand:SF 1 "nonimmediate_operand")))]
4979   "TARGET_SSE2 && TARGET_SSE_MATH
4980    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4981    && optimize_function_for_speed_p (cfun)
4982    && SSE_REG_P (operands[0])
4983    && (!SSE_REG_P (operands[1])
4984        || REGNO (operands[0]) != REGNO (operands[1]))
4985    && (!EXT_REX_SSE_REG_P (operands[0])
4986        || TARGET_AVX512VL)"
4987   [(set (match_dup 0)
4988         (vec_merge:V2DF
4989           (float_extend:V2DF
4990             (vec_select:V2SF
4991               (match_dup 1)
4992               (parallel [(const_int 0) (const_int 1)])))
4993           (match_dup 0)
4994           (const_int 1)))]
4996   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4997                                      DFmode, 0);
4998   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4999                                      SFmode, 0);
5000   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5003 ;; Avoid store forwarding (partial memory) stall penalty
5004 ;; by passing DImode value through XMM registers.  */
5006 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5007   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5008         (float:X87MODEF
5009           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5010    (clobber (match_scratch:V4SI 3 "=X,x"))
5011    (clobber (match_scratch:V4SI 4 "=X,x"))
5012    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5013   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5014    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5015    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5016   "#"
5017   [(set_attr "type" "multi")
5018    (set_attr "mode" "<X87MODEF:MODE>")
5019    (set_attr "unit" "i387")
5020    (set_attr "fp_int_src" "true")])
5022 (define_split
5023   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5024         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5025    (clobber (match_scratch:V4SI 3))
5026    (clobber (match_scratch:V4SI 4))
5027    (clobber (match_operand:DI 2 "memory_operand"))]
5028   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5029    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5030    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5031    && reload_completed"
5032   [(set (match_dup 2) (match_dup 3))
5033    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5035   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5036      Assemble the 64-bit DImode value in an xmm register.  */
5037   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5038                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5039   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5040                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5041   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5042                                          operands[4]));
5044   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5047 (define_split
5048   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5049         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5050    (clobber (match_scratch:V4SI 3))
5051    (clobber (match_scratch:V4SI 4))
5052    (clobber (match_operand:DI 2 "memory_operand"))]
5053   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5054    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5055    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5056    && reload_completed"
5057   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5059 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5060   [(set (match_operand:MODEF 0 "register_operand")
5061         (unsigned_float:MODEF
5062           (match_operand:SWI12 1 "nonimmediate_operand")))]
5063   "!TARGET_64BIT
5064    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5066   operands[1] = convert_to_mode (SImode, operands[1], 1);
5067   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5068   DONE;
5071 ;; Avoid store forwarding (partial memory) stall penalty by extending
5072 ;; SImode value to DImode through XMM register instead of pushing two
5073 ;; SImode values to stack. Also note that fild loads from memory only.
5075 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5076   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5077         (unsigned_float:X87MODEF
5078           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5079    (clobber (match_scratch:DI 3 "=x"))
5080    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5081   "!TARGET_64BIT
5082    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5083    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5084   "#"
5085   "&& reload_completed"
5086   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5087    (set (match_dup 2) (match_dup 3))
5088    (set (match_dup 0)
5089         (float:X87MODEF (match_dup 2)))]
5090   ""
5091   [(set_attr "type" "multi")
5092    (set_attr "mode" "<MODE>")])
5094 (define_expand "floatunssi<mode>2"
5095   [(parallel
5096      [(set (match_operand:X87MODEF 0 "register_operand")
5097            (unsigned_float:X87MODEF
5098              (match_operand:SI 1 "nonimmediate_operand")))
5099       (clobber (match_scratch:DI 3))
5100       (clobber (match_dup 2))])]
5101   "!TARGET_64BIT
5102    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5103         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5104        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5106   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5107     {
5108       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5109       DONE;
5110     }
5111   else
5112     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5115 (define_expand "floatunsdisf2"
5116   [(use (match_operand:SF 0 "register_operand"))
5117    (use (match_operand:DI 1 "nonimmediate_operand"))]
5118   "TARGET_64BIT && TARGET_SSE_MATH"
5119   "x86_emit_floatuns (operands); DONE;")
5121 (define_expand "floatunsdidf2"
5122   [(use (match_operand:DF 0 "register_operand"))
5123    (use (match_operand:DI 1 "nonimmediate_operand"))]
5124   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5125    && TARGET_SSE2 && TARGET_SSE_MATH"
5127   if (TARGET_64BIT)
5128     x86_emit_floatuns (operands);
5129   else
5130     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5131   DONE;
5134 ;; Load effective address instructions
5136 (define_insn_and_split "*lea<mode>"
5137   [(set (match_operand:SWI48 0 "register_operand" "=r")
5138         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5139   ""
5141   if (SImode_address_operand (operands[1], VOIDmode))
5142     {
5143       gcc_assert (TARGET_64BIT);
5144       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5145     }
5146   else 
5147     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5149   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5150   [(const_int 0)]
5152   machine_mode mode = <MODE>mode;
5153   rtx pat;
5155   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5156      change operands[] array behind our back.  */
5157   pat = PATTERN (curr_insn);
5159   operands[0] = SET_DEST (pat);
5160   operands[1] = SET_SRC (pat);
5162   /* Emit all operations in SImode for zero-extended addresses.  */
5163   if (SImode_address_operand (operands[1], VOIDmode))
5164     mode = SImode;
5166   ix86_split_lea_for_addr (curr_insn, operands, mode);
5168   /* Zero-extend return register to DImode for zero-extended addresses.  */
5169   if (mode != <MODE>mode)
5170     emit_insn (gen_zero_extendsidi2
5171                (operands[0], gen_lowpart (mode, operands[0])));
5173   DONE;
5175   [(set_attr "type" "lea")
5176    (set (attr "mode")
5177      (if_then_else
5178        (match_operand 1 "SImode_address_operand")
5179        (const_string "SI")
5180        (const_string "<MODE>")))])
5182 ;; Add instructions
5184 (define_expand "add<mode>3"
5185   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5186         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5187                     (match_operand:SDWIM 2 "<general_operand>")))]
5188   ""
5189   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5191 (define_insn_and_split "*add<dwi>3_doubleword"
5192   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5193         (plus:<DWI>
5194           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5195           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5196    (clobber (reg:CC FLAGS_REG))]
5197   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5198   "#"
5199   "reload_completed"
5200   [(parallel [(set (reg:CC FLAGS_REG)
5201                    (unspec:CC [(match_dup 1) (match_dup 2)]
5202                               UNSPEC_ADD_CARRY))
5203               (set (match_dup 0)
5204                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5205    (parallel [(set (match_dup 3)
5206                    (plus:DWIH
5207                      (match_dup 4)
5208                      (plus:DWIH
5209                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5210                        (match_dup 5))))
5211               (clobber (reg:CC FLAGS_REG))])]
5212   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5214 (define_insn "*add<mode>3_cc"
5215   [(set (reg:CC FLAGS_REG)
5216         (unspec:CC
5217           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5218            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5219           UNSPEC_ADD_CARRY))
5220    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5221         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5222   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5223   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5224   [(set_attr "type" "alu")
5225    (set_attr "mode" "<MODE>")])
5227 (define_insn "addqi3_cc"
5228   [(set (reg:CC FLAGS_REG)
5229         (unspec:CC
5230           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5231            (match_operand:QI 2 "general_operand" "qn,qm")]
5232           UNSPEC_ADD_CARRY))
5233    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5234         (plus:QI (match_dup 1) (match_dup 2)))]
5235   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5236   "add{b}\t{%2, %0|%0, %2}"
5237   [(set_attr "type" "alu")
5238    (set_attr "mode" "QI")])
5240 (define_insn "*add<mode>_1"
5241   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5242         (plus:SWI48
5243           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5244           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5245    (clobber (reg:CC FLAGS_REG))]
5246   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5248   switch (get_attr_type (insn))
5249     {
5250     case TYPE_LEA:
5251       return "#";
5253     case TYPE_INCDEC:
5254       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5255       if (operands[2] == const1_rtx)
5256         return "inc{<imodesuffix>}\t%0";
5257       else
5258         {
5259           gcc_assert (operands[2] == constm1_rtx);
5260           return "dec{<imodesuffix>}\t%0";
5261         }
5263     default:
5264       /* For most processors, ADD is faster than LEA.  This alternative
5265          was added to use ADD as much as possible.  */
5266       if (which_alternative == 2)
5267         std::swap (operands[1], operands[2]);
5268         
5269       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5270       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5271         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5273       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5274     }
5276   [(set (attr "type")
5277      (cond [(eq_attr "alternative" "3")
5278               (const_string "lea")
5279             (match_operand:SWI48 2 "incdec_operand")
5280               (const_string "incdec")
5281            ]
5282            (const_string "alu")))
5283    (set (attr "length_immediate")
5284       (if_then_else
5285         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5286         (const_string "1")
5287         (const_string "*")))
5288    (set_attr "mode" "<MODE>")])
5290 ;; It may seem that nonimmediate operand is proper one for operand 1.
5291 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5292 ;; we take care in ix86_binary_operator_ok to not allow two memory
5293 ;; operands so proper swapping will be done in reload.  This allow
5294 ;; patterns constructed from addsi_1 to match.
5296 (define_insn "addsi_1_zext"
5297   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5298         (zero_extend:DI
5299           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5300                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5301    (clobber (reg:CC FLAGS_REG))]
5302   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5304   switch (get_attr_type (insn))
5305     {
5306     case TYPE_LEA:
5307       return "#";
5309     case TYPE_INCDEC:
5310       if (operands[2] == const1_rtx)
5311         return "inc{l}\t%k0";
5312       else
5313         {
5314           gcc_assert (operands[2] == constm1_rtx);
5315           return "dec{l}\t%k0";
5316         }
5318     default:
5319       /* For most processors, ADD is faster than LEA.  This alternative
5320          was added to use ADD as much as possible.  */
5321       if (which_alternative == 1)
5322         std::swap (operands[1], operands[2]);
5324       if (x86_maybe_negate_const_int (&operands[2], SImode))
5325         return "sub{l}\t{%2, %k0|%k0, %2}";
5327       return "add{l}\t{%2, %k0|%k0, %2}";
5328     }
5330   [(set (attr "type")
5331      (cond [(eq_attr "alternative" "2")
5332               (const_string "lea")
5333             (match_operand:SI 2 "incdec_operand")
5334               (const_string "incdec")
5335            ]
5336            (const_string "alu")))
5337    (set (attr "length_immediate")
5338       (if_then_else
5339         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5340         (const_string "1")
5341         (const_string "*")))
5342    (set_attr "mode" "SI")])
5344 (define_insn "*addhi_1"
5345   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5346         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5347                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5348    (clobber (reg:CC FLAGS_REG))]
5349   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_LEA:
5354       return "#";
5356     case TYPE_INCDEC:
5357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5358       if (operands[2] == const1_rtx)
5359         return "inc{w}\t%0";
5360       else
5361         {
5362           gcc_assert (operands[2] == constm1_rtx);
5363           return "dec{w}\t%0";
5364         }
5366     default:
5367       /* For most processors, ADD is faster than LEA.  This alternative
5368          was added to use ADD as much as possible.  */
5369       if (which_alternative == 2)
5370         std::swap (operands[1], operands[2]);
5372       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5373       if (x86_maybe_negate_const_int (&operands[2], HImode))
5374         return "sub{w}\t{%2, %0|%0, %2}";
5376       return "add{w}\t{%2, %0|%0, %2}";
5377     }
5379   [(set (attr "type")
5380      (cond [(eq_attr "alternative" "3")
5381               (const_string "lea")
5382             (match_operand:HI 2 "incdec_operand")
5383               (const_string "incdec")
5384            ]
5385            (const_string "alu")))
5386    (set (attr "length_immediate")
5387       (if_then_else
5388         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5389         (const_string "1")
5390         (const_string "*")))
5391    (set_attr "mode" "HI,HI,HI,SI")])
5393 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5394 (define_insn "*addqi_1"
5395   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5396         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5397                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5398    (clobber (reg:CC FLAGS_REG))]
5399   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5401   bool widen = (which_alternative == 3 || which_alternative == 4);
5403   switch (get_attr_type (insn))
5404     {
5405     case TYPE_LEA:
5406       return "#";
5408     case TYPE_INCDEC:
5409       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410       if (operands[2] == const1_rtx)
5411         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5412       else
5413         {
5414           gcc_assert (operands[2] == constm1_rtx);
5415           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5416         }
5418     default:
5419       /* For most processors, ADD is faster than LEA.  These alternatives
5420          were added to use ADD as much as possible.  */
5421       if (which_alternative == 2 || which_alternative == 4)
5422         std::swap (operands[1], operands[2]);
5424       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5425       if (x86_maybe_negate_const_int (&operands[2], QImode))
5426         {
5427           if (widen)
5428             return "sub{l}\t{%2, %k0|%k0, %2}";
5429           else
5430             return "sub{b}\t{%2, %0|%0, %2}";
5431         }
5432       if (widen)
5433         return "add{l}\t{%k2, %k0|%k0, %k2}";
5434       else
5435         return "add{b}\t{%2, %0|%0, %2}";
5436     }
5438   [(set (attr "type")
5439      (cond [(eq_attr "alternative" "5")
5440               (const_string "lea")
5441             (match_operand:QI 2 "incdec_operand")
5442               (const_string "incdec")
5443            ]
5444            (const_string "alu")))
5445    (set (attr "length_immediate")
5446       (if_then_else
5447         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5448         (const_string "1")
5449         (const_string "*")))
5450    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5452 (define_insn "*addqi_1_slp"
5453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5454         (plus:QI (match_dup 0)
5455                  (match_operand:QI 1 "general_operand" "qn,qm")))
5456    (clobber (reg:CC FLAGS_REG))]
5457   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5458    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5460   switch (get_attr_type (insn))
5461     {
5462     case TYPE_INCDEC:
5463       if (operands[1] == const1_rtx)
5464         return "inc{b}\t%0";
5465       else
5466         {
5467           gcc_assert (operands[1] == constm1_rtx);
5468           return "dec{b}\t%0";
5469         }
5471     default:
5472       if (x86_maybe_negate_const_int (&operands[1], QImode))
5473         return "sub{b}\t{%1, %0|%0, %1}";
5475       return "add{b}\t{%1, %0|%0, %1}";
5476     }
5478   [(set (attr "type")
5479      (if_then_else (match_operand:QI 1 "incdec_operand")
5480         (const_string "incdec")
5481         (const_string "alu1")))
5482    (set (attr "memory")
5483      (if_then_else (match_operand 1 "memory_operand")
5484         (const_string "load")
5485         (const_string "none")))
5486    (set_attr "mode" "QI")])
5488 ;; Split non destructive adds if we cannot use lea.
5489 (define_split
5490   [(set (match_operand:SWI48 0 "register_operand")
5491         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5492                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5493    (clobber (reg:CC FLAGS_REG))]
5494   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5495   [(set (match_dup 0) (match_dup 1))
5496    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5497               (clobber (reg:CC FLAGS_REG))])])
5499 ;; Convert add to the lea pattern to avoid flags dependency.
5500 (define_split
5501   [(set (match_operand:SWI 0 "register_operand")
5502         (plus:SWI (match_operand:SWI 1 "register_operand")
5503                   (match_operand:SWI 2 "<nonmemory_operand>")))
5504    (clobber (reg:CC FLAGS_REG))]
5505   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5506   [(const_int 0)]
5508   machine_mode mode = <MODE>mode;
5509   rtx pat;
5511   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5512     { 
5513       mode = SImode; 
5514       operands[0] = gen_lowpart (mode, operands[0]);
5515       operands[1] = gen_lowpart (mode, operands[1]);
5516       operands[2] = gen_lowpart (mode, operands[2]);
5517     }
5519   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5521   emit_insn (gen_rtx_SET (operands[0], pat));
5522   DONE;
5525 ;; Split non destructive adds if we cannot use lea.
5526 (define_split
5527   [(set (match_operand:DI 0 "register_operand")
5528         (zero_extend:DI
5529           (plus:SI (match_operand:SI 1 "register_operand")
5530                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5531    (clobber (reg:CC FLAGS_REG))]
5532   "TARGET_64BIT
5533    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5534   [(set (match_dup 3) (match_dup 1))
5535    (parallel [(set (match_dup 0)
5536                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5537               (clobber (reg:CC FLAGS_REG))])]
5538   "operands[3] = gen_lowpart (SImode, operands[0]);")
5540 ;; Convert add to the lea pattern to avoid flags dependency.
5541 (define_split
5542   [(set (match_operand:DI 0 "register_operand")
5543         (zero_extend:DI
5544           (plus:SI (match_operand:SI 1 "register_operand")
5545                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5546    (clobber (reg:CC FLAGS_REG))]
5547   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5548   [(set (match_dup 0)
5549         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5551 (define_insn "*add<mode>_2"
5552   [(set (reg FLAGS_REG)
5553         (compare
5554           (plus:SWI
5555             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5556             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5557           (const_int 0)))
5558    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5559         (plus:SWI (match_dup 1) (match_dup 2)))]
5560   "ix86_match_ccmode (insn, CCGOCmode)
5561    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5563   switch (get_attr_type (insn))
5564     {
5565     case TYPE_INCDEC:
5566       if (operands[2] == const1_rtx)
5567         return "inc{<imodesuffix>}\t%0";
5568       else
5569         {
5570           gcc_assert (operands[2] == constm1_rtx);
5571           return "dec{<imodesuffix>}\t%0";
5572         }
5574     default:
5575       if (which_alternative == 2)
5576         std::swap (operands[1], operands[2]);
5577         
5578       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5580         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5582       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5583     }
5585   [(set (attr "type")
5586      (if_then_else (match_operand:SWI 2 "incdec_operand")
5587         (const_string "incdec")
5588         (const_string "alu")))
5589    (set (attr "length_immediate")
5590       (if_then_else
5591         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5592         (const_string "1")
5593         (const_string "*")))
5594    (set_attr "mode" "<MODE>")])
5596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5597 (define_insn "*addsi_2_zext"
5598   [(set (reg FLAGS_REG)
5599         (compare
5600           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5601                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5602           (const_int 0)))
5603    (set (match_operand:DI 0 "register_operand" "=r,r")
5604         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5605   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5606    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5608   switch (get_attr_type (insn))
5609     {
5610     case TYPE_INCDEC:
5611       if (operands[2] == const1_rtx)
5612         return "inc{l}\t%k0";
5613       else
5614         {
5615           gcc_assert (operands[2] == constm1_rtx);
5616           return "dec{l}\t%k0";
5617         }
5619     default:
5620       if (which_alternative == 1)
5621         std::swap (operands[1], operands[2]);
5623       if (x86_maybe_negate_const_int (&operands[2], SImode))
5624         return "sub{l}\t{%2, %k0|%k0, %2}";
5626       return "add{l}\t{%2, %k0|%k0, %2}";
5627     }
5629   [(set (attr "type")
5630      (if_then_else (match_operand:SI 2 "incdec_operand")
5631         (const_string "incdec")
5632         (const_string "alu")))
5633    (set (attr "length_immediate")
5634       (if_then_else
5635         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5636         (const_string "1")
5637         (const_string "*")))
5638    (set_attr "mode" "SI")])
5640 (define_insn "*add<mode>_3"
5641   [(set (reg FLAGS_REG)
5642         (compare
5643           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5644           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5645    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5646   "ix86_match_ccmode (insn, CCZmode)
5647    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5649   switch (get_attr_type (insn))
5650     {
5651     case TYPE_INCDEC:
5652       if (operands[2] == const1_rtx)
5653         return "inc{<imodesuffix>}\t%0";
5654       else
5655         {
5656           gcc_assert (operands[2] == constm1_rtx);
5657           return "dec{<imodesuffix>}\t%0";
5658         }
5660     default:
5661       if (which_alternative == 1)
5662         std::swap (operands[1], operands[2]);
5664       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5665       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5666         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5668       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5669     }
5671   [(set (attr "type")
5672      (if_then_else (match_operand:SWI 2 "incdec_operand")
5673         (const_string "incdec")
5674         (const_string "alu")))
5675    (set (attr "length_immediate")
5676       (if_then_else
5677         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5678         (const_string "1")
5679         (const_string "*")))
5680    (set_attr "mode" "<MODE>")])
5682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5683 (define_insn "*addsi_3_zext"
5684   [(set (reg FLAGS_REG)
5685         (compare
5686           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5687           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5688    (set (match_operand:DI 0 "register_operand" "=r,r")
5689         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5690   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5691    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5693   switch (get_attr_type (insn))
5694     {
5695     case TYPE_INCDEC:
5696       if (operands[2] == const1_rtx)
5697         return "inc{l}\t%k0";
5698       else
5699         {
5700           gcc_assert (operands[2] == constm1_rtx);
5701           return "dec{l}\t%k0";
5702         }
5704     default:
5705       if (which_alternative == 1)
5706         std::swap (operands[1], operands[2]);
5708       if (x86_maybe_negate_const_int (&operands[2], SImode))
5709         return "sub{l}\t{%2, %k0|%k0, %2}";
5711       return "add{l}\t{%2, %k0|%k0, %2}";
5712     }
5714   [(set (attr "type")
5715      (if_then_else (match_operand:SI 2 "incdec_operand")
5716         (const_string "incdec")
5717         (const_string "alu")))
5718    (set (attr "length_immediate")
5719       (if_then_else
5720         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5721         (const_string "1")
5722         (const_string "*")))
5723    (set_attr "mode" "SI")])
5725 ; For comparisons against 1, -1 and 128, we may generate better code
5726 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5727 ; is matched then.  We can't accept general immediate, because for
5728 ; case of overflows,  the result is messed up.
5729 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5730 ; only for comparisons not depending on it.
5732 (define_insn "*adddi_4"
5733   [(set (reg FLAGS_REG)
5734         (compare
5735           (match_operand:DI 1 "nonimmediate_operand" "0")
5736           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5737    (clobber (match_scratch:DI 0 "=rm"))]
5738   "TARGET_64BIT
5739    && ix86_match_ccmode (insn, CCGCmode)"
5741   switch (get_attr_type (insn))
5742     {
5743     case TYPE_INCDEC:
5744       if (operands[2] == constm1_rtx)
5745         return "inc{q}\t%0";
5746       else
5747         {
5748           gcc_assert (operands[2] == const1_rtx);
5749           return "dec{q}\t%0";
5750         }
5752     default:
5753       if (x86_maybe_negate_const_int (&operands[2], DImode))
5754         return "add{q}\t{%2, %0|%0, %2}";
5756       return "sub{q}\t{%2, %0|%0, %2}";
5757     }
5759   [(set (attr "type")
5760      (if_then_else (match_operand:DI 2 "incdec_operand")
5761         (const_string "incdec")
5762         (const_string "alu")))
5763    (set (attr "length_immediate")
5764       (if_then_else
5765         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5766         (const_string "1")
5767         (const_string "*")))
5768    (set_attr "mode" "DI")])
5770 ; For comparisons against 1, -1 and 128, we may generate better code
5771 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5772 ; is matched then.  We can't accept general immediate, because for
5773 ; case of overflows,  the result is messed up.
5774 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5775 ; only for comparisons not depending on it.
5777 (define_insn "*add<mode>_4"
5778   [(set (reg FLAGS_REG)
5779         (compare
5780           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5781           (match_operand:SWI124 2 "const_int_operand" "n")))
5782    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5783   "ix86_match_ccmode (insn, CCGCmode)"
5785   switch (get_attr_type (insn))
5786     {
5787     case TYPE_INCDEC:
5788       if (operands[2] == constm1_rtx)
5789         return "inc{<imodesuffix>}\t%0";
5790       else
5791         {
5792           gcc_assert (operands[2] == const1_rtx);
5793           return "dec{<imodesuffix>}\t%0";
5794         }
5796     default:
5797       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5798         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5800       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5801     }
5803   [(set (attr "type")
5804      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5805         (const_string "incdec")
5806         (const_string "alu")))
5807    (set (attr "length_immediate")
5808       (if_then_else
5809         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5810         (const_string "1")
5811         (const_string "*")))
5812    (set_attr "mode" "<MODE>")])
5814 (define_insn "*add<mode>_5"
5815   [(set (reg FLAGS_REG)
5816         (compare
5817           (plus:SWI
5818             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5819             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5820           (const_int 0)))
5821    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5822   "ix86_match_ccmode (insn, CCGOCmode)
5823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5825   switch (get_attr_type (insn))
5826     {
5827     case TYPE_INCDEC:
5828       if (operands[2] == const1_rtx)
5829         return "inc{<imodesuffix>}\t%0";
5830       else
5831         {
5832           gcc_assert (operands[2] == constm1_rtx);
5833           return "dec{<imodesuffix>}\t%0";
5834         }
5836     default:
5837       if (which_alternative == 1)
5838         std::swap (operands[1], operands[2]);
5840       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5842         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5844       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5845     }
5847   [(set (attr "type")
5848      (if_then_else (match_operand:SWI 2 "incdec_operand")
5849         (const_string "incdec")
5850         (const_string "alu")))
5851    (set (attr "length_immediate")
5852       (if_then_else
5853         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5854         (const_string "1")
5855         (const_string "*")))
5856    (set_attr "mode" "<MODE>")])
5858 (define_insn "addqi_ext_1"
5859   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5860                          (const_int 8)
5861                          (const_int 8))
5862         (plus:SI
5863           (zero_extract:SI
5864             (match_operand 1 "ext_register_operand" "0,0")
5865             (const_int 8)
5866             (const_int 8))
5867           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5868    (clobber (reg:CC FLAGS_REG))]
5869   ""
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{b}\t%h0";
5876       else
5877         {
5878           gcc_assert (operands[2] == constm1_rtx);
5879           return "dec{b}\t%h0";
5880         }
5882     default:
5883       return "add{b}\t{%2, %h0|%h0, %2}";
5884     }
5886   [(set_attr "isa" "*,nox64")
5887    (set (attr "type")
5888      (if_then_else (match_operand:QI 2 "incdec_operand")
5889         (const_string "incdec")
5890         (const_string "alu")))
5891    (set_attr "modrm" "1")
5892    (set_attr "mode" "QI")])
5894 (define_insn "*addqi_ext_2"
5895   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5896                          (const_int 8)
5897                          (const_int 8))
5898         (plus:SI
5899           (zero_extract:SI
5900             (match_operand 1 "ext_register_operand" "%0")
5901             (const_int 8)
5902             (const_int 8))
5903           (zero_extract:SI
5904             (match_operand 2 "ext_register_operand" "Q")
5905             (const_int 8)
5906             (const_int 8))))
5907    (clobber (reg:CC FLAGS_REG))]
5908   ""
5909   "add{b}\t{%h2, %h0|%h0, %h2}"
5910   [(set_attr "type" "alu")
5911    (set_attr "mode" "QI")])
5913 ;; Add with jump on overflow.
5914 (define_expand "addv<mode>4"
5915   [(parallel [(set (reg:CCO FLAGS_REG)
5916                    (eq:CCO (plus:<DWI>
5917                               (sign_extend:<DWI>
5918                                  (match_operand:SWI 1 "nonimmediate_operand"))
5919                               (match_dup 4))
5920                            (sign_extend:<DWI>
5921                               (plus:SWI (match_dup 1)
5922                                         (match_operand:SWI 2
5923                                            "<general_operand>")))))
5924               (set (match_operand:SWI 0 "register_operand")
5925                    (plus:SWI (match_dup 1) (match_dup 2)))])
5926    (set (pc) (if_then_else
5927                (eq (reg:CCO FLAGS_REG) (const_int 0))
5928                (label_ref (match_operand 3))
5929                (pc)))]
5930   ""
5932   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5933   if (CONST_INT_P (operands[2]))
5934     operands[4] = operands[2];
5935   else
5936     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5939 (define_insn "*addv<mode>4"
5940   [(set (reg:CCO FLAGS_REG)
5941         (eq:CCO (plus:<DWI>
5942                    (sign_extend:<DWI>
5943                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5944                    (sign_extend:<DWI>
5945                       (match_operand:SWI 2 "<general_sext_operand>"
5946                                            "<r>mWe,<r>We")))
5947                 (sign_extend:<DWI>
5948                    (plus:SWI (match_dup 1) (match_dup 2)))))
5949    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5950         (plus:SWI (match_dup 1) (match_dup 2)))]
5951   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5952   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5953   [(set_attr "type" "alu")
5954    (set_attr "mode" "<MODE>")])
5956 (define_insn "*addv<mode>4_1"
5957   [(set (reg:CCO FLAGS_REG)
5958         (eq:CCO (plus:<DWI>
5959                    (sign_extend:<DWI>
5960                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5961                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5962                 (sign_extend:<DWI>
5963                    (plus:SWI (match_dup 1)
5964                              (match_operand:SWI 2 "x86_64_immediate_operand"
5965                                                   "<i>")))))
5966    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5967         (plus:SWI (match_dup 1) (match_dup 2)))]
5968   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5969    && CONST_INT_P (operands[2])
5970    && INTVAL (operands[2]) == INTVAL (operands[3])"
5971   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5972   [(set_attr "type" "alu")
5973    (set_attr "mode" "<MODE>")
5974    (set (attr "length_immediate")
5975         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5976                   (const_string "1")
5977                (match_test "<MODE_SIZE> == 8")
5978                   (const_string "4")]
5979               (const_string "<MODE_SIZE>")))])
5981 ;; The lea patterns for modes less than 32 bits need to be matched by
5982 ;; several insns converted to real lea by splitters.
5984 (define_insn_and_split "*lea_general_1"
5985   [(set (match_operand 0 "register_operand" "=r")
5986         (plus (plus (match_operand 1 "index_register_operand" "l")
5987                     (match_operand 2 "register_operand" "r"))
5988               (match_operand 3 "immediate_operand" "i")))]
5989   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5993    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5994        || GET_MODE (operands[3]) == VOIDmode)"
5995   "#"
5996   "&& reload_completed"
5997   [(const_int 0)]
5999   machine_mode mode = SImode;
6000   rtx pat;
6002   operands[0] = gen_lowpart (mode, operands[0]);
6003   operands[1] = gen_lowpart (mode, operands[1]);
6004   operands[2] = gen_lowpart (mode, operands[2]);
6005   operands[3] = gen_lowpart (mode, operands[3]);
6007   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6008                       operands[3]);
6010   emit_insn (gen_rtx_SET (operands[0], pat));
6011   DONE;
6013   [(set_attr "type" "lea")
6014    (set_attr "mode" "SI")])
6016 (define_insn_and_split "*lea_general_2"
6017   [(set (match_operand 0 "register_operand" "=r")
6018         (plus (mult (match_operand 1 "index_register_operand" "l")
6019                     (match_operand 2 "const248_operand" "n"))
6020               (match_operand 3 "nonmemory_operand" "ri")))]
6021   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6022    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6023    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6024    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6025        || GET_MODE (operands[3]) == VOIDmode)"
6026   "#"
6027   "&& reload_completed"
6028   [(const_int 0)]
6030   machine_mode mode = SImode;
6031   rtx pat;
6033   operands[0] = gen_lowpart (mode, operands[0]);
6034   operands[1] = gen_lowpart (mode, operands[1]);
6035   operands[3] = gen_lowpart (mode, operands[3]);
6037   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6038                       operands[3]);
6040   emit_insn (gen_rtx_SET (operands[0], pat));
6041   DONE;
6043   [(set_attr "type" "lea")
6044    (set_attr "mode" "SI")])
6046 (define_insn_and_split "*lea_general_3"
6047   [(set (match_operand 0 "register_operand" "=r")
6048         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6049                           (match_operand 2 "const248_operand" "n"))
6050                     (match_operand 3 "register_operand" "r"))
6051               (match_operand 4 "immediate_operand" "i")))]
6052   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6053    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6055    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6056   "#"
6057   "&& reload_completed"
6058   [(const_int 0)]
6060   machine_mode mode = SImode;
6061   rtx pat;
6063   operands[0] = gen_lowpart (mode, operands[0]);
6064   operands[1] = gen_lowpart (mode, operands[1]);
6065   operands[3] = gen_lowpart (mode, operands[3]);
6066   operands[4] = gen_lowpart (mode, operands[4]);
6068   pat = gen_rtx_PLUS (mode,
6069                       gen_rtx_PLUS (mode,
6070                                     gen_rtx_MULT (mode, operands[1],
6071                                                         operands[2]),
6072                                     operands[3]),
6073                       operands[4]);
6075   emit_insn (gen_rtx_SET (operands[0], pat));
6076   DONE;
6078   [(set_attr "type" "lea")
6079    (set_attr "mode" "SI")])
6081 (define_insn_and_split "*lea_general_4"
6082   [(set (match_operand 0 "register_operand" "=r")
6083         (any_or (ashift
6084                   (match_operand 1 "index_register_operand" "l")
6085                   (match_operand 2 "const_int_operand" "n"))
6086                 (match_operand 3 "const_int_operand" "n")))]
6087   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6088       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6089     || GET_MODE (operands[0]) == SImode
6090     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6091    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6092    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6093    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6094        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6095   "#"
6096   "&& reload_completed"
6097   [(const_int 0)]
6099   machine_mode mode = GET_MODE (operands[0]);
6100   rtx pat;
6102   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6103     { 
6104       mode = SImode; 
6105       operands[0] = gen_lowpart (mode, operands[0]);
6106       operands[1] = gen_lowpart (mode, operands[1]);
6107     }
6109   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6111   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6112                        INTVAL (operands[3]));
6114   emit_insn (gen_rtx_SET (operands[0], pat));
6115   DONE;
6117   [(set_attr "type" "lea")
6118    (set (attr "mode")
6119       (if_then_else (match_operand:DI 0)
6120         (const_string "DI")
6121         (const_string "SI")))])
6123 ;; Subtract instructions
6125 (define_expand "sub<mode>3"
6126   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6127         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6128                      (match_operand:SDWIM 2 "<general_operand>")))]
6129   ""
6130   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6132 (define_insn_and_split "*sub<dwi>3_doubleword"
6133   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6134         (minus:<DWI>
6135           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6136           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6137    (clobber (reg:CC FLAGS_REG))]
6138   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6139   "#"
6140   "reload_completed"
6141   [(parallel [(set (reg:CC FLAGS_REG)
6142                    (compare:CC (match_dup 1) (match_dup 2)))
6143               (set (match_dup 0)
6144                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6145    (parallel [(set (match_dup 3)
6146                    (minus:DWIH
6147                      (match_dup 4)
6148                      (plus:DWIH
6149                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6150                        (match_dup 5))))
6151               (clobber (reg:CC FLAGS_REG))])]
6152   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6154 (define_insn "*sub<mode>_1"
6155   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6156         (minus:SWI
6157           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6158           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6159    (clobber (reg:CC FLAGS_REG))]
6160   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6161   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6162   [(set_attr "type" "alu")
6163    (set_attr "mode" "<MODE>")])
6165 (define_insn "*subsi_1_zext"
6166   [(set (match_operand:DI 0 "register_operand" "=r")
6167         (zero_extend:DI
6168           (minus:SI (match_operand:SI 1 "register_operand" "0")
6169                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6172   "sub{l}\t{%2, %k0|%k0, %2}"
6173   [(set_attr "type" "alu")
6174    (set_attr "mode" "SI")])
6176 (define_insn "*subqi_1_slp"
6177   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6178         (minus:QI (match_dup 0)
6179                   (match_operand:QI 1 "general_operand" "qn,qm")))
6180    (clobber (reg:CC FLAGS_REG))]
6181   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6182    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6183   "sub{b}\t{%1, %0|%0, %1}"
6184   [(set_attr "type" "alu1")
6185    (set_attr "mode" "QI")])
6187 (define_insn "*sub<mode>_2"
6188   [(set (reg FLAGS_REG)
6189         (compare
6190           (minus:SWI
6191             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6192             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6193           (const_int 0)))
6194    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6195         (minus:SWI (match_dup 1) (match_dup 2)))]
6196   "ix86_match_ccmode (insn, CCGOCmode)
6197    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6198   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6199   [(set_attr "type" "alu")
6200    (set_attr "mode" "<MODE>")])
6202 (define_insn "*subsi_2_zext"
6203   [(set (reg FLAGS_REG)
6204         (compare
6205           (minus:SI (match_operand:SI 1 "register_operand" "0")
6206                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6207           (const_int 0)))
6208    (set (match_operand:DI 0 "register_operand" "=r")
6209         (zero_extend:DI
6210           (minus:SI (match_dup 1)
6211                     (match_dup 2))))]
6212   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6213    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6214   "sub{l}\t{%2, %k0|%k0, %2}"
6215   [(set_attr "type" "alu")
6216    (set_attr "mode" "SI")])
6218 ;; Subtract with jump on overflow.
6219 (define_expand "subv<mode>4"
6220   [(parallel [(set (reg:CCO FLAGS_REG)
6221                    (eq:CCO (minus:<DWI>
6222                               (sign_extend:<DWI>
6223                                  (match_operand:SWI 1 "nonimmediate_operand"))
6224                               (match_dup 4))
6225                            (sign_extend:<DWI>
6226                               (minus:SWI (match_dup 1)
6227                                          (match_operand:SWI 2
6228                                             "<general_operand>")))))
6229               (set (match_operand:SWI 0 "register_operand")
6230                    (minus:SWI (match_dup 1) (match_dup 2)))])
6231    (set (pc) (if_then_else
6232                (eq (reg:CCO FLAGS_REG) (const_int 0))
6233                (label_ref (match_operand 3))
6234                (pc)))]
6235   ""
6237   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6238   if (CONST_INT_P (operands[2]))
6239     operands[4] = operands[2];
6240   else
6241     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6244 (define_insn "*subv<mode>4"
6245   [(set (reg:CCO FLAGS_REG)
6246         (eq:CCO (minus:<DWI>
6247                    (sign_extend:<DWI>
6248                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6249                    (sign_extend:<DWI>
6250                       (match_operand:SWI 2 "<general_sext_operand>"
6251                                            "<r>We,<r>m")))
6252                 (sign_extend:<DWI>
6253                    (minus:SWI (match_dup 1) (match_dup 2)))))
6254    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6255         (minus:SWI (match_dup 1) (match_dup 2)))]
6256   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6257   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6258   [(set_attr "type" "alu")
6259    (set_attr "mode" "<MODE>")])
6261 (define_insn "*subv<mode>4_1"
6262   [(set (reg:CCO FLAGS_REG)
6263         (eq:CCO (minus:<DWI>
6264                    (sign_extend:<DWI>
6265                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6266                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6267                 (sign_extend:<DWI>
6268                    (minus:SWI (match_dup 1)
6269                               (match_operand:SWI 2 "x86_64_immediate_operand"
6270                                                    "<i>")))))
6271    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6272         (minus:SWI (match_dup 1) (match_dup 2)))]
6273   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6274    && CONST_INT_P (operands[2])
6275    && INTVAL (operands[2]) == INTVAL (operands[3])"
6276   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6277   [(set_attr "type" "alu")
6278    (set_attr "mode" "<MODE>")
6279    (set (attr "length_immediate")
6280         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6281                   (const_string "1")
6282                (match_test "<MODE_SIZE> == 8")
6283                   (const_string "4")]
6284               (const_string "<MODE_SIZE>")))])
6286 (define_insn "*sub<mode>_3"
6287   [(set (reg FLAGS_REG)
6288         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6289                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6290    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6291         (minus:SWI (match_dup 1) (match_dup 2)))]
6292   "ix86_match_ccmode (insn, CCmode)
6293    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6294   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6295   [(set_attr "type" "alu")
6296    (set_attr "mode" "<MODE>")])
6298 (define_insn "*subsi_3_zext"
6299   [(set (reg FLAGS_REG)
6300         (compare (match_operand:SI 1 "register_operand" "0")
6301                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6302    (set (match_operand:DI 0 "register_operand" "=r")
6303         (zero_extend:DI
6304           (minus:SI (match_dup 1)
6305                     (match_dup 2))))]
6306   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6307    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6308   "sub{l}\t{%2, %1|%1, %2}"
6309   [(set_attr "type" "alu")
6310    (set_attr "mode" "SI")])
6312 ;; Add with carry and subtract with borrow
6314 (define_expand "<plusminus_insn><mode>3_carry"
6315   [(parallel
6316     [(set (match_operand:SWI 0 "nonimmediate_operand")
6317           (plusminus:SWI
6318             (match_operand:SWI 1 "nonimmediate_operand")
6319             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6320                        [(match_operand 3 "flags_reg_operand")
6321                         (const_int 0)])
6322                       (match_operand:SWI 2 "<general_operand>"))))
6323      (clobber (reg:CC FLAGS_REG))])]
6324   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6326 (define_insn "*<plusminus_insn><mode>3_carry"
6327   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6328         (plusminus:SWI
6329           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6330           (plus:SWI
6331             (match_operator 3 "ix86_carry_flag_operator"
6332              [(reg FLAGS_REG) (const_int 0)])
6333             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6334    (clobber (reg:CC FLAGS_REG))]
6335   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6336   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6337   [(set_attr "type" "alu")
6338    (set_attr "use_carry" "1")
6339    (set_attr "pent_pair" "pu")
6340    (set_attr "mode" "<MODE>")])
6342 (define_insn "*addsi3_carry_zext"
6343   [(set (match_operand:DI 0 "register_operand" "=r")
6344         (zero_extend:DI
6345           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6346                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6347                              [(reg FLAGS_REG) (const_int 0)])
6348                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6349    (clobber (reg:CC FLAGS_REG))]
6350   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6351   "adc{l}\t{%2, %k0|%k0, %2}"
6352   [(set_attr "type" "alu")
6353    (set_attr "use_carry" "1")
6354    (set_attr "pent_pair" "pu")
6355    (set_attr "mode" "SI")])
6357 (define_insn "*subsi3_carry_zext"
6358   [(set (match_operand:DI 0 "register_operand" "=r")
6359         (zero_extend:DI
6360           (minus:SI (match_operand:SI 1 "register_operand" "0")
6361                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6362                               [(reg FLAGS_REG) (const_int 0)])
6363                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6366   "sbb{l}\t{%2, %k0|%k0, %2}"
6367   [(set_attr "type" "alu")
6368    (set_attr "pent_pair" "pu")
6369    (set_attr "mode" "SI")])
6371 ;; ADCX instruction
6373 (define_insn "adcx<mode>3"
6374   [(set (reg:CCC FLAGS_REG)
6375         (compare:CCC
6376           (plus:SWI48
6377             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6378             (plus:SWI48
6379               (match_operator 4 "ix86_carry_flag_operator"
6380                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6381               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6382           (const_int 0)))
6383    (set (match_operand:SWI48 0 "register_operand" "=r")
6384         (plus:SWI48 (match_dup 1)
6385                     (plus:SWI48 (match_op_dup 4
6386                                  [(match_dup 3) (const_int 0)])
6387                                 (match_dup 2))))]
6388   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6389   "adcx\t{%2, %0|%0, %2}"
6390   [(set_attr "type" "alu")
6391    (set_attr "use_carry" "1")
6392    (set_attr "mode" "<MODE>")])
6394 ;; Overflow setting add instructions
6396 (define_insn "*add<mode>3_cconly_overflow"
6397   [(set (reg:CCC FLAGS_REG)
6398         (compare:CCC
6399           (plus:SWI
6400             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6401             (match_operand:SWI 2 "<general_operand>" "<g>"))
6402           (match_dup 1)))
6403    (clobber (match_scratch:SWI 0 "=<r>"))]
6404   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6405   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6406   [(set_attr "type" "alu")
6407    (set_attr "mode" "<MODE>")])
6409 (define_insn "*add<mode>3_cc_overflow"
6410   [(set (reg:CCC FLAGS_REG)
6411         (compare:CCC
6412             (plus:SWI
6413                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6414                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6415             (match_dup 1)))
6416    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6417         (plus:SWI (match_dup 1) (match_dup 2)))]
6418   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6419   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6420   [(set_attr "type" "alu")
6421    (set_attr "mode" "<MODE>")])
6423 (define_insn "*addsi3_zext_cc_overflow"
6424   [(set (reg:CCC FLAGS_REG)
6425         (compare:CCC
6426           (plus:SI
6427             (match_operand:SI 1 "nonimmediate_operand" "%0")
6428             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6429           (match_dup 1)))
6430    (set (match_operand:DI 0 "register_operand" "=r")
6431         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6432   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6433   "add{l}\t{%2, %k0|%k0, %2}"
6434   [(set_attr "type" "alu")
6435    (set_attr "mode" "SI")])
6437 ;; The patterns that match these are at the end of this file.
6439 (define_expand "<plusminus_insn>xf3"
6440   [(set (match_operand:XF 0 "register_operand")
6441         (plusminus:XF
6442           (match_operand:XF 1 "register_operand")
6443           (match_operand:XF 2 "register_operand")))]
6444   "TARGET_80387")
6446 (define_expand "<plusminus_insn><mode>3"
6447   [(set (match_operand:MODEF 0 "register_operand")
6448         (plusminus:MODEF
6449           (match_operand:MODEF 1 "register_operand")
6450           (match_operand:MODEF 2 "nonimmediate_operand")))]
6451   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6452     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6454 ;; Multiply instructions
6456 (define_expand "mul<mode>3"
6457   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6458                    (mult:SWIM248
6459                      (match_operand:SWIM248 1 "register_operand")
6460                      (match_operand:SWIM248 2 "<general_operand>")))
6461               (clobber (reg:CC FLAGS_REG))])])
6463 (define_expand "mulqi3"
6464   [(parallel [(set (match_operand:QI 0 "register_operand")
6465                    (mult:QI
6466                      (match_operand:QI 1 "register_operand")
6467                      (match_operand:QI 2 "nonimmediate_operand")))
6468               (clobber (reg:CC FLAGS_REG))])]
6469   "TARGET_QIMODE_MATH")
6471 ;; On AMDFAM10
6472 ;; IMUL reg32/64, reg32/64, imm8        Direct
6473 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6474 ;; IMUL reg32/64, reg32/64, imm32       Direct
6475 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6476 ;; IMUL reg32/64, reg32/64              Direct
6477 ;; IMUL reg32/64, mem32/64              Direct
6479 ;; On BDVER1, all above IMULs use DirectPath
6481 (define_insn "*mul<mode>3_1"
6482   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6483         (mult:SWI48
6484           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6485           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6486    (clobber (reg:CC FLAGS_REG))]
6487   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6488   "@
6489    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6490    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6491    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6492   [(set_attr "type" "imul")
6493    (set_attr "prefix_0f" "0,0,1")
6494    (set (attr "athlon_decode")
6495         (cond [(eq_attr "cpu" "athlon")
6496                   (const_string "vector")
6497                (eq_attr "alternative" "1")
6498                   (const_string "vector")
6499                (and (eq_attr "alternative" "2")
6500                     (match_operand 1 "memory_operand"))
6501                   (const_string "vector")]
6502               (const_string "direct")))
6503    (set (attr "amdfam10_decode")
6504         (cond [(and (eq_attr "alternative" "0,1")
6505                     (match_operand 1 "memory_operand"))
6506                   (const_string "vector")]
6507               (const_string "direct")))
6508    (set_attr "bdver1_decode" "direct")
6509    (set_attr "mode" "<MODE>")])
6511 (define_insn "*mulsi3_1_zext"
6512   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6513         (zero_extend:DI
6514           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6515                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6516    (clobber (reg:CC FLAGS_REG))]
6517   "TARGET_64BIT
6518    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6519   "@
6520    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6521    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6522    imul{l}\t{%2, %k0|%k0, %2}"
6523   [(set_attr "type" "imul")
6524    (set_attr "prefix_0f" "0,0,1")
6525    (set (attr "athlon_decode")
6526         (cond [(eq_attr "cpu" "athlon")
6527                   (const_string "vector")
6528                (eq_attr "alternative" "1")
6529                   (const_string "vector")
6530                (and (eq_attr "alternative" "2")
6531                     (match_operand 1 "memory_operand"))
6532                   (const_string "vector")]
6533               (const_string "direct")))
6534    (set (attr "amdfam10_decode")
6535         (cond [(and (eq_attr "alternative" "0,1")
6536                     (match_operand 1 "memory_operand"))
6537                   (const_string "vector")]
6538               (const_string "direct")))
6539    (set_attr "bdver1_decode" "direct")
6540    (set_attr "mode" "SI")])
6542 ;; On AMDFAM10
6543 ;; IMUL reg16, reg16, imm8      VectorPath
6544 ;; IMUL reg16, mem16, imm8      VectorPath
6545 ;; IMUL reg16, reg16, imm16     VectorPath
6546 ;; IMUL reg16, mem16, imm16     VectorPath
6547 ;; IMUL reg16, reg16            Direct
6548 ;; IMUL reg16, mem16            Direct
6550 ;; On BDVER1, all HI MULs use DoublePath
6552 (define_insn "*mulhi3_1"
6553   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6554         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6555                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6556    (clobber (reg:CC FLAGS_REG))]
6557   "TARGET_HIMODE_MATH
6558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6559   "@
6560    imul{w}\t{%2, %1, %0|%0, %1, %2}
6561    imul{w}\t{%2, %1, %0|%0, %1, %2}
6562    imul{w}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "imul")
6564    (set_attr "prefix_0f" "0,0,1")
6565    (set (attr "athlon_decode")
6566         (cond [(eq_attr "cpu" "athlon")
6567                   (const_string "vector")
6568                (eq_attr "alternative" "1,2")
6569                   (const_string "vector")]
6570               (const_string "direct")))
6571    (set (attr "amdfam10_decode")
6572         (cond [(eq_attr "alternative" "0,1")
6573                   (const_string "vector")]
6574               (const_string "direct")))
6575    (set_attr "bdver1_decode" "double")
6576    (set_attr "mode" "HI")])
6578 ;;On AMDFAM10 and BDVER1
6579 ;; MUL reg8     Direct
6580 ;; MUL mem8     Direct
6582 (define_insn "*mulqi3_1"
6583   [(set (match_operand:QI 0 "register_operand" "=a")
6584         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6585                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6586    (clobber (reg:CC FLAGS_REG))]
6587   "TARGET_QIMODE_MATH
6588    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6589   "mul{b}\t%2"
6590   [(set_attr "type" "imul")
6591    (set_attr "length_immediate" "0")
6592    (set (attr "athlon_decode")
6593      (if_then_else (eq_attr "cpu" "athlon")
6594         (const_string "vector")
6595         (const_string "direct")))
6596    (set_attr "amdfam10_decode" "direct")
6597    (set_attr "bdver1_decode" "direct")
6598    (set_attr "mode" "QI")])
6600 ;; Multiply with jump on overflow.
6601 (define_expand "mulv<mode>4"
6602   [(parallel [(set (reg:CCO FLAGS_REG)
6603                    (eq:CCO (mult:<DWI>
6604                               (sign_extend:<DWI>
6605                                  (match_operand:SWI48 1 "register_operand"))
6606                               (match_dup 4))
6607                            (sign_extend:<DWI>
6608                               (mult:SWI48 (match_dup 1)
6609                                           (match_operand:SWI48 2
6610                                              "<general_operand>")))))
6611               (set (match_operand:SWI48 0 "register_operand")
6612                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6613    (set (pc) (if_then_else
6614                (eq (reg:CCO FLAGS_REG) (const_int 0))
6615                (label_ref (match_operand 3))
6616                (pc)))]
6617   ""
6619   if (CONST_INT_P (operands[2]))
6620     operands[4] = operands[2];
6621   else
6622     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6625 (define_insn "*mulv<mode>4"
6626   [(set (reg:CCO FLAGS_REG)
6627         (eq:CCO (mult:<DWI>
6628                    (sign_extend:<DWI>
6629                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6630                    (sign_extend:<DWI>
6631                       (match_operand:SWI48 2 "<general_sext_operand>"
6632                                              "We,mr")))
6633                 (sign_extend:<DWI>
6634                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6635    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6636         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6637   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6638   "@
6639    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6640    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "imul")
6642    (set_attr "prefix_0f" "0,1")
6643    (set (attr "athlon_decode")
6644         (cond [(eq_attr "cpu" "athlon")
6645                   (const_string "vector")
6646                (eq_attr "alternative" "0")
6647                   (const_string "vector")
6648                (and (eq_attr "alternative" "1")
6649                     (match_operand 1 "memory_operand"))
6650                   (const_string "vector")]
6651               (const_string "direct")))
6652    (set (attr "amdfam10_decode")
6653         (cond [(and (eq_attr "alternative" "1")
6654                     (match_operand 1 "memory_operand"))
6655                   (const_string "vector")]
6656               (const_string "direct")))
6657    (set_attr "bdver1_decode" "direct")
6658    (set_attr "mode" "<MODE>")])
6660 (define_insn "*mulv<mode>4_1"
6661   [(set (reg:CCO FLAGS_REG)
6662         (eq:CCO (mult:<DWI>
6663                    (sign_extend:<DWI>
6664                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6665                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6666                 (sign_extend:<DWI>
6667                    (mult:SWI48 (match_dup 1)
6668                                (match_operand:SWI 2 "x86_64_immediate_operand"
6669                                                     "K,<i>")))))
6670    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6671         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6672   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6673    && CONST_INT_P (operands[2])
6674    && INTVAL (operands[2]) == INTVAL (operands[3])"
6675   "@
6676    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6677    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6678   [(set_attr "type" "imul")
6679    (set (attr "athlon_decode")
6680         (cond [(eq_attr "cpu" "athlon")
6681                   (const_string "vector")
6682                (eq_attr "alternative" "1")
6683                   (const_string "vector")]
6684               (const_string "direct")))
6685    (set (attr "amdfam10_decode")
6686         (cond [(match_operand 1 "memory_operand")
6687                   (const_string "vector")]
6688               (const_string "direct")))
6689    (set_attr "bdver1_decode" "direct")
6690    (set_attr "mode" "<MODE>")
6691    (set (attr "length_immediate")
6692         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6693                   (const_string "1")
6694                (match_test "<MODE_SIZE> == 8")
6695                   (const_string "4")]
6696               (const_string "<MODE_SIZE>")))])
6698 (define_expand "umulv<mode>4"
6699   [(parallel [(set (reg:CCO FLAGS_REG)
6700                    (eq:CCO (mult:<DWI>
6701                               (zero_extend:<DWI>
6702                                  (match_operand:SWI48 1
6703                                                       "nonimmediate_operand"))
6704                               (zero_extend:<DWI>
6705                                  (match_operand:SWI48 2
6706                                                       "nonimmediate_operand")))
6707                            (zero_extend:<DWI>
6708                               (mult:SWI48 (match_dup 1) (match_dup 2)))))
6709               (set (match_operand:SWI48 0 "register_operand")
6710                    (mult:SWI48 (match_dup 1) (match_dup 2)))
6711               (clobber (match_scratch:SWI48 4))])
6712    (set (pc) (if_then_else
6713                (eq (reg:CCO FLAGS_REG) (const_int 0))
6714                (label_ref (match_operand 3))
6715                (pc)))]
6716   ""
6718   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6719     operands[1] = force_reg (<MODE>mode, operands[1]);
6722 (define_insn "*umulv<mode>4"
6723   [(set (reg:CCO FLAGS_REG)
6724         (eq:CCO (mult:<DWI>
6725                    (zero_extend:<DWI>
6726                       (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6727                    (zero_extend:<DWI>
6728                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6729                 (zero_extend:<DWI>
6730                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6731    (set (match_operand:SWI48 0 "register_operand" "=a")
6732         (mult:SWI48 (match_dup 1) (match_dup 2)))
6733    (clobber (match_scratch:SWI48 3 "=d"))]
6734   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735   "mul{<imodesuffix>}\t%2"
6736   [(set_attr "type" "imul")
6737    (set_attr "length_immediate" "0")
6738    (set (attr "athlon_decode")
6739      (if_then_else (eq_attr "cpu" "athlon")
6740        (const_string "vector")
6741        (const_string "double")))
6742    (set_attr "amdfam10_decode" "double")
6743    (set_attr "bdver1_decode" "direct")
6744    (set_attr "mode" "<MODE>")])
6746 (define_expand "<u>mulvqi4"
6747   [(parallel [(set (reg:CCO FLAGS_REG)
6748                    (eq:CCO (mult:HI
6749                               (any_extend:HI
6750                                  (match_operand:QI 1 "nonimmediate_operand"))
6751                               (any_extend:HI
6752                                  (match_operand:QI 2 "nonimmediate_operand")))
6753                            (any_extend:HI
6754                               (mult:QI (match_dup 1) (match_dup 2)))))
6755               (set (match_operand:QI 0 "register_operand")
6756                    (mult:QI (match_dup 1) (match_dup 2)))])
6757    (set (pc) (if_then_else
6758                (eq (reg:CCO FLAGS_REG) (const_int 0))
6759                (label_ref (match_operand 3))
6760                (pc)))]
6761   "TARGET_QIMODE_MATH"
6763   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6764     operands[1] = force_reg (QImode, operands[1]);
6767 (define_insn "*<u>mulvqi4"
6768   [(set (reg:CCO FLAGS_REG)
6769         (eq:CCO (mult:HI
6770                    (any_extend:HI
6771                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
6772                    (any_extend:HI
6773                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
6774                 (any_extend:HI
6775                    (mult:QI (match_dup 1) (match_dup 2)))))
6776    (set (match_operand:QI 0 "register_operand" "=a")
6777         (mult:QI (match_dup 1) (match_dup 2)))]
6778   "TARGET_QIMODE_MATH
6779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780   "<sgnprefix>mul{b}\t%2"
6781   [(set_attr "type" "imul")
6782    (set_attr "length_immediate" "0")
6783    (set (attr "athlon_decode")
6784      (if_then_else (eq_attr "cpu" "athlon")
6785         (const_string "vector")
6786         (const_string "direct")))
6787    (set_attr "amdfam10_decode" "direct")
6788    (set_attr "bdver1_decode" "direct")
6789    (set_attr "mode" "QI")])
6791 (define_expand "<u>mul<mode><dwi>3"
6792   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6793                    (mult:<DWI>
6794                      (any_extend:<DWI>
6795                        (match_operand:DWIH 1 "nonimmediate_operand"))
6796                      (any_extend:<DWI>
6797                        (match_operand:DWIH 2 "register_operand"))))
6798               (clobber (reg:CC FLAGS_REG))])])
6800 (define_expand "<u>mulqihi3"
6801   [(parallel [(set (match_operand:HI 0 "register_operand")
6802                    (mult:HI
6803                      (any_extend:HI
6804                        (match_operand:QI 1 "nonimmediate_operand"))
6805                      (any_extend:HI
6806                        (match_operand:QI 2 "register_operand"))))
6807               (clobber (reg:CC FLAGS_REG))])]
6808   "TARGET_QIMODE_MATH")
6810 (define_insn "*bmi2_umul<mode><dwi>3_1"
6811   [(set (match_operand:DWIH 0 "register_operand" "=r")
6812         (mult:DWIH
6813           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6814           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6815    (set (match_operand:DWIH 1 "register_operand" "=r")
6816         (truncate:DWIH
6817           (lshiftrt:<DWI>
6818             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6819                         (zero_extend:<DWI> (match_dup 3)))
6820             (match_operand:QI 4 "const_int_operand" "n"))))]
6821   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6822    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823   "mulx\t{%3, %0, %1|%1, %0, %3}"
6824   [(set_attr "type" "imulx")
6825    (set_attr "prefix" "vex")
6826    (set_attr "mode" "<MODE>")])
6828 (define_insn "*umul<mode><dwi>3_1"
6829   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6830         (mult:<DWI>
6831           (zero_extend:<DWI>
6832             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6833           (zero_extend:<DWI>
6834             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6837   "@
6838    #
6839    mul{<imodesuffix>}\t%2"
6840   [(set_attr "isa" "bmi2,*")
6841    (set_attr "type" "imulx,imul")
6842    (set_attr "length_immediate" "*,0")
6843    (set (attr "athlon_decode")
6844         (cond [(eq_attr "alternative" "1")
6845                  (if_then_else (eq_attr "cpu" "athlon")
6846                    (const_string "vector")
6847                    (const_string "double"))]
6848               (const_string "*")))
6849    (set_attr "amdfam10_decode" "*,double")
6850    (set_attr "bdver1_decode" "*,direct")
6851    (set_attr "prefix" "vex,orig")
6852    (set_attr "mode" "<MODE>")])
6854 ;; Convert mul to the mulx pattern to avoid flags dependency.
6855 (define_split
6856  [(set (match_operand:<DWI> 0 "register_operand")
6857        (mult:<DWI>
6858          (zero_extend:<DWI>
6859            (match_operand:DWIH 1 "register_operand"))
6860          (zero_extend:<DWI>
6861            (match_operand:DWIH 2 "nonimmediate_operand"))))
6862   (clobber (reg:CC FLAGS_REG))]
6863  "TARGET_BMI2 && reload_completed
6864   && true_regnum (operands[1]) == DX_REG"
6865   [(parallel [(set (match_dup 3)
6866                    (mult:DWIH (match_dup 1) (match_dup 2)))
6867               (set (match_dup 4)
6868                    (truncate:DWIH
6869                      (lshiftrt:<DWI>
6870                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6871                                    (zero_extend:<DWI> (match_dup 2)))
6872                        (match_dup 5))))])]
6874   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6879 (define_insn "*mul<mode><dwi>3_1"
6880   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6881         (mult:<DWI>
6882           (sign_extend:<DWI>
6883             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6884           (sign_extend:<DWI>
6885             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888   "imul{<imodesuffix>}\t%2"
6889   [(set_attr "type" "imul")
6890    (set_attr "length_immediate" "0")
6891    (set (attr "athlon_decode")
6892      (if_then_else (eq_attr "cpu" "athlon")
6893         (const_string "vector")
6894         (const_string "double")))
6895    (set_attr "amdfam10_decode" "double")
6896    (set_attr "bdver1_decode" "direct")
6897    (set_attr "mode" "<MODE>")])
6899 (define_insn "*<u>mulqihi3_1"
6900   [(set (match_operand:HI 0 "register_operand" "=a")
6901         (mult:HI
6902           (any_extend:HI
6903             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6904           (any_extend:HI
6905             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6906    (clobber (reg:CC FLAGS_REG))]
6907   "TARGET_QIMODE_MATH
6908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6909   "<sgnprefix>mul{b}\t%2"
6910   [(set_attr "type" "imul")
6911    (set_attr "length_immediate" "0")
6912    (set (attr "athlon_decode")
6913      (if_then_else (eq_attr "cpu" "athlon")
6914         (const_string "vector")
6915         (const_string "direct")))
6916    (set_attr "amdfam10_decode" "direct")
6917    (set_attr "bdver1_decode" "direct")
6918    (set_attr "mode" "QI")])
6920 (define_expand "<s>mul<mode>3_highpart"
6921   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6922                    (truncate:SWI48
6923                      (lshiftrt:<DWI>
6924                        (mult:<DWI>
6925                          (any_extend:<DWI>
6926                            (match_operand:SWI48 1 "nonimmediate_operand"))
6927                          (any_extend:<DWI>
6928                            (match_operand:SWI48 2 "register_operand")))
6929                        (match_dup 4))))
6930               (clobber (match_scratch:SWI48 3))
6931               (clobber (reg:CC FLAGS_REG))])]
6932   ""
6933   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935 (define_insn "*<s>muldi3_highpart_1"
6936   [(set (match_operand:DI 0 "register_operand" "=d")
6937         (truncate:DI
6938           (lshiftrt:TI
6939             (mult:TI
6940               (any_extend:TI
6941                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6942               (any_extend:TI
6943                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6944             (const_int 64))))
6945    (clobber (match_scratch:DI 3 "=1"))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "TARGET_64BIT
6948    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949   "<sgnprefix>mul{q}\t%2"
6950   [(set_attr "type" "imul")
6951    (set_attr "length_immediate" "0")
6952    (set (attr "athlon_decode")
6953      (if_then_else (eq_attr "cpu" "athlon")
6954         (const_string "vector")
6955         (const_string "double")))
6956    (set_attr "amdfam10_decode" "double")
6957    (set_attr "bdver1_decode" "direct")
6958    (set_attr "mode" "DI")])
6960 (define_insn "*<s>mulsi3_highpart_1"
6961   [(set (match_operand:SI 0 "register_operand" "=d")
6962         (truncate:SI
6963           (lshiftrt:DI
6964             (mult:DI
6965               (any_extend:DI
6966                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6967               (any_extend:DI
6968                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6969             (const_int 32))))
6970    (clobber (match_scratch:SI 3 "=1"))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973   "<sgnprefix>mul{l}\t%2"
6974   [(set_attr "type" "imul")
6975    (set_attr "length_immediate" "0")
6976    (set (attr "athlon_decode")
6977      (if_then_else (eq_attr "cpu" "athlon")
6978         (const_string "vector")
6979         (const_string "double")))
6980    (set_attr "amdfam10_decode" "double")
6981    (set_attr "bdver1_decode" "direct")
6982    (set_attr "mode" "SI")])
6984 (define_insn "*<s>mulsi3_highpart_zext"
6985   [(set (match_operand:DI 0 "register_operand" "=d")
6986         (zero_extend:DI (truncate:SI
6987           (lshiftrt:DI
6988             (mult:DI (any_extend:DI
6989                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6990                      (any_extend:DI
6991                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6992             (const_int 32)))))
6993    (clobber (match_scratch:SI 3 "=1"))
6994    (clobber (reg:CC FLAGS_REG))]
6995   "TARGET_64BIT
6996    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997   "<sgnprefix>mul{l}\t%2"
6998   [(set_attr "type" "imul")
6999    (set_attr "length_immediate" "0")
7000    (set (attr "athlon_decode")
7001      (if_then_else (eq_attr "cpu" "athlon")
7002         (const_string "vector")
7003         (const_string "double")))
7004    (set_attr "amdfam10_decode" "double")
7005    (set_attr "bdver1_decode" "direct")
7006    (set_attr "mode" "SI")])
7008 ;; The patterns that match these are at the end of this file.
7010 (define_expand "mulxf3"
7011   [(set (match_operand:XF 0 "register_operand")
7012         (mult:XF (match_operand:XF 1 "register_operand")
7013                  (match_operand:XF 2 "register_operand")))]
7014   "TARGET_80387")
7016 (define_expand "mul<mode>3"
7017   [(set (match_operand:MODEF 0 "register_operand")
7018         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7019                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7020   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7021     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023 ;; Divide instructions
7025 ;; The patterns that match these are at the end of this file.
7027 (define_expand "divxf3"
7028   [(set (match_operand:XF 0 "register_operand")
7029         (div:XF (match_operand:XF 1 "register_operand")
7030                 (match_operand:XF 2 "register_operand")))]
7031   "TARGET_80387")
7033 (define_expand "divdf3"
7034   [(set (match_operand:DF 0 "register_operand")
7035         (div:DF (match_operand:DF 1 "register_operand")
7036                 (match_operand:DF 2 "nonimmediate_operand")))]
7037    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7038     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040 (define_expand "divsf3"
7041   [(set (match_operand:SF 0 "register_operand")
7042         (div:SF (match_operand:SF 1 "register_operand")
7043                 (match_operand:SF 2 "nonimmediate_operand")))]
7044   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7045     || TARGET_SSE_MATH"
7047   if (TARGET_SSE_MATH
7048       && TARGET_RECIP_DIV
7049       && optimize_insn_for_speed_p ()
7050       && flag_finite_math_only && !flag_trapping_math
7051       && flag_unsafe_math_optimizations)
7052     {
7053       ix86_emit_swdivsf (operands[0], operands[1],
7054                          operands[2], SFmode);
7055       DONE;
7056     }
7059 ;; Divmod instructions.
7061 (define_expand "divmod<mode>4"
7062   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7063                    (div:SWIM248
7064                      (match_operand:SWIM248 1 "register_operand")
7065                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7066               (set (match_operand:SWIM248 3 "register_operand")
7067                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7068               (clobber (reg:CC FLAGS_REG))])])
7070 ;; Split with 8bit unsigned divide:
7071 ;;      if (dividend an divisor are in [0-255])
7072 ;;         use 8bit unsigned integer divide
7073 ;;       else
7074 ;;         use original integer divide
7075 (define_split
7076   [(set (match_operand:SWI48 0 "register_operand")
7077         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7078                     (match_operand:SWI48 3 "nonimmediate_operand")))
7079    (set (match_operand:SWI48 1 "register_operand")
7080         (mod:SWI48 (match_dup 2) (match_dup 3)))
7081    (clobber (reg:CC FLAGS_REG))]
7082   "TARGET_USE_8BIT_IDIV
7083    && TARGET_QIMODE_MATH
7084    && can_create_pseudo_p ()
7085    && !optimize_insn_for_size_p ()"
7086   [(const_int 0)]
7087   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089 (define_insn_and_split "divmod<mode>4_1"
7090   [(set (match_operand:SWI48 0 "register_operand" "=a")
7091         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7092                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7093    (set (match_operand:SWI48 1 "register_operand" "=&d")
7094         (mod:SWI48 (match_dup 2) (match_dup 3)))
7095    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7096    (clobber (reg:CC FLAGS_REG))]
7097   ""
7098   "#"
7099   "reload_completed"
7100   [(parallel [(set (match_dup 1)
7101                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7102               (clobber (reg:CC FLAGS_REG))])
7103    (parallel [(set (match_dup 0)
7104                    (div:SWI48 (match_dup 2) (match_dup 3)))
7105               (set (match_dup 1)
7106                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7107               (use (match_dup 1))
7108               (clobber (reg:CC FLAGS_REG))])]
7110   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7113     operands[4] = operands[2];
7114   else
7115     {
7116       /* Avoid use of cltd in favor of a mov+shift.  */
7117       emit_move_insn (operands[1], operands[2]);
7118       operands[4] = operands[1];
7119     }
7121   [(set_attr "type" "multi")
7122    (set_attr "mode" "<MODE>")])
7124 (define_insn_and_split "*divmod<mode>4"
7125   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7126         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7127                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7128    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7129         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130    (clobber (reg:CC FLAGS_REG))]
7131   ""
7132   "#"
7133   "reload_completed"
7134   [(parallel [(set (match_dup 1)
7135                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7136               (clobber (reg:CC FLAGS_REG))])
7137    (parallel [(set (match_dup 0)
7138                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7139               (set (match_dup 1)
7140                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7141               (use (match_dup 1))
7142               (clobber (reg:CC FLAGS_REG))])]
7144   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146   if (<MODE>mode != HImode
7147       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7148     operands[4] = operands[2];
7149   else
7150     {
7151       /* Avoid use of cltd in favor of a mov+shift.  */
7152       emit_move_insn (operands[1], operands[2]);
7153       operands[4] = operands[1];
7154     }
7156   [(set_attr "type" "multi")
7157    (set_attr "mode" "<MODE>")])
7159 (define_insn "*divmod<mode>4_noext"
7160   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7161         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7162                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7163    (set (match_operand:SWIM248 1 "register_operand" "=d")
7164         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7165    (use (match_operand:SWIM248 4 "register_operand" "1"))
7166    (clobber (reg:CC FLAGS_REG))]
7167   ""
7168   "idiv{<imodesuffix>}\t%3"
7169   [(set_attr "type" "idiv")
7170    (set_attr "mode" "<MODE>")])
7172 (define_expand "divmodqi4"
7173   [(parallel [(set (match_operand:QI 0 "register_operand")
7174                    (div:QI
7175                      (match_operand:QI 1 "register_operand")
7176                      (match_operand:QI 2 "nonimmediate_operand")))
7177               (set (match_operand:QI 3 "register_operand")
7178                    (mod:QI (match_dup 1) (match_dup 2)))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "TARGET_QIMODE_MATH"
7182   rtx div, mod, insn;
7183   rtx tmp0, tmp1;
7184   
7185   tmp0 = gen_reg_rtx (HImode);
7186   tmp1 = gen_reg_rtx (HImode);
7188   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7189      in AX.  */
7190   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193   /* Extract remainder from AH.  */
7194   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195   insn = emit_move_insn (operands[3], tmp1);
7197   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198   set_unique_reg_note (insn, REG_EQUAL, mod);
7200   /* Extract quotient from AL.  */
7201   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204   set_unique_reg_note (insn, REG_EQUAL, div);
7206   DONE;
7209 ;; Divide AX by r/m8, with result stored in
7210 ;; AL <- Quotient
7211 ;; AH <- Remainder
7212 ;; Change div/mod to HImode and extend the second argument to HImode
7213 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7214 ;; combine may fail.
7215 (define_insn "divmodhiqi3"
7216   [(set (match_operand:HI 0 "register_operand" "=a")
7217         (ior:HI
7218           (ashift:HI
7219             (zero_extend:HI
7220               (truncate:QI
7221                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7222                         (sign_extend:HI
7223                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7224             (const_int 8))
7225           (zero_extend:HI
7226             (truncate:QI
7227               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7228    (clobber (reg:CC FLAGS_REG))]
7229   "TARGET_QIMODE_MATH"
7230   "idiv{b}\t%2"
7231   [(set_attr "type" "idiv")
7232    (set_attr "mode" "QI")])
7234 (define_expand "udivmod<mode>4"
7235   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7236                    (udiv:SWIM248
7237                      (match_operand:SWIM248 1 "register_operand")
7238                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7239               (set (match_operand:SWIM248 3 "register_operand")
7240                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7241               (clobber (reg:CC FLAGS_REG))])])
7243 ;; Split with 8bit unsigned divide:
7244 ;;      if (dividend an divisor are in [0-255])
7245 ;;         use 8bit unsigned integer divide
7246 ;;       else
7247 ;;         use original integer divide
7248 (define_split
7249   [(set (match_operand:SWI48 0 "register_operand")
7250         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7251                     (match_operand:SWI48 3 "nonimmediate_operand")))
7252    (set (match_operand:SWI48 1 "register_operand")
7253         (umod:SWI48 (match_dup 2) (match_dup 3)))
7254    (clobber (reg:CC FLAGS_REG))]
7255   "TARGET_USE_8BIT_IDIV
7256    && TARGET_QIMODE_MATH
7257    && can_create_pseudo_p ()
7258    && !optimize_insn_for_size_p ()"
7259   [(const_int 0)]
7260   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262 (define_insn_and_split "udivmod<mode>4_1"
7263   [(set (match_operand:SWI48 0 "register_operand" "=a")
7264         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7265                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7266    (set (match_operand:SWI48 1 "register_operand" "=&d")
7267         (umod:SWI48 (match_dup 2) (match_dup 3)))
7268    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7269    (clobber (reg:CC FLAGS_REG))]
7270   ""
7271   "#"
7272   "reload_completed"
7273   [(set (match_dup 1) (const_int 0))
7274    (parallel [(set (match_dup 0)
7275                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7276               (set (match_dup 1)
7277                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7278               (use (match_dup 1))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   [(set_attr "type" "multi")
7282    (set_attr "mode" "<MODE>")])
7284 (define_insn_and_split "*udivmod<mode>4"
7285   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7286         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7287                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7288    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7289         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290    (clobber (reg:CC FLAGS_REG))]
7291   ""
7292   "#"
7293   "reload_completed"
7294   [(set (match_dup 1) (const_int 0))
7295    (parallel [(set (match_dup 0)
7296                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7297               (set (match_dup 1)
7298                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7299               (use (match_dup 1))
7300               (clobber (reg:CC FLAGS_REG))])]
7301   ""
7302   [(set_attr "type" "multi")
7303    (set_attr "mode" "<MODE>")])
7305 ;; Optimize division or modulo by constant power of 2, if the constant
7306 ;; materializes only after expansion.
7307 (define_insn_and_split "*udivmod<mode>4_pow2"
7308   [(set (match_operand:SWI48 0 "register_operand" "=r")
7309         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7310                     (match_operand:SWI48 3 "const_int_operand" "n")))
7311    (set (match_operand:SWI48 1 "register_operand" "=r")
7312         (umod:SWI48 (match_dup 2) (match_dup 3)))
7313    (clobber (reg:CC FLAGS_REG))]
7314   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7315    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7316   "#"
7317   "&& 1"
7318   [(set (match_dup 1) (match_dup 2))
7319    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7320               (clobber (reg:CC FLAGS_REG))])
7321    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7322               (clobber (reg:CC FLAGS_REG))])]
7324   int v = exact_log2 (UINTVAL (operands[3]));
7325   operands[4] = GEN_INT (v);
7326   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7328   [(set_attr "type" "multi")
7329    (set_attr "mode" "<MODE>")])
7331 (define_insn "*udivmod<mode>4_noext"
7332   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7333         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7334                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7335    (set (match_operand:SWIM248 1 "register_operand" "=d")
7336         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7337    (use (match_operand:SWIM248 4 "register_operand" "1"))
7338    (clobber (reg:CC FLAGS_REG))]
7339   ""
7340   "div{<imodesuffix>}\t%3"
7341   [(set_attr "type" "idiv")
7342    (set_attr "mode" "<MODE>")])
7344 (define_expand "udivmodqi4"
7345   [(parallel [(set (match_operand:QI 0 "register_operand")
7346                    (udiv:QI
7347                      (match_operand:QI 1 "register_operand")
7348                      (match_operand:QI 2 "nonimmediate_operand")))
7349               (set (match_operand:QI 3 "register_operand")
7350                    (umod:QI (match_dup 1) (match_dup 2)))
7351               (clobber (reg:CC FLAGS_REG))])]
7352   "TARGET_QIMODE_MATH"
7354   rtx div, mod, insn;
7355   rtx tmp0, tmp1;
7356   
7357   tmp0 = gen_reg_rtx (HImode);
7358   tmp1 = gen_reg_rtx (HImode);
7360   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7361      in AX.  */
7362   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7363   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7365   /* Extract remainder from AH.  */
7366   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7367   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7368   insn = emit_move_insn (operands[3], tmp1);
7370   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7371   set_unique_reg_note (insn, REG_EQUAL, mod);
7373   /* Extract quotient from AL.  */
7374   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7376   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7377   set_unique_reg_note (insn, REG_EQUAL, div);
7379   DONE;
7382 (define_insn "udivmodhiqi3"
7383   [(set (match_operand:HI 0 "register_operand" "=a")
7384         (ior:HI
7385           (ashift:HI
7386             (zero_extend:HI
7387               (truncate:QI
7388                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7389                         (zero_extend:HI
7390                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7391             (const_int 8))
7392           (zero_extend:HI
7393             (truncate:QI
7394               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7395    (clobber (reg:CC FLAGS_REG))]
7396   "TARGET_QIMODE_MATH"
7397   "div{b}\t%2"
7398   [(set_attr "type" "idiv")
7399    (set_attr "mode" "QI")])
7401 ;; We cannot use div/idiv for double division, because it causes
7402 ;; "division by zero" on the overflow and that's not what we expect
7403 ;; from truncate.  Because true (non truncating) double division is
7404 ;; never generated, we can't create this insn anyway.
7406 ;(define_insn ""
7407 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7408 ;       (truncate:SI
7409 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7410 ;                  (zero_extend:DI
7411 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7412 ;   (set (match_operand:SI 3 "register_operand" "=d")
7413 ;       (truncate:SI
7414 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7415 ;   (clobber (reg:CC FLAGS_REG))]
7416 ;  ""
7417 ;  "div{l}\t{%2, %0|%0, %2}"
7418 ;  [(set_attr "type" "idiv")])
7420 ;;- Logical AND instructions
7422 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7423 ;; Note that this excludes ah.
7425 (define_expand "testsi_ccno_1"
7426   [(set (reg:CCNO FLAGS_REG)
7427         (compare:CCNO
7428           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7429                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7430           (const_int 0)))])
7432 (define_expand "testqi_ccz_1"
7433   [(set (reg:CCZ FLAGS_REG)
7434         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7435                              (match_operand:QI 1 "nonmemory_operand"))
7436                  (const_int 0)))])
7438 (define_expand "testdi_ccno_1"
7439   [(set (reg:CCNO FLAGS_REG)
7440         (compare:CCNO
7441           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7442                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7443           (const_int 0)))]
7444   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7446 (define_insn "*testdi_1"
7447   [(set (reg FLAGS_REG)
7448         (compare
7449          (and:DI
7450           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7451           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7452          (const_int 0)))]
7453   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7455   "@
7456    test{l}\t{%k1, %k0|%k0, %k1}
7457    test{l}\t{%k1, %k0|%k0, %k1}
7458    test{q}\t{%1, %0|%0, %1}
7459    test{q}\t{%1, %0|%0, %1}
7460    test{q}\t{%1, %0|%0, %1}"
7461   [(set_attr "type" "test")
7462    (set_attr "modrm" "0,1,0,1,1")
7463    (set_attr "mode" "SI,SI,DI,DI,DI")])
7465 (define_insn "*testqi_1_maybe_si"
7466   [(set (reg FLAGS_REG)
7467         (compare
7468           (and:QI
7469             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7470             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7471           (const_int 0)))]
7472    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7473     && ix86_match_ccmode (insn,
7474                          CONST_INT_P (operands[1])
7475                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7477   if (which_alternative == 3)
7478     {
7479       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7480         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7481       return "test{l}\t{%1, %k0|%k0, %1}";
7482     }
7483   return "test{b}\t{%1, %0|%0, %1}";
7485   [(set_attr "type" "test")
7486    (set_attr "modrm" "0,1,1,1")
7487    (set_attr "mode" "QI,QI,QI,SI")
7488    (set_attr "pent_pair" "uv,np,uv,np")])
7490 (define_insn "*test<mode>_1"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493          (and:SWI124
7494           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7495           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7496          (const_int 0)))]
7497   "ix86_match_ccmode (insn, CCNOmode)
7498    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7499   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7500   [(set_attr "type" "test")
7501    (set_attr "modrm" "0,1,1")
7502    (set_attr "mode" "<MODE>")
7503    (set_attr "pent_pair" "uv,np,uv")])
7505 (define_expand "testqi_ext_ccno_0"
7506   [(set (reg:CCNO FLAGS_REG)
7507         (compare:CCNO
7508           (and:SI
7509             (zero_extract:SI
7510               (match_operand 0 "ext_register_operand")
7511               (const_int 8)
7512               (const_int 8))
7513             (match_operand 1 "const_int_operand"))
7514           (const_int 0)))])
7516 (define_insn "*testqi_ext_0"
7517   [(set (reg FLAGS_REG)
7518         (compare
7519           (and:SI
7520             (zero_extract:SI
7521               (match_operand 0 "ext_register_operand" "Q")
7522               (const_int 8)
7523               (const_int 8))
7524             (match_operand 1 "const_int_operand" "n"))
7525           (const_int 0)))]
7526   "ix86_match_ccmode (insn, CCNOmode)"
7527   "test{b}\t{%1, %h0|%h0, %1}"
7528   [(set_attr "type" "test")
7529    (set_attr "mode" "QI")
7530    (set_attr "length_immediate" "1")
7531    (set_attr "modrm" "1")
7532    (set_attr "pent_pair" "np")])
7534 (define_insn "*testqi_ext_1"
7535   [(set (reg FLAGS_REG)
7536         (compare
7537           (and:SI
7538             (zero_extract:SI
7539               (match_operand 0 "ext_register_operand" "Q,Q")
7540               (const_int 8)
7541               (const_int 8))
7542             (zero_extend:SI
7543               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7544           (const_int 0)))]
7545   "ix86_match_ccmode (insn, CCNOmode)"
7546   "test{b}\t{%1, %h0|%h0, %1}"
7547   [(set_attr "isa" "*,nox64")
7548    (set_attr "type" "test")
7549    (set_attr "mode" "QI")])
7551 (define_insn "*testqi_ext_2"
7552   [(set (reg FLAGS_REG)
7553         (compare
7554           (and:SI
7555             (zero_extract:SI
7556               (match_operand 0 "ext_register_operand" "Q")
7557               (const_int 8)
7558               (const_int 8))
7559             (zero_extract:SI
7560               (match_operand 1 "ext_register_operand" "Q")
7561               (const_int 8)
7562               (const_int 8)))
7563           (const_int 0)))]
7564   "ix86_match_ccmode (insn, CCNOmode)"
7565   "test{b}\t{%h1, %h0|%h0, %h1}"
7566   [(set_attr "type" "test")
7567    (set_attr "mode" "QI")])
7569 ;; Combine likes to form bit extractions for some tests.  Humor it.
7570 (define_insn "*testqi_ext_3"
7571   [(set (reg FLAGS_REG)
7572         (compare (zero_extract:SWI48
7573                    (match_operand 0 "nonimmediate_operand" "rm")
7574                    (match_operand:SWI48 1 "const_int_operand")
7575                    (match_operand:SWI48 2 "const_int_operand"))
7576                  (const_int 0)))]
7577   "ix86_match_ccmode (insn, CCNOmode)
7578    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7579        || GET_MODE (operands[0]) == SImode
7580        || GET_MODE (operands[0]) == HImode
7581        || GET_MODE (operands[0]) == QImode)
7582    /* Ensure that resulting mask is zero or sign extended operand.  */
7583    && INTVAL (operands[2]) >= 0
7584    && ((INTVAL (operands[1]) > 0
7585         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7586        || (<MODE>mode == DImode
7587            && INTVAL (operands[1]) > 32
7588            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7589   "#")
7591 (define_split
7592   [(set (match_operand 0 "flags_reg_operand")
7593         (match_operator 1 "compare_operator"
7594           [(zero_extract
7595              (match_operand 2 "nonimmediate_operand")
7596              (match_operand 3 "const_int_operand")
7597              (match_operand 4 "const_int_operand"))
7598            (const_int 0)]))]
7599   "ix86_match_ccmode (insn, CCNOmode)"
7600   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7602   rtx val = operands[2];
7603   HOST_WIDE_INT len = INTVAL (operands[3]);
7604   HOST_WIDE_INT pos = INTVAL (operands[4]);
7605   HOST_WIDE_INT mask;
7606   machine_mode mode, submode;
7608   mode = GET_MODE (val);
7609   if (MEM_P (val))
7610     {
7611       /* ??? Combine likes to put non-volatile mem extractions in QImode
7612          no matter the size of the test.  So find a mode that works.  */
7613       if (! MEM_VOLATILE_P (val))
7614         {
7615           mode = smallest_mode_for_size (pos + len, MODE_INT);
7616           val = adjust_address (val, mode, 0);
7617         }
7618     }
7619   else if (GET_CODE (val) == SUBREG
7620            && (submode = GET_MODE (SUBREG_REG (val)),
7621                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7622            && pos + len <= GET_MODE_BITSIZE (submode)
7623            && GET_MODE_CLASS (submode) == MODE_INT)
7624     {
7625       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7626       mode = submode;
7627       val = SUBREG_REG (val);
7628     }
7629   else if (mode == HImode && pos + len <= 8)
7630     {
7631       /* Small HImode tests can be converted to QImode.  */
7632       mode = QImode;
7633       val = gen_lowpart (QImode, val);
7634     }
7636   if (len == HOST_BITS_PER_WIDE_INT)
7637     mask = -1;
7638   else
7639     mask = ((HOST_WIDE_INT)1 << len) - 1;
7640   mask <<= pos;
7642   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7645 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7646 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7647 ;; this is relatively important trick.
7648 ;; Do the conversion only post-reload to avoid limiting of the register class
7649 ;; to QI regs.
7650 (define_split
7651   [(set (match_operand 0 "flags_reg_operand")
7652         (match_operator 1 "compare_operator"
7653           [(and (match_operand 2 "QIreg_operand")
7654                 (match_operand 3 "const_int_operand"))
7655            (const_int 0)]))]
7656    "reload_completed
7657     && GET_MODE (operands[2]) != QImode
7658     && ((ix86_match_ccmode (insn, CCZmode)
7659          && !(INTVAL (operands[3]) & ~(255 << 8)))
7660         || (ix86_match_ccmode (insn, CCNOmode)
7661             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7662   [(set (match_dup 0)
7663         (match_op_dup 1
7664           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7665                    (match_dup 3))
7666            (const_int 0)]))]
7668   operands[2] = gen_lowpart (SImode, operands[2]);
7669   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7672 (define_split
7673   [(set (match_operand 0 "flags_reg_operand")
7674         (match_operator 1 "compare_operator"
7675           [(and (match_operand 2 "nonimmediate_operand")
7676                 (match_operand 3 "const_int_operand"))
7677            (const_int 0)]))]
7678    "reload_completed
7679     && GET_MODE (operands[2]) != QImode
7680     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7681     && ((ix86_match_ccmode (insn, CCZmode)
7682          && !(INTVAL (operands[3]) & ~255))
7683         || (ix86_match_ccmode (insn, CCNOmode)
7684             && !(INTVAL (operands[3]) & ~127)))"
7685   [(set (match_dup 0)
7686         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7687                          (const_int 0)]))]
7689   operands[2] = gen_lowpart (QImode, operands[2]);
7690   operands[3] = gen_lowpart (QImode, operands[3]);
7693 (define_split
7694   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7695         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7696                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7697    (clobber (reg:CC FLAGS_REG))]
7698   "TARGET_AVX512F && reload_completed"
7699   [(set (match_dup 0)
7700         (any_logic:SWI1248x (match_dup 1)
7701                             (match_dup 2)))])
7703 (define_insn "*k<logic><mode>"
7704   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7705         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7706                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7707   "TARGET_AVX512F"
7708   {
7709     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7710       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7711     else
7712       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7713   }
7714   [(set_attr "mode" "<MODE>")
7715    (set_attr "type" "msklog")
7716    (set_attr "prefix" "vex")])
7718 ;; %%% This used to optimize known byte-wide and operations to memory,
7719 ;; and sometimes to QImode registers.  If this is considered useful,
7720 ;; it should be done with splitters.
7722 (define_expand "and<mode>3"
7723   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7724         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7725                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7726   ""
7728   machine_mode mode = <MODE>mode;
7729   rtx (*insn) (rtx, rtx);
7731   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7732     {
7733       HOST_WIDE_INT ival = INTVAL (operands[2]);
7735       if (ival == (HOST_WIDE_INT) 0xffffffff)
7736         mode = SImode;
7737       else if (ival == 0xffff)
7738         mode = HImode;
7739       else if (ival == 0xff)
7740         mode = QImode;
7741       }
7743   if (mode == <MODE>mode)
7744     {
7745       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7746       DONE;
7747     }
7749   if (<MODE>mode == DImode)
7750     insn = (mode == SImode)
7751            ? gen_zero_extendsidi2
7752            : (mode == HImode)
7753            ? gen_zero_extendhidi2
7754            : gen_zero_extendqidi2;
7755   else if (<MODE>mode == SImode)
7756     insn = (mode == HImode)
7757            ? gen_zero_extendhisi2
7758            : gen_zero_extendqisi2;
7759   else if (<MODE>mode == HImode)
7760     insn = gen_zero_extendqihi2;
7761   else
7762     gcc_unreachable ();
7764   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7765   DONE;
7768 (define_insn "*anddi_1"
7769   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7770         (and:DI
7771          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7772          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7776   switch (get_attr_type (insn))
7777     {
7778     case TYPE_IMOVX:
7779       return "#";
7781     case TYPE_MSKLOG:
7782       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7784     default:
7785       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7786       if (get_attr_mode (insn) == MODE_SI)
7787         return "and{l}\t{%k2, %k0|%k0, %k2}";
7788       else
7789         return "and{q}\t{%2, %0|%0, %2}";
7790     }
7792   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7793    (set_attr "length_immediate" "*,*,*,0,0")
7794    (set (attr "prefix_rex")
7795      (if_then_else
7796        (and (eq_attr "type" "imovx")
7797             (and (match_test "INTVAL (operands[2]) == 0xff")
7798                  (match_operand 1 "ext_QIreg_operand")))
7799        (const_string "1")
7800        (const_string "*")))
7801    (set_attr "mode" "SI,DI,DI,SI,DI")])
7803 (define_insn "*andsi_1"
7804   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7805         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7806                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7807    (clobber (reg:CC FLAGS_REG))]
7808   "ix86_binary_operator_ok (AND, SImode, operands)"
7810   switch (get_attr_type (insn))
7811     {
7812     case TYPE_IMOVX:
7813       return "#";
7815     case TYPE_MSKLOG:
7816       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7818     default:
7819       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7820       return "and{l}\t{%2, %0|%0, %2}";
7821     }
7823   [(set_attr "type" "alu,alu,imovx,msklog")
7824    (set (attr "prefix_rex")
7825      (if_then_else
7826        (and (eq_attr "type" "imovx")
7827             (and (match_test "INTVAL (operands[2]) == 0xff")
7828                  (match_operand 1 "ext_QIreg_operand")))
7829        (const_string "1")
7830        (const_string "*")))
7831    (set_attr "length_immediate" "*,*,0,0")
7832    (set_attr "mode" "SI")])
7834 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7835 (define_insn "*andsi_1_zext"
7836   [(set (match_operand:DI 0 "register_operand" "=r")
7837         (zero_extend:DI
7838           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7839                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7840    (clobber (reg:CC FLAGS_REG))]
7841   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7842   "and{l}\t{%2, %k0|%k0, %2}"
7843   [(set_attr "type" "alu")
7844    (set_attr "mode" "SI")])
7846 (define_insn "*andhi_1"
7847   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7848         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7849                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7850    (clobber (reg:CC FLAGS_REG))]
7851   "ix86_binary_operator_ok (AND, HImode, operands)"
7853   switch (get_attr_type (insn))
7854     {
7855     case TYPE_IMOVX:
7856       return "#";
7858     case TYPE_MSKLOG:
7859       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7861     default:
7862       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7863       return "and{w}\t{%2, %0|%0, %2}";
7864     }
7866   [(set_attr "type" "alu,alu,imovx,msklog")
7867    (set_attr "length_immediate" "*,*,0,*")
7868    (set (attr "prefix_rex")
7869      (if_then_else
7870        (and (eq_attr "type" "imovx")
7871             (match_operand 1 "ext_QIreg_operand"))
7872        (const_string "1")
7873        (const_string "*")))
7874    (set_attr "mode" "HI,HI,SI,HI")])
7876 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7877 (define_insn "*andqi_1"
7878   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7879         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7880                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7881    (clobber (reg:CC FLAGS_REG))]
7882   "ix86_binary_operator_ok (AND, QImode, operands)"
7884   switch (which_alternative)
7885     {
7886     case 0:
7887     case 1:
7888       return "and{b}\t{%2, %0|%0, %2}";
7889     case 2:
7890       return "and{l}\t{%k2, %k0|%k0, %k2}";
7891     case 3:
7892       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7893                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7894     default:
7895       gcc_unreachable ();
7896     }
7898   [(set_attr "type" "alu,alu,alu,msklog")
7899    (set_attr "mode" "QI,QI,SI,HI")])
7901 (define_insn "*andqi_1_slp"
7902   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7903         (and:QI (match_dup 0)
7904                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7905    (clobber (reg:CC FLAGS_REG))]
7906   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7907    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908   "and{b}\t{%1, %0|%0, %1}"
7909   [(set_attr "type" "alu1")
7910    (set_attr "mode" "QI")])
7912 (define_insn "kandn<mode>"
7913   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7914         (and:SWI12
7915           (not:SWI12
7916             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7917           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7918    (clobber (reg:CC FLAGS_REG))]
7919   "TARGET_AVX512F"
7921   switch (which_alternative)
7922     {
7923     case 0:
7924       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7925     case 1:
7926       return "#";
7927     case 2:
7928       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7929         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7930       else
7931         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7932     default:
7933       gcc_unreachable ();
7934     }
7936   [(set_attr "isa" "bmi,*,avx512f")
7937    (set_attr "type" "bitmanip,*,msklog")
7938    (set_attr "prefix" "*,*,vex")
7939    (set_attr "btver2_decode" "direct,*,*")
7940    (set_attr "mode" "<MODE>")])
7942 (define_split
7943   [(set (match_operand:SWI12 0 "general_reg_operand")
7944         (and:SWI12
7945           (not:SWI12
7946             (match_dup 0))
7947           (match_operand:SWI12 1 "general_reg_operand")))
7948    (clobber (reg:CC FLAGS_REG))]
7949   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7950   [(set (match_dup 0)
7951         (not:HI (match_dup 0)))
7952    (parallel [(set (match_dup 0)
7953                    (and:HI (match_dup 0)
7954                            (match_dup 1)))
7955               (clobber (reg:CC FLAGS_REG))])])
7957 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7958 (define_split
7959   [(set (match_operand:DI 0 "register_operand")
7960         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7961                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7962    (clobber (reg:CC FLAGS_REG))]
7963   "TARGET_64BIT"
7964   [(parallel [(set (match_dup 0)
7965                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7966               (clobber (reg:CC FLAGS_REG))])]
7967   "operands[2] = gen_lowpart (SImode, operands[2]);")
7969 (define_split
7970   [(set (match_operand:SWI248 0 "register_operand")
7971         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7972                     (match_operand:SWI248 2 "const_int_operand")))
7973    (clobber (reg:CC FLAGS_REG))]
7974   "reload_completed
7975    && true_regnum (operands[0]) != true_regnum (operands[1])"
7976   [(const_int 0)]
7978   HOST_WIDE_INT ival = INTVAL (operands[2]);
7979   machine_mode mode;
7980   rtx (*insn) (rtx, rtx);
7982   if (ival == (HOST_WIDE_INT) 0xffffffff)
7983     mode = SImode;
7984   else if (ival == 0xffff)
7985     mode = HImode;
7986   else
7987     {
7988       gcc_assert (ival == 0xff);
7989       mode = QImode;
7990     }
7992   if (<MODE>mode == DImode)
7993     insn = (mode == SImode)
7994            ? gen_zero_extendsidi2
7995            : (mode == HImode)
7996            ? gen_zero_extendhidi2
7997            : gen_zero_extendqidi2;
7998   else
7999     {
8000       if (<MODE>mode != SImode)
8001         /* Zero extend to SImode to avoid partial register stalls.  */
8002         operands[0] = gen_lowpart (SImode, operands[0]);
8004       insn = (mode == HImode)
8005              ? gen_zero_extendhisi2
8006              : gen_zero_extendqisi2;
8007     }
8008   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8009   DONE;
8012 (define_split
8013   [(set (match_operand:SWI48 0 "register_operand")
8014         (and:SWI48 (match_dup 0)
8015                    (const_int -65536)))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8018     || optimize_function_for_size_p (cfun)"
8019   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8020   "operands[1] = gen_lowpart (HImode, operands[0]);")
8022 (define_split
8023   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8024         (and:SWI248 (match_dup 0)
8025                     (const_int -256)))
8026    (clobber (reg:CC FLAGS_REG))]
8027   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8028    && reload_completed"
8029   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8030   "operands[1] = gen_lowpart (QImode, operands[0]);")
8032 (define_split
8033   [(set (match_operand:SWI248 0 "QIreg_operand")
8034         (and:SWI248 (match_dup 0)
8035                     (const_int -65281)))
8036    (clobber (reg:CC FLAGS_REG))]
8037   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8038    && reload_completed"
8039   [(parallel [(set (zero_extract:SI (match_dup 0)
8040                                     (const_int 8)
8041                                     (const_int 8))
8042                    (xor:SI
8043                      (zero_extract:SI (match_dup 0)
8044                                       (const_int 8)
8045                                       (const_int 8))
8046                      (zero_extract:SI (match_dup 0)
8047                                       (const_int 8)
8048                                       (const_int 8))))
8049               (clobber (reg:CC FLAGS_REG))])]
8050   "operands[0] = gen_lowpart (SImode, operands[0]);")
8052 (define_insn "*anddi_2"
8053   [(set (reg FLAGS_REG)
8054         (compare
8055          (and:DI
8056           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8057           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8058          (const_int 0)))
8059    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8060         (and:DI (match_dup 1) (match_dup 2)))]
8061   "TARGET_64BIT
8062    && ix86_match_ccmode
8063         (insn,
8064          /* If we are going to emit andl instead of andq, and the operands[2]
8065             constant might have the SImode sign bit set, make sure the sign
8066             flag isn't tested, because the instruction will set the sign flag
8067             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8068             conservatively assume it might have bit 31 set.  */
8069          (satisfies_constraint_Z (operands[2])
8070           && (!CONST_INT_P (operands[2])
8071               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8072          ? CCZmode : CCNOmode)
8073    && ix86_binary_operator_ok (AND, DImode, operands)"
8074   "@
8075    and{l}\t{%k2, %k0|%k0, %k2}
8076    and{q}\t{%2, %0|%0, %2}
8077    and{q}\t{%2, %0|%0, %2}"
8078   [(set_attr "type" "alu")
8079    (set_attr "mode" "SI,DI,DI")])
8081 (define_insn "*andqi_2_maybe_si"
8082   [(set (reg FLAGS_REG)
8083         (compare (and:QI
8084                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8085                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8086                  (const_int 0)))
8087    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8088         (and:QI (match_dup 1) (match_dup 2)))]
8089   "ix86_binary_operator_ok (AND, QImode, operands)
8090    && ix86_match_ccmode (insn,
8091                          CONST_INT_P (operands[2])
8092                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8094   if (which_alternative == 2)
8095     {
8096       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8097         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8098       return "and{l}\t{%2, %k0|%k0, %2}";
8099     }
8100   return "and{b}\t{%2, %0|%0, %2}";
8102   [(set_attr "type" "alu")
8103    (set_attr "mode" "QI,QI,SI")])
8105 (define_insn "*and<mode>_2"
8106   [(set (reg FLAGS_REG)
8107         (compare (and:SWI124
8108                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8109                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8110                  (const_int 0)))
8111    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8112         (and:SWI124 (match_dup 1) (match_dup 2)))]
8113   "ix86_match_ccmode (insn, CCNOmode)
8114    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8115   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8116   [(set_attr "type" "alu")
8117    (set_attr "mode" "<MODE>")])
8119 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8120 (define_insn "*andsi_2_zext"
8121   [(set (reg FLAGS_REG)
8122         (compare (and:SI
8123                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8124                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8125                  (const_int 0)))
8126    (set (match_operand:DI 0 "register_operand" "=r")
8127         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8129    && ix86_binary_operator_ok (AND, SImode, operands)"
8130   "and{l}\t{%2, %k0|%k0, %2}"
8131   [(set_attr "type" "alu")
8132    (set_attr "mode" "SI")])
8134 (define_insn "*andqi_2_slp"
8135   [(set (reg FLAGS_REG)
8136         (compare (and:QI
8137                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8138                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8139                  (const_int 0)))
8140    (set (strict_low_part (match_dup 0))
8141         (and:QI (match_dup 0) (match_dup 1)))]
8142   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8143    && ix86_match_ccmode (insn, CCNOmode)
8144    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8145   "and{b}\t{%1, %0|%0, %1}"
8146   [(set_attr "type" "alu1")
8147    (set_attr "mode" "QI")])
8149 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8150 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8151 ;; for a QImode operand, which of course failed.
8152 (define_insn "andqi_ext_0"
8153   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8154                          (const_int 8)
8155                          (const_int 8))
8156         (and:SI
8157           (zero_extract:SI
8158             (match_operand 1 "ext_register_operand" "0")
8159             (const_int 8)
8160             (const_int 8))
8161           (match_operand 2 "const_int_operand" "n")))
8162    (clobber (reg:CC FLAGS_REG))]
8163   ""
8164   "and{b}\t{%2, %h0|%h0, %2}"
8165   [(set_attr "type" "alu")
8166    (set_attr "length_immediate" "1")
8167    (set_attr "modrm" "1")
8168    (set_attr "mode" "QI")])
8170 ;; Generated by peephole translating test to and.  This shows up
8171 ;; often in fp comparisons.
8172 (define_insn "*andqi_ext_0_cc"
8173   [(set (reg FLAGS_REG)
8174         (compare
8175           (and:SI
8176             (zero_extract:SI
8177               (match_operand 1 "ext_register_operand" "0")
8178               (const_int 8)
8179               (const_int 8))
8180             (match_operand 2 "const_int_operand" "n"))
8181           (const_int 0)))
8182    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8183                          (const_int 8)
8184                          (const_int 8))
8185         (and:SI
8186           (zero_extract:SI
8187             (match_dup 1)
8188             (const_int 8)
8189             (const_int 8))
8190           (match_dup 2)))]
8191   "ix86_match_ccmode (insn, CCNOmode)"
8192   "and{b}\t{%2, %h0|%h0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "length_immediate" "1")
8195    (set_attr "modrm" "1")
8196    (set_attr "mode" "QI")])
8198 (define_insn "*andqi_ext_1"
8199   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8200                          (const_int 8)
8201                          (const_int 8))
8202         (and:SI
8203           (zero_extract:SI
8204             (match_operand 1 "ext_register_operand" "0,0")
8205             (const_int 8)
8206             (const_int 8))
8207           (zero_extend:SI
8208             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8209    (clobber (reg:CC FLAGS_REG))]
8210   ""
8211   "and{b}\t{%2, %h0|%h0, %2}"
8212   [(set_attr "isa" "*,nox64")
8213    (set_attr "type" "alu")
8214    (set_attr "length_immediate" "0")
8215    (set_attr "mode" "QI")])
8217 (define_insn "*andqi_ext_2"
8218   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8219                          (const_int 8)
8220                          (const_int 8))
8221         (and:SI
8222           (zero_extract:SI
8223             (match_operand 1 "ext_register_operand" "%0")
8224             (const_int 8)
8225             (const_int 8))
8226           (zero_extract:SI
8227             (match_operand 2 "ext_register_operand" "Q")
8228             (const_int 8)
8229             (const_int 8))))
8230    (clobber (reg:CC FLAGS_REG))]
8231   ""
8232   "and{b}\t{%h2, %h0|%h0, %h2}"
8233   [(set_attr "type" "alu")
8234    (set_attr "length_immediate" "0")
8235    (set_attr "mode" "QI")])
8237 ;; Convert wide AND instructions with immediate operand to shorter QImode
8238 ;; equivalents when possible.
8239 ;; Don't do the splitting with memory operands, since it introduces risk
8240 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8241 ;; for size, but that can (should?) be handled by generic code instead.
8242 (define_split
8243   [(set (match_operand 0 "QIreg_operand")
8244         (and (match_operand 1 "register_operand")
8245              (match_operand 2 "const_int_operand")))
8246    (clobber (reg:CC FLAGS_REG))]
8247    "reload_completed
8248     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8249     && !(~INTVAL (operands[2]) & ~(255 << 8))
8250     && GET_MODE (operands[0]) != QImode"
8251   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8252                    (and:SI (zero_extract:SI (match_dup 1)
8253                                             (const_int 8) (const_int 8))
8254                            (match_dup 2)))
8255               (clobber (reg:CC FLAGS_REG))])]
8257   operands[0] = gen_lowpart (SImode, operands[0]);
8258   operands[1] = gen_lowpart (SImode, operands[1]);
8259   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8262 ;; Since AND can be encoded with sign extended immediate, this is only
8263 ;; profitable when 7th bit is not set.
8264 (define_split
8265   [(set (match_operand 0 "any_QIreg_operand")
8266         (and (match_operand 1 "general_operand")
8267              (match_operand 2 "const_int_operand")))
8268    (clobber (reg:CC FLAGS_REG))]
8269    "reload_completed
8270     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271     && !(~INTVAL (operands[2]) & ~255)
8272     && !(INTVAL (operands[2]) & 128)
8273     && GET_MODE (operands[0]) != QImode"
8274   [(parallel [(set (strict_low_part (match_dup 0))
8275                    (and:QI (match_dup 1)
8276                            (match_dup 2)))
8277               (clobber (reg:CC FLAGS_REG))])]
8279   operands[0] = gen_lowpart (QImode, operands[0]);
8280   operands[1] = gen_lowpart (QImode, operands[1]);
8281   operands[2] = gen_lowpart (QImode, operands[2]);
8284 ;; Logical inclusive and exclusive OR instructions
8286 ;; %%% This used to optimize known byte-wide and operations to memory.
8287 ;; If this is considered useful, it should be done with splitters.
8289 (define_expand "<code><mode>3"
8290   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8291         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8292                      (match_operand:SWIM 2 "<general_operand>")))]
8293   ""
8294   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8296 (define_insn "*<code><mode>_1"
8297   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8298         (any_or:SWI48
8299          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8300          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8301    (clobber (reg:CC FLAGS_REG))]
8302   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8303   "@
8304    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8305    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8306    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8307   [(set_attr "type" "alu,alu,msklog")
8308    (set_attr "mode" "<MODE>")])
8310 (define_insn "*<code>hi_1"
8311   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8312         (any_or:HI
8313          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8314          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8315    (clobber (reg:CC FLAGS_REG))]
8316   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8317   "@
8318   <logic>{w}\t{%2, %0|%0, %2}
8319   <logic>{w}\t{%2, %0|%0, %2}
8320   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8321   [(set_attr "type" "alu,alu,msklog")
8322    (set_attr "mode" "HI")])
8324 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8325 (define_insn "*<code>qi_1"
8326   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8327         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8328                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8329    (clobber (reg:CC FLAGS_REG))]
8330   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8331   "@
8332    <logic>{b}\t{%2, %0|%0, %2}
8333    <logic>{b}\t{%2, %0|%0, %2}
8334    <logic>{l}\t{%k2, %k0|%k0, %k2}
8335    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8336   [(set_attr "type" "alu,alu,alu,msklog")
8337    (set_attr "mode" "QI,QI,SI,HI")])
8339 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8340 (define_insn "*<code>si_1_zext"
8341   [(set (match_operand:DI 0 "register_operand" "=r")
8342         (zero_extend:DI
8343          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8344                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8347   "<logic>{l}\t{%2, %k0|%k0, %2}"
8348   [(set_attr "type" "alu")
8349    (set_attr "mode" "SI")])
8351 (define_insn "*<code>si_1_zext_imm"
8352   [(set (match_operand:DI 0 "register_operand" "=r")
8353         (any_or:DI
8354          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8355          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8356    (clobber (reg:CC FLAGS_REG))]
8357   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8358   "<logic>{l}\t{%2, %k0|%k0, %2}"
8359   [(set_attr "type" "alu")
8360    (set_attr "mode" "SI")])
8362 (define_insn "*<code>qi_1_slp"
8363   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8364         (any_or:QI (match_dup 0)
8365                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8366    (clobber (reg:CC FLAGS_REG))]
8367   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8368    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8369   "<logic>{b}\t{%1, %0|%0, %1}"
8370   [(set_attr "type" "alu1")
8371    (set_attr "mode" "QI")])
8373 (define_insn "*<code><mode>_2"
8374   [(set (reg FLAGS_REG)
8375         (compare (any_or:SWI
8376                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8377                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8378                  (const_int 0)))
8379    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8380         (any_or:SWI (match_dup 1) (match_dup 2)))]
8381   "ix86_match_ccmode (insn, CCNOmode)
8382    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8383   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8384   [(set_attr "type" "alu")
8385    (set_attr "mode" "<MODE>")])
8387 (define_insn "kxnor<mode>"
8388   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8389         (not:SWI12
8390           (xor:SWI12
8391             (match_operand:SWI12 1 "register_operand" "0,k")
8392             (match_operand:SWI12 2 "register_operand" "r,k"))))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "TARGET_AVX512F"
8396   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8397     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8398   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8400   [(set_attr "type" "*,msklog")
8401    (set_attr "prefix" "*,vex")
8402    (set_attr "mode" "<MODE>")])
8404 (define_insn "kxnor<mode>"
8405   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8406         (not:SWI48x
8407           (xor:SWI48x
8408             (match_operand:SWI48x 1 "register_operand" "0,k")
8409             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8410    (clobber (reg:CC FLAGS_REG))]
8411   "TARGET_AVX512BW"
8412   "@
8413    #
8414    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8415   [(set_attr "type" "*,msklog")
8416    (set_attr "prefix" "*,vex")
8417    (set_attr "mode" "<MODE>")])
8419 (define_split
8420   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8421         (not:SWI1248x
8422           (xor:SWI1248x
8423             (match_dup 0)
8424             (match_operand:SWI1248x 1 "general_reg_operand"))))
8425    (clobber (reg:CC FLAGS_REG))]
8426   "TARGET_AVX512F && reload_completed"
8427    [(parallel [(set (match_dup 0)
8428                     (xor:HI (match_dup 0)
8429                             (match_dup 1)))
8430                (clobber (reg:CC FLAGS_REG))])
8431     (set (match_dup 0)
8432          (not:HI (match_dup 0)))])
8434 ;;There are kortrest[bdq] but no intrinsics for them.
8435 ;;We probably don't need to implement them.
8436 (define_insn "kortestzhi"
8437   [(set (reg:CCZ FLAGS_REG)
8438         (compare:CCZ
8439           (ior:HI
8440             (match_operand:HI 0 "register_operand" "k")
8441             (match_operand:HI 1 "register_operand" "k"))
8442           (const_int 0)))]
8443   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8444   "kortestw\t{%1, %0|%0, %1}"
8445   [(set_attr "mode" "HI")
8446    (set_attr "type" "msklog")
8447    (set_attr "prefix" "vex")])
8449 (define_insn "kortestchi"
8450   [(set (reg:CCC FLAGS_REG)
8451         (compare:CCC
8452           (ior:HI
8453             (match_operand:HI 0 "register_operand" "k")
8454             (match_operand:HI 1 "register_operand" "k"))
8455           (const_int -1)))]
8456   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8457   "kortestw\t{%1, %0|%0, %1}"
8458   [(set_attr "mode" "HI")
8459    (set_attr "type" "msklog")
8460    (set_attr "prefix" "vex")])
8462 (define_insn "kunpckhi"
8463   [(set (match_operand:HI 0 "register_operand" "=k")
8464         (ior:HI
8465           (ashift:HI
8466             (match_operand:HI 1 "register_operand" "k")
8467             (const_int 8))
8468           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8469   "TARGET_AVX512F"
8470   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8471   [(set_attr "mode" "HI")
8472    (set_attr "type" "msklog")
8473    (set_attr "prefix" "vex")])
8475 (define_insn "kunpcksi"
8476   [(set (match_operand:SI 0 "register_operand" "=k")
8477         (ior:SI
8478           (ashift:SI
8479             (match_operand:SI 1 "register_operand" "k")
8480             (const_int 16))
8481           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8482   "TARGET_AVX512BW"
8483   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8484   [(set_attr "mode" "SI")])
8486 (define_insn "kunpckdi"
8487   [(set (match_operand:DI 0 "register_operand" "=k")
8488         (ior:DI
8489           (ashift:DI
8490             (match_operand:DI 1 "register_operand" "k")
8491             (const_int 32))
8492           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8493   "TARGET_AVX512BW"
8494   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8495   [(set_attr "mode" "DI")])
8497 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8498 ;; ??? Special case for immediate operand is missing - it is tricky.
8499 (define_insn "*<code>si_2_zext"
8500   [(set (reg FLAGS_REG)
8501         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8502                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8503                  (const_int 0)))
8504    (set (match_operand:DI 0 "register_operand" "=r")
8505         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8506   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8507    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8508   "<logic>{l}\t{%2, %k0|%k0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "SI")])
8512 (define_insn "*<code>si_2_zext_imm"
8513   [(set (reg FLAGS_REG)
8514         (compare (any_or:SI
8515                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8516                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8517                  (const_int 0)))
8518    (set (match_operand:DI 0 "register_operand" "=r")
8519         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8521    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8522   "<logic>{l}\t{%2, %k0|%k0, %2}"
8523   [(set_attr "type" "alu")
8524    (set_attr "mode" "SI")])
8526 (define_insn "*<code>qi_2_slp"
8527   [(set (reg FLAGS_REG)
8528         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8529                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8530                  (const_int 0)))
8531    (set (strict_low_part (match_dup 0))
8532         (any_or:QI (match_dup 0) (match_dup 1)))]
8533   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8534    && ix86_match_ccmode (insn, CCNOmode)
8535    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8536   "<logic>{b}\t{%1, %0|%0, %1}"
8537   [(set_attr "type" "alu1")
8538    (set_attr "mode" "QI")])
8540 (define_insn "*<code><mode>_3"
8541   [(set (reg FLAGS_REG)
8542         (compare (any_or:SWI
8543                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8544                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8545                  (const_int 0)))
8546    (clobber (match_scratch:SWI 0 "=<r>"))]
8547   "ix86_match_ccmode (insn, CCNOmode)
8548    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8549   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8550   [(set_attr "type" "alu")
8551    (set_attr "mode" "<MODE>")])
8553 (define_insn "*<code>qi_ext_0"
8554   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8555                          (const_int 8)
8556                          (const_int 8))
8557         (any_or:SI
8558           (zero_extract:SI
8559             (match_operand 1 "ext_register_operand" "0")
8560             (const_int 8)
8561             (const_int 8))
8562           (match_operand 2 "const_int_operand" "n")))
8563    (clobber (reg:CC FLAGS_REG))]
8564   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8565   "<logic>{b}\t{%2, %h0|%h0, %2}"
8566   [(set_attr "type" "alu")
8567    (set_attr "length_immediate" "1")
8568    (set_attr "modrm" "1")
8569    (set_attr "mode" "QI")])
8571 (define_insn "*<code>qi_ext_1"
8572   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8573                          (const_int 8)
8574                          (const_int 8))
8575         (any_or:SI
8576           (zero_extract:SI
8577             (match_operand 1 "ext_register_operand" "0,0")
8578             (const_int 8)
8579             (const_int 8))
8580           (zero_extend:SI
8581             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8582    (clobber (reg:CC FLAGS_REG))]
8583   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8584   "<logic>{b}\t{%2, %h0|%h0, %2}"
8585   [(set_attr "isa" "*,nox64")
8586    (set_attr "type" "alu")
8587    (set_attr "length_immediate" "0")
8588    (set_attr "mode" "QI")])
8590 (define_insn "*<code>qi_ext_2"
8591   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8592                          (const_int 8)
8593                          (const_int 8))
8594         (any_or:SI
8595           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8596                            (const_int 8)
8597                            (const_int 8))
8598           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8599                            (const_int 8)
8600                            (const_int 8))))
8601    (clobber (reg:CC FLAGS_REG))]
8602   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8603   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "length_immediate" "0")
8606    (set_attr "mode" "QI")])
8608 (define_split
8609   [(set (match_operand 0 "QIreg_operand")
8610         (any_or (match_operand 1 "register_operand")
8611                 (match_operand 2 "const_int_operand")))
8612    (clobber (reg:CC FLAGS_REG))]
8613    "reload_completed
8614     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8615     && !(INTVAL (operands[2]) & ~(255 << 8))
8616     && GET_MODE (operands[0]) != QImode"
8617   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8618                    (any_or:SI (zero_extract:SI (match_dup 1)
8619                                                (const_int 8) (const_int 8))
8620                               (match_dup 2)))
8621               (clobber (reg:CC FLAGS_REG))])]
8623   operands[0] = gen_lowpart (SImode, operands[0]);
8624   operands[1] = gen_lowpart (SImode, operands[1]);
8625   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8628 ;; Since OR can be encoded with sign extended immediate, this is only
8629 ;; profitable when 7th bit is set.
8630 (define_split
8631   [(set (match_operand 0 "any_QIreg_operand")
8632         (any_or (match_operand 1 "general_operand")
8633                 (match_operand 2 "const_int_operand")))
8634    (clobber (reg:CC FLAGS_REG))]
8635    "reload_completed
8636     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8637     && !(INTVAL (operands[2]) & ~255)
8638     && (INTVAL (operands[2]) & 128)
8639     && GET_MODE (operands[0]) != QImode"
8640   [(parallel [(set (strict_low_part (match_dup 0))
8641                    (any_or:QI (match_dup 1)
8642                               (match_dup 2)))
8643               (clobber (reg:CC FLAGS_REG))])]
8645   operands[0] = gen_lowpart (QImode, operands[0]);
8646   operands[1] = gen_lowpart (QImode, operands[1]);
8647   operands[2] = gen_lowpart (QImode, operands[2]);
8650 (define_expand "xorqi_cc_ext_1"
8651   [(parallel [
8652      (set (reg:CCNO FLAGS_REG)
8653           (compare:CCNO
8654             (xor:SI
8655               (zero_extract:SI
8656                 (match_operand 1 "ext_register_operand")
8657                 (const_int 8)
8658                 (const_int 8))
8659               (match_operand:QI 2 "const_int_operand"))
8660             (const_int 0)))
8661      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8662                            (const_int 8)
8663                            (const_int 8))
8664           (xor:SI
8665             (zero_extract:SI
8666              (match_dup 1)
8667              (const_int 8)
8668              (const_int 8))
8669             (match_dup 2)))])])
8671 (define_insn "*xorqi_cc_ext_1"
8672   [(set (reg FLAGS_REG)
8673         (compare
8674           (xor:SI
8675             (zero_extract:SI
8676               (match_operand 1 "ext_register_operand" "0,0")
8677               (const_int 8)
8678               (const_int 8))
8679             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8680           (const_int 0)))
8681    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8682                          (const_int 8)
8683                          (const_int 8))
8684         (xor:SI
8685           (zero_extract:SI
8686            (match_dup 1)
8687            (const_int 8)
8688            (const_int 8))
8689           (match_dup 2)))]
8690   "ix86_match_ccmode (insn, CCNOmode)"
8691   "xor{b}\t{%2, %h0|%h0, %2}"
8692   [(set_attr "isa" "*,nox64")
8693    (set_attr "type" "alu")
8694    (set_attr "modrm" "1")
8695    (set_attr "mode" "QI")])
8697 ;; Negation instructions
8699 (define_expand "neg<mode>2"
8700   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8701         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8702   ""
8703   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8705 (define_insn_and_split "*neg<dwi>2_doubleword"
8706   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8707         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8710   "#"
8711   "reload_completed"
8712   [(parallel
8713     [(set (reg:CCZ FLAGS_REG)
8714           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8715      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8716    (parallel
8717     [(set (match_dup 2)
8718           (plus:DWIH (match_dup 3)
8719                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8720                                 (const_int 0))))
8721      (clobber (reg:CC FLAGS_REG))])
8722    (parallel
8723     [(set (match_dup 2)
8724           (neg:DWIH (match_dup 2)))
8725      (clobber (reg:CC FLAGS_REG))])]
8726   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8728 (define_insn "*neg<mode>2_1"
8729   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8730         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8731    (clobber (reg:CC FLAGS_REG))]
8732   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8733   "neg{<imodesuffix>}\t%0"
8734   [(set_attr "type" "negnot")
8735    (set_attr "mode" "<MODE>")])
8737 ;; Combine is quite creative about this pattern.
8738 (define_insn "*negsi2_1_zext"
8739   [(set (match_operand:DI 0 "register_operand" "=r")
8740         (lshiftrt:DI
8741           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8742                              (const_int 32)))
8743         (const_int 32)))
8744    (clobber (reg:CC FLAGS_REG))]
8745   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8746   "neg{l}\t%k0"
8747   [(set_attr "type" "negnot")
8748    (set_attr "mode" "SI")])
8750 ;; The problem with neg is that it does not perform (compare x 0),
8751 ;; it really performs (compare 0 x), which leaves us with the zero
8752 ;; flag being the only useful item.
8754 (define_insn "*neg<mode>2_cmpz"
8755   [(set (reg:CCZ FLAGS_REG)
8756         (compare:CCZ
8757           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8758                    (const_int 0)))
8759    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8760         (neg:SWI (match_dup 1)))]
8761   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8762   "neg{<imodesuffix>}\t%0"
8763   [(set_attr "type" "negnot")
8764    (set_attr "mode" "<MODE>")])
8766 (define_insn "*negsi2_cmpz_zext"
8767   [(set (reg:CCZ FLAGS_REG)
8768         (compare:CCZ
8769           (lshiftrt:DI
8770             (neg:DI (ashift:DI
8771                       (match_operand:DI 1 "register_operand" "0")
8772                       (const_int 32)))
8773             (const_int 32))
8774           (const_int 0)))
8775    (set (match_operand:DI 0 "register_operand" "=r")
8776         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8777                                         (const_int 32)))
8778                      (const_int 32)))]
8779   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8780   "neg{l}\t%k0"
8781   [(set_attr "type" "negnot")
8782    (set_attr "mode" "SI")])
8784 ;; Negate with jump on overflow.
8785 (define_expand "negv<mode>3"
8786   [(parallel [(set (reg:CCO FLAGS_REG)
8787                    (ne:CCO (match_operand:SWI 1 "register_operand")
8788                            (match_dup 3)))
8789               (set (match_operand:SWI 0 "register_operand")
8790                    (neg:SWI (match_dup 1)))])
8791    (set (pc) (if_then_else
8792                (eq (reg:CCO FLAGS_REG) (const_int 0))
8793                (label_ref (match_operand 2))
8794                (pc)))]
8795   ""
8797   operands[3]
8798     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8799                     <MODE>mode);
8802 (define_insn "*negv<mode>3"
8803   [(set (reg:CCO FLAGS_REG)
8804         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8805                 (match_operand:SWI 2 "const_int_operand")))
8806    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8807         (neg:SWI (match_dup 1)))]
8808   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8809    && mode_signbit_p (<MODE>mode, operands[2])"
8810   "neg{<imodesuffix>}\t%0"
8811   [(set_attr "type" "negnot")
8812    (set_attr "mode" "<MODE>")])
8814 ;; Changing of sign for FP values is doable using integer unit too.
8816 (define_expand "<code><mode>2"
8817   [(set (match_operand:X87MODEF 0 "register_operand")
8818         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8819   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8820   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8822 (define_insn "*absneg<mode>2_mixed"
8823   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8824         (match_operator:MODEF 3 "absneg_operator"
8825           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8826    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8829   "#"
8830   [(set (attr "enabled")
8831      (cond [(eq_attr "alternative" "2")
8832               (symbol_ref "TARGET_MIX_SSE_I387")
8833            ]
8834            (symbol_ref "true")))])
8836 (define_insn "*absneg<mode>2_i387"
8837   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8838         (match_operator:X87MODEF 3 "absneg_operator"
8839           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8840    (use (match_operand 2))
8841    (clobber (reg:CC FLAGS_REG))]
8842   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8843   "#")
8845 (define_expand "<code>tf2"
8846   [(set (match_operand:TF 0 "register_operand")
8847         (absneg:TF (match_operand:TF 1 "register_operand")))]
8848   "TARGET_SSE"
8849   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8851 (define_insn "*absnegtf2_sse"
8852   [(set (match_operand:TF 0 "register_operand" "=x,x")
8853         (match_operator:TF 3 "absneg_operator"
8854           [(match_operand:TF 1 "register_operand" "0,x")]))
8855    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "TARGET_SSE"
8858   "#")
8860 ;; Splitters for fp abs and neg.
8862 (define_split
8863   [(set (match_operand 0 "fp_register_operand")
8864         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8865    (use (match_operand 2))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "reload_completed"
8868   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8870 (define_split
8871   [(set (match_operand 0 "register_operand")
8872         (match_operator 3 "absneg_operator"
8873           [(match_operand 1 "register_operand")]))
8874    (use (match_operand 2 "nonimmediate_operand"))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "reload_completed && SSE_REG_P (operands[0])"
8877   [(set (match_dup 0) (match_dup 3))]
8879   machine_mode mode = GET_MODE (operands[0]);
8880   machine_mode vmode = GET_MODE (operands[2]);
8881   rtx tmp;
8883   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8884   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8885   if (operands_match_p (operands[0], operands[2]))
8886     std::swap (operands[1], operands[2]);
8887   if (GET_CODE (operands[3]) == ABS)
8888     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8889   else
8890     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8891   operands[3] = tmp;
8894 (define_split
8895   [(set (match_operand:SF 0 "register_operand")
8896         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8897    (use (match_operand:V4SF 2))
8898    (clobber (reg:CC FLAGS_REG))]
8899   "reload_completed"
8900   [(parallel [(set (match_dup 0) (match_dup 1))
8901               (clobber (reg:CC FLAGS_REG))])]
8903   rtx tmp;
8904   operands[0] = gen_lowpart (SImode, operands[0]);
8905   if (GET_CODE (operands[1]) == ABS)
8906     {
8907       tmp = gen_int_mode (0x7fffffff, SImode);
8908       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8909     }
8910   else
8911     {
8912       tmp = gen_int_mode (0x80000000, SImode);
8913       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8914     }
8915   operands[1] = tmp;
8918 (define_split
8919   [(set (match_operand:DF 0 "register_operand")
8920         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8921    (use (match_operand 2))
8922    (clobber (reg:CC FLAGS_REG))]
8923   "reload_completed"
8924   [(parallel [(set (match_dup 0) (match_dup 1))
8925               (clobber (reg:CC FLAGS_REG))])]
8927   rtx tmp;
8928   if (TARGET_64BIT)
8929     {
8930       tmp = gen_lowpart (DImode, operands[0]);
8931       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8932       operands[0] = tmp;
8934       if (GET_CODE (operands[1]) == ABS)
8935         tmp = const0_rtx;
8936       else
8937         tmp = gen_rtx_NOT (DImode, tmp);
8938     }
8939   else
8940     {
8941       operands[0] = gen_highpart (SImode, operands[0]);
8942       if (GET_CODE (operands[1]) == ABS)
8943         {
8944           tmp = gen_int_mode (0x7fffffff, SImode);
8945           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8946         }
8947       else
8948         {
8949           tmp = gen_int_mode (0x80000000, SImode);
8950           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8951         }
8952     }
8953   operands[1] = tmp;
8956 (define_split
8957   [(set (match_operand:XF 0 "register_operand")
8958         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8959    (use (match_operand 2))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "reload_completed"
8962   [(parallel [(set (match_dup 0) (match_dup 1))
8963               (clobber (reg:CC FLAGS_REG))])]
8965   rtx tmp;
8966   operands[0] = gen_rtx_REG (SImode,
8967                              true_regnum (operands[0])
8968                              + (TARGET_64BIT ? 1 : 2));
8969   if (GET_CODE (operands[1]) == ABS)
8970     {
8971       tmp = GEN_INT (0x7fff);
8972       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8973     }
8974   else
8975     {
8976       tmp = GEN_INT (0x8000);
8977       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8978     }
8979   operands[1] = tmp;
8982 ;; Conditionalize these after reload. If they match before reload, we
8983 ;; lose the clobber and ability to use integer instructions.
8985 (define_insn "*<code><mode>2_1"
8986   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8987         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8988   "TARGET_80387
8989    && (reload_completed
8990        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8991   "f<absneg_mnemonic>"
8992   [(set_attr "type" "fsgn")
8993    (set_attr "mode" "<MODE>")])
8995 (define_insn "*<code>extendsfdf2"
8996   [(set (match_operand:DF 0 "register_operand" "=f")
8997         (absneg:DF (float_extend:DF
8998                      (match_operand:SF 1 "register_operand" "0"))))]
8999   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9000   "f<absneg_mnemonic>"
9001   [(set_attr "type" "fsgn")
9002    (set_attr "mode" "DF")])
9004 (define_insn "*<code>extendsfxf2"
9005   [(set (match_operand:XF 0 "register_operand" "=f")
9006         (absneg:XF (float_extend:XF
9007                      (match_operand:SF 1 "register_operand" "0"))))]
9008   "TARGET_80387"
9009   "f<absneg_mnemonic>"
9010   [(set_attr "type" "fsgn")
9011    (set_attr "mode" "XF")])
9013 (define_insn "*<code>extenddfxf2"
9014   [(set (match_operand:XF 0 "register_operand" "=f")
9015         (absneg:XF (float_extend:XF
9016                      (match_operand:DF 1 "register_operand" "0"))))]
9017   "TARGET_80387"
9018   "f<absneg_mnemonic>"
9019   [(set_attr "type" "fsgn")
9020    (set_attr "mode" "XF")])
9022 ;; Copysign instructions
9024 (define_mode_iterator CSGNMODE [SF DF TF])
9025 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9027 (define_expand "copysign<mode>3"
9028   [(match_operand:CSGNMODE 0 "register_operand")
9029    (match_operand:CSGNMODE 1 "nonmemory_operand")
9030    (match_operand:CSGNMODE 2 "register_operand")]
9031   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9032    || (TARGET_SSE && (<MODE>mode == TFmode))"
9033   "ix86_expand_copysign (operands); DONE;")
9035 (define_insn_and_split "copysign<mode>3_const"
9036   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9037         (unspec:CSGNMODE
9038           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9039            (match_operand:CSGNMODE 2 "register_operand" "0")
9040            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9041           UNSPEC_COPYSIGN))]
9042   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9043    || (TARGET_SSE && (<MODE>mode == TFmode))"
9044   "#"
9045   "&& reload_completed"
9046   [(const_int 0)]
9047   "ix86_split_copysign_const (operands); DONE;")
9049 (define_insn "copysign<mode>3_var"
9050   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9051         (unspec:CSGNMODE
9052           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9053            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9054            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9055            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9056           UNSPEC_COPYSIGN))
9057    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9058   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9059    || (TARGET_SSE && (<MODE>mode == TFmode))"
9060   "#")
9062 (define_split
9063   [(set (match_operand:CSGNMODE 0 "register_operand")
9064         (unspec:CSGNMODE
9065           [(match_operand:CSGNMODE 2 "register_operand")
9066            (match_operand:CSGNMODE 3 "register_operand")
9067            (match_operand:<CSGNVMODE> 4)
9068            (match_operand:<CSGNVMODE> 5)]
9069           UNSPEC_COPYSIGN))
9070    (clobber (match_scratch:<CSGNVMODE> 1))]
9071   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9072     || (TARGET_SSE && (<MODE>mode == TFmode)))
9073    && reload_completed"
9074   [(const_int 0)]
9075   "ix86_split_copysign_var (operands); DONE;")
9077 ;; One complement instructions
9079 (define_expand "one_cmpl<mode>2"
9080   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9081         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9082   ""
9083   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9085 (define_insn "*one_cmpl<mode>2_1"
9086   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9087         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9088   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9089   "@
9090    not{<imodesuffix>}\t%0
9091    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9092   [(set_attr "isa" "*,avx512bw")
9093    (set_attr "type" "negnot,msklog")
9094    (set_attr "prefix" "*,vex")
9095    (set_attr "mode" "<MODE>")])
9097 (define_insn "*one_cmplhi2_1"
9098   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9099         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9100   "ix86_unary_operator_ok (NOT, HImode, operands)"
9101   "@
9102    not{w}\t%0
9103    knotw\t{%1, %0|%0, %1}"
9104   [(set_attr "isa" "*,avx512f")
9105    (set_attr "type" "negnot,msklog")
9106    (set_attr "prefix" "*,vex")
9107    (set_attr "mode" "HI")])
9109 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9110 (define_insn "*one_cmplqi2_1"
9111   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9112         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9113   "ix86_unary_operator_ok (NOT, QImode, operands)"
9115   switch (which_alternative)
9116     {
9117     case 0:
9118       return "not{b}\t%0";
9119     case 1:
9120       return "not{l}\t%k0";
9121     case 2:
9122       if (TARGET_AVX512DQ)
9123         return "knotb\t{%1, %0|%0, %1}";
9124       return "knotw\t{%1, %0|%0, %1}";
9125     default:
9126       gcc_unreachable ();
9127     }
9129   [(set_attr "isa" "*,*,avx512f")
9130    (set_attr "type" "negnot,negnot,msklog")
9131    (set_attr "prefix" "*,*,vex")
9132    (set_attr "mode" "QI,SI,QI")])
9134 ;; ??? Currently never generated - xor is used instead.
9135 (define_insn "*one_cmplsi2_1_zext"
9136   [(set (match_operand:DI 0 "register_operand" "=r")
9137         (zero_extend:DI
9138           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9139   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9140   "not{l}\t%k0"
9141   [(set_attr "type" "negnot")
9142    (set_attr "mode" "SI")])
9144 (define_insn "*one_cmpl<mode>2_2"
9145   [(set (reg FLAGS_REG)
9146         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9147                  (const_int 0)))
9148    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9149         (not:SWI (match_dup 1)))]
9150   "ix86_match_ccmode (insn, CCNOmode)
9151    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9152   "#"
9153   [(set_attr "type" "alu1")
9154    (set_attr "mode" "<MODE>")])
9156 (define_split
9157   [(set (match_operand 0 "flags_reg_operand")
9158         (match_operator 2 "compare_operator"
9159           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9160            (const_int 0)]))
9161    (set (match_operand:SWI 1 "nonimmediate_operand")
9162         (not:SWI (match_dup 3)))]
9163   "ix86_match_ccmode (insn, CCNOmode)"
9164   [(parallel [(set (match_dup 0)
9165                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9166                                     (const_int 0)]))
9167               (set (match_dup 1)
9168                    (xor:SWI (match_dup 3) (const_int -1)))])])
9170 ;; ??? Currently never generated - xor is used instead.
9171 (define_insn "*one_cmplsi2_2_zext"
9172   [(set (reg FLAGS_REG)
9173         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9174                  (const_int 0)))
9175    (set (match_operand:DI 0 "register_operand" "=r")
9176         (zero_extend:DI (not:SI (match_dup 1))))]
9177   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9178    && ix86_unary_operator_ok (NOT, SImode, operands)"
9179   "#"
9180   [(set_attr "type" "alu1")
9181    (set_attr "mode" "SI")])
9183 (define_split
9184   [(set (match_operand 0 "flags_reg_operand")
9185         (match_operator 2 "compare_operator"
9186           [(not:SI (match_operand:SI 3 "register_operand"))
9187            (const_int 0)]))
9188    (set (match_operand:DI 1 "register_operand")
9189         (zero_extend:DI (not:SI (match_dup 3))))]
9190   "ix86_match_ccmode (insn, CCNOmode)"
9191   [(parallel [(set (match_dup 0)
9192                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9193                                     (const_int 0)]))
9194               (set (match_dup 1)
9195                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9197 ;; Shift instructions
9199 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9200 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9201 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9202 ;; from the assembler input.
9204 ;; This instruction shifts the target reg/mem as usual, but instead of
9205 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9206 ;; is a left shift double, bits are taken from the high order bits of
9207 ;; reg, else if the insn is a shift right double, bits are taken from the
9208 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9209 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9211 ;; Since sh[lr]d does not change the `reg' operand, that is done
9212 ;; separately, making all shifts emit pairs of shift double and normal
9213 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9214 ;; support a 63 bit shift, each shift where the count is in a reg expands
9215 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9217 ;; If the shift count is a constant, we need never emit more than one
9218 ;; shift pair, instead using moves and sign extension for counts greater
9219 ;; than 31.
9221 (define_expand "ashl<mode>3"
9222   [(set (match_operand:SDWIM 0 "<shift_operand>")
9223         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9224                       (match_operand:QI 2 "nonmemory_operand")))]
9225   ""
9226   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9228 (define_insn "*ashl<mode>3_doubleword"
9229   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9230         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9231                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9232    (clobber (reg:CC FLAGS_REG))]
9233   ""
9234   "#"
9235   [(set_attr "type" "multi")])
9237 (define_split
9238   [(set (match_operand:DWI 0 "register_operand")
9239         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9240                     (match_operand:QI 2 "nonmemory_operand")))
9241    (clobber (reg:CC FLAGS_REG))]
9242   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9243   [(const_int 0)]
9244   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9246 ;; By default we don't ask for a scratch register, because when DWImode
9247 ;; values are manipulated, registers are already at a premium.  But if
9248 ;; we have one handy, we won't turn it away.
9250 (define_peephole2
9251   [(match_scratch:DWIH 3 "r")
9252    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9253                    (ashift:<DWI>
9254                      (match_operand:<DWI> 1 "nonmemory_operand")
9255                      (match_operand:QI 2 "nonmemory_operand")))
9256               (clobber (reg:CC FLAGS_REG))])
9257    (match_dup 3)]
9258   "TARGET_CMOVE"
9259   [(const_int 0)]
9260   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9262 (define_insn "x86_64_shld"
9263   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9264         (ior:DI (ashift:DI (match_dup 0)
9265                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9266                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9267                   (minus:QI (const_int 64) (match_dup 2)))))
9268    (clobber (reg:CC FLAGS_REG))]
9269   "TARGET_64BIT"
9270   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9271   [(set_attr "type" "ishift")
9272    (set_attr "prefix_0f" "1")
9273    (set_attr "mode" "DI")
9274    (set_attr "athlon_decode" "vector")
9275    (set_attr "amdfam10_decode" "vector")
9276    (set_attr "bdver1_decode" "vector")])
9278 (define_insn "x86_shld"
9279   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9280         (ior:SI (ashift:SI (match_dup 0)
9281                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9282                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9283                   (minus:QI (const_int 32) (match_dup 2)))))
9284    (clobber (reg:CC FLAGS_REG))]
9285   ""
9286   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9287   [(set_attr "type" "ishift")
9288    (set_attr "prefix_0f" "1")
9289    (set_attr "mode" "SI")
9290    (set_attr "pent_pair" "np")
9291    (set_attr "athlon_decode" "vector")
9292    (set_attr "amdfam10_decode" "vector")
9293    (set_attr "bdver1_decode" "vector")])
9295 (define_expand "x86_shift<mode>_adj_1"
9296   [(set (reg:CCZ FLAGS_REG)
9297         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9298                              (match_dup 4))
9299                      (const_int 0)))
9300    (set (match_operand:SWI48 0 "register_operand")
9301         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9302                             (match_operand:SWI48 1 "register_operand")
9303                             (match_dup 0)))
9304    (set (match_dup 1)
9305         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9306                             (match_operand:SWI48 3 "register_operand")
9307                             (match_dup 1)))]
9308   "TARGET_CMOVE"
9309   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9311 (define_expand "x86_shift<mode>_adj_2"
9312   [(use (match_operand:SWI48 0 "register_operand"))
9313    (use (match_operand:SWI48 1 "register_operand"))
9314    (use (match_operand:QI 2 "register_operand"))]
9315   ""
9317   rtx_code_label *label = gen_label_rtx ();
9318   rtx tmp;
9320   emit_insn (gen_testqi_ccz_1 (operands[2],
9321                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9323   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9324   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9325   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9326                               gen_rtx_LABEL_REF (VOIDmode, label),
9327                               pc_rtx);
9328   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9329   JUMP_LABEL (tmp) = label;
9331   emit_move_insn (operands[0], operands[1]);
9332   ix86_expand_clear (operands[1]);
9334   emit_label (label);
9335   LABEL_NUSES (label) = 1;
9337   DONE;
9340 ;; Avoid useless masking of count operand.
9341 (define_insn "*ashl<mode>3_mask"
9342   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9343         (ashift:SWI48
9344           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9345           (subreg:QI
9346             (and:SI
9347               (match_operand:SI 2 "register_operand" "c")
9348               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9349    (clobber (reg:CC FLAGS_REG))]
9350   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9351    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9352       == GET_MODE_BITSIZE (<MODE>mode)-1"
9354   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9356   [(set_attr "type" "ishift")
9357    (set_attr "mode" "<MODE>")])
9359 (define_insn "*bmi2_ashl<mode>3_1"
9360   [(set (match_operand:SWI48 0 "register_operand" "=r")
9361         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9362                       (match_operand:SWI48 2 "register_operand" "r")))]
9363   "TARGET_BMI2"
9364   "shlx\t{%2, %1, %0|%0, %1, %2}"
9365   [(set_attr "type" "ishiftx")
9366    (set_attr "mode" "<MODE>")])
9368 (define_insn "*ashl<mode>3_1"
9369   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9370         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9371                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9372    (clobber (reg:CC FLAGS_REG))]
9373   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9375   switch (get_attr_type (insn))
9376     {
9377     case TYPE_LEA:
9378     case TYPE_ISHIFTX:
9379       return "#";
9381     case TYPE_ALU:
9382       gcc_assert (operands[2] == const1_rtx);
9383       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9384       return "add{<imodesuffix>}\t%0, %0";
9386     default:
9387       if (operands[2] == const1_rtx
9388           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9389         return "sal{<imodesuffix>}\t%0";
9390       else
9391         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9392     }
9394   [(set_attr "isa" "*,*,bmi2")
9395    (set (attr "type")
9396      (cond [(eq_attr "alternative" "1")
9397               (const_string "lea")
9398             (eq_attr "alternative" "2")
9399               (const_string "ishiftx")
9400             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9401                       (match_operand 0 "register_operand"))
9402                  (match_operand 2 "const1_operand"))
9403               (const_string "alu")
9404            ]
9405            (const_string "ishift")))
9406    (set (attr "length_immediate")
9407      (if_then_else
9408        (ior (eq_attr "type" "alu")
9409             (and (eq_attr "type" "ishift")
9410                  (and (match_operand 2 "const1_operand")
9411                       (ior (match_test "TARGET_SHIFT1")
9412                            (match_test "optimize_function_for_size_p (cfun)")))))
9413        (const_string "0")
9414        (const_string "*")))
9415    (set_attr "mode" "<MODE>")])
9417 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9418 (define_split
9419   [(set (match_operand:SWI48 0 "register_operand")
9420         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9421                       (match_operand:QI 2 "register_operand")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   "TARGET_BMI2 && reload_completed"
9424   [(set (match_dup 0)
9425         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9426   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9428 (define_insn "*bmi2_ashlsi3_1_zext"
9429   [(set (match_operand:DI 0 "register_operand" "=r")
9430         (zero_extend:DI
9431           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9432                      (match_operand:SI 2 "register_operand" "r"))))]
9433   "TARGET_64BIT && TARGET_BMI2"
9434   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9435   [(set_attr "type" "ishiftx")
9436    (set_attr "mode" "SI")])
9438 (define_insn "*ashlsi3_1_zext"
9439   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9440         (zero_extend:DI
9441           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9442                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9443    (clobber (reg:CC FLAGS_REG))]
9444   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9446   switch (get_attr_type (insn))
9447     {
9448     case TYPE_LEA:
9449     case TYPE_ISHIFTX:
9450       return "#";
9452     case TYPE_ALU:
9453       gcc_assert (operands[2] == const1_rtx);
9454       return "add{l}\t%k0, %k0";
9456     default:
9457       if (operands[2] == const1_rtx
9458           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9459         return "sal{l}\t%k0";
9460       else
9461         return "sal{l}\t{%2, %k0|%k0, %2}";
9462     }
9464   [(set_attr "isa" "*,*,bmi2")
9465    (set (attr "type")
9466      (cond [(eq_attr "alternative" "1")
9467               (const_string "lea")
9468             (eq_attr "alternative" "2")
9469               (const_string "ishiftx")
9470             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471                  (match_operand 2 "const1_operand"))
9472               (const_string "alu")
9473            ]
9474            (const_string "ishift")))
9475    (set (attr "length_immediate")
9476      (if_then_else
9477        (ior (eq_attr "type" "alu")
9478             (and (eq_attr "type" "ishift")
9479                  (and (match_operand 2 "const1_operand")
9480                       (ior (match_test "TARGET_SHIFT1")
9481                            (match_test "optimize_function_for_size_p (cfun)")))))
9482        (const_string "0")
9483        (const_string "*")))
9484    (set_attr "mode" "SI")])
9486 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9487 (define_split
9488   [(set (match_operand:DI 0 "register_operand")
9489         (zero_extend:DI
9490           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9491                      (match_operand:QI 2 "register_operand"))))
9492    (clobber (reg:CC FLAGS_REG))]
9493   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9494   [(set (match_dup 0)
9495         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496   "operands[2] = gen_lowpart (SImode, operands[2]);")
9498 (define_insn "*ashlhi3_1"
9499   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9500         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9501                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9505   switch (get_attr_type (insn))
9506     {
9507     case TYPE_LEA:
9508       return "#";
9510     case TYPE_ALU:
9511       gcc_assert (operands[2] == const1_rtx);
9512       return "add{w}\t%0, %0";
9514     default:
9515       if (operands[2] == const1_rtx
9516           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9517         return "sal{w}\t%0";
9518       else
9519         return "sal{w}\t{%2, %0|%0, %2}";
9520     }
9522   [(set (attr "type")
9523      (cond [(eq_attr "alternative" "1")
9524               (const_string "lea")
9525             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9526                       (match_operand 0 "register_operand"))
9527                  (match_operand 2 "const1_operand"))
9528               (const_string "alu")
9529            ]
9530            (const_string "ishift")))
9531    (set (attr "length_immediate")
9532      (if_then_else
9533        (ior (eq_attr "type" "alu")
9534             (and (eq_attr "type" "ishift")
9535                  (and (match_operand 2 "const1_operand")
9536                       (ior (match_test "TARGET_SHIFT1")
9537                            (match_test "optimize_function_for_size_p (cfun)")))))
9538        (const_string "0")
9539        (const_string "*")))
9540    (set_attr "mode" "HI,SI")])
9542 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9543 (define_insn "*ashlqi3_1"
9544   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9545         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9546                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9547    (clobber (reg:CC FLAGS_REG))]
9548   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9550   switch (get_attr_type (insn))
9551     {
9552     case TYPE_LEA:
9553       return "#";
9555     case TYPE_ALU:
9556       gcc_assert (operands[2] == const1_rtx);
9557       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9558         return "add{l}\t%k0, %k0";
9559       else
9560         return "add{b}\t%0, %0";
9562     default:
9563       if (operands[2] == const1_rtx
9564           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9565         {
9566           if (get_attr_mode (insn) == MODE_SI)
9567             return "sal{l}\t%k0";
9568           else
9569             return "sal{b}\t%0";
9570         }
9571       else
9572         {
9573           if (get_attr_mode (insn) == MODE_SI)
9574             return "sal{l}\t{%2, %k0|%k0, %2}";
9575           else
9576             return "sal{b}\t{%2, %0|%0, %2}";
9577         }
9578     }
9580   [(set (attr "type")
9581      (cond [(eq_attr "alternative" "2")
9582               (const_string "lea")
9583             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584                       (match_operand 0 "register_operand"))
9585                  (match_operand 2 "const1_operand"))
9586               (const_string "alu")
9587            ]
9588            (const_string "ishift")))
9589    (set (attr "length_immediate")
9590      (if_then_else
9591        (ior (eq_attr "type" "alu")
9592             (and (eq_attr "type" "ishift")
9593                  (and (match_operand 2 "const1_operand")
9594                       (ior (match_test "TARGET_SHIFT1")
9595                            (match_test "optimize_function_for_size_p (cfun)")))))
9596        (const_string "0")
9597        (const_string "*")))
9598    (set_attr "mode" "QI,SI,SI")])
9600 (define_insn "*ashlqi3_1_slp"
9601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9602         (ashift:QI (match_dup 0)
9603                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9604    (clobber (reg:CC FLAGS_REG))]
9605   "(optimize_function_for_size_p (cfun)
9606     || !TARGET_PARTIAL_FLAG_REG_STALL
9607     || (operands[1] == const1_rtx
9608         && (TARGET_SHIFT1
9609             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9611   switch (get_attr_type (insn))
9612     {
9613     case TYPE_ALU:
9614       gcc_assert (operands[1] == const1_rtx);
9615       return "add{b}\t%0, %0";
9617     default:
9618       if (operands[1] == const1_rtx
9619           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9620         return "sal{b}\t%0";
9621       else
9622         return "sal{b}\t{%1, %0|%0, %1}";
9623     }
9625   [(set (attr "type")
9626      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9627                       (match_operand 0 "register_operand"))
9628                  (match_operand 1 "const1_operand"))
9629               (const_string "alu")
9630            ]
9631            (const_string "ishift1")))
9632    (set (attr "length_immediate")
9633      (if_then_else
9634        (ior (eq_attr "type" "alu")
9635             (and (eq_attr "type" "ishift1")
9636                  (and (match_operand 1 "const1_operand")
9637                       (ior (match_test "TARGET_SHIFT1")
9638                            (match_test "optimize_function_for_size_p (cfun)")))))
9639        (const_string "0")
9640        (const_string "*")))
9641    (set_attr "mode" "QI")])
9643 ;; Convert ashift to the lea pattern to avoid flags dependency.
9644 (define_split
9645   [(set (match_operand 0 "register_operand")
9646         (ashift (match_operand 1 "index_register_operand")
9647                 (match_operand:QI 2 "const_int_operand")))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9650    && reload_completed
9651    && true_regnum (operands[0]) != true_regnum (operands[1])"
9652   [(const_int 0)]
9654   machine_mode mode = GET_MODE (operands[0]);
9655   rtx pat;
9657   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9658     { 
9659       mode = SImode; 
9660       operands[0] = gen_lowpart (mode, operands[0]);
9661       operands[1] = gen_lowpart (mode, operands[1]);
9662     }
9664   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9666   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9668   emit_insn (gen_rtx_SET (operands[0], pat));
9669   DONE;
9672 ;; Convert ashift to the lea pattern to avoid flags dependency.
9673 (define_split
9674   [(set (match_operand:DI 0 "register_operand")
9675         (zero_extend:DI
9676           (ashift:SI (match_operand:SI 1 "index_register_operand")
9677                      (match_operand:QI 2 "const_int_operand"))))
9678    (clobber (reg:CC FLAGS_REG))]
9679   "TARGET_64BIT && reload_completed
9680    && true_regnum (operands[0]) != true_regnum (operands[1])"
9681   [(set (match_dup 0)
9682         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9684   operands[1] = gen_lowpart (SImode, operands[1]);
9685   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9688 ;; This pattern can't accept a variable shift count, since shifts by
9689 ;; zero don't affect the flags.  We assume that shifts by constant
9690 ;; zero are optimized away.
9691 (define_insn "*ashl<mode>3_cmp"
9692   [(set (reg FLAGS_REG)
9693         (compare
9694           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9695                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9696           (const_int 0)))
9697    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9698         (ashift:SWI (match_dup 1) (match_dup 2)))]
9699   "(optimize_function_for_size_p (cfun)
9700     || !TARGET_PARTIAL_FLAG_REG_STALL
9701     || (operands[2] == const1_rtx
9702         && (TARGET_SHIFT1
9703             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9704    && ix86_match_ccmode (insn, CCGOCmode)
9705    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9707   switch (get_attr_type (insn))
9708     {
9709     case TYPE_ALU:
9710       gcc_assert (operands[2] == const1_rtx);
9711       return "add{<imodesuffix>}\t%0, %0";
9713     default:
9714       if (operands[2] == const1_rtx
9715           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9716         return "sal{<imodesuffix>}\t%0";
9717       else
9718         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9719     }
9721   [(set (attr "type")
9722      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9723                       (match_operand 0 "register_operand"))
9724                  (match_operand 2 "const1_operand"))
9725               (const_string "alu")
9726            ]
9727            (const_string "ishift")))
9728    (set (attr "length_immediate")
9729      (if_then_else
9730        (ior (eq_attr "type" "alu")
9731             (and (eq_attr "type" "ishift")
9732                  (and (match_operand 2 "const1_operand")
9733                       (ior (match_test "TARGET_SHIFT1")
9734                            (match_test "optimize_function_for_size_p (cfun)")))))
9735        (const_string "0")
9736        (const_string "*")))
9737    (set_attr "mode" "<MODE>")])
9739 (define_insn "*ashlsi3_cmp_zext"
9740   [(set (reg FLAGS_REG)
9741         (compare
9742           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9743                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9744           (const_int 0)))
9745    (set (match_operand:DI 0 "register_operand" "=r")
9746         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9747   "TARGET_64BIT
9748    && (optimize_function_for_size_p (cfun)
9749        || !TARGET_PARTIAL_FLAG_REG_STALL
9750        || (operands[2] == const1_rtx
9751            && (TARGET_SHIFT1
9752                || TARGET_DOUBLE_WITH_ADD)))
9753    && ix86_match_ccmode (insn, CCGOCmode)
9754    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9756   switch (get_attr_type (insn))
9757     {
9758     case TYPE_ALU:
9759       gcc_assert (operands[2] == const1_rtx);
9760       return "add{l}\t%k0, %k0";
9762     default:
9763       if (operands[2] == const1_rtx
9764           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9765         return "sal{l}\t%k0";
9766       else
9767         return "sal{l}\t{%2, %k0|%k0, %2}";
9768     }
9770   [(set (attr "type")
9771      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9772                  (match_operand 2 "const1_operand"))
9773               (const_string "alu")
9774            ]
9775            (const_string "ishift")))
9776    (set (attr "length_immediate")
9777      (if_then_else
9778        (ior (eq_attr "type" "alu")
9779             (and (eq_attr "type" "ishift")
9780                  (and (match_operand 2 "const1_operand")
9781                       (ior (match_test "TARGET_SHIFT1")
9782                            (match_test "optimize_function_for_size_p (cfun)")))))
9783        (const_string "0")
9784        (const_string "*")))
9785    (set_attr "mode" "SI")])
9787 (define_insn "*ashl<mode>3_cconly"
9788   [(set (reg FLAGS_REG)
9789         (compare
9790           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9791                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9792           (const_int 0)))
9793    (clobber (match_scratch:SWI 0 "=<r>"))]
9794   "(optimize_function_for_size_p (cfun)
9795     || !TARGET_PARTIAL_FLAG_REG_STALL
9796     || (operands[2] == const1_rtx
9797         && (TARGET_SHIFT1
9798             || TARGET_DOUBLE_WITH_ADD)))
9799    && ix86_match_ccmode (insn, CCGOCmode)"
9801   switch (get_attr_type (insn))
9802     {
9803     case TYPE_ALU:
9804       gcc_assert (operands[2] == const1_rtx);
9805       return "add{<imodesuffix>}\t%0, %0";
9807     default:
9808       if (operands[2] == const1_rtx
9809           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9810         return "sal{<imodesuffix>}\t%0";
9811       else
9812         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9813     }
9815   [(set (attr "type")
9816      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9817                       (match_operand 0 "register_operand"))
9818                  (match_operand 2 "const1_operand"))
9819               (const_string "alu")
9820            ]
9821            (const_string "ishift")))
9822    (set (attr "length_immediate")
9823      (if_then_else
9824        (ior (eq_attr "type" "alu")
9825             (and (eq_attr "type" "ishift")
9826                  (and (match_operand 2 "const1_operand")
9827                       (ior (match_test "TARGET_SHIFT1")
9828                            (match_test "optimize_function_for_size_p (cfun)")))))
9829        (const_string "0")
9830        (const_string "*")))
9831    (set_attr "mode" "<MODE>")])
9833 ;; See comment above `ashl<mode>3' about how this works.
9835 (define_expand "<shift_insn><mode>3"
9836   [(set (match_operand:SDWIM 0 "<shift_operand>")
9837         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9838                            (match_operand:QI 2 "nonmemory_operand")))]
9839   ""
9840   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9842 ;; Avoid useless masking of count operand.
9843 (define_insn "*<shift_insn><mode>3_mask"
9844   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9845         (any_shiftrt:SWI48
9846           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9847           (subreg:QI
9848             (and:SI
9849               (match_operand:SI 2 "register_operand" "c")
9850               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9851    (clobber (reg:CC FLAGS_REG))]
9852   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9853    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9854       == GET_MODE_BITSIZE (<MODE>mode)-1"
9856   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9858   [(set_attr "type" "ishift")
9859    (set_attr "mode" "<MODE>")])
9861 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9862   [(set (match_operand:DWI 0 "register_operand" "=r")
9863         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9864                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9865    (clobber (reg:CC FLAGS_REG))]
9866   ""
9867   "#"
9868   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9869   [(const_int 0)]
9870   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9871   [(set_attr "type" "multi")])
9873 ;; By default we don't ask for a scratch register, because when DWImode
9874 ;; values are manipulated, registers are already at a premium.  But if
9875 ;; we have one handy, we won't turn it away.
9877 (define_peephole2
9878   [(match_scratch:DWIH 3 "r")
9879    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9880                    (any_shiftrt:<DWI>
9881                      (match_operand:<DWI> 1 "register_operand")
9882                      (match_operand:QI 2 "nonmemory_operand")))
9883               (clobber (reg:CC FLAGS_REG))])
9884    (match_dup 3)]
9885   "TARGET_CMOVE"
9886   [(const_int 0)]
9887   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9889 (define_insn "x86_64_shrd"
9890   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9891         (ior:DI (lshiftrt:DI (match_dup 0)
9892                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9893                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9894                   (minus:QI (const_int 64) (match_dup 2)))))
9895    (clobber (reg:CC FLAGS_REG))]
9896   "TARGET_64BIT"
9897   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9898   [(set_attr "type" "ishift")
9899    (set_attr "prefix_0f" "1")
9900    (set_attr "mode" "DI")
9901    (set_attr "athlon_decode" "vector")
9902    (set_attr "amdfam10_decode" "vector")
9903    (set_attr "bdver1_decode" "vector")])
9905 (define_insn "x86_shrd"
9906   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9907         (ior:SI (lshiftrt:SI (match_dup 0)
9908                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9909                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9910                   (minus:QI (const_int 32) (match_dup 2)))))
9911    (clobber (reg:CC FLAGS_REG))]
9912   ""
9913   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9914   [(set_attr "type" "ishift")
9915    (set_attr "prefix_0f" "1")
9916    (set_attr "mode" "SI")
9917    (set_attr "pent_pair" "np")
9918    (set_attr "athlon_decode" "vector")
9919    (set_attr "amdfam10_decode" "vector")
9920    (set_attr "bdver1_decode" "vector")])
9922 (define_insn "ashrdi3_cvt"
9923   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9924         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9925                      (match_operand:QI 2 "const_int_operand")))
9926    (clobber (reg:CC FLAGS_REG))]
9927   "TARGET_64BIT && INTVAL (operands[2]) == 63
9928    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9929    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9930   "@
9931    {cqto|cqo}
9932    sar{q}\t{%2, %0|%0, %2}"
9933   [(set_attr "type" "imovx,ishift")
9934    (set_attr "prefix_0f" "0,*")
9935    (set_attr "length_immediate" "0,*")
9936    (set_attr "modrm" "0,1")
9937    (set_attr "mode" "DI")])
9939 (define_insn "ashrsi3_cvt"
9940   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9941         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9942                      (match_operand:QI 2 "const_int_operand")))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "INTVAL (operands[2]) == 31
9945    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9946    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9947   "@
9948    {cltd|cdq}
9949    sar{l}\t{%2, %0|%0, %2}"
9950   [(set_attr "type" "imovx,ishift")
9951    (set_attr "prefix_0f" "0,*")
9952    (set_attr "length_immediate" "0,*")
9953    (set_attr "modrm" "0,1")
9954    (set_attr "mode" "SI")])
9956 (define_insn "*ashrsi3_cvt_zext"
9957   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9958         (zero_extend:DI
9959           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9960                        (match_operand:QI 2 "const_int_operand"))))
9961    (clobber (reg:CC FLAGS_REG))]
9962   "TARGET_64BIT && INTVAL (operands[2]) == 31
9963    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9964    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9965   "@
9966    {cltd|cdq}
9967    sar{l}\t{%2, %k0|%k0, %2}"
9968   [(set_attr "type" "imovx,ishift")
9969    (set_attr "prefix_0f" "0,*")
9970    (set_attr "length_immediate" "0,*")
9971    (set_attr "modrm" "0,1")
9972    (set_attr "mode" "SI")])
9974 (define_expand "x86_shift<mode>_adj_3"
9975   [(use (match_operand:SWI48 0 "register_operand"))
9976    (use (match_operand:SWI48 1 "register_operand"))
9977    (use (match_operand:QI 2 "register_operand"))]
9978   ""
9980   rtx_code_label *label = gen_label_rtx ();
9981   rtx tmp;
9983   emit_insn (gen_testqi_ccz_1 (operands[2],
9984                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9986   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9987   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9988   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9989                               gen_rtx_LABEL_REF (VOIDmode, label),
9990                               pc_rtx);
9991   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9992   JUMP_LABEL (tmp) = label;
9994   emit_move_insn (operands[0], operands[1]);
9995   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9996                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9997   emit_label (label);
9998   LABEL_NUSES (label) = 1;
10000   DONE;
10003 (define_insn "*bmi2_<shift_insn><mode>3_1"
10004   [(set (match_operand:SWI48 0 "register_operand" "=r")
10005         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10006                            (match_operand:SWI48 2 "register_operand" "r")))]
10007   "TARGET_BMI2"
10008   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10009   [(set_attr "type" "ishiftx")
10010    (set_attr "mode" "<MODE>")])
10012 (define_insn "*<shift_insn><mode>3_1"
10013   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10014         (any_shiftrt:SWI48
10015           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10016           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10017    (clobber (reg:CC FLAGS_REG))]
10018   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10020   switch (get_attr_type (insn))
10021     {
10022     case TYPE_ISHIFTX:
10023       return "#";
10025     default:
10026       if (operands[2] == const1_rtx
10027           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028         return "<shift>{<imodesuffix>}\t%0";
10029       else
10030         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10031     }
10033   [(set_attr "isa" "*,bmi2")
10034    (set_attr "type" "ishift,ishiftx")
10035    (set (attr "length_immediate")
10036      (if_then_else
10037        (and (match_operand 2 "const1_operand")
10038             (ior (match_test "TARGET_SHIFT1")
10039                  (match_test "optimize_function_for_size_p (cfun)")))
10040        (const_string "0")
10041        (const_string "*")))
10042    (set_attr "mode" "<MODE>")])
10044 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10045 (define_split
10046   [(set (match_operand:SWI48 0 "register_operand")
10047         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10048                            (match_operand:QI 2 "register_operand")))
10049    (clobber (reg:CC FLAGS_REG))]
10050   "TARGET_BMI2 && reload_completed"
10051   [(set (match_dup 0)
10052         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10053   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10055 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10056   [(set (match_operand:DI 0 "register_operand" "=r")
10057         (zero_extend:DI
10058           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10059                           (match_operand:SI 2 "register_operand" "r"))))]
10060   "TARGET_64BIT && TARGET_BMI2"
10061   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10062   [(set_attr "type" "ishiftx")
10063    (set_attr "mode" "SI")])
10065 (define_insn "*<shift_insn>si3_1_zext"
10066   [(set (match_operand:DI 0 "register_operand" "=r,r")
10067         (zero_extend:DI
10068           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10069                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10070    (clobber (reg:CC FLAGS_REG))]
10071   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10073   switch (get_attr_type (insn))
10074     {
10075     case TYPE_ISHIFTX:
10076       return "#";
10078     default:
10079       if (operands[2] == const1_rtx
10080           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10081         return "<shift>{l}\t%k0";
10082       else
10083         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10084     }
10086   [(set_attr "isa" "*,bmi2")
10087    (set_attr "type" "ishift,ishiftx")
10088    (set (attr "length_immediate")
10089      (if_then_else
10090        (and (match_operand 2 "const1_operand")
10091             (ior (match_test "TARGET_SHIFT1")
10092                  (match_test "optimize_function_for_size_p (cfun)")))
10093        (const_string "0")
10094        (const_string "*")))
10095    (set_attr "mode" "SI")])
10097 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10098 (define_split
10099   [(set (match_operand:DI 0 "register_operand")
10100         (zero_extend:DI
10101           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10102                           (match_operand:QI 2 "register_operand"))))
10103    (clobber (reg:CC FLAGS_REG))]
10104   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10105   [(set (match_dup 0)
10106         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10107   "operands[2] = gen_lowpart (SImode, operands[2]);")
10109 (define_insn "*<shift_insn><mode>3_1"
10110   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10111         (any_shiftrt:SWI12
10112           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10113           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10114    (clobber (reg:CC FLAGS_REG))]
10115   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10117   if (operands[2] == const1_rtx
10118       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119     return "<shift>{<imodesuffix>}\t%0";
10120   else
10121     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10123   [(set_attr "type" "ishift")
10124    (set (attr "length_immediate")
10125      (if_then_else
10126        (and (match_operand 2 "const1_operand")
10127             (ior (match_test "TARGET_SHIFT1")
10128                  (match_test "optimize_function_for_size_p (cfun)")))
10129        (const_string "0")
10130        (const_string "*")))
10131    (set_attr "mode" "<MODE>")])
10133 (define_insn "*<shift_insn>qi3_1_slp"
10134   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10135         (any_shiftrt:QI (match_dup 0)
10136                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10137    (clobber (reg:CC FLAGS_REG))]
10138   "(optimize_function_for_size_p (cfun)
10139     || !TARGET_PARTIAL_REG_STALL
10140     || (operands[1] == const1_rtx
10141         && TARGET_SHIFT1))"
10143   if (operands[1] == const1_rtx
10144       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10145     return "<shift>{b}\t%0";
10146   else
10147     return "<shift>{b}\t{%1, %0|%0, %1}";
10149   [(set_attr "type" "ishift1")
10150    (set (attr "length_immediate")
10151      (if_then_else
10152        (and (match_operand 1 "const1_operand")
10153             (ior (match_test "TARGET_SHIFT1")
10154                  (match_test "optimize_function_for_size_p (cfun)")))
10155        (const_string "0")
10156        (const_string "*")))
10157    (set_attr "mode" "QI")])
10159 ;; This pattern can't accept a variable shift count, since shifts by
10160 ;; zero don't affect the flags.  We assume that shifts by constant
10161 ;; zero are optimized away.
10162 (define_insn "*<shift_insn><mode>3_cmp"
10163   [(set (reg FLAGS_REG)
10164         (compare
10165           (any_shiftrt:SWI
10166             (match_operand:SWI 1 "nonimmediate_operand" "0")
10167             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10168           (const_int 0)))
10169    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10170         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10171   "(optimize_function_for_size_p (cfun)
10172     || !TARGET_PARTIAL_FLAG_REG_STALL
10173     || (operands[2] == const1_rtx
10174         && TARGET_SHIFT1))
10175    && ix86_match_ccmode (insn, CCGOCmode)
10176    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10178   if (operands[2] == const1_rtx
10179       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10180     return "<shift>{<imodesuffix>}\t%0";
10181   else
10182     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10184   [(set_attr "type" "ishift")
10185    (set (attr "length_immediate")
10186      (if_then_else
10187        (and (match_operand 2 "const1_operand")
10188             (ior (match_test "TARGET_SHIFT1")
10189                  (match_test "optimize_function_for_size_p (cfun)")))
10190        (const_string "0")
10191        (const_string "*")))
10192    (set_attr "mode" "<MODE>")])
10194 (define_insn "*<shift_insn>si3_cmp_zext"
10195   [(set (reg FLAGS_REG)
10196         (compare
10197           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10198                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10199           (const_int 0)))
10200    (set (match_operand:DI 0 "register_operand" "=r")
10201         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10202   "TARGET_64BIT
10203    && (optimize_function_for_size_p (cfun)
10204        || !TARGET_PARTIAL_FLAG_REG_STALL
10205        || (operands[2] == const1_rtx
10206            && TARGET_SHIFT1))
10207    && ix86_match_ccmode (insn, CCGOCmode)
10208    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10210   if (operands[2] == const1_rtx
10211       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10212     return "<shift>{l}\t%k0";
10213   else
10214     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10216   [(set_attr "type" "ishift")
10217    (set (attr "length_immediate")
10218      (if_then_else
10219        (and (match_operand 2 "const1_operand")
10220             (ior (match_test "TARGET_SHIFT1")
10221                  (match_test "optimize_function_for_size_p (cfun)")))
10222        (const_string "0")
10223        (const_string "*")))
10224    (set_attr "mode" "SI")])
10226 (define_insn "*<shift_insn><mode>3_cconly"
10227   [(set (reg FLAGS_REG)
10228         (compare
10229           (any_shiftrt:SWI
10230             (match_operand:SWI 1 "register_operand" "0")
10231             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10232           (const_int 0)))
10233    (clobber (match_scratch:SWI 0 "=<r>"))]
10234   "(optimize_function_for_size_p (cfun)
10235     || !TARGET_PARTIAL_FLAG_REG_STALL
10236     || (operands[2] == const1_rtx
10237         && TARGET_SHIFT1))
10238    && ix86_match_ccmode (insn, CCGOCmode)"
10240   if (operands[2] == const1_rtx
10241       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10242     return "<shift>{<imodesuffix>}\t%0";
10243   else
10244     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10246   [(set_attr "type" "ishift")
10247    (set (attr "length_immediate")
10248      (if_then_else
10249        (and (match_operand 2 "const1_operand")
10250             (ior (match_test "TARGET_SHIFT1")
10251                  (match_test "optimize_function_for_size_p (cfun)")))
10252        (const_string "0")
10253        (const_string "*")))
10254    (set_attr "mode" "<MODE>")])
10256 ;; Rotate instructions
10258 (define_expand "<rotate_insn>ti3"
10259   [(set (match_operand:TI 0 "register_operand")
10260         (any_rotate:TI (match_operand:TI 1 "register_operand")
10261                        (match_operand:QI 2 "nonmemory_operand")))]
10262   "TARGET_64BIT"
10264   if (const_1_to_63_operand (operands[2], VOIDmode))
10265     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10266                 (operands[0], operands[1], operands[2]));
10267   else
10268     FAIL;
10270   DONE;
10273 (define_expand "<rotate_insn>di3"
10274   [(set (match_operand:DI 0 "shiftdi_operand")
10275         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10276                        (match_operand:QI 2 "nonmemory_operand")))]
10277  ""
10279   if (TARGET_64BIT)
10280     ix86_expand_binary_operator (<CODE>, DImode, operands);
10281   else if (const_1_to_31_operand (operands[2], VOIDmode))
10282     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10283                 (operands[0], operands[1], operands[2]));
10284   else
10285     FAIL;
10287   DONE;
10290 (define_expand "<rotate_insn><mode>3"
10291   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10292         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10293                             (match_operand:QI 2 "nonmemory_operand")))]
10294   ""
10295   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10297 ;; Avoid useless masking of count operand.
10298 (define_insn "*<rotate_insn><mode>3_mask"
10299   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10300         (any_rotate:SWI48
10301           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10302           (subreg:QI
10303             (and:SI
10304               (match_operand:SI 2 "register_operand" "c")
10305               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10306    (clobber (reg:CC FLAGS_REG))]
10307   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10308    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10309       == GET_MODE_BITSIZE (<MODE>mode)-1"
10311   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10313   [(set_attr "type" "rotate")
10314    (set_attr "mode" "<MODE>")])
10316 ;; Implement rotation using two double-precision
10317 ;; shift instructions and a scratch register.
10319 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10320  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10321        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10322                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10323   (clobber (reg:CC FLAGS_REG))
10324   (clobber (match_scratch:DWIH 3 "=&r"))]
10325  ""
10326  "#"
10327  "reload_completed"
10328  [(set (match_dup 3) (match_dup 4))
10329   (parallel
10330    [(set (match_dup 4)
10331          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10332                    (lshiftrt:DWIH (match_dup 5)
10333                                   (minus:QI (match_dup 6) (match_dup 2)))))
10334     (clobber (reg:CC FLAGS_REG))])
10335   (parallel
10336    [(set (match_dup 5)
10337          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10338                    (lshiftrt:DWIH (match_dup 3)
10339                                   (minus:QI (match_dup 6) (match_dup 2)))))
10340     (clobber (reg:CC FLAGS_REG))])]
10342   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10344   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10347 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10348  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10349        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10350                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10351   (clobber (reg:CC FLAGS_REG))
10352   (clobber (match_scratch:DWIH 3 "=&r"))]
10353  ""
10354  "#"
10355  "reload_completed"
10356  [(set (match_dup 3) (match_dup 4))
10357   (parallel
10358    [(set (match_dup 4)
10359          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10360                    (ashift:DWIH (match_dup 5)
10361                                 (minus:QI (match_dup 6) (match_dup 2)))))
10362     (clobber (reg:CC FLAGS_REG))])
10363   (parallel
10364    [(set (match_dup 5)
10365          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10366                    (ashift:DWIH (match_dup 3)
10367                                 (minus:QI (match_dup 6) (match_dup 2)))))
10368     (clobber (reg:CC FLAGS_REG))])]
10370   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10372   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10375 (define_insn "*bmi2_rorx<mode>3_1"
10376   [(set (match_operand:SWI48 0 "register_operand" "=r")
10377         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10378                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10379   "TARGET_BMI2"
10380   "rorx\t{%2, %1, %0|%0, %1, %2}"
10381   [(set_attr "type" "rotatex")
10382    (set_attr "mode" "<MODE>")])
10384 (define_insn "*<rotate_insn><mode>3_1"
10385   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10386         (any_rotate:SWI48
10387           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10388           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10389    (clobber (reg:CC FLAGS_REG))]
10390   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392   switch (get_attr_type (insn))
10393     {
10394     case TYPE_ROTATEX:
10395       return "#";
10397     default:
10398       if (operands[2] == const1_rtx
10399           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10400         return "<rotate>{<imodesuffix>}\t%0";
10401       else
10402         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10403     }
10405   [(set_attr "isa" "*,bmi2")
10406    (set_attr "type" "rotate,rotatex")
10407    (set (attr "length_immediate")
10408      (if_then_else
10409        (and (eq_attr "type" "rotate")
10410             (and (match_operand 2 "const1_operand")
10411                  (ior (match_test "TARGET_SHIFT1")
10412                       (match_test "optimize_function_for_size_p (cfun)"))))
10413        (const_string "0")
10414        (const_string "*")))
10415    (set_attr "mode" "<MODE>")])
10417 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10418 (define_split
10419   [(set (match_operand:SWI48 0 "register_operand")
10420         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10421                       (match_operand:QI 2 "immediate_operand")))
10422    (clobber (reg:CC FLAGS_REG))]
10423   "TARGET_BMI2 && reload_completed"
10424   [(set (match_dup 0)
10425         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10427   operands[2]
10428     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10431 (define_split
10432   [(set (match_operand:SWI48 0 "register_operand")
10433         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10434                         (match_operand:QI 2 "immediate_operand")))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "TARGET_BMI2 && reload_completed"
10437   [(set (match_dup 0)
10438         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10440 (define_insn "*bmi2_rorxsi3_1_zext"
10441   [(set (match_operand:DI 0 "register_operand" "=r")
10442         (zero_extend:DI
10443           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10444                        (match_operand:QI 2 "immediate_operand" "I"))))]
10445   "TARGET_64BIT && TARGET_BMI2"
10446   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10447   [(set_attr "type" "rotatex")
10448    (set_attr "mode" "SI")])
10450 (define_insn "*<rotate_insn>si3_1_zext"
10451   [(set (match_operand:DI 0 "register_operand" "=r,r")
10452         (zero_extend:DI
10453           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10454                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10455    (clobber (reg:CC FLAGS_REG))]
10456   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10458   switch (get_attr_type (insn))
10459     {
10460     case TYPE_ROTATEX:
10461       return "#";
10463     default:
10464       if (operands[2] == const1_rtx
10465           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10466         return "<rotate>{l}\t%k0";
10467       else
10468         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10469     }
10471   [(set_attr "isa" "*,bmi2")
10472    (set_attr "type" "rotate,rotatex")
10473    (set (attr "length_immediate")
10474      (if_then_else
10475        (and (eq_attr "type" "rotate")
10476             (and (match_operand 2 "const1_operand")
10477                  (ior (match_test "TARGET_SHIFT1")
10478                       (match_test "optimize_function_for_size_p (cfun)"))))
10479        (const_string "0")
10480        (const_string "*")))
10481    (set_attr "mode" "SI")])
10483 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10484 (define_split
10485   [(set (match_operand:DI 0 "register_operand")
10486         (zero_extend:DI
10487           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10488                      (match_operand:QI 2 "immediate_operand"))))
10489    (clobber (reg:CC FLAGS_REG))]
10490   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10491   [(set (match_dup 0)
10492         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10494   operands[2]
10495     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10498 (define_split
10499   [(set (match_operand:DI 0 "register_operand")
10500         (zero_extend:DI
10501           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10502                        (match_operand:QI 2 "immediate_operand"))))
10503    (clobber (reg:CC FLAGS_REG))]
10504   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10505   [(set (match_dup 0)
10506         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10508 (define_insn "*<rotate_insn><mode>3_1"
10509   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10510         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10511                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10512    (clobber (reg:CC FLAGS_REG))]
10513   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10515   if (operands[2] == const1_rtx
10516       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10517     return "<rotate>{<imodesuffix>}\t%0";
10518   else
10519     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10521   [(set_attr "type" "rotate")
10522    (set (attr "length_immediate")
10523      (if_then_else
10524        (and (match_operand 2 "const1_operand")
10525             (ior (match_test "TARGET_SHIFT1")
10526                  (match_test "optimize_function_for_size_p (cfun)")))
10527        (const_string "0")
10528        (const_string "*")))
10529    (set_attr "mode" "<MODE>")])
10531 (define_insn "*<rotate_insn>qi3_1_slp"
10532   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10533         (any_rotate:QI (match_dup 0)
10534                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10535    (clobber (reg:CC FLAGS_REG))]
10536   "(optimize_function_for_size_p (cfun)
10537     || !TARGET_PARTIAL_REG_STALL
10538     || (operands[1] == const1_rtx
10539         && TARGET_SHIFT1))"
10541   if (operands[1] == const1_rtx
10542       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10543     return "<rotate>{b}\t%0";
10544   else
10545     return "<rotate>{b}\t{%1, %0|%0, %1}";
10547   [(set_attr "type" "rotate1")
10548    (set (attr "length_immediate")
10549      (if_then_else
10550        (and (match_operand 1 "const1_operand")
10551             (ior (match_test "TARGET_SHIFT1")
10552                  (match_test "optimize_function_for_size_p (cfun)")))
10553        (const_string "0")
10554        (const_string "*")))
10555    (set_attr "mode" "QI")])
10557 (define_split
10558  [(set (match_operand:HI 0 "register_operand")
10559        (any_rotate:HI (match_dup 0) (const_int 8)))
10560   (clobber (reg:CC FLAGS_REG))]
10561  "reload_completed
10562   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10563  [(parallel [(set (strict_low_part (match_dup 0))
10564                   (bswap:HI (match_dup 0)))
10565              (clobber (reg:CC FLAGS_REG))])])
10567 ;; Bit set / bit test instructions
10569 (define_expand "extv"
10570   [(set (match_operand:SI 0 "register_operand")
10571         (sign_extract:SI (match_operand:SI 1 "register_operand")
10572                          (match_operand:SI 2 "const8_operand")
10573                          (match_operand:SI 3 "const8_operand")))]
10574   ""
10576   /* Handle extractions from %ah et al.  */
10577   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10578     FAIL;
10580   /* From mips.md: extract_bit_field doesn't verify that our source
10581      matches the predicate, so check it again here.  */
10582   if (! ext_register_operand (operands[1], VOIDmode))
10583     FAIL;
10586 (define_expand "extzv"
10587   [(set (match_operand:SI 0 "register_operand")
10588         (zero_extract:SI (match_operand 1 "ext_register_operand")
10589                          (match_operand:SI 2 "const8_operand")
10590                          (match_operand:SI 3 "const8_operand")))]
10591   ""
10593   /* Handle extractions from %ah et al.  */
10594   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10595     FAIL;
10597   /* From mips.md: extract_bit_field doesn't verify that our source
10598      matches the predicate, so check it again here.  */
10599   if (! ext_register_operand (operands[1], VOIDmode))
10600     FAIL;
10603 (define_expand "insv"
10604   [(set (zero_extract (match_operand 0 "register_operand")
10605                       (match_operand 1 "const_int_operand")
10606                       (match_operand 2 "const_int_operand"))
10607         (match_operand 3 "register_operand"))]
10608   ""
10610   rtx (*gen_mov_insv_1) (rtx, rtx);
10612   if (ix86_expand_pinsr (operands))
10613     DONE;
10615   /* Handle insertions to %ah et al.  */
10616   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10617     FAIL;
10619   /* From mips.md: insert_bit_field doesn't verify that our source
10620      matches the predicate, so check it again here.  */
10621   if (! ext_register_operand (operands[0], VOIDmode))
10622     FAIL;
10624   gen_mov_insv_1 = (TARGET_64BIT
10625                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10627   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10628   DONE;
10631 ;; %%% bts, btr, btc, bt.
10632 ;; In general these instructions are *slow* when applied to memory,
10633 ;; since they enforce atomic operation.  When applied to registers,
10634 ;; it depends on the cpu implementation.  They're never faster than
10635 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10636 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10637 ;; within the instruction itself, so operating on bits in the high
10638 ;; 32-bits of a register becomes easier.
10640 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10641 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10642 ;; negdf respectively, so they can never be disabled entirely.
10644 (define_insn "*btsq"
10645   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10646                          (const_int 1)
10647                          (match_operand:DI 1 "const_0_to_63_operand"))
10648         (const_int 1))
10649    (clobber (reg:CC FLAGS_REG))]
10650   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10651   "bts{q}\t{%1, %0|%0, %1}"
10652   [(set_attr "type" "alu1")
10653    (set_attr "prefix_0f" "1")
10654    (set_attr "mode" "DI")])
10656 (define_insn "*btrq"
10657   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10658                          (const_int 1)
10659                          (match_operand:DI 1 "const_0_to_63_operand"))
10660         (const_int 0))
10661    (clobber (reg:CC FLAGS_REG))]
10662   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10663   "btr{q}\t{%1, %0|%0, %1}"
10664   [(set_attr "type" "alu1")
10665    (set_attr "prefix_0f" "1")
10666    (set_attr "mode" "DI")])
10668 (define_insn "*btcq"
10669   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10670                          (const_int 1)
10671                          (match_operand:DI 1 "const_0_to_63_operand"))
10672         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10673    (clobber (reg:CC FLAGS_REG))]
10674   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10675   "btc{q}\t{%1, %0|%0, %1}"
10676   [(set_attr "type" "alu1")
10677    (set_attr "prefix_0f" "1")
10678    (set_attr "mode" "DI")])
10680 ;; Allow Nocona to avoid these instructions if a register is available.
10682 (define_peephole2
10683   [(match_scratch:DI 2 "r")
10684    (parallel [(set (zero_extract:DI
10685                      (match_operand:DI 0 "register_operand")
10686                      (const_int 1)
10687                      (match_operand:DI 1 "const_0_to_63_operand"))
10688                    (const_int 1))
10689               (clobber (reg:CC FLAGS_REG))])]
10690   "TARGET_64BIT && !TARGET_USE_BT"
10691   [(const_int 0)]
10693   int i = INTVAL (operands[1]);
10695   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10697   if (i >= 31)
10698     {
10699       emit_move_insn (operands[2], op1);
10700       op1 = operands[2];
10701     }
10703   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10704   DONE;
10707 (define_peephole2
10708   [(match_scratch:DI 2 "r")
10709    (parallel [(set (zero_extract:DI
10710                      (match_operand:DI 0 "register_operand")
10711                      (const_int 1)
10712                      (match_operand:DI 1 "const_0_to_63_operand"))
10713                    (const_int 0))
10714               (clobber (reg:CC FLAGS_REG))])]
10715   "TARGET_64BIT && !TARGET_USE_BT"
10716   [(const_int 0)]
10718   int i = INTVAL (operands[1]);
10720   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10722   if (i >= 32)
10723     {
10724       emit_move_insn (operands[2], op1);
10725       op1 = operands[2];
10726     }
10728   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10729   DONE;
10732 (define_peephole2
10733   [(match_scratch:DI 2 "r")
10734    (parallel [(set (zero_extract:DI
10735                      (match_operand:DI 0 "register_operand")
10736                      (const_int 1)
10737                      (match_operand:DI 1 "const_0_to_63_operand"))
10738               (not:DI (zero_extract:DI
10739                         (match_dup 0) (const_int 1) (match_dup 1))))
10740               (clobber (reg:CC FLAGS_REG))])]
10741   "TARGET_64BIT && !TARGET_USE_BT"
10742   [(const_int 0)]
10744   int i = INTVAL (operands[1]);
10746   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10748   if (i >= 31)
10749     {
10750       emit_move_insn (operands[2], op1);
10751       op1 = operands[2];
10752     }
10754   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10755   DONE;
10758 (define_insn "*bt<mode>"
10759   [(set (reg:CCC FLAGS_REG)
10760         (compare:CCC
10761           (zero_extract:SWI48
10762             (match_operand:SWI48 0 "register_operand" "r")
10763             (const_int 1)
10764             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10765           (const_int 0)))]
10766   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10767   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10768   [(set_attr "type" "alu1")
10769    (set_attr "prefix_0f" "1")
10770    (set_attr "mode" "<MODE>")])
10772 ;; Store-flag instructions.
10774 ;; For all sCOND expanders, also expand the compare or test insn that
10775 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10777 (define_insn_and_split "*setcc_di_1"
10778   [(set (match_operand:DI 0 "register_operand" "=q")
10779         (match_operator:DI 1 "ix86_comparison_operator"
10780           [(reg FLAGS_REG) (const_int 0)]))]
10781   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10782   "#"
10783   "&& reload_completed"
10784   [(set (match_dup 2) (match_dup 1))
10785    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10787   PUT_MODE (operands[1], QImode);
10788   operands[2] = gen_lowpart (QImode, operands[0]);
10791 (define_insn_and_split "*setcc_si_1_and"
10792   [(set (match_operand:SI 0 "register_operand" "=q")
10793         (match_operator:SI 1 "ix86_comparison_operator"
10794           [(reg FLAGS_REG) (const_int 0)]))
10795    (clobber (reg:CC FLAGS_REG))]
10796   "!TARGET_PARTIAL_REG_STALL
10797    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10798   "#"
10799   "&& reload_completed"
10800   [(set (match_dup 2) (match_dup 1))
10801    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10802               (clobber (reg:CC FLAGS_REG))])]
10804   PUT_MODE (operands[1], QImode);
10805   operands[2] = gen_lowpart (QImode, operands[0]);
10808 (define_insn_and_split "*setcc_si_1_movzbl"
10809   [(set (match_operand:SI 0 "register_operand" "=q")
10810         (match_operator:SI 1 "ix86_comparison_operator"
10811           [(reg FLAGS_REG) (const_int 0)]))]
10812   "!TARGET_PARTIAL_REG_STALL
10813    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10814   "#"
10815   "&& reload_completed"
10816   [(set (match_dup 2) (match_dup 1))
10817    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10819   PUT_MODE (operands[1], QImode);
10820   operands[2] = gen_lowpart (QImode, operands[0]);
10823 (define_insn "*setcc_qi"
10824   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10825         (match_operator:QI 1 "ix86_comparison_operator"
10826           [(reg FLAGS_REG) (const_int 0)]))]
10827   ""
10828   "set%C1\t%0"
10829   [(set_attr "type" "setcc")
10830    (set_attr "mode" "QI")])
10832 (define_insn "*setcc_qi_slp"
10833   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10834         (match_operator:QI 1 "ix86_comparison_operator"
10835           [(reg FLAGS_REG) (const_int 0)]))]
10836   ""
10837   "set%C1\t%0"
10838   [(set_attr "type" "setcc")
10839    (set_attr "mode" "QI")])
10841 ;; In general it is not safe to assume too much about CCmode registers,
10842 ;; so simplify-rtx stops when it sees a second one.  Under certain
10843 ;; conditions this is safe on x86, so help combine not create
10845 ;;      seta    %al
10846 ;;      testb   %al, %al
10847 ;;      sete    %al
10849 (define_split
10850   [(set (match_operand:QI 0 "nonimmediate_operand")
10851         (ne:QI (match_operator 1 "ix86_comparison_operator"
10852                  [(reg FLAGS_REG) (const_int 0)])
10853             (const_int 0)))]
10854   ""
10855   [(set (match_dup 0) (match_dup 1))]
10856   "PUT_MODE (operands[1], QImode);")
10858 (define_split
10859   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10860         (ne:QI (match_operator 1 "ix86_comparison_operator"
10861                  [(reg FLAGS_REG) (const_int 0)])
10862             (const_int 0)))]
10863   ""
10864   [(set (match_dup 0) (match_dup 1))]
10865   "PUT_MODE (operands[1], QImode);")
10867 (define_split
10868   [(set (match_operand:QI 0 "nonimmediate_operand")
10869         (eq:QI (match_operator 1 "ix86_comparison_operator"
10870                  [(reg FLAGS_REG) (const_int 0)])
10871             (const_int 0)))]
10872   ""
10873   [(set (match_dup 0) (match_dup 1))]
10875   rtx new_op1 = copy_rtx (operands[1]);
10876   operands[1] = new_op1;
10877   PUT_MODE (new_op1, QImode);
10878   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10879                                              GET_MODE (XEXP (new_op1, 0))));
10881   /* Make sure that (a) the CCmode we have for the flags is strong
10882      enough for the reversed compare or (b) we have a valid FP compare.  */
10883   if (! ix86_comparison_operator (new_op1, VOIDmode))
10884     FAIL;
10887 (define_split
10888   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10889         (eq:QI (match_operator 1 "ix86_comparison_operator"
10890                  [(reg FLAGS_REG) (const_int 0)])
10891             (const_int 0)))]
10892   ""
10893   [(set (match_dup 0) (match_dup 1))]
10895   rtx new_op1 = copy_rtx (operands[1]);
10896   operands[1] = new_op1;
10897   PUT_MODE (new_op1, QImode);
10898   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10899                                              GET_MODE (XEXP (new_op1, 0))));
10901   /* Make sure that (a) the CCmode we have for the flags is strong
10902      enough for the reversed compare or (b) we have a valid FP compare.  */
10903   if (! ix86_comparison_operator (new_op1, VOIDmode))
10904     FAIL;
10907 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10908 ;; subsequent logical operations are used to imitate conditional moves.
10909 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10910 ;; it directly.
10912 (define_insn "setcc_<mode>_sse"
10913   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10914         (match_operator:MODEF 3 "sse_comparison_operator"
10915           [(match_operand:MODEF 1 "register_operand" "0,x")
10916            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10917   "SSE_FLOAT_MODE_P (<MODE>mode)"
10918   "@
10919    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10920    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10921   [(set_attr "isa" "noavx,avx")
10922    (set_attr "type" "ssecmp")
10923    (set_attr "length_immediate" "1")
10924    (set_attr "prefix" "orig,vex")
10925    (set_attr "mode" "<MODE>")])
10927 ;; Basic conditional jump instructions.
10928 ;; We ignore the overflow flag for signed branch instructions.
10930 (define_insn "*jcc_1_bnd"
10931   [(set (pc)
10932         (if_then_else (match_operator 1 "ix86_comparison_operator"
10933                                       [(reg FLAGS_REG) (const_int 0)])
10934                       (label_ref (match_operand 0))
10935                       (pc)))]
10936   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10937   "bnd %+j%C1\t%l0"
10938   [(set_attr "type" "ibr")
10939    (set_attr "modrm" "0")
10940    (set (attr "length")
10941            (if_then_else (and (ge (minus (match_dup 0) (pc))
10942                                   (const_int -126))
10943                               (lt (minus (match_dup 0) (pc))
10944                                   (const_int 128)))
10945              (const_int 3)
10946              (const_int 7)))])
10948 (define_insn "*jcc_1"
10949   [(set (pc)
10950         (if_then_else (match_operator 1 "ix86_comparison_operator"
10951                                       [(reg FLAGS_REG) (const_int 0)])
10952                       (label_ref (match_operand 0))
10953                       (pc)))]
10954   ""
10955   "%+j%C1\t%l0"
10956   [(set_attr "type" "ibr")
10957    (set_attr "modrm" "0")
10958    (set (attr "length")
10959            (if_then_else (and (ge (minus (match_dup 0) (pc))
10960                                   (const_int -126))
10961                               (lt (minus (match_dup 0) (pc))
10962                                   (const_int 128)))
10963              (const_int 2)
10964              (const_int 6)))])
10966 (define_insn "*jcc_2_bnd"
10967   [(set (pc)
10968         (if_then_else (match_operator 1 "ix86_comparison_operator"
10969                                       [(reg FLAGS_REG) (const_int 0)])
10970                       (pc)
10971                       (label_ref (match_operand 0))))]
10972   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10973   "bnd %+j%c1\t%l0"
10974   [(set_attr "type" "ibr")
10975    (set_attr "modrm" "0")
10976    (set (attr "length")
10977            (if_then_else (and (ge (minus (match_dup 0) (pc))
10978                                   (const_int -126))
10979                               (lt (minus (match_dup 0) (pc))
10980                                   (const_int 128)))
10981              (const_int 3)
10982              (const_int 7)))])
10984 (define_insn "*jcc_2"
10985   [(set (pc)
10986         (if_then_else (match_operator 1 "ix86_comparison_operator"
10987                                       [(reg FLAGS_REG) (const_int 0)])
10988                       (pc)
10989                       (label_ref (match_operand 0))))]
10990   ""
10991   "%+j%c1\t%l0"
10992   [(set_attr "type" "ibr")
10993    (set_attr "modrm" "0")
10994    (set (attr "length")
10995            (if_then_else (and (ge (minus (match_dup 0) (pc))
10996                                   (const_int -126))
10997                               (lt (minus (match_dup 0) (pc))
10998                                   (const_int 128)))
10999              (const_int 2)
11000              (const_int 6)))])
11002 ;; In general it is not safe to assume too much about CCmode registers,
11003 ;; so simplify-rtx stops when it sees a second one.  Under certain
11004 ;; conditions this is safe on x86, so help combine not create
11006 ;;      seta    %al
11007 ;;      testb   %al, %al
11008 ;;      je      Lfoo
11010 (define_split
11011   [(set (pc)
11012         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11013                                       [(reg FLAGS_REG) (const_int 0)])
11014                           (const_int 0))
11015                       (label_ref (match_operand 1))
11016                       (pc)))]
11017   ""
11018   [(set (pc)
11019         (if_then_else (match_dup 0)
11020                       (label_ref (match_dup 1))
11021                       (pc)))]
11022   "PUT_MODE (operands[0], VOIDmode);")
11024 (define_split
11025   [(set (pc)
11026         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11027                                       [(reg FLAGS_REG) (const_int 0)])
11028                           (const_int 0))
11029                       (label_ref (match_operand 1))
11030                       (pc)))]
11031   ""
11032   [(set (pc)
11033         (if_then_else (match_dup 0)
11034                       (label_ref (match_dup 1))
11035                       (pc)))]
11037   rtx new_op0 = copy_rtx (operands[0]);
11038   operands[0] = new_op0;
11039   PUT_MODE (new_op0, VOIDmode);
11040   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11041                                              GET_MODE (XEXP (new_op0, 0))));
11043   /* Make sure that (a) the CCmode we have for the flags is strong
11044      enough for the reversed compare or (b) we have a valid FP compare.  */
11045   if (! ix86_comparison_operator (new_op0, VOIDmode))
11046     FAIL;
11049 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11050 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11051 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11052 ;; appropriate modulo of the bit offset value.
11054 (define_insn_and_split "*jcc_bt<mode>"
11055   [(set (pc)
11056         (if_then_else (match_operator 0 "bt_comparison_operator"
11057                         [(zero_extract:SWI48
11058                            (match_operand:SWI48 1 "register_operand" "r")
11059                            (const_int 1)
11060                            (zero_extend:SI
11061                              (match_operand:QI 2 "register_operand" "r")))
11062                          (const_int 0)])
11063                       (label_ref (match_operand 3))
11064                       (pc)))
11065    (clobber (reg:CC FLAGS_REG))]
11066   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11067   "#"
11068   "&& 1"
11069   [(set (reg:CCC FLAGS_REG)
11070         (compare:CCC
11071           (zero_extract:SWI48
11072             (match_dup 1)
11073             (const_int 1)
11074             (match_dup 2))
11075           (const_int 0)))
11076    (set (pc)
11077         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11078                       (label_ref (match_dup 3))
11079                       (pc)))]
11081   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11083   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11086 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11087 ;; zero extended to SImode.
11088 (define_insn_and_split "*jcc_bt<mode>_1"
11089   [(set (pc)
11090         (if_then_else (match_operator 0 "bt_comparison_operator"
11091                         [(zero_extract:SWI48
11092                            (match_operand:SWI48 1 "register_operand" "r")
11093                            (const_int 1)
11094                            (match_operand:SI 2 "register_operand" "r"))
11095                          (const_int 0)])
11096                       (label_ref (match_operand 3))
11097                       (pc)))
11098    (clobber (reg:CC FLAGS_REG))]
11099   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11100   "#"
11101   "&& 1"
11102   [(set (reg:CCC FLAGS_REG)
11103         (compare:CCC
11104           (zero_extract:SWI48
11105             (match_dup 1)
11106             (const_int 1)
11107             (match_dup 2))
11108           (const_int 0)))
11109    (set (pc)
11110         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11111                       (label_ref (match_dup 3))
11112                       (pc)))]
11114   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11116   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11119 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11120 ;; also for DImode, this is what combine produces.
11121 (define_insn_and_split "*jcc_bt<mode>_mask"
11122   [(set (pc)
11123         (if_then_else (match_operator 0 "bt_comparison_operator"
11124                         [(zero_extract:SWI48
11125                            (match_operand:SWI48 1 "register_operand" "r")
11126                            (const_int 1)
11127                            (and:SI
11128                              (match_operand:SI 2 "register_operand" "r")
11129                              (match_operand:SI 3 "const_int_operand" "n")))])
11130                       (label_ref (match_operand 4))
11131                       (pc)))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11134    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11135       == GET_MODE_BITSIZE (<MODE>mode)-1"
11136   "#"
11137   "&& 1"
11138   [(set (reg:CCC FLAGS_REG)
11139         (compare:CCC
11140           (zero_extract:SWI48
11141             (match_dup 1)
11142             (const_int 1)
11143             (match_dup 2))
11144           (const_int 0)))
11145    (set (pc)
11146         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11147                       (label_ref (match_dup 4))
11148                       (pc)))]
11150   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11152   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11155 (define_insn_and_split "*jcc_btsi_1"
11156   [(set (pc)
11157         (if_then_else (match_operator 0 "bt_comparison_operator"
11158                         [(and:SI
11159                            (lshiftrt:SI
11160                              (match_operand:SI 1 "register_operand" "r")
11161                              (match_operand:QI 2 "register_operand" "r"))
11162                            (const_int 1))
11163                          (const_int 0)])
11164                       (label_ref (match_operand 3))
11165                       (pc)))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11168   "#"
11169   "&& 1"
11170   [(set (reg:CCC FLAGS_REG)
11171         (compare:CCC
11172           (zero_extract:SI
11173             (match_dup 1)
11174             (const_int 1)
11175             (match_dup 2))
11176           (const_int 0)))
11177    (set (pc)
11178         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11179                       (label_ref (match_dup 3))
11180                       (pc)))]
11182   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11184   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11187 ;; avoid useless masking of bit offset operand
11188 (define_insn_and_split "*jcc_btsi_mask_1"
11189   [(set (pc)
11190         (if_then_else
11191           (match_operator 0 "bt_comparison_operator"
11192             [(and:SI
11193                (lshiftrt:SI
11194                  (match_operand:SI 1 "register_operand" "r")
11195                  (subreg:QI
11196                    (and:SI
11197                      (match_operand:SI 2 "register_operand" "r")
11198                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11199                (const_int 1))
11200              (const_int 0)])
11201           (label_ref (match_operand 4))
11202           (pc)))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11205    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11206   "#"
11207   "&& 1"
11208   [(set (reg:CCC FLAGS_REG)
11209         (compare:CCC
11210           (zero_extract:SI
11211             (match_dup 1)
11212             (const_int 1)
11213             (match_dup 2))
11214           (const_int 0)))
11215    (set (pc)
11216         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11217                       (label_ref (match_dup 4))
11218                       (pc)))]
11219   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11221 ;; Define combination compare-and-branch fp compare instructions to help
11222 ;; combine.
11224 (define_insn "*jcc<mode>_0_i387"
11225   [(set (pc)
11226         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11227                         [(match_operand:X87MODEF 1 "register_operand" "f")
11228                          (match_operand:X87MODEF 2 "const0_operand")])
11229           (label_ref (match_operand 3))
11230           (pc)))
11231    (clobber (reg:CCFP FPSR_REG))
11232    (clobber (reg:CCFP FLAGS_REG))
11233    (clobber (match_scratch:HI 4 "=a"))]
11234   "TARGET_80387 && !TARGET_CMOVE"
11235   "#")
11237 (define_insn "*jcc<mode>_0_r_i387"
11238   [(set (pc)
11239         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11240                         [(match_operand:X87MODEF 1 "register_operand" "f")
11241                          (match_operand:X87MODEF 2 "const0_operand")])
11242           (pc)
11243           (label_ref (match_operand 3))))
11244    (clobber (reg:CCFP FPSR_REG))
11245    (clobber (reg:CCFP FLAGS_REG))
11246    (clobber (match_scratch:HI 4 "=a"))]
11247   "TARGET_80387 && !TARGET_CMOVE"
11248   "#")
11250 (define_insn "*jccxf_i387"
11251   [(set (pc)
11252         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11253                         [(match_operand:XF 1 "register_operand" "f")
11254                          (match_operand:XF 2 "register_operand" "f")])
11255           (label_ref (match_operand 3))
11256           (pc)))
11257    (clobber (reg:CCFP FPSR_REG))
11258    (clobber (reg:CCFP FLAGS_REG))
11259    (clobber (match_scratch:HI 4 "=a"))]
11260   "TARGET_80387 && !TARGET_CMOVE"
11261   "#")
11263 (define_insn "*jccxf_r_i387"
11264   [(set (pc)
11265         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11266                         [(match_operand:XF 1 "register_operand" "f")
11267                          (match_operand:XF 2 "register_operand" "f")])
11268           (pc)
11269           (label_ref (match_operand 3))))
11270    (clobber (reg:CCFP FPSR_REG))
11271    (clobber (reg:CCFP FLAGS_REG))
11272    (clobber (match_scratch:HI 4 "=a"))]
11273   "TARGET_80387 && !TARGET_CMOVE"
11274   "#")
11276 (define_insn "*jcc<mode>_i387"
11277   [(set (pc)
11278         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11279                         [(match_operand:MODEF 1 "register_operand" "f")
11280                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11281           (label_ref (match_operand 3))
11282           (pc)))
11283    (clobber (reg:CCFP FPSR_REG))
11284    (clobber (reg:CCFP FLAGS_REG))
11285    (clobber (match_scratch:HI 4 "=a"))]
11286   "TARGET_80387 && !TARGET_CMOVE"
11287   "#")
11289 (define_insn "*jcc<mode>_r_i387"
11290   [(set (pc)
11291         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11292                         [(match_operand:MODEF 1 "register_operand" "f")
11293                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11294           (pc)
11295           (label_ref (match_operand 3))))
11296    (clobber (reg:CCFP FPSR_REG))
11297    (clobber (reg:CCFP FLAGS_REG))
11298    (clobber (match_scratch:HI 4 "=a"))]
11299   "TARGET_80387 && !TARGET_CMOVE"
11300   "#")
11302 (define_insn "*jccu<mode>_i387"
11303   [(set (pc)
11304         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11305                         [(match_operand:X87MODEF 1 "register_operand" "f")
11306                          (match_operand:X87MODEF 2 "register_operand" "f")])
11307           (label_ref (match_operand 3))
11308           (pc)))
11309    (clobber (reg:CCFP FPSR_REG))
11310    (clobber (reg:CCFP FLAGS_REG))
11311    (clobber (match_scratch:HI 4 "=a"))]
11312   "TARGET_80387 && !TARGET_CMOVE"
11313   "#")
11315 (define_insn "*jccu<mode>_r_i387"
11316   [(set (pc)
11317         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11318                         [(match_operand:X87MODEF 1 "register_operand" "f")
11319                          (match_operand:X87MODEF 2 "register_operand" "f")])
11320           (pc)
11321           (label_ref (match_operand 3))))
11322    (clobber (reg:CCFP FPSR_REG))
11323    (clobber (reg:CCFP FLAGS_REG))
11324    (clobber (match_scratch:HI 4 "=a"))]
11325   "TARGET_80387 && !TARGET_CMOVE"
11326   "#")
11328 (define_split
11329   [(set (pc)
11330         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11331                         [(match_operand:X87MODEF 1 "register_operand")
11332                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11333           (match_operand 3)
11334           (match_operand 4)))
11335    (clobber (reg:CCFP FPSR_REG))
11336    (clobber (reg:CCFP FLAGS_REG))]
11337   "TARGET_80387 && !TARGET_CMOVE
11338    && reload_completed"
11339   [(const_int 0)]
11341   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11342                         operands[3], operands[4], NULL_RTX);
11343   DONE;
11346 (define_split
11347   [(set (pc)
11348         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11349                         [(match_operand:X87MODEF 1 "register_operand")
11350                          (match_operand:X87MODEF 2 "general_operand")])
11351           (match_operand 3)
11352           (match_operand 4)))
11353    (clobber (reg:CCFP FPSR_REG))
11354    (clobber (reg:CCFP FLAGS_REG))
11355    (clobber (match_scratch:HI 5))]
11356   "TARGET_80387 && !TARGET_CMOVE
11357    && reload_completed"
11358   [(const_int 0)]
11360   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11361                         operands[3], operands[4], operands[5]);
11362   DONE;
11365 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11366 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11367 ;; with a precedence over other operators and is always put in the first
11368 ;; place. Swap condition and operands to match ficom instruction.
11370 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11371   [(set (pc)
11372         (if_then_else
11373           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11374             [(match_operator:X87MODEF 1 "float_operator"
11375               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11376              (match_operand:X87MODEF 3 "register_operand" "f")])
11377           (label_ref (match_operand 4))
11378           (pc)))
11379    (clobber (reg:CCFP FPSR_REG))
11380    (clobber (reg:CCFP FLAGS_REG))
11381    (clobber (match_scratch:HI 5 "=a"))]
11382   "TARGET_80387 && !TARGET_CMOVE
11383    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11384        || optimize_function_for_size_p (cfun))"
11385   "#")
11387 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11388   [(set (pc)
11389         (if_then_else
11390           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11391             [(match_operator:X87MODEF 1 "float_operator"
11392               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11393              (match_operand:X87MODEF 3 "register_operand" "f")])
11394           (pc)
11395           (label_ref (match_operand 4))))
11396    (clobber (reg:CCFP FPSR_REG))
11397    (clobber (reg:CCFP FLAGS_REG))
11398    (clobber (match_scratch:HI 5 "=a"))]
11399   "TARGET_80387 && !TARGET_CMOVE
11400    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11401        || optimize_function_for_size_p (cfun))"
11402   "#")
11404 (define_split
11405   [(set (pc)
11406         (if_then_else
11407           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11408             [(match_operator:X87MODEF 1 "float_operator"
11409               [(match_operand:SWI24 2 "memory_operand")])
11410              (match_operand:X87MODEF 3 "register_operand")])
11411           (match_operand 4)
11412           (match_operand 5)))
11413    (clobber (reg:CCFP FPSR_REG))
11414    (clobber (reg:CCFP FLAGS_REG))
11415    (clobber (match_scratch:HI 6))]
11416   "TARGET_80387 && !TARGET_CMOVE
11417    && reload_completed"
11418   [(const_int 0)]
11420   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11421                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11422                         operands[4], operands[5], operands[6]);
11423   DONE;
11426 ;; Unconditional and other jump instructions
11428 (define_insn "jump_bnd"
11429   [(set (pc)
11430         (label_ref (match_operand 0)))]
11431   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11432   "bnd jmp\t%l0"
11433   [(set_attr "type" "ibr")
11434    (set (attr "length")
11435            (if_then_else (and (ge (minus (match_dup 0) (pc))
11436                                   (const_int -126))
11437                               (lt (minus (match_dup 0) (pc))
11438                                   (const_int 128)))
11439              (const_int 3)
11440              (const_int 6)))
11441    (set_attr "modrm" "0")])
11443 (define_insn "jump"
11444   [(set (pc)
11445         (label_ref (match_operand 0)))]
11446   ""
11447   "jmp\t%l0"
11448   [(set_attr "type" "ibr")
11449    (set (attr "length")
11450            (if_then_else (and (ge (minus (match_dup 0) (pc))
11451                                   (const_int -126))
11452                               (lt (minus (match_dup 0) (pc))
11453                                   (const_int 128)))
11454              (const_int 2)
11455              (const_int 5)))
11456    (set_attr "modrm" "0")])
11458 (define_expand "indirect_jump"
11459   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11460   ""
11462   if (TARGET_X32)
11463     operands[0] = convert_memory_address (word_mode, operands[0]);
11466 (define_insn "*indirect_jump"
11467   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11468   ""
11469   "%!jmp\t%A0"
11470   [(set_attr "type" "ibr")
11471    (set_attr "length_immediate" "0")])
11473 (define_expand "tablejump"
11474   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11475               (use (label_ref (match_operand 1)))])]
11476   ""
11478   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11479      relative.  Convert the relative address to an absolute address.  */
11480   if (flag_pic)
11481     {
11482       rtx op0, op1;
11483       enum rtx_code code;
11485       /* We can't use @GOTOFF for text labels on VxWorks;
11486          see gotoff_operand.  */
11487       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11488         {
11489           code = PLUS;
11490           op0 = operands[0];
11491           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11492         }
11493       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11494         {
11495           code = PLUS;
11496           op0 = operands[0];
11497           op1 = pic_offset_table_rtx;
11498         }
11499       else
11500         {
11501           code = MINUS;
11502           op0 = pic_offset_table_rtx;
11503           op1 = operands[0];
11504         }
11506       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11507                                          OPTAB_DIRECT);
11508     }
11510   if (TARGET_X32)
11511     operands[0] = convert_memory_address (word_mode, operands[0]);
11514 (define_insn "*tablejump_1"
11515   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11516    (use (label_ref (match_operand 1)))]
11517   ""
11518   "%!jmp\t%A0"
11519   [(set_attr "type" "ibr")
11520    (set_attr "length_immediate" "0")])
11522 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11524 (define_peephole2
11525   [(set (reg FLAGS_REG) (match_operand 0))
11526    (set (match_operand:QI 1 "register_operand")
11527         (match_operator:QI 2 "ix86_comparison_operator"
11528           [(reg FLAGS_REG) (const_int 0)]))
11529    (set (match_operand 3 "any_QIreg_operand")
11530         (zero_extend (match_dup 1)))]
11531   "(peep2_reg_dead_p (3, operands[1])
11532     || operands_match_p (operands[1], operands[3]))
11533    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11534   [(set (match_dup 4) (match_dup 0))
11535    (set (strict_low_part (match_dup 5))
11536         (match_dup 2))]
11538   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11539   operands[5] = gen_lowpart (QImode, operands[3]);
11540   ix86_expand_clear (operands[3]);
11543 (define_peephole2
11544   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11545               (match_operand 4)])
11546    (set (match_operand:QI 1 "register_operand")
11547         (match_operator:QI 2 "ix86_comparison_operator"
11548           [(reg FLAGS_REG) (const_int 0)]))
11549    (set (match_operand 3 "any_QIreg_operand")
11550         (zero_extend (match_dup 1)))]
11551   "(peep2_reg_dead_p (3, operands[1])
11552     || operands_match_p (operands[1], operands[3]))
11553    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11554    && ! (GET_CODE (operands[4]) == CLOBBER
11555          && reg_mentioned_p (operands[3], operands[4]))"
11556   [(parallel [(set (match_dup 5) (match_dup 0))
11557               (match_dup 4)])
11558    (set (strict_low_part (match_dup 6))
11559         (match_dup 2))]
11561   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11562   operands[6] = gen_lowpart (QImode, operands[3]);
11563   ix86_expand_clear (operands[3]);
11566 ;; Similar, but match zero extend with andsi3.
11568 (define_peephole2
11569   [(set (reg FLAGS_REG) (match_operand 0))
11570    (set (match_operand:QI 1 "register_operand")
11571         (match_operator:QI 2 "ix86_comparison_operator"
11572           [(reg FLAGS_REG) (const_int 0)]))
11573    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11574                    (and:SI (match_dup 3) (const_int 255)))
11575               (clobber (reg:CC FLAGS_REG))])]
11576   "REGNO (operands[1]) == REGNO (operands[3])
11577    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11578   [(set (match_dup 4) (match_dup 0))
11579    (set (strict_low_part (match_dup 5))
11580         (match_dup 2))]
11582   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11583   operands[5] = gen_lowpart (QImode, operands[3]);
11584   ix86_expand_clear (operands[3]);
11587 (define_peephole2
11588   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11589               (match_operand 4)])
11590    (set (match_operand:QI 1 "register_operand")
11591         (match_operator:QI 2 "ix86_comparison_operator"
11592           [(reg FLAGS_REG) (const_int 0)]))
11593    (parallel [(set (match_operand 3 "any_QIreg_operand")
11594                    (zero_extend (match_dup 1)))
11595               (clobber (reg:CC FLAGS_REG))])]
11596   "(peep2_reg_dead_p (3, operands[1])
11597     || operands_match_p (operands[1], operands[3]))
11598    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11599    && ! (GET_CODE (operands[4]) == CLOBBER
11600          && reg_mentioned_p (operands[3], operands[4]))"
11601   [(parallel [(set (match_dup 5) (match_dup 0))
11602               (match_dup 4)])
11603    (set (strict_low_part (match_dup 6))
11604         (match_dup 2))]
11606   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11607   operands[6] = gen_lowpart (QImode, operands[3]);
11608   ix86_expand_clear (operands[3]);
11611 ;; Call instructions.
11613 ;; The predicates normally associated with named expanders are not properly
11614 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11615 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11617 ;; P6 processors will jump to the address after the decrement when %esp
11618 ;; is used as a call operand, so they will execute return address as a code.
11619 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11621 ;; Register constraint for call instruction.
11622 (define_mode_attr c [(SI "l") (DI "r")])
11624 ;; Call subroutine returning no value.
11626 (define_expand "call"
11627   [(call (match_operand:QI 0)
11628          (match_operand 1))
11629    (use (match_operand 2))]
11630   ""
11632   ix86_expand_call (NULL, operands[0], operands[1],
11633                     operands[2], NULL, false);
11634   DONE;
11637 (define_expand "sibcall"
11638   [(call (match_operand:QI 0)
11639          (match_operand 1))
11640    (use (match_operand 2))]
11641   ""
11643   ix86_expand_call (NULL, operands[0], operands[1],
11644                     operands[2], NULL, true);
11645   DONE;
11648 (define_insn "*call"
11649   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11650          (match_operand 1))]
11651   "!SIBLING_CALL_P (insn)"
11652   "* return ix86_output_call_insn (insn, operands[0]);"
11653   [(set_attr "type" "call")])
11655 (define_insn "*sibcall"
11656   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11657          (match_operand 1))]
11658   "SIBLING_CALL_P (insn)"
11659   "* return ix86_output_call_insn (insn, operands[0]);"
11660   [(set_attr "type" "call")])
11662 (define_insn "*sibcall_memory"
11663   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11664          (match_operand 1))
11665    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11666   "!TARGET_X32"
11667   "* return ix86_output_call_insn (insn, operands[0]);"
11668   [(set_attr "type" "call")])
11670 (define_peephole2
11671   [(set (match_operand:W 0 "register_operand")
11672         (match_operand:W 1 "memory_operand"))
11673    (call (mem:QI (match_dup 0))
11674          (match_operand 3))]
11675   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11676    && peep2_reg_dead_p (2, operands[0])"
11677   [(parallel [(call (mem:QI (match_dup 1))
11678                     (match_dup 3))
11679               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11681 (define_peephole2
11682   [(set (match_operand:W 0 "register_operand")
11683         (match_operand:W 1 "memory_operand"))
11684    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11685    (call (mem:QI (match_dup 0))
11686          (match_operand 3))]
11687   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11688    && peep2_reg_dead_p (3, operands[0])"
11689   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11690    (parallel [(call (mem:QI (match_dup 1))
11691                     (match_dup 3))
11692               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11694 (define_expand "call_pop"
11695   [(parallel [(call (match_operand:QI 0)
11696                     (match_operand:SI 1))
11697               (set (reg:SI SP_REG)
11698                    (plus:SI (reg:SI SP_REG)
11699                             (match_operand:SI 3)))])]
11700   "!TARGET_64BIT"
11702   ix86_expand_call (NULL, operands[0], operands[1],
11703                     operands[2], operands[3], false);
11704   DONE;
11707 (define_insn "*call_pop"
11708   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11709          (match_operand 1))
11710    (set (reg:SI SP_REG)
11711         (plus:SI (reg:SI SP_REG)
11712                  (match_operand:SI 2 "immediate_operand" "i")))]
11713   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11714   "* return ix86_output_call_insn (insn, operands[0]);"
11715   [(set_attr "type" "call")])
11717 (define_insn "*sibcall_pop"
11718   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11719          (match_operand 1))
11720    (set (reg:SI SP_REG)
11721         (plus:SI (reg:SI SP_REG)
11722                  (match_operand:SI 2 "immediate_operand" "i")))]
11723   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11724   "* return ix86_output_call_insn (insn, operands[0]);"
11725   [(set_attr "type" "call")])
11727 (define_insn "*sibcall_pop_memory"
11728   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11729          (match_operand 1))
11730    (set (reg:SI SP_REG)
11731         (plus:SI (reg:SI SP_REG)
11732                  (match_operand:SI 2 "immediate_operand" "i")))
11733    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11734   "!TARGET_64BIT"
11735   "* return ix86_output_call_insn (insn, operands[0]);"
11736   [(set_attr "type" "call")])
11738 (define_peephole2
11739   [(set (match_operand:SI 0 "register_operand")
11740         (match_operand:SI 1 "memory_operand"))
11741    (parallel [(call (mem:QI (match_dup 0))
11742                     (match_operand 3))
11743               (set (reg:SI SP_REG)
11744                    (plus:SI (reg:SI SP_REG)
11745                             (match_operand:SI 4 "immediate_operand")))])]
11746   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11747    && peep2_reg_dead_p (2, operands[0])"
11748   [(parallel [(call (mem:QI (match_dup 1))
11749                     (match_dup 3))
11750               (set (reg:SI SP_REG)
11751                    (plus:SI (reg:SI SP_REG)
11752                             (match_dup 4)))
11753               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11755 (define_peephole2
11756   [(set (match_operand:SI 0 "register_operand")
11757         (match_operand:SI 1 "memory_operand"))
11758    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11759    (parallel [(call (mem:QI (match_dup 0))
11760                     (match_operand 3))
11761               (set (reg:SI SP_REG)
11762                    (plus:SI (reg:SI SP_REG)
11763                             (match_operand:SI 4 "immediate_operand")))])]
11764   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11765    && peep2_reg_dead_p (3, operands[0])"
11766   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11767    (parallel [(call (mem:QI (match_dup 1))
11768                     (match_dup 3))
11769               (set (reg:SI SP_REG)
11770                    (plus:SI (reg:SI SP_REG)
11771                             (match_dup 4)))
11772               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11774 ;; Combining simple memory jump instruction
11776 (define_peephole2
11777   [(set (match_operand:W 0 "register_operand")
11778         (match_operand:W 1 "memory_operand"))
11779    (set (pc) (match_dup 0))]
11780   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11781   [(set (pc) (match_dup 1))])
11783 ;; Call subroutine, returning value in operand 0
11785 (define_expand "call_value"
11786   [(set (match_operand 0)
11787         (call (match_operand:QI 1)
11788               (match_operand 2)))
11789    (use (match_operand 3))]
11790   ""
11792   ix86_expand_call (operands[0], operands[1], operands[2],
11793                     operands[3], NULL, false);
11794   DONE;
11797 (define_expand "sibcall_value"
11798   [(set (match_operand 0)
11799         (call (match_operand:QI 1)
11800               (match_operand 2)))
11801    (use (match_operand 3))]
11802   ""
11804   ix86_expand_call (operands[0], operands[1], operands[2],
11805                     operands[3], NULL, true);
11806   DONE;
11809 (define_insn "*call_value"
11810   [(set (match_operand 0)
11811         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11812               (match_operand 2)))]
11813   "!SIBLING_CALL_P (insn)"
11814   "* return ix86_output_call_insn (insn, operands[1]);"
11815   [(set_attr "type" "callv")])
11817 (define_insn "*sibcall_value"
11818   [(set (match_operand 0)
11819         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11820               (match_operand 2)))]
11821   "SIBLING_CALL_P (insn)"
11822   "* return ix86_output_call_insn (insn, operands[1]);"
11823   [(set_attr "type" "callv")])
11825 (define_insn "*sibcall_value_memory"
11826   [(set (match_operand 0)
11827         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11828               (match_operand 2)))
11829    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11830   "!TARGET_X32"
11831   "* return ix86_output_call_insn (insn, operands[1]);"
11832   [(set_attr "type" "callv")])
11834 (define_peephole2
11835   [(set (match_operand:W 0 "register_operand")
11836         (match_operand:W 1 "memory_operand"))
11837    (set (match_operand 2)
11838    (call (mem:QI (match_dup 0))
11839                  (match_operand 3)))]
11840   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11841    && peep2_reg_dead_p (2, operands[0])"
11842   [(parallel [(set (match_dup 2)
11843                    (call (mem:QI (match_dup 1))
11844                          (match_dup 3)))
11845               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11847 (define_peephole2
11848   [(set (match_operand:W 0 "register_operand")
11849         (match_operand:W 1 "memory_operand"))
11850    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11851    (set (match_operand 2)
11852         (call (mem:QI (match_dup 0))
11853               (match_operand 3)))]
11854   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11855    && peep2_reg_dead_p (3, operands[0])"
11856   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11857    (parallel [(set (match_dup 2)
11858                    (call (mem:QI (match_dup 1))
11859                          (match_dup 3)))
11860               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11862 (define_expand "call_value_pop"
11863   [(parallel [(set (match_operand 0)
11864                    (call (match_operand:QI 1)
11865                          (match_operand:SI 2)))
11866               (set (reg:SI SP_REG)
11867                    (plus:SI (reg:SI SP_REG)
11868                             (match_operand:SI 4)))])]
11869   "!TARGET_64BIT"
11871   ix86_expand_call (operands[0], operands[1], operands[2],
11872                     operands[3], operands[4], false);
11873   DONE;
11876 (define_insn "*call_value_pop"
11877   [(set (match_operand 0)
11878         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11879               (match_operand 2)))
11880    (set (reg:SI SP_REG)
11881         (plus:SI (reg:SI SP_REG)
11882                  (match_operand:SI 3 "immediate_operand" "i")))]
11883   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11884   "* return ix86_output_call_insn (insn, operands[1]);"
11885   [(set_attr "type" "callv")])
11887 (define_insn "*sibcall_value_pop"
11888   [(set (match_operand 0)
11889         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11890               (match_operand 2)))
11891    (set (reg:SI SP_REG)
11892         (plus:SI (reg:SI SP_REG)
11893                  (match_operand:SI 3 "immediate_operand" "i")))]
11894   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11895   "* return ix86_output_call_insn (insn, operands[1]);"
11896   [(set_attr "type" "callv")])
11898 (define_insn "*sibcall_value_pop_memory"
11899   [(set (match_operand 0)
11900         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11901               (match_operand 2)))
11902    (set (reg:SI SP_REG)
11903         (plus:SI (reg:SI SP_REG)
11904                  (match_operand:SI 3 "immediate_operand" "i")))
11905    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11906   "!TARGET_64BIT"
11907   "* return ix86_output_call_insn (insn, operands[1]);"
11908   [(set_attr "type" "callv")])
11910 (define_peephole2
11911   [(set (match_operand:SI 0 "register_operand")
11912         (match_operand:SI 1 "memory_operand"))
11913    (parallel [(set (match_operand 2)
11914                    (call (mem:QI (match_dup 0))
11915                          (match_operand 3)))
11916               (set (reg:SI SP_REG)
11917                    (plus:SI (reg:SI SP_REG)
11918                             (match_operand:SI 4 "immediate_operand")))])]
11919   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11920    && peep2_reg_dead_p (2, operands[0])"
11921   [(parallel [(set (match_dup 2)
11922                    (call (mem:QI (match_dup 1))
11923                          (match_dup 3)))
11924               (set (reg:SI SP_REG)
11925                    (plus:SI (reg:SI SP_REG)
11926                             (match_dup 4)))
11927               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11929 (define_peephole2
11930   [(set (match_operand:SI 0 "register_operand")
11931         (match_operand:SI 1 "memory_operand"))
11932    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11933    (parallel [(set (match_operand 2)
11934                    (call (mem:QI (match_dup 0))
11935                          (match_operand 3)))
11936               (set (reg:SI SP_REG)
11937                    (plus:SI (reg:SI SP_REG)
11938                             (match_operand:SI 4 "immediate_operand")))])]
11939   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11940    && peep2_reg_dead_p (3, operands[0])"
11941   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11942    (parallel [(set (match_dup 2)
11943                    (call (mem:QI (match_dup 1))
11944                          (match_dup 3)))
11945               (set (reg:SI SP_REG)
11946                    (plus:SI (reg:SI SP_REG)
11947                             (match_dup 4)))
11948               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11950 ;; Call subroutine returning any type.
11952 (define_expand "untyped_call"
11953   [(parallel [(call (match_operand 0)
11954                     (const_int 0))
11955               (match_operand 1)
11956               (match_operand 2)])]
11957   ""
11959   int i;
11961   /* In order to give reg-stack an easier job in validating two
11962      coprocessor registers as containing a possible return value,
11963      simply pretend the untyped call returns a complex long double
11964      value. 
11966      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11967      and should have the default ABI.  */
11969   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11970                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11971                     operands[0], const0_rtx,
11972                     GEN_INT ((TARGET_64BIT
11973                               ? (ix86_abi == SYSV_ABI
11974                                  ? X86_64_SSE_REGPARM_MAX
11975                                  : X86_64_MS_SSE_REGPARM_MAX)
11976                               : X86_32_SSE_REGPARM_MAX)
11977                              - 1),
11978                     NULL, false);
11980   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11981     {
11982       rtx set = XVECEXP (operands[2], 0, i);
11983       emit_move_insn (SET_DEST (set), SET_SRC (set));
11984     }
11986   /* The optimizer does not know that the call sets the function value
11987      registers we stored in the result block.  We avoid problems by
11988      claiming that all hard registers are used and clobbered at this
11989      point.  */
11990   emit_insn (gen_blockage ());
11992   DONE;
11995 ;; Prologue and epilogue instructions
11997 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11998 ;; all of memory.  This blocks insns from being moved across this point.
12000 (define_insn "blockage"
12001   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12002   ""
12003   ""
12004   [(set_attr "length" "0")])
12006 ;; Do not schedule instructions accessing memory across this point.
12008 (define_expand "memory_blockage"
12009   [(set (match_dup 0)
12010         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12011   ""
12013   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12014   MEM_VOLATILE_P (operands[0]) = 1;
12017 (define_insn "*memory_blockage"
12018   [(set (match_operand:BLK 0)
12019         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12020   ""
12021   ""
12022   [(set_attr "length" "0")])
12024 ;; As USE insns aren't meaningful after reload, this is used instead
12025 ;; to prevent deleting instructions setting registers for PIC code
12026 (define_insn "prologue_use"
12027   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12028   ""
12029   ""
12030   [(set_attr "length" "0")])
12032 ;; Insn emitted into the body of a function to return from a function.
12033 ;; This is only done if the function's epilogue is known to be simple.
12034 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12036 (define_expand "return"
12037   [(simple_return)]
12038   "ix86_can_use_return_insn_p ()"
12040   if (crtl->args.pops_args)
12041     {
12042       rtx popc = GEN_INT (crtl->args.pops_args);
12043       emit_jump_insn (gen_simple_return_pop_internal (popc));
12044       DONE;
12045     }
12048 ;; We need to disable this for TARGET_SEH, as otherwise
12049 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12050 ;; the maximum size of prologue in unwind information.
12052 (define_expand "simple_return"
12053   [(simple_return)]
12054   "!TARGET_SEH"
12056   if (crtl->args.pops_args)
12057     {
12058       rtx popc = GEN_INT (crtl->args.pops_args);
12059       emit_jump_insn (gen_simple_return_pop_internal (popc));
12060       DONE;
12061     }
12064 (define_insn "simple_return_internal"
12065   [(simple_return)]
12066   "reload_completed"
12067   "%!ret"
12068   [(set_attr "length_nobnd" "1")
12069    (set_attr "atom_unit" "jeu")
12070    (set_attr "length_immediate" "0")
12071    (set_attr "modrm" "0")])
12073 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12074 ;; instruction Athlon and K8 have.
12076 (define_insn "simple_return_internal_long"
12077   [(simple_return)
12078    (unspec [(const_int 0)] UNSPEC_REP)]
12079   "reload_completed"
12081   if (ix86_bnd_prefixed_insn_p (insn))
12082     return "%!ret";
12084   return "rep%; ret";
12086   [(set_attr "length" "2")
12087    (set_attr "atom_unit" "jeu")
12088    (set_attr "length_immediate" "0")
12089    (set_attr "prefix_rep" "1")
12090    (set_attr "modrm" "0")])
12092 (define_insn "simple_return_pop_internal"
12093   [(simple_return)
12094    (use (match_operand:SI 0 "const_int_operand"))]
12095   "reload_completed"
12096   "%!ret\t%0"
12097   [(set_attr "length_nobnd" "3")
12098    (set_attr "atom_unit" "jeu")
12099    (set_attr "length_immediate" "2")
12100    (set_attr "modrm" "0")])
12102 (define_insn "simple_return_indirect_internal"
12103   [(simple_return)
12104    (use (match_operand:SI 0 "register_operand" "r"))]
12105   "reload_completed"
12106   "%!jmp\t%A0"
12107   [(set_attr "type" "ibr")
12108    (set_attr "length_immediate" "0")])
12110 (define_insn "nop"
12111   [(const_int 0)]
12112   ""
12113   "nop"
12114   [(set_attr "length" "1")
12115    (set_attr "length_immediate" "0")
12116    (set_attr "modrm" "0")])
12118 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12119 (define_insn "nops"
12120   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12121                     UNSPECV_NOPS)]
12122   "reload_completed"
12124   int num = INTVAL (operands[0]);
12126   gcc_assert (IN_RANGE (num, 1, 8));
12128   while (num--)
12129     fputs ("\tnop\n", asm_out_file);
12131   return "";
12133   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12134    (set_attr "length_immediate" "0")
12135    (set_attr "modrm" "0")])
12137 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12138 ;; branch prediction penalty for the third jump in a 16-byte
12139 ;; block on K8.
12141 (define_insn "pad"
12142   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12143   ""
12145 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12146   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12147 #else
12148   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12149      The align insn is used to avoid 3 jump instructions in the row to improve
12150      branch prediction and the benefits hardly outweigh the cost of extra 8
12151      nops on the average inserted by full alignment pseudo operation.  */
12152 #endif
12153   return "";
12155   [(set_attr "length" "16")])
12157 (define_expand "prologue"
12158   [(const_int 0)]
12159   ""
12160   "ix86_expand_prologue (); DONE;")
12162 (define_insn "set_got"
12163   [(set (match_operand:SI 0 "register_operand" "=r")
12164         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12165    (clobber (reg:CC FLAGS_REG))]
12166   "!TARGET_64BIT"
12167   "* return output_set_got (operands[0], NULL_RTX);"
12168   [(set_attr "type" "multi")
12169    (set_attr "length" "12")])
12171 (define_insn "set_got_labelled"
12172   [(set (match_operand:SI 0 "register_operand" "=r")
12173         (unspec:SI [(label_ref (match_operand 1))]
12174          UNSPEC_SET_GOT))
12175    (clobber (reg:CC FLAGS_REG))]
12176   "!TARGET_64BIT"
12177   "* return output_set_got (operands[0], operands[1]);"
12178   [(set_attr "type" "multi")
12179    (set_attr "length" "12")])
12181 (define_insn "set_got_rex64"
12182   [(set (match_operand:DI 0 "register_operand" "=r")
12183         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12184   "TARGET_64BIT"
12185   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12186   [(set_attr "type" "lea")
12187    (set_attr "length_address" "4")
12188    (set_attr "mode" "DI")])
12190 (define_insn "set_rip_rex64"
12191   [(set (match_operand:DI 0 "register_operand" "=r")
12192         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12193   "TARGET_64BIT"
12194   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12195   [(set_attr "type" "lea")
12196    (set_attr "length_address" "4")
12197    (set_attr "mode" "DI")])
12199 (define_insn "set_got_offset_rex64"
12200   [(set (match_operand:DI 0 "register_operand" "=r")
12201         (unspec:DI
12202           [(label_ref (match_operand 1))]
12203           UNSPEC_SET_GOT_OFFSET))]
12204   "TARGET_LP64"
12205   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12206   [(set_attr "type" "imov")
12207    (set_attr "length_immediate" "0")
12208    (set_attr "length_address" "8")
12209    (set_attr "mode" "DI")])
12211 (define_expand "epilogue"
12212   [(const_int 0)]
12213   ""
12214   "ix86_expand_epilogue (1); DONE;")
12216 (define_expand "sibcall_epilogue"
12217   [(const_int 0)]
12218   ""
12219   "ix86_expand_epilogue (0); DONE;")
12221 (define_expand "eh_return"
12222   [(use (match_operand 0 "register_operand"))]
12223   ""
12225   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12227   /* Tricky bit: we write the address of the handler to which we will
12228      be returning into someone else's stack frame, one word below the
12229      stack address we wish to restore.  */
12230   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12231   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12232   tmp = gen_rtx_MEM (Pmode, tmp);
12233   emit_move_insn (tmp, ra);
12235   emit_jump_insn (gen_eh_return_internal ());
12236   emit_barrier ();
12237   DONE;
12240 (define_insn_and_split "eh_return_internal"
12241   [(eh_return)]
12242   ""
12243   "#"
12244   "epilogue_completed"
12245   [(const_int 0)]
12246   "ix86_expand_epilogue (2); DONE;")
12248 (define_insn "leave"
12249   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12250    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12251    (clobber (mem:BLK (scratch)))]
12252   "!TARGET_64BIT"
12253   "leave"
12254   [(set_attr "type" "leave")])
12256 (define_insn "leave_rex64"
12257   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12258    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12259    (clobber (mem:BLK (scratch)))]
12260   "TARGET_64BIT"
12261   "leave"
12262   [(set_attr "type" "leave")])
12264 ;; Handle -fsplit-stack.
12266 (define_expand "split_stack_prologue"
12267   [(const_int 0)]
12268   ""
12270   ix86_expand_split_stack_prologue ();
12271   DONE;
12274 ;; In order to support the call/return predictor, we use a return
12275 ;; instruction which the middle-end doesn't see.
12276 (define_insn "split_stack_return"
12277   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12278                      UNSPECV_SPLIT_STACK_RETURN)]
12279   ""
12281   if (operands[0] == const0_rtx)
12282     return "ret";
12283   else
12284     return "ret\t%0";
12286   [(set_attr "atom_unit" "jeu")
12287    (set_attr "modrm" "0")
12288    (set (attr "length")
12289         (if_then_else (match_operand:SI 0 "const0_operand")
12290                       (const_int 1)
12291                       (const_int 3)))
12292    (set (attr "length_immediate")
12293         (if_then_else (match_operand:SI 0 "const0_operand")
12294                       (const_int 0)
12295                       (const_int 2)))])
12297 ;; If there are operand 0 bytes available on the stack, jump to
12298 ;; operand 1.
12300 (define_expand "split_stack_space_check"
12301   [(set (pc) (if_then_else
12302               (ltu (minus (reg SP_REG)
12303                           (match_operand 0 "register_operand"))
12304                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12305               (label_ref (match_operand 1))
12306               (pc)))]
12307   ""
12309   rtx reg, size, limit;
12311   reg = gen_reg_rtx (Pmode);
12312   size = force_reg (Pmode, operands[0]);
12313   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12314   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12315                           UNSPEC_STACK_CHECK);
12316   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12317   ix86_expand_branch (GEU, reg, limit, operands[1]);
12319   DONE;
12322 ;; Bit manipulation instructions.
12324 (define_expand "ffs<mode>2"
12325   [(set (match_dup 2) (const_int -1))
12326    (parallel [(set (match_dup 3) (match_dup 4))
12327               (set (match_operand:SWI48 0 "register_operand")
12328                    (ctz:SWI48
12329                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12330    (set (match_dup 0) (if_then_else:SWI48
12331                         (eq (match_dup 3) (const_int 0))
12332                         (match_dup 2)
12333                         (match_dup 0)))
12334    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12335               (clobber (reg:CC FLAGS_REG))])]
12336   ""
12338   machine_mode flags_mode;
12340   if (<MODE>mode == SImode && !TARGET_CMOVE)
12341     {
12342       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12343       DONE;
12344     }
12346   flags_mode
12347     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12349   operands[2] = gen_reg_rtx (<MODE>mode);
12350   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12351   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12354 (define_insn_and_split "ffssi2_no_cmove"
12355   [(set (match_operand:SI 0 "register_operand" "=r")
12356         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12357    (clobber (match_scratch:SI 2 "=&q"))
12358    (clobber (reg:CC FLAGS_REG))]
12359   "!TARGET_CMOVE"
12360   "#"
12361   "&& reload_completed"
12362   [(parallel [(set (match_dup 4) (match_dup 5))
12363               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12364    (set (strict_low_part (match_dup 3))
12365         (eq:QI (match_dup 4) (const_int 0)))
12366    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12367               (clobber (reg:CC FLAGS_REG))])
12368    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12369               (clobber (reg:CC FLAGS_REG))])
12370    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12371               (clobber (reg:CC FLAGS_REG))])]
12373   machine_mode flags_mode
12374     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12376   operands[3] = gen_lowpart (QImode, operands[2]);
12377   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12378   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12380   ix86_expand_clear (operands[2]);
12383 (define_insn "*tzcnt<mode>_1"
12384   [(set (reg:CCC FLAGS_REG)
12385         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12386                      (const_int 0)))
12387    (set (match_operand:SWI48 0 "register_operand" "=r")
12388         (ctz:SWI48 (match_dup 1)))]
12389   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12390   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12391   [(set_attr "type" "alu1")
12392    (set_attr "prefix_0f" "1")
12393    (set_attr "prefix_rep" "1")
12394    (set_attr "btver2_decode" "double")
12395    (set_attr "mode" "<MODE>")])
12397 (define_insn "*bsf<mode>_1"
12398   [(set (reg:CCZ FLAGS_REG)
12399         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12400                      (const_int 0)))
12401    (set (match_operand:SWI48 0 "register_operand" "=r")
12402         (ctz:SWI48 (match_dup 1)))]
12403   ""
12404   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12405   [(set_attr "type" "alu1")
12406    (set_attr "prefix_0f" "1")
12407    (set_attr "btver2_decode" "double")
12408    (set_attr "mode" "<MODE>")])
12410 (define_expand "ctz<mode>2"
12411   [(parallel
12412     [(set (match_operand:SWI248 0 "register_operand")
12413           (ctz:SWI248
12414             (match_operand:SWI248 1 "nonimmediate_operand")))
12415      (clobber (reg:CC FLAGS_REG))])])
12417 ; False dependency happens when destination is only updated by tzcnt,
12418 ; lzcnt or popcnt.  There is no false dependency when destination is
12419 ; also used in source.
12420 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12421   [(set (match_operand:SWI48 0 "register_operand" "=r")
12422         (ctz:SWI48
12423           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12424    (clobber (reg:CC FLAGS_REG))]
12425   "(TARGET_BMI || TARGET_GENERIC)
12426    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12427   "#"
12428   "&& reload_completed"
12429   [(parallel
12430     [(set (match_dup 0)
12431           (ctz:SWI48 (match_dup 1)))
12432      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12433      (clobber (reg:CC FLAGS_REG))])]
12435   if (!reg_mentioned_p (operands[0], operands[1]))
12436     ix86_expand_clear (operands[0]);
12439 (define_insn "*ctz<mode>2_falsedep"
12440   [(set (match_operand:SWI48 0 "register_operand" "=r")
12441         (ctz:SWI48
12442           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12443    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12444            UNSPEC_INSN_FALSE_DEP)
12445    (clobber (reg:CC FLAGS_REG))]
12446   ""
12448   if (TARGET_BMI)
12449     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12450   else if (TARGET_GENERIC)
12451     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12452     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12453   else
12454     gcc_unreachable ();
12456   [(set_attr "type" "alu1")
12457    (set_attr "prefix_0f" "1")
12458    (set_attr "prefix_rep" "1")
12459    (set_attr "mode" "<MODE>")])
12461 (define_insn "*ctz<mode>2"
12462   [(set (match_operand:SWI248 0 "register_operand" "=r")
12463         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   ""
12467   if (TARGET_BMI)
12468     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12469   else if (optimize_function_for_size_p (cfun))
12470     ;
12471   else if (TARGET_GENERIC)
12472     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12473     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12475   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12477   [(set_attr "type" "alu1")
12478    (set_attr "prefix_0f" "1")
12479    (set (attr "prefix_rep")
12480      (if_then_else
12481        (ior (match_test "TARGET_BMI")
12482             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12483                  (match_test "TARGET_GENERIC")))
12484        (const_string "1")
12485        (const_string "0")))
12486    (set_attr "mode" "<MODE>")])
12488 (define_expand "clz<mode>2"
12489   [(parallel
12490      [(set (match_operand:SWI248 0 "register_operand")
12491            (minus:SWI248
12492              (match_dup 2)
12493              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12494       (clobber (reg:CC FLAGS_REG))])
12495    (parallel
12496      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12497       (clobber (reg:CC FLAGS_REG))])]
12498   ""
12500   if (TARGET_LZCNT)
12501     {
12502       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12503       DONE;
12504     }
12505   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12508 (define_expand "clz<mode>2_lzcnt"
12509   [(parallel
12510     [(set (match_operand:SWI248 0 "register_operand")
12511           (clz:SWI248
12512             (match_operand:SWI248 1 "nonimmediate_operand")))
12513      (clobber (reg:CC FLAGS_REG))])]
12514   "TARGET_LZCNT")
12516 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12517   [(set (match_operand:SWI48 0 "register_operand" "=r")
12518         (clz:SWI48
12519           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12520    (clobber (reg:CC FLAGS_REG))]
12521   "TARGET_LZCNT
12522    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12523   "#"
12524   "&& reload_completed"
12525   [(parallel
12526     [(set (match_dup 0)
12527           (clz:SWI48 (match_dup 1)))
12528      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12529      (clobber (reg:CC FLAGS_REG))])]
12531   if (!reg_mentioned_p (operands[0], operands[1]))
12532     ix86_expand_clear (operands[0]);
12535 (define_insn "*clz<mode>2_lzcnt_falsedep"
12536   [(set (match_operand:SWI48 0 "register_operand" "=r")
12537         (clz:SWI48
12538           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12539    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12540            UNSPEC_INSN_FALSE_DEP)
12541    (clobber (reg:CC FLAGS_REG))]
12542   "TARGET_LZCNT"
12543   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12544   [(set_attr "prefix_rep" "1")
12545    (set_attr "type" "bitmanip")
12546    (set_attr "mode" "<MODE>")])
12548 (define_insn "*clz<mode>2_lzcnt"
12549   [(set (match_operand:SWI248 0 "register_operand" "=r")
12550         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12551    (clobber (reg:CC FLAGS_REG))]
12552   "TARGET_LZCNT"
12553   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12554   [(set_attr "prefix_rep" "1")
12555    (set_attr "type" "bitmanip")
12556    (set_attr "mode" "<MODE>")])
12558 ;; BMI instructions.
12559 (define_insn "*bmi_andn_<mode>"
12560   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12561         (and:SWI48
12562           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12563           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12564    (clobber (reg:CC FLAGS_REG))]
12565   "TARGET_BMI"
12566   "andn\t{%2, %1, %0|%0, %1, %2}"
12567   [(set_attr "type" "bitmanip")
12568    (set_attr "btver2_decode" "direct, double")
12569    (set_attr "mode" "<MODE>")])
12571 (define_insn "*bmi_andn_<mode>_ccno"
12572   [(set (reg FLAGS_REG)
12573         (compare
12574           (and:SWI48
12575             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12576             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12577           (const_int 0)))
12578    (clobber (match_scratch:SWI48 0 "=r,r"))]
12579   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12580   "andn\t{%2, %1, %0|%0, %1, %2}"
12581   [(set_attr "type" "bitmanip")
12582    (set_attr "btver2_decode" "direct, double")
12583    (set_attr "mode" "<MODE>")])
12585 (define_insn "bmi_bextr_<mode>"
12586   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12587         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12588                        (match_operand:SWI48 2 "register_operand" "r,r")]
12589                       UNSPEC_BEXTR))
12590    (clobber (reg:CC FLAGS_REG))]
12591   "TARGET_BMI"
12592   "bextr\t{%2, %1, %0|%0, %1, %2}"
12593   [(set_attr "type" "bitmanip")
12594    (set_attr "btver2_decode" "direct, double")
12595    (set_attr "mode" "<MODE>")])
12597 (define_insn "*bmi_bextr_<mode>_ccz"
12598   [(set (reg:CCZ FLAGS_REG)
12599         (compare:CCZ
12600           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12601                          (match_operand:SWI48 2 "register_operand" "r,r")]
12602                         UNSPEC_BEXTR)
12603           (const_int 0)))
12604    (clobber (match_scratch:SWI48 0 "=r,r"))]
12605   "TARGET_BMI"
12606   "bextr\t{%2, %1, %0|%0, %1, %2}"
12607   [(set_attr "type" "bitmanip")
12608    (set_attr "btver2_decode" "direct, double")
12609    (set_attr "mode" "<MODE>")])
12611 (define_insn "*bmi_blsi_<mode>"
12612   [(set (match_operand:SWI48 0 "register_operand" "=r")
12613         (and:SWI48
12614           (neg:SWI48
12615             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12616           (match_dup 1)))
12617    (clobber (reg:CC FLAGS_REG))]
12618   "TARGET_BMI"
12619   "blsi\t{%1, %0|%0, %1}"
12620   [(set_attr "type" "bitmanip")
12621    (set_attr "btver2_decode" "double")
12622    (set_attr "mode" "<MODE>")])
12624 (define_insn "*bmi_blsmsk_<mode>"
12625   [(set (match_operand:SWI48 0 "register_operand" "=r")
12626         (xor:SWI48
12627           (plus:SWI48
12628             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12629             (const_int -1))
12630           (match_dup 1)))
12631    (clobber (reg:CC FLAGS_REG))]
12632   "TARGET_BMI"
12633   "blsmsk\t{%1, %0|%0, %1}"
12634   [(set_attr "type" "bitmanip")
12635    (set_attr "btver2_decode" "double")
12636    (set_attr "mode" "<MODE>")])
12638 (define_insn "*bmi_blsr_<mode>"
12639   [(set (match_operand:SWI48 0 "register_operand" "=r")
12640         (and:SWI48
12641           (plus:SWI48
12642             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12643             (const_int -1))
12644           (match_dup 1)))
12645    (clobber (reg:CC FLAGS_REG))]
12646    "TARGET_BMI"
12647    "blsr\t{%1, %0|%0, %1}"
12648   [(set_attr "type" "bitmanip")
12649    (set_attr "btver2_decode" "double")
12650    (set_attr "mode" "<MODE>")])
12652 ;; BMI2 instructions.
12653 (define_expand "bmi2_bzhi_<mode>3"
12654   [(parallel
12655     [(set (match_operand:SWI48 0 "register_operand")
12656           (zero_extract:SWI48
12657             (match_operand:SWI48 1 "nonimmediate_operand")
12658             (umin:SWI48
12659               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12660                          (const_int 255))
12661               (match_dup 3))
12662             (const_int 0)))
12663      (clobber (reg:CC FLAGS_REG))])]
12664   "TARGET_BMI2"
12665   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12667 (define_insn "*bmi2_bzhi_<mode>3"
12668   [(set (match_operand:SWI48 0 "register_operand" "=r")
12669         (zero_extract:SWI48
12670           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12671           (umin:SWI48
12672             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12673                        (const_int 255))
12674             (match_operand:SWI48 3 "const_int_operand" "n"))
12675           (const_int 0)))
12676    (clobber (reg:CC FLAGS_REG))]
12677   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12678   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12679   [(set_attr "type" "bitmanip")
12680    (set_attr "prefix" "vex")
12681    (set_attr "mode" "<MODE>")])
12683 (define_mode_attr k [(SI "k") (DI "q")])
12685 (define_insn "*bmi2_bzhi_<mode>3_1"
12686   [(set (match_operand:SWI48 0 "register_operand" "=r")
12687         (zero_extract:SWI48
12688           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12689           (umin:SWI48
12690             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12691             (match_operand:SWI48 3 "const_int_operand" "n"))
12692           (const_int 0)))
12693    (clobber (reg:CC FLAGS_REG))]
12694   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12695   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12696   [(set_attr "type" "bitmanip")
12697    (set_attr "prefix" "vex")
12698    (set_attr "mode" "<MODE>")])
12700 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12701   [(set (reg:CCZ FLAGS_REG)
12702         (compare:CCZ
12703           (zero_extract:SWI48
12704             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12705             (umin:SWI48
12706               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12707               (match_operand:SWI48 3 "const_int_operand" "n"))
12708             (const_int 0))
12709         (const_int 0)))
12710    (clobber (match_scratch:SWI48 0 "=r"))]
12711   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12712   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12713   [(set_attr "type" "bitmanip")
12714    (set_attr "prefix" "vex")
12715    (set_attr "mode" "<MODE>")])
12717 (define_insn "bmi2_pdep_<mode>3"
12718   [(set (match_operand:SWI48 0 "register_operand" "=r")
12719         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12720                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12721                        UNSPEC_PDEP))]
12722   "TARGET_BMI2"
12723   "pdep\t{%2, %1, %0|%0, %1, %2}"
12724   [(set_attr "type" "bitmanip")
12725    (set_attr "prefix" "vex")
12726    (set_attr "mode" "<MODE>")])
12728 (define_insn "bmi2_pext_<mode>3"
12729   [(set (match_operand:SWI48 0 "register_operand" "=r")
12730         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12731                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12732                        UNSPEC_PEXT))]
12733   "TARGET_BMI2"
12734   "pext\t{%2, %1, %0|%0, %1, %2}"
12735   [(set_attr "type" "bitmanip")
12736    (set_attr "prefix" "vex")
12737    (set_attr "mode" "<MODE>")])
12739 ;; TBM instructions.
12740 (define_insn "tbm_bextri_<mode>"
12741   [(set (match_operand:SWI48 0 "register_operand" "=r")
12742         (zero_extract:SWI48
12743           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12744           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12745           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12746    (clobber (reg:CC FLAGS_REG))]
12747    "TARGET_TBM"
12749   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12750   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12752   [(set_attr "type" "bitmanip")
12753    (set_attr "mode" "<MODE>")])
12755 (define_insn "*tbm_blcfill_<mode>"
12756   [(set (match_operand:SWI48 0 "register_operand" "=r")
12757         (and:SWI48
12758           (plus:SWI48
12759             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12760             (const_int 1))
12761           (match_dup 1)))
12762    (clobber (reg:CC FLAGS_REG))]
12763    "TARGET_TBM"
12764    "blcfill\t{%1, %0|%0, %1}"
12765   [(set_attr "type" "bitmanip")
12766    (set_attr "mode" "<MODE>")])
12768 (define_insn "*tbm_blci_<mode>"
12769   [(set (match_operand:SWI48 0 "register_operand" "=r")
12770         (ior:SWI48
12771           (not:SWI48
12772             (plus:SWI48
12773               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12774               (const_int 1)))
12775           (match_dup 1)))
12776    (clobber (reg:CC FLAGS_REG))]
12777    "TARGET_TBM"
12778    "blci\t{%1, %0|%0, %1}"
12779   [(set_attr "type" "bitmanip")
12780    (set_attr "mode" "<MODE>")])
12782 (define_insn "*tbm_blcic_<mode>"
12783   [(set (match_operand:SWI48 0 "register_operand" "=r")
12784         (and:SWI48
12785           (plus:SWI48
12786             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12787             (const_int 1))
12788           (not:SWI48
12789             (match_dup 1))))
12790    (clobber (reg:CC FLAGS_REG))]
12791    "TARGET_TBM"
12792    "blcic\t{%1, %0|%0, %1}"
12793   [(set_attr "type" "bitmanip")
12794    (set_attr "mode" "<MODE>")])
12796 (define_insn "*tbm_blcmsk_<mode>"
12797   [(set (match_operand:SWI48 0 "register_operand" "=r")
12798         (xor:SWI48
12799           (plus:SWI48
12800             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12801             (const_int 1))
12802           (match_dup 1)))
12803    (clobber (reg:CC FLAGS_REG))]
12804    "TARGET_TBM"
12805    "blcmsk\t{%1, %0|%0, %1}"
12806   [(set_attr "type" "bitmanip")
12807    (set_attr "mode" "<MODE>")])
12809 (define_insn "*tbm_blcs_<mode>"
12810   [(set (match_operand:SWI48 0 "register_operand" "=r")
12811         (ior:SWI48
12812           (plus:SWI48
12813             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12814             (const_int 1))
12815           (match_dup 1)))
12816    (clobber (reg:CC FLAGS_REG))]
12817    "TARGET_TBM"
12818    "blcs\t{%1, %0|%0, %1}"
12819   [(set_attr "type" "bitmanip")
12820    (set_attr "mode" "<MODE>")])
12822 (define_insn "*tbm_blsfill_<mode>"
12823   [(set (match_operand:SWI48 0 "register_operand" "=r")
12824         (ior:SWI48
12825           (plus:SWI48
12826             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12827             (const_int -1))
12828           (match_dup 1)))
12829    (clobber (reg:CC FLAGS_REG))]
12830    "TARGET_TBM"
12831    "blsfill\t{%1, %0|%0, %1}"
12832   [(set_attr "type" "bitmanip")
12833    (set_attr "mode" "<MODE>")])
12835 (define_insn "*tbm_blsic_<mode>"
12836   [(set (match_operand:SWI48 0 "register_operand" "=r")
12837         (ior:SWI48
12838           (plus:SWI48
12839             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12840             (const_int -1))
12841           (not:SWI48
12842             (match_dup 1))))
12843    (clobber (reg:CC FLAGS_REG))]
12844    "TARGET_TBM"
12845    "blsic\t{%1, %0|%0, %1}"
12846   [(set_attr "type" "bitmanip")
12847    (set_attr "mode" "<MODE>")])
12849 (define_insn "*tbm_t1mskc_<mode>"
12850   [(set (match_operand:SWI48 0 "register_operand" "=r")
12851         (ior:SWI48
12852           (plus:SWI48
12853             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12854             (const_int 1))
12855           (not:SWI48
12856             (match_dup 1))))
12857    (clobber (reg:CC FLAGS_REG))]
12858    "TARGET_TBM"
12859    "t1mskc\t{%1, %0|%0, %1}"
12860   [(set_attr "type" "bitmanip")
12861    (set_attr "mode" "<MODE>")])
12863 (define_insn "*tbm_tzmsk_<mode>"
12864   [(set (match_operand:SWI48 0 "register_operand" "=r")
12865         (and:SWI48
12866           (plus:SWI48
12867             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12868             (const_int -1))
12869           (not:SWI48
12870             (match_dup 1))))
12871    (clobber (reg:CC FLAGS_REG))]
12872    "TARGET_TBM"
12873    "tzmsk\t{%1, %0|%0, %1}"
12874   [(set_attr "type" "bitmanip")
12875    (set_attr "mode" "<MODE>")])
12877 (define_insn "bsr_rex64"
12878   [(set (match_operand:DI 0 "register_operand" "=r")
12879         (minus:DI (const_int 63)
12880                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12881    (clobber (reg:CC FLAGS_REG))]
12882   "TARGET_64BIT"
12883   "bsr{q}\t{%1, %0|%0, %1}"
12884   [(set_attr "type" "alu1")
12885    (set_attr "prefix_0f" "1")
12886    (set_attr "mode" "DI")])
12888 (define_insn "bsr"
12889   [(set (match_operand:SI 0 "register_operand" "=r")
12890         (minus:SI (const_int 31)
12891                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12892    (clobber (reg:CC FLAGS_REG))]
12893   ""
12894   "bsr{l}\t{%1, %0|%0, %1}"
12895   [(set_attr "type" "alu1")
12896    (set_attr "prefix_0f" "1")
12897    (set_attr "mode" "SI")])
12899 (define_insn "*bsrhi"
12900   [(set (match_operand:HI 0 "register_operand" "=r")
12901         (minus:HI (const_int 15)
12902                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12903    (clobber (reg:CC FLAGS_REG))]
12904   ""
12905   "bsr{w}\t{%1, %0|%0, %1}"
12906   [(set_attr "type" "alu1")
12907    (set_attr "prefix_0f" "1")
12908    (set_attr "mode" "HI")])
12910 (define_expand "popcount<mode>2"
12911   [(parallel
12912     [(set (match_operand:SWI248 0 "register_operand")
12913           (popcount:SWI248
12914             (match_operand:SWI248 1 "nonimmediate_operand")))
12915      (clobber (reg:CC FLAGS_REG))])]
12916   "TARGET_POPCNT")
12918 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12919   [(set (match_operand:SWI48 0 "register_operand" "=r")
12920         (popcount:SWI48
12921           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12922    (clobber (reg:CC FLAGS_REG))]
12923   "TARGET_POPCNT
12924    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12925   "#"
12926   "&& reload_completed"
12927   [(parallel
12928     [(set (match_dup 0)
12929           (popcount:SWI48 (match_dup 1)))
12930      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12931      (clobber (reg:CC FLAGS_REG))])]
12933   if (!reg_mentioned_p (operands[0], operands[1]))
12934     ix86_expand_clear (operands[0]);
12937 (define_insn "*popcount<mode>2_falsedep"
12938   [(set (match_operand:SWI48 0 "register_operand" "=r")
12939         (popcount:SWI48
12940           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12941    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12942            UNSPEC_INSN_FALSE_DEP)
12943    (clobber (reg:CC FLAGS_REG))]
12944   "TARGET_POPCNT"
12946 #if TARGET_MACHO
12947   return "popcnt\t{%1, %0|%0, %1}";
12948 #else
12949   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12950 #endif
12952   [(set_attr "prefix_rep" "1")
12953    (set_attr "type" "bitmanip")
12954    (set_attr "mode" "<MODE>")])
12956 (define_insn "*popcount<mode>2"
12957   [(set (match_operand:SWI248 0 "register_operand" "=r")
12958         (popcount:SWI248
12959           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12960    (clobber (reg:CC FLAGS_REG))]
12961   "TARGET_POPCNT"
12963 #if TARGET_MACHO
12964   return "popcnt\t{%1, %0|%0, %1}";
12965 #else
12966   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12967 #endif
12969   [(set_attr "prefix_rep" "1")
12970    (set_attr "type" "bitmanip")
12971    (set_attr "mode" "<MODE>")])
12973 (define_expand "bswapdi2"
12974   [(set (match_operand:DI 0 "register_operand")
12975         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12976   "TARGET_64BIT"
12978   if (!TARGET_MOVBE)
12979     operands[1] = force_reg (DImode, operands[1]);
12982 (define_expand "bswapsi2"
12983   [(set (match_operand:SI 0 "register_operand")
12984         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12985   ""
12987   if (TARGET_MOVBE)
12988     ;
12989   else if (TARGET_BSWAP)
12990     operands[1] = force_reg (SImode, operands[1]);
12991   else
12992     {
12993       rtx x = operands[0];
12995       emit_move_insn (x, operands[1]);
12996       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12997       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12998       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12999       DONE;
13000     }
13003 (define_insn "*bswap<mode>2_movbe"
13004   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13005         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13006   "TARGET_MOVBE
13007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13008   "@
13009     bswap\t%0
13010     movbe\t{%1, %0|%0, %1}
13011     movbe\t{%1, %0|%0, %1}"
13012   [(set_attr "type" "bitmanip,imov,imov")
13013    (set_attr "modrm" "0,1,1")
13014    (set_attr "prefix_0f" "*,1,1")
13015    (set_attr "prefix_extra" "*,1,1")
13016    (set_attr "mode" "<MODE>")])
13018 (define_insn "*bswap<mode>2"
13019   [(set (match_operand:SWI48 0 "register_operand" "=r")
13020         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13021   "TARGET_BSWAP"
13022   "bswap\t%0"
13023   [(set_attr "type" "bitmanip")
13024    (set_attr "modrm" "0")
13025    (set_attr "mode" "<MODE>")])
13027 (define_insn "*bswaphi_lowpart_1"
13028   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13029         (bswap:HI (match_dup 0)))
13030    (clobber (reg:CC FLAGS_REG))]
13031   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13032   "@
13033     xchg{b}\t{%h0, %b0|%b0, %h0}
13034     rol{w}\t{$8, %0|%0, 8}"
13035   [(set_attr "length" "2,4")
13036    (set_attr "mode" "QI,HI")])
13038 (define_insn "bswaphi_lowpart"
13039   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13040         (bswap:HI (match_dup 0)))
13041    (clobber (reg:CC FLAGS_REG))]
13042   ""
13043   "rol{w}\t{$8, %0|%0, 8}"
13044   [(set_attr "length" "4")
13045    (set_attr "mode" "HI")])
13047 (define_expand "paritydi2"
13048   [(set (match_operand:DI 0 "register_operand")
13049         (parity:DI (match_operand:DI 1 "register_operand")))]
13050   "! TARGET_POPCNT"
13052   rtx scratch = gen_reg_rtx (QImode);
13053   rtx cond;
13055   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13056                                 NULL_RTX, operands[1]));
13058   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13059                          gen_rtx_REG (CCmode, FLAGS_REG),
13060                          const0_rtx);
13061   emit_insn (gen_rtx_SET (scratch, cond));
13063   if (TARGET_64BIT)
13064     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13065   else
13066     {
13067       rtx tmp = gen_reg_rtx (SImode);
13069       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13070       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13071     }
13072   DONE;
13075 (define_expand "paritysi2"
13076   [(set (match_operand:SI 0 "register_operand")
13077         (parity:SI (match_operand:SI 1 "register_operand")))]
13078   "! TARGET_POPCNT"
13080   rtx scratch = gen_reg_rtx (QImode);
13081   rtx cond;
13083   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13085   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13086                          gen_rtx_REG (CCmode, FLAGS_REG),
13087                          const0_rtx);
13088   emit_insn (gen_rtx_SET (scratch, cond));
13090   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13091   DONE;
13094 (define_insn_and_split "paritydi2_cmp"
13095   [(set (reg:CC FLAGS_REG)
13096         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13097                    UNSPEC_PARITY))
13098    (clobber (match_scratch:DI 0 "=r"))
13099    (clobber (match_scratch:SI 1 "=&r"))
13100    (clobber (match_scratch:HI 2 "=Q"))]
13101   "! TARGET_POPCNT"
13102   "#"
13103   "&& reload_completed"
13104   [(parallel
13105      [(set (match_dup 1)
13106            (xor:SI (match_dup 1) (match_dup 4)))
13107       (clobber (reg:CC FLAGS_REG))])
13108    (parallel
13109      [(set (reg:CC FLAGS_REG)
13110            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13111       (clobber (match_dup 1))
13112       (clobber (match_dup 2))])]
13114   operands[4] = gen_lowpart (SImode, operands[3]);
13116   if (TARGET_64BIT)
13117     {
13118       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13119       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13120     }
13121   else
13122     operands[1] = gen_highpart (SImode, operands[3]);
13125 (define_insn_and_split "paritysi2_cmp"
13126   [(set (reg:CC FLAGS_REG)
13127         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13128                    UNSPEC_PARITY))
13129    (clobber (match_scratch:SI 0 "=r"))
13130    (clobber (match_scratch:HI 1 "=&Q"))]
13131   "! TARGET_POPCNT"
13132   "#"
13133   "&& reload_completed"
13134   [(parallel
13135      [(set (match_dup 1)
13136            (xor:HI (match_dup 1) (match_dup 3)))
13137       (clobber (reg:CC FLAGS_REG))])
13138    (parallel
13139      [(set (reg:CC FLAGS_REG)
13140            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13141       (clobber (match_dup 1))])]
13143   operands[3] = gen_lowpart (HImode, operands[2]);
13145   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13146   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13149 (define_insn "*parityhi2_cmp"
13150   [(set (reg:CC FLAGS_REG)
13151         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13152                    UNSPEC_PARITY))
13153    (clobber (match_scratch:HI 0 "=Q"))]
13154   "! TARGET_POPCNT"
13155   "xor{b}\t{%h0, %b0|%b0, %h0}"
13156   [(set_attr "length" "2")
13157    (set_attr "mode" "HI")])
13160 ;; Thread-local storage patterns for ELF.
13162 ;; Note that these code sequences must appear exactly as shown
13163 ;; in order to allow linker relaxation.
13165 (define_insn "*tls_global_dynamic_32_gnu"
13166   [(set (match_operand:SI 0 "register_operand" "=a")
13167         (unspec:SI
13168          [(match_operand:SI 1 "register_operand" "b")
13169           (match_operand 2 "tls_symbolic_operand")
13170           (match_operand 3 "constant_call_address_operand" "Bz")
13171           (reg:SI SP_REG)]
13172          UNSPEC_TLS_GD))
13173    (clobber (match_scratch:SI 4 "=d"))
13174    (clobber (match_scratch:SI 5 "=c"))
13175    (clobber (reg:CC FLAGS_REG))]
13176   "!TARGET_64BIT && TARGET_GNU_TLS"
13178   output_asm_insn
13179     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13180   if (TARGET_SUN_TLS)
13181 #ifdef HAVE_AS_IX86_TLSGDPLT
13182     return "call\t%a2@tlsgdplt";
13183 #else
13184     return "call\t%p3@plt";
13185 #endif
13186   return "call\t%P3";
13188   [(set_attr "type" "multi")
13189    (set_attr "length" "12")])
13191 (define_expand "tls_global_dynamic_32"
13192   [(parallel
13193     [(set (match_operand:SI 0 "register_operand")
13194           (unspec:SI [(match_operand:SI 2 "register_operand")
13195                       (match_operand 1 "tls_symbolic_operand")
13196                       (match_operand 3 "constant_call_address_operand")
13197                       (reg:SI SP_REG)]
13198                      UNSPEC_TLS_GD))
13199      (clobber (match_scratch:SI 4))
13200      (clobber (match_scratch:SI 5))
13201      (clobber (reg:CC FLAGS_REG))])]
13202   ""
13203   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13205 (define_insn "*tls_global_dynamic_64_<mode>"
13206   [(set (match_operand:P 0 "register_operand" "=a")
13207         (call:P
13208          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13209          (match_operand 3)))
13210    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13211              UNSPEC_TLS_GD)]
13212   "TARGET_64BIT"
13214   if (!TARGET_X32)
13215     fputs (ASM_BYTE "0x66\n", asm_out_file);
13216   output_asm_insn
13217     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13218   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13219   fputs ("\trex64\n", asm_out_file);
13220   if (TARGET_SUN_TLS)
13221     return "call\t%p2@plt";
13222   return "call\t%P2";
13224   [(set_attr "type" "multi")
13225    (set (attr "length")
13226         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13228 (define_insn "*tls_global_dynamic_64_largepic"
13229   [(set (match_operand:DI 0 "register_operand" "=a")
13230         (call:DI
13231          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13232                           (match_operand:DI 3 "immediate_operand" "i")))
13233          (match_operand 4)))
13234    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13235              UNSPEC_TLS_GD)]
13236   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13237    && GET_CODE (operands[3]) == CONST
13238    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13239    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13241   output_asm_insn
13242     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13243   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13244   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13245   return "call\t{*%%rax|rax}";
13247   [(set_attr "type" "multi")
13248    (set_attr "length" "22")])
13250 (define_expand "tls_global_dynamic_64_<mode>"
13251   [(parallel
13252     [(set (match_operand:P 0 "register_operand")
13253           (call:P
13254            (mem:QI (match_operand 2))
13255            (const_int 0)))
13256      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13257                UNSPEC_TLS_GD)])]
13258   "TARGET_64BIT"
13259   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13261 (define_insn "*tls_local_dynamic_base_32_gnu"
13262   [(set (match_operand:SI 0 "register_operand" "=a")
13263         (unspec:SI
13264          [(match_operand:SI 1 "register_operand" "b")
13265           (match_operand 2 "constant_call_address_operand" "Bz")
13266           (reg:SI SP_REG)]
13267          UNSPEC_TLS_LD_BASE))
13268    (clobber (match_scratch:SI 3 "=d"))
13269    (clobber (match_scratch:SI 4 "=c"))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "!TARGET_64BIT && TARGET_GNU_TLS"
13273   output_asm_insn
13274     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13275   if (TARGET_SUN_TLS)
13276     {
13277       if (HAVE_AS_IX86_TLSLDMPLT)
13278         return "call\t%&@tlsldmplt";
13279       else
13280         return "call\t%p2@plt";
13281     }
13282   return "call\t%P2";
13284   [(set_attr "type" "multi")
13285    (set_attr "length" "11")])
13287 (define_expand "tls_local_dynamic_base_32"
13288   [(parallel
13289      [(set (match_operand:SI 0 "register_operand")
13290            (unspec:SI
13291             [(match_operand:SI 1 "register_operand")
13292              (match_operand 2 "constant_call_address_operand")
13293              (reg:SI SP_REG)]
13294             UNSPEC_TLS_LD_BASE))
13295       (clobber (match_scratch:SI 3))
13296       (clobber (match_scratch:SI 4))
13297       (clobber (reg:CC FLAGS_REG))])]
13298   ""
13299   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13301 (define_insn "*tls_local_dynamic_base_64_<mode>"
13302   [(set (match_operand:P 0 "register_operand" "=a")
13303         (call:P
13304          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13305          (match_operand 2)))
13306    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13307   "TARGET_64BIT"
13309   output_asm_insn
13310     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13311   if (TARGET_SUN_TLS)
13312     return "call\t%p1@plt";
13313   return "call\t%P1";
13315   [(set_attr "type" "multi")
13316    (set_attr "length" "12")])
13318 (define_insn "*tls_local_dynamic_base_64_largepic"
13319   [(set (match_operand:DI 0 "register_operand" "=a")
13320         (call:DI
13321          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13322                           (match_operand:DI 2 "immediate_operand" "i")))
13323          (match_operand 3)))
13324    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13325   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13326    && GET_CODE (operands[2]) == CONST
13327    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13328    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13330   output_asm_insn
13331     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13332   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13333   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13334   return "call\t{*%%rax|rax}";
13336   [(set_attr "type" "multi")
13337    (set_attr "length" "22")])
13339 (define_expand "tls_local_dynamic_base_64_<mode>"
13340   [(parallel
13341      [(set (match_operand:P 0 "register_operand")
13342            (call:P
13343             (mem:QI (match_operand 1))
13344             (const_int 0)))
13345       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13346   "TARGET_64BIT"
13347   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13349 ;; Local dynamic of a single variable is a lose.  Show combine how
13350 ;; to convert that back to global dynamic.
13352 (define_insn_and_split "*tls_local_dynamic_32_once"
13353   [(set (match_operand:SI 0 "register_operand" "=a")
13354         (plus:SI
13355          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13356                      (match_operand 2 "constant_call_address_operand" "Bz")
13357                      (reg:SI SP_REG)]
13358                     UNSPEC_TLS_LD_BASE)
13359          (const:SI (unspec:SI
13360                     [(match_operand 3 "tls_symbolic_operand")]
13361                     UNSPEC_DTPOFF))))
13362    (clobber (match_scratch:SI 4 "=d"))
13363    (clobber (match_scratch:SI 5 "=c"))
13364    (clobber (reg:CC FLAGS_REG))]
13365   ""
13366   "#"
13367   ""
13368   [(parallel
13369      [(set (match_dup 0)
13370            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13371                        (reg:SI SP_REG)]
13372                       UNSPEC_TLS_GD))
13373       (clobber (match_dup 4))
13374       (clobber (match_dup 5))
13375       (clobber (reg:CC FLAGS_REG))])])
13377 ;; Segment register for the thread base ptr load
13378 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13380 ;; Load and add the thread base pointer from %<tp_seg>:0.
13381 (define_insn "*load_tp_x32"
13382   [(set (match_operand:SI 0 "register_operand" "=r")
13383         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13384   "TARGET_X32"
13385   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13386   [(set_attr "type" "imov")
13387    (set_attr "modrm" "0")
13388    (set_attr "length" "7")
13389    (set_attr "memory" "load")
13390    (set_attr "imm_disp" "false")])
13392 (define_insn "*load_tp_x32_zext"
13393   [(set (match_operand:DI 0 "register_operand" "=r")
13394         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13395   "TARGET_X32"
13396   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13397   [(set_attr "type" "imov")
13398    (set_attr "modrm" "0")
13399    (set_attr "length" "7")
13400    (set_attr "memory" "load")
13401    (set_attr "imm_disp" "false")])
13403 (define_insn "*load_tp_<mode>"
13404   [(set (match_operand:P 0 "register_operand" "=r")
13405         (unspec:P [(const_int 0)] UNSPEC_TP))]
13406   "!TARGET_X32"
13407   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13408   [(set_attr "type" "imov")
13409    (set_attr "modrm" "0")
13410    (set_attr "length" "7")
13411    (set_attr "memory" "load")
13412    (set_attr "imm_disp" "false")])
13414 (define_insn "*add_tp_x32"
13415   [(set (match_operand:SI 0 "register_operand" "=r")
13416         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13417                  (match_operand:SI 1 "register_operand" "0")))
13418    (clobber (reg:CC FLAGS_REG))]
13419   "TARGET_X32"
13420   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13421   [(set_attr "type" "alu")
13422    (set_attr "modrm" "0")
13423    (set_attr "length" "7")
13424    (set_attr "memory" "load")
13425    (set_attr "imm_disp" "false")])
13427 (define_insn "*add_tp_x32_zext"
13428   [(set (match_operand:DI 0 "register_operand" "=r")
13429         (zero_extend:DI
13430           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13431                    (match_operand:SI 1 "register_operand" "0"))))
13432    (clobber (reg:CC FLAGS_REG))]
13433   "TARGET_X32"
13434   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13435   [(set_attr "type" "alu")
13436    (set_attr "modrm" "0")
13437    (set_attr "length" "7")
13438    (set_attr "memory" "load")
13439    (set_attr "imm_disp" "false")])
13441 (define_insn "*add_tp_<mode>"
13442   [(set (match_operand:P 0 "register_operand" "=r")
13443         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13444                 (match_operand:P 1 "register_operand" "0")))
13445    (clobber (reg:CC FLAGS_REG))]
13446   "!TARGET_X32"
13447   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13448   [(set_attr "type" "alu")
13449    (set_attr "modrm" "0")
13450    (set_attr "length" "7")
13451    (set_attr "memory" "load")
13452    (set_attr "imm_disp" "false")])
13454 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13455 ;; %rax as destination of the initial executable code sequence.
13456 (define_insn "tls_initial_exec_64_sun"
13457   [(set (match_operand:DI 0 "register_operand" "=a")
13458         (unspec:DI
13459          [(match_operand 1 "tls_symbolic_operand")]
13460          UNSPEC_TLS_IE_SUN))
13461    (clobber (reg:CC FLAGS_REG))]
13462   "TARGET_64BIT && TARGET_SUN_TLS"
13464   output_asm_insn
13465     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13466   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13468   [(set_attr "type" "multi")])
13470 ;; GNU2 TLS patterns can be split.
13472 (define_expand "tls_dynamic_gnu2_32"
13473   [(set (match_dup 3)
13474         (plus:SI (match_operand:SI 2 "register_operand")
13475                  (const:SI
13476                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13477                              UNSPEC_TLSDESC))))
13478    (parallel
13479     [(set (match_operand:SI 0 "register_operand")
13480           (unspec:SI [(match_dup 1) (match_dup 3)
13481                       (match_dup 2) (reg:SI SP_REG)]
13482                       UNSPEC_TLSDESC))
13483      (clobber (reg:CC FLAGS_REG))])]
13484   "!TARGET_64BIT && TARGET_GNU2_TLS"
13486   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13487   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13490 (define_insn "*tls_dynamic_gnu2_lea_32"
13491   [(set (match_operand:SI 0 "register_operand" "=r")
13492         (plus:SI (match_operand:SI 1 "register_operand" "b")
13493                  (const:SI
13494                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13495                               UNSPEC_TLSDESC))))]
13496   "!TARGET_64BIT && TARGET_GNU2_TLS"
13497   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13498   [(set_attr "type" "lea")
13499    (set_attr "mode" "SI")
13500    (set_attr "length" "6")
13501    (set_attr "length_address" "4")])
13503 (define_insn "*tls_dynamic_gnu2_call_32"
13504   [(set (match_operand:SI 0 "register_operand" "=a")
13505         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13506                     (match_operand:SI 2 "register_operand" "0")
13507                     ;; we have to make sure %ebx still points to the GOT
13508                     (match_operand:SI 3 "register_operand" "b")
13509                     (reg:SI SP_REG)]
13510                    UNSPEC_TLSDESC))
13511    (clobber (reg:CC FLAGS_REG))]
13512   "!TARGET_64BIT && TARGET_GNU2_TLS"
13513   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13514   [(set_attr "type" "call")
13515    (set_attr "length" "2")
13516    (set_attr "length_address" "0")])
13518 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13519   [(set (match_operand:SI 0 "register_operand" "=&a")
13520         (plus:SI
13521          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13522                      (match_operand:SI 4)
13523                      (match_operand:SI 2 "register_operand" "b")
13524                      (reg:SI SP_REG)]
13525                     UNSPEC_TLSDESC)
13526          (const:SI (unspec:SI
13527                     [(match_operand 1 "tls_symbolic_operand")]
13528                     UNSPEC_DTPOFF))))
13529    (clobber (reg:CC FLAGS_REG))]
13530   "!TARGET_64BIT && TARGET_GNU2_TLS"
13531   "#"
13532   ""
13533   [(set (match_dup 0) (match_dup 5))]
13535   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13536   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13539 (define_expand "tls_dynamic_gnu2_64"
13540   [(set (match_dup 2)
13541         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13542                    UNSPEC_TLSDESC))
13543    (parallel
13544     [(set (match_operand:DI 0 "register_operand")
13545           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13546                      UNSPEC_TLSDESC))
13547      (clobber (reg:CC FLAGS_REG))])]
13548   "TARGET_64BIT && TARGET_GNU2_TLS"
13550   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13551   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13554 (define_insn "*tls_dynamic_gnu2_lea_64"
13555   [(set (match_operand:DI 0 "register_operand" "=r")
13556         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13557                    UNSPEC_TLSDESC))]
13558   "TARGET_64BIT && TARGET_GNU2_TLS"
13559   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13560   [(set_attr "type" "lea")
13561    (set_attr "mode" "DI")
13562    (set_attr "length" "7")
13563    (set_attr "length_address" "4")])
13565 (define_insn "*tls_dynamic_gnu2_call_64"
13566   [(set (match_operand:DI 0 "register_operand" "=a")
13567         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13568                     (match_operand:DI 2 "register_operand" "0")
13569                     (reg:DI SP_REG)]
13570                    UNSPEC_TLSDESC))
13571    (clobber (reg:CC FLAGS_REG))]
13572   "TARGET_64BIT && TARGET_GNU2_TLS"
13573   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13574   [(set_attr "type" "call")
13575    (set_attr "length" "2")
13576    (set_attr "length_address" "0")])
13578 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13579   [(set (match_operand:DI 0 "register_operand" "=&a")
13580         (plus:DI
13581          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13582                      (match_operand:DI 3)
13583                      (reg:DI SP_REG)]
13584                     UNSPEC_TLSDESC)
13585          (const:DI (unspec:DI
13586                     [(match_operand 1 "tls_symbolic_operand")]
13587                     UNSPEC_DTPOFF))))
13588    (clobber (reg:CC FLAGS_REG))]
13589   "TARGET_64BIT && TARGET_GNU2_TLS"
13590   "#"
13591   ""
13592   [(set (match_dup 0) (match_dup 4))]
13594   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13595   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13598 ;; These patterns match the binary 387 instructions for addM3, subM3,
13599 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13600 ;; SFmode.  The first is the normal insn, the second the same insn but
13601 ;; with one operand a conversion, and the third the same insn but with
13602 ;; the other operand a conversion.  The conversion may be SFmode or
13603 ;; SImode if the target mode DFmode, but only SImode if the target mode
13604 ;; is SFmode.
13606 ;; Gcc is slightly more smart about handling normal two address instructions
13607 ;; so use special patterns for add and mull.
13609 (define_insn "*fop_<mode>_comm_mixed"
13610   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13611         (match_operator:MODEF 3 "binary_fp_operator"
13612           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13613            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13614   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13615    && COMMUTATIVE_ARITH_P (operands[3])
13616    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13617   "* return output_387_binary_op (insn, operands);"
13618   [(set (attr "type")
13619         (if_then_else (eq_attr "alternative" "1,2")
13620            (if_then_else (match_operand:MODEF 3 "mult_operator")
13621               (const_string "ssemul")
13622               (const_string "sseadd"))
13623            (if_then_else (match_operand:MODEF 3 "mult_operator")
13624               (const_string "fmul")
13625               (const_string "fop"))))
13626    (set_attr "isa" "*,noavx,avx")
13627    (set_attr "prefix" "orig,orig,vex")
13628    (set_attr "mode" "<MODE>")
13629    (set (attr "enabled")
13630      (cond [(eq_attr "alternative" "0")
13631               (symbol_ref "TARGET_MIX_SSE_I387")
13632            ]
13633            (const_string "*")))])
13635 (define_insn "*fop_<mode>_comm_i387"
13636   [(set (match_operand:MODEF 0 "register_operand" "=f")
13637         (match_operator:MODEF 3 "binary_fp_operator"
13638           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13639            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13640   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13641    && COMMUTATIVE_ARITH_P (operands[3])
13642    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13643   "* return output_387_binary_op (insn, operands);"
13644   [(set (attr "type")
13645         (if_then_else (match_operand:MODEF 3 "mult_operator")
13646            (const_string "fmul")
13647            (const_string "fop")))
13648    (set_attr "mode" "<MODE>")])
13650 (define_insn "*rcpsf2_sse"
13651   [(set (match_operand:SF 0 "register_operand" "=x")
13652         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13653                    UNSPEC_RCP))]
13654   "TARGET_SSE_MATH"
13655   "%vrcpss\t{%1, %d0|%d0, %1}"
13656   [(set_attr "type" "sse")
13657    (set_attr "atom_sse_attr" "rcp")
13658    (set_attr "btver2_sse_attr" "rcp")
13659    (set_attr "prefix" "maybe_vex")
13660    (set_attr "mode" "SF")])
13662 (define_insn "*fop_<mode>_1_mixed"
13663   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13664         (match_operator:MODEF 3 "binary_fp_operator"
13665           [(match_operand:MODEF 1
13666              "register_mixssei387nonimm_operand" "0,fm,0,v")
13667            (match_operand:MODEF 2
13668              "nonimmediate_operand"              "fm,0,xm,vm")]))]
13669   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13670    && !COMMUTATIVE_ARITH_P (operands[3])
13671    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13672   "* return output_387_binary_op (insn, operands);"
13673   [(set (attr "type")
13674         (cond [(and (eq_attr "alternative" "2,3")
13675                     (match_operand:MODEF 3 "mult_operator"))
13676                  (const_string "ssemul")
13677                (and (eq_attr "alternative" "2,3")
13678                     (match_operand:MODEF 3 "div_operator"))
13679                  (const_string "ssediv")
13680                (eq_attr "alternative" "2,3")
13681                  (const_string "sseadd")
13682                (match_operand:MODEF 3 "mult_operator")
13683                  (const_string "fmul")
13684                (match_operand:MODEF 3 "div_operator")
13685                  (const_string "fdiv")
13686               ]
13687               (const_string "fop")))
13688    (set_attr "isa" "*,*,noavx,avx")
13689    (set_attr "prefix" "orig,orig,orig,vex")
13690    (set_attr "mode" "<MODE>")
13691    (set (attr "enabled")
13692      (cond [(eq_attr "alternative" "0,1")
13693               (symbol_ref "TARGET_MIX_SSE_I387")
13694            ]
13695            (const_string "*")))])
13697 ;; This pattern is not fully shadowed by the pattern above.
13698 (define_insn "*fop_<mode>_1_i387"
13699   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13700         (match_operator:MODEF 3 "binary_fp_operator"
13701           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13702            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13703   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13704    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13705    && !COMMUTATIVE_ARITH_P (operands[3])
13706    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13707   "* return output_387_binary_op (insn, operands);"
13708   [(set (attr "type")
13709         (cond [(match_operand:MODEF 3 "mult_operator")
13710                  (const_string "fmul")
13711                (match_operand:MODEF 3 "div_operator")
13712                  (const_string "fdiv")
13713               ]
13714               (const_string "fop")))
13715    (set_attr "mode" "<MODE>")])
13717 ;; ??? Add SSE splitters for these!
13718 (define_insn "*fop_<MODEF:mode>_2_i387"
13719   [(set (match_operand:MODEF 0 "register_operand" "=f")
13720         (match_operator:MODEF 3 "binary_fp_operator"
13721           [(float:MODEF
13722              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13723            (match_operand:MODEF 2 "register_operand" "0")]))]
13724   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13725    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13726    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13727        || optimize_function_for_size_p (cfun))"
13728   { return output_387_binary_op (insn, operands); }
13729   [(set (attr "type")
13730         (cond [(match_operand:MODEF 3 "mult_operator")
13731                  (const_string "fmul")
13732                (match_operand:MODEF 3 "div_operator")
13733                  (const_string "fdiv")
13734               ]
13735               (const_string "fop")))
13736    (set_attr "fp_int_src" "true")
13737    (set_attr "mode" "<SWI24:MODE>")])
13739 (define_insn "*fop_<MODEF:mode>_3_i387"
13740   [(set (match_operand:MODEF 0 "register_operand" "=f")
13741         (match_operator:MODEF 3 "binary_fp_operator"
13742           [(match_operand:MODEF 1 "register_operand" "0")
13743            (float:MODEF
13744              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13745   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13746    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13747    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13748        || optimize_function_for_size_p (cfun))"
13749   { return output_387_binary_op (insn, operands); }
13750   [(set (attr "type")
13751         (cond [(match_operand:MODEF 3 "mult_operator")
13752                  (const_string "fmul")
13753                (match_operand:MODEF 3 "div_operator")
13754                  (const_string "fdiv")
13755               ]
13756               (const_string "fop")))
13757    (set_attr "fp_int_src" "true")
13758    (set_attr "mode" "<MODE>")])
13760 (define_insn "*fop_df_4_i387"
13761   [(set (match_operand:DF 0 "register_operand" "=f,f")
13762         (match_operator:DF 3 "binary_fp_operator"
13763            [(float_extend:DF
13764              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13765             (match_operand:DF 2 "register_operand" "0,f")]))]
13766   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13767    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13768    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13769   "* return output_387_binary_op (insn, operands);"
13770   [(set (attr "type")
13771         (cond [(match_operand:DF 3 "mult_operator")
13772                  (const_string "fmul")
13773                (match_operand:DF 3 "div_operator")
13774                  (const_string "fdiv")
13775               ]
13776               (const_string "fop")))
13777    (set_attr "mode" "SF")])
13779 (define_insn "*fop_df_5_i387"
13780   [(set (match_operand:DF 0 "register_operand" "=f,f")
13781         (match_operator:DF 3 "binary_fp_operator"
13782           [(match_operand:DF 1 "register_operand" "0,f")
13783            (float_extend:DF
13784             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13785   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13786    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13787   "* return output_387_binary_op (insn, operands);"
13788   [(set (attr "type")
13789         (cond [(match_operand:DF 3 "mult_operator")
13790                  (const_string "fmul")
13791                (match_operand:DF 3 "div_operator")
13792                  (const_string "fdiv")
13793               ]
13794               (const_string "fop")))
13795    (set_attr "mode" "SF")])
13797 (define_insn "*fop_df_6_i387"
13798   [(set (match_operand:DF 0 "register_operand" "=f,f")
13799         (match_operator:DF 3 "binary_fp_operator"
13800           [(float_extend:DF
13801             (match_operand:SF 1 "register_operand" "0,f"))
13802            (float_extend:DF
13803             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13804   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13805    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13806   "* return output_387_binary_op (insn, operands);"
13807   [(set (attr "type")
13808         (cond [(match_operand:DF 3 "mult_operator")
13809                  (const_string "fmul")
13810                (match_operand:DF 3 "div_operator")
13811                  (const_string "fdiv")
13812               ]
13813               (const_string "fop")))
13814    (set_attr "mode" "SF")])
13816 (define_insn "*fop_xf_comm_i387"
13817   [(set (match_operand:XF 0 "register_operand" "=f")
13818         (match_operator:XF 3 "binary_fp_operator"
13819                         [(match_operand:XF 1 "register_operand" "%0")
13820                          (match_operand:XF 2 "register_operand" "f")]))]
13821   "TARGET_80387
13822    && COMMUTATIVE_ARITH_P (operands[3])"
13823   "* return output_387_binary_op (insn, operands);"
13824   [(set (attr "type")
13825         (if_then_else (match_operand:XF 3 "mult_operator")
13826            (const_string "fmul")
13827            (const_string "fop")))
13828    (set_attr "mode" "XF")])
13830 (define_insn "*fop_xf_1_i387"
13831   [(set (match_operand:XF 0 "register_operand" "=f,f")
13832         (match_operator:XF 3 "binary_fp_operator"
13833                         [(match_operand:XF 1 "register_operand" "0,f")
13834                          (match_operand:XF 2 "register_operand" "f,0")]))]
13835   "TARGET_80387
13836    && !COMMUTATIVE_ARITH_P (operands[3])"
13837   "* return output_387_binary_op (insn, operands);"
13838   [(set (attr "type")
13839         (cond [(match_operand:XF 3 "mult_operator")
13840                  (const_string "fmul")
13841                (match_operand:XF 3 "div_operator")
13842                  (const_string "fdiv")
13843               ]
13844               (const_string "fop")))
13845    (set_attr "mode" "XF")])
13847 (define_insn "*fop_xf_2_i387"
13848   [(set (match_operand:XF 0 "register_operand" "=f")
13849         (match_operator:XF 3 "binary_fp_operator"
13850           [(float:XF
13851              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13852            (match_operand:XF 2 "register_operand" "0")]))]
13853   "TARGET_80387
13854    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13855   { return output_387_binary_op (insn, operands); }
13856   [(set (attr "type")
13857         (cond [(match_operand:XF 3 "mult_operator")
13858                  (const_string "fmul")
13859                (match_operand:XF 3 "div_operator")
13860                  (const_string "fdiv")
13861               ]
13862               (const_string "fop")))
13863    (set_attr "fp_int_src" "true")
13864    (set_attr "mode" "<MODE>")])
13866 (define_insn "*fop_xf_3_i387"
13867   [(set (match_operand:XF 0 "register_operand" "=f")
13868         (match_operator:XF 3 "binary_fp_operator"
13869           [(match_operand:XF 1 "register_operand" "0")
13870            (float:XF
13871              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13872   "TARGET_80387
13873    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13874   { return output_387_binary_op (insn, operands); }
13875   [(set (attr "type")
13876         (cond [(match_operand:XF 3 "mult_operator")
13877                  (const_string "fmul")
13878                (match_operand:XF 3 "div_operator")
13879                  (const_string "fdiv")
13880               ]
13881               (const_string "fop")))
13882    (set_attr "fp_int_src" "true")
13883    (set_attr "mode" "<MODE>")])
13885 (define_insn "*fop_xf_4_i387"
13886   [(set (match_operand:XF 0 "register_operand" "=f,f")
13887         (match_operator:XF 3 "binary_fp_operator"
13888            [(float_extend:XF
13889               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13890             (match_operand:XF 2 "register_operand" "0,f")]))]
13891   "TARGET_80387"
13892   "* return output_387_binary_op (insn, operands);"
13893   [(set (attr "type")
13894         (cond [(match_operand:XF 3 "mult_operator")
13895                  (const_string "fmul")
13896                (match_operand:XF 3 "div_operator")
13897                  (const_string "fdiv")
13898               ]
13899               (const_string "fop")))
13900    (set_attr "mode" "<MODE>")])
13902 (define_insn "*fop_xf_5_i387"
13903   [(set (match_operand:XF 0 "register_operand" "=f,f")
13904         (match_operator:XF 3 "binary_fp_operator"
13905           [(match_operand:XF 1 "register_operand" "0,f")
13906            (float_extend:XF
13907              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13908   "TARGET_80387"
13909   "* return output_387_binary_op (insn, operands);"
13910   [(set (attr "type")
13911         (cond [(match_operand:XF 3 "mult_operator")
13912                  (const_string "fmul")
13913                (match_operand:XF 3 "div_operator")
13914                  (const_string "fdiv")
13915               ]
13916               (const_string "fop")))
13917    (set_attr "mode" "<MODE>")])
13919 (define_insn "*fop_xf_6_i387"
13920   [(set (match_operand:XF 0 "register_operand" "=f,f")
13921         (match_operator:XF 3 "binary_fp_operator"
13922           [(float_extend:XF
13923              (match_operand:MODEF 1 "register_operand" "0,f"))
13924            (float_extend:XF
13925              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13926   "TARGET_80387"
13927   "* return output_387_binary_op (insn, operands);"
13928   [(set (attr "type")
13929         (cond [(match_operand:XF 3 "mult_operator")
13930                  (const_string "fmul")
13931                (match_operand:XF 3 "div_operator")
13932                  (const_string "fdiv")
13933               ]
13934               (const_string "fop")))
13935    (set_attr "mode" "<MODE>")])
13937 ;; FPU special functions.
13939 ;; This pattern implements a no-op XFmode truncation for
13940 ;; all fancy i386 XFmode math functions.
13942 (define_insn "truncxf<mode>2_i387_noop_unspec"
13943   [(set (match_operand:MODEF 0 "register_operand" "=f")
13944         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13945         UNSPEC_TRUNC_NOOP))]
13946   "TARGET_USE_FANCY_MATH_387"
13947   "* return output_387_reg_move (insn, operands);"
13948   [(set_attr "type" "fmov")
13949    (set_attr "mode" "<MODE>")])
13951 (define_insn "sqrtxf2"
13952   [(set (match_operand:XF 0 "register_operand" "=f")
13953         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13954   "TARGET_USE_FANCY_MATH_387"
13955   "fsqrt"
13956   [(set_attr "type" "fpspc")
13957    (set_attr "mode" "XF")
13958    (set_attr "athlon_decode" "direct")
13959    (set_attr "amdfam10_decode" "direct")
13960    (set_attr "bdver1_decode" "direct")])
13962 (define_insn "sqrt_extend<mode>xf2_i387"
13963   [(set (match_operand:XF 0 "register_operand" "=f")
13964         (sqrt:XF
13965           (float_extend:XF
13966             (match_operand:MODEF 1 "register_operand" "0"))))]
13967   "TARGET_USE_FANCY_MATH_387"
13968   "fsqrt"
13969   [(set_attr "type" "fpspc")
13970    (set_attr "mode" "XF")
13971    (set_attr "athlon_decode" "direct")
13972    (set_attr "amdfam10_decode" "direct")
13973    (set_attr "bdver1_decode" "direct")])
13975 (define_insn "*rsqrtsf2_sse"
13976   [(set (match_operand:SF 0 "register_operand" "=x")
13977         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13978                    UNSPEC_RSQRT))]
13979   "TARGET_SSE_MATH"
13980   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13981   [(set_attr "type" "sse")
13982    (set_attr "atom_sse_attr" "rcp")
13983    (set_attr "btver2_sse_attr" "rcp")
13984    (set_attr "prefix" "maybe_vex")
13985    (set_attr "mode" "SF")])
13987 (define_expand "rsqrtsf2"
13988   [(set (match_operand:SF 0 "register_operand")
13989         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13990                    UNSPEC_RSQRT))]
13991   "TARGET_SSE_MATH"
13993   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13994   DONE;
13997 (define_insn "*sqrt<mode>2_sse"
13998   [(set (match_operand:MODEF 0 "register_operand" "=v")
13999         (sqrt:MODEF
14000           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14001   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14002   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14003   [(set_attr "type" "sse")
14004    (set_attr "atom_sse_attr" "sqrt")
14005    (set_attr "btver2_sse_attr" "sqrt")
14006    (set_attr "prefix" "maybe_vex")
14007    (set_attr "mode" "<MODE>")
14008    (set_attr "athlon_decode" "*")
14009    (set_attr "amdfam10_decode" "*")
14010    (set_attr "bdver1_decode" "*")])
14012 (define_expand "sqrt<mode>2"
14013   [(set (match_operand:MODEF 0 "register_operand")
14014         (sqrt:MODEF
14015           (match_operand:MODEF 1 "nonimmediate_operand")))]
14016   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14017    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14019   if (<MODE>mode == SFmode
14020       && TARGET_SSE_MATH
14021       && TARGET_RECIP_SQRT
14022       && !optimize_function_for_size_p (cfun)
14023       && flag_finite_math_only && !flag_trapping_math
14024       && flag_unsafe_math_optimizations)
14025     {
14026       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14027       DONE;
14028     }
14030   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14031     {
14032       rtx op0 = gen_reg_rtx (XFmode);
14033       rtx op1 = force_reg (<MODE>mode, operands[1]);
14035       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14036       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14037       DONE;
14038    }
14041 (define_insn "fpremxf4_i387"
14042   [(set (match_operand:XF 0 "register_operand" "=f")
14043         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14044                     (match_operand:XF 3 "register_operand" "1")]
14045                    UNSPEC_FPREM_F))
14046    (set (match_operand:XF 1 "register_operand" "=u")
14047         (unspec:XF [(match_dup 2) (match_dup 3)]
14048                    UNSPEC_FPREM_U))
14049    (set (reg:CCFP FPSR_REG)
14050         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14051                      UNSPEC_C2_FLAG))]
14052   "TARGET_USE_FANCY_MATH_387
14053    && flag_finite_math_only"
14054   "fprem"
14055   [(set_attr "type" "fpspc")
14056    (set_attr "mode" "XF")])
14058 (define_expand "fmodxf3"
14059   [(use (match_operand:XF 0 "register_operand"))
14060    (use (match_operand:XF 1 "general_operand"))
14061    (use (match_operand:XF 2 "general_operand"))]
14062   "TARGET_USE_FANCY_MATH_387
14063    && flag_finite_math_only"
14065   rtx_code_label *label = gen_label_rtx ();
14067   rtx op1 = gen_reg_rtx (XFmode);
14068   rtx op2 = gen_reg_rtx (XFmode);
14070   emit_move_insn (op2, operands[2]);
14071   emit_move_insn (op1, operands[1]);
14073   emit_label (label);
14074   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14075   ix86_emit_fp_unordered_jump (label);
14076   LABEL_NUSES (label) = 1;
14078   emit_move_insn (operands[0], op1);
14079   DONE;
14082 (define_expand "fmod<mode>3"
14083   [(use (match_operand:MODEF 0 "register_operand"))
14084    (use (match_operand:MODEF 1 "general_operand"))
14085    (use (match_operand:MODEF 2 "general_operand"))]
14086   "TARGET_USE_FANCY_MATH_387
14087    && flag_finite_math_only"
14089   rtx (*gen_truncxf) (rtx, rtx);
14091   rtx_code_label *label = gen_label_rtx ();
14093   rtx op1 = gen_reg_rtx (XFmode);
14094   rtx op2 = gen_reg_rtx (XFmode);
14096   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14097   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14099   emit_label (label);
14100   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14101   ix86_emit_fp_unordered_jump (label);
14102   LABEL_NUSES (label) = 1;
14104   /* Truncate the result properly for strict SSE math.  */
14105   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14106       && !TARGET_MIX_SSE_I387)
14107     gen_truncxf = gen_truncxf<mode>2;
14108   else
14109     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14111   emit_insn (gen_truncxf (operands[0], op1));
14112   DONE;
14115 (define_insn "fprem1xf4_i387"
14116   [(set (match_operand:XF 0 "register_operand" "=f")
14117         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14118                     (match_operand:XF 3 "register_operand" "1")]
14119                    UNSPEC_FPREM1_F))
14120    (set (match_operand:XF 1 "register_operand" "=u")
14121         (unspec:XF [(match_dup 2) (match_dup 3)]
14122                    UNSPEC_FPREM1_U))
14123    (set (reg:CCFP FPSR_REG)
14124         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14125                      UNSPEC_C2_FLAG))]
14126   "TARGET_USE_FANCY_MATH_387
14127    && flag_finite_math_only"
14128   "fprem1"
14129   [(set_attr "type" "fpspc")
14130    (set_attr "mode" "XF")])
14132 (define_expand "remainderxf3"
14133   [(use (match_operand:XF 0 "register_operand"))
14134    (use (match_operand:XF 1 "general_operand"))
14135    (use (match_operand:XF 2 "general_operand"))]
14136   "TARGET_USE_FANCY_MATH_387
14137    && flag_finite_math_only"
14139   rtx_code_label *label = gen_label_rtx ();
14141   rtx op1 = gen_reg_rtx (XFmode);
14142   rtx op2 = gen_reg_rtx (XFmode);
14144   emit_move_insn (op2, operands[2]);
14145   emit_move_insn (op1, operands[1]);
14147   emit_label (label);
14148   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14149   ix86_emit_fp_unordered_jump (label);
14150   LABEL_NUSES (label) = 1;
14152   emit_move_insn (operands[0], op1);
14153   DONE;
14156 (define_expand "remainder<mode>3"
14157   [(use (match_operand:MODEF 0 "register_operand"))
14158    (use (match_operand:MODEF 1 "general_operand"))
14159    (use (match_operand:MODEF 2 "general_operand"))]
14160   "TARGET_USE_FANCY_MATH_387
14161    && flag_finite_math_only"
14163   rtx (*gen_truncxf) (rtx, rtx);
14165   rtx_code_label *label = gen_label_rtx ();
14167   rtx op1 = gen_reg_rtx (XFmode);
14168   rtx op2 = gen_reg_rtx (XFmode);
14170   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14171   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14173   emit_label (label);
14175   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14176   ix86_emit_fp_unordered_jump (label);
14177   LABEL_NUSES (label) = 1;
14179   /* Truncate the result properly for strict SSE math.  */
14180   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14181       && !TARGET_MIX_SSE_I387)
14182     gen_truncxf = gen_truncxf<mode>2;
14183   else
14184     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14186   emit_insn (gen_truncxf (operands[0], op1));
14187   DONE;
14190 (define_int_iterator SINCOS
14191         [UNSPEC_SIN
14192          UNSPEC_COS])
14194 (define_int_attr sincos
14195         [(UNSPEC_SIN "sin")
14196          (UNSPEC_COS "cos")])
14198 (define_insn "*<sincos>xf2_i387"
14199   [(set (match_operand:XF 0 "register_operand" "=f")
14200         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14201                    SINCOS))]
14202   "TARGET_USE_FANCY_MATH_387
14203    && flag_unsafe_math_optimizations"
14204   "f<sincos>"
14205   [(set_attr "type" "fpspc")
14206    (set_attr "mode" "XF")])
14208 (define_insn "*<sincos>_extend<mode>xf2_i387"
14209   [(set (match_operand:XF 0 "register_operand" "=f")
14210         (unspec:XF [(float_extend:XF
14211                       (match_operand:MODEF 1 "register_operand" "0"))]
14212                    SINCOS))]
14213   "TARGET_USE_FANCY_MATH_387
14214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215        || TARGET_MIX_SSE_I387)
14216    && flag_unsafe_math_optimizations"
14217   "f<sincos>"
14218   [(set_attr "type" "fpspc")
14219    (set_attr "mode" "XF")])
14221 ;; When sincos pattern is defined, sin and cos builtin functions will be
14222 ;; expanded to sincos pattern with one of its outputs left unused.
14223 ;; CSE pass will figure out if two sincos patterns can be combined,
14224 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14225 ;; depending on the unused output.
14227 (define_insn "sincosxf3"
14228   [(set (match_operand:XF 0 "register_operand" "=f")
14229         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14230                    UNSPEC_SINCOS_COS))
14231    (set (match_operand:XF 1 "register_operand" "=u")
14232         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14233   "TARGET_USE_FANCY_MATH_387
14234    && flag_unsafe_math_optimizations"
14235   "fsincos"
14236   [(set_attr "type" "fpspc")
14237    (set_attr "mode" "XF")])
14239 (define_split
14240   [(set (match_operand:XF 0 "register_operand")
14241         (unspec:XF [(match_operand:XF 2 "register_operand")]
14242                    UNSPEC_SINCOS_COS))
14243    (set (match_operand:XF 1 "register_operand")
14244         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14245   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14246    && can_create_pseudo_p ()"
14247   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14249 (define_split
14250   [(set (match_operand:XF 0 "register_operand")
14251         (unspec:XF [(match_operand:XF 2 "register_operand")]
14252                    UNSPEC_SINCOS_COS))
14253    (set (match_operand:XF 1 "register_operand")
14254         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14255   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14256    && can_create_pseudo_p ()"
14257   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14259 (define_insn "sincos_extend<mode>xf3_i387"
14260   [(set (match_operand:XF 0 "register_operand" "=f")
14261         (unspec:XF [(float_extend:XF
14262                       (match_operand:MODEF 2 "register_operand" "0"))]
14263                    UNSPEC_SINCOS_COS))
14264    (set (match_operand:XF 1 "register_operand" "=u")
14265         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14266   "TARGET_USE_FANCY_MATH_387
14267    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14268        || TARGET_MIX_SSE_I387)
14269    && flag_unsafe_math_optimizations"
14270   "fsincos"
14271   [(set_attr "type" "fpspc")
14272    (set_attr "mode" "XF")])
14274 (define_split
14275   [(set (match_operand:XF 0 "register_operand")
14276         (unspec:XF [(float_extend:XF
14277                       (match_operand:MODEF 2 "register_operand"))]
14278                    UNSPEC_SINCOS_COS))
14279    (set (match_operand:XF 1 "register_operand")
14280         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14281   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14282    && can_create_pseudo_p ()"
14283   [(set (match_dup 1)
14284         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14286 (define_split
14287   [(set (match_operand:XF 0 "register_operand")
14288         (unspec:XF [(float_extend:XF
14289                       (match_operand:MODEF 2 "register_operand"))]
14290                    UNSPEC_SINCOS_COS))
14291    (set (match_operand:XF 1 "register_operand")
14292         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14293   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14294    && can_create_pseudo_p ()"
14295   [(set (match_dup 0)
14296         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14298 (define_expand "sincos<mode>3"
14299   [(use (match_operand:MODEF 0 "register_operand"))
14300    (use (match_operand:MODEF 1 "register_operand"))
14301    (use (match_operand:MODEF 2 "register_operand"))]
14302   "TARGET_USE_FANCY_MATH_387
14303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304        || TARGET_MIX_SSE_I387)
14305    && flag_unsafe_math_optimizations"
14307   rtx op0 = gen_reg_rtx (XFmode);
14308   rtx op1 = gen_reg_rtx (XFmode);
14310   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14311   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14312   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14313   DONE;
14316 (define_insn "fptanxf4_i387"
14317   [(set (match_operand:XF 0 "register_operand" "=f")
14318         (match_operand:XF 3 "const_double_operand" "F"))
14319    (set (match_operand:XF 1 "register_operand" "=u")
14320         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14321                    UNSPEC_TAN))]
14322   "TARGET_USE_FANCY_MATH_387
14323    && flag_unsafe_math_optimizations
14324    && standard_80387_constant_p (operands[3]) == 2"
14325   "fptan"
14326   [(set_attr "type" "fpspc")
14327    (set_attr "mode" "XF")])
14329 (define_insn "fptan_extend<mode>xf4_i387"
14330   [(set (match_operand:MODEF 0 "register_operand" "=f")
14331         (match_operand:MODEF 3 "const_double_operand" "F"))
14332    (set (match_operand:XF 1 "register_operand" "=u")
14333         (unspec:XF [(float_extend:XF
14334                       (match_operand:MODEF 2 "register_operand" "0"))]
14335                    UNSPEC_TAN))]
14336   "TARGET_USE_FANCY_MATH_387
14337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14338        || TARGET_MIX_SSE_I387)
14339    && flag_unsafe_math_optimizations
14340    && standard_80387_constant_p (operands[3]) == 2"
14341   "fptan"
14342   [(set_attr "type" "fpspc")
14343    (set_attr "mode" "XF")])
14345 (define_expand "tanxf2"
14346   [(use (match_operand:XF 0 "register_operand"))
14347    (use (match_operand:XF 1 "register_operand"))]
14348   "TARGET_USE_FANCY_MATH_387
14349    && flag_unsafe_math_optimizations"
14351   rtx one = gen_reg_rtx (XFmode);
14352   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14354   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14355   DONE;
14358 (define_expand "tan<mode>2"
14359   [(use (match_operand:MODEF 0 "register_operand"))
14360    (use (match_operand:MODEF 1 "register_operand"))]
14361   "TARGET_USE_FANCY_MATH_387
14362    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14363        || TARGET_MIX_SSE_I387)
14364    && flag_unsafe_math_optimizations"
14366   rtx op0 = gen_reg_rtx (XFmode);
14368   rtx one = gen_reg_rtx (<MODE>mode);
14369   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14371   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14372                                              operands[1], op2));
14373   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14374   DONE;
14377 (define_insn "*fpatanxf3_i387"
14378   [(set (match_operand:XF 0 "register_operand" "=f")
14379         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14380                     (match_operand:XF 2 "register_operand" "u")]
14381                    UNSPEC_FPATAN))
14382    (clobber (match_scratch:XF 3 "=2"))]
14383   "TARGET_USE_FANCY_MATH_387
14384    && flag_unsafe_math_optimizations"
14385   "fpatan"
14386   [(set_attr "type" "fpspc")
14387    (set_attr "mode" "XF")])
14389 (define_insn "fpatan_extend<mode>xf3_i387"
14390   [(set (match_operand:XF 0 "register_operand" "=f")
14391         (unspec:XF [(float_extend:XF
14392                       (match_operand:MODEF 1 "register_operand" "0"))
14393                     (float_extend:XF
14394                       (match_operand:MODEF 2 "register_operand" "u"))]
14395                    UNSPEC_FPATAN))
14396    (clobber (match_scratch:XF 3 "=2"))]
14397   "TARGET_USE_FANCY_MATH_387
14398    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14399        || TARGET_MIX_SSE_I387)
14400    && flag_unsafe_math_optimizations"
14401   "fpatan"
14402   [(set_attr "type" "fpspc")
14403    (set_attr "mode" "XF")])
14405 (define_expand "atan2xf3"
14406   [(parallel [(set (match_operand:XF 0 "register_operand")
14407                    (unspec:XF [(match_operand:XF 2 "register_operand")
14408                                (match_operand:XF 1 "register_operand")]
14409                               UNSPEC_FPATAN))
14410               (clobber (match_scratch:XF 3))])]
14411   "TARGET_USE_FANCY_MATH_387
14412    && flag_unsafe_math_optimizations")
14414 (define_expand "atan2<mode>3"
14415   [(use (match_operand:MODEF 0 "register_operand"))
14416    (use (match_operand:MODEF 1 "register_operand"))
14417    (use (match_operand:MODEF 2 "register_operand"))]
14418   "TARGET_USE_FANCY_MATH_387
14419    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14420        || TARGET_MIX_SSE_I387)
14421    && flag_unsafe_math_optimizations"
14423   rtx op0 = gen_reg_rtx (XFmode);
14425   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14426   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14427   DONE;
14430 (define_expand "atanxf2"
14431   [(parallel [(set (match_operand:XF 0 "register_operand")
14432                    (unspec:XF [(match_dup 2)
14433                                (match_operand:XF 1 "register_operand")]
14434                               UNSPEC_FPATAN))
14435               (clobber (match_scratch:XF 3))])]
14436   "TARGET_USE_FANCY_MATH_387
14437    && flag_unsafe_math_optimizations"
14439   operands[2] = gen_reg_rtx (XFmode);
14440   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14443 (define_expand "atan<mode>2"
14444   [(use (match_operand:MODEF 0 "register_operand"))
14445    (use (match_operand:MODEF 1 "register_operand"))]
14446   "TARGET_USE_FANCY_MATH_387
14447    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14448        || TARGET_MIX_SSE_I387)
14449    && flag_unsafe_math_optimizations"
14451   rtx op0 = gen_reg_rtx (XFmode);
14453   rtx op2 = gen_reg_rtx (<MODE>mode);
14454   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14456   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14457   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14458   DONE;
14461 (define_expand "asinxf2"
14462   [(set (match_dup 2)
14463         (mult:XF (match_operand:XF 1 "register_operand")
14464                  (match_dup 1)))
14465    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14466    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14467    (parallel [(set (match_operand:XF 0 "register_operand")
14468                    (unspec:XF [(match_dup 5) (match_dup 1)]
14469                               UNSPEC_FPATAN))
14470               (clobber (match_scratch:XF 6))])]
14471   "TARGET_USE_FANCY_MATH_387
14472    && flag_unsafe_math_optimizations"
14474   int i;
14476   if (optimize_insn_for_size_p ())
14477     FAIL;
14479   for (i = 2; i < 6; i++)
14480     operands[i] = gen_reg_rtx (XFmode);
14482   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14485 (define_expand "asin<mode>2"
14486   [(use (match_operand:MODEF 0 "register_operand"))
14487    (use (match_operand:MODEF 1 "general_operand"))]
14488  "TARGET_USE_FANCY_MATH_387
14489    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14490        || TARGET_MIX_SSE_I387)
14491    && flag_unsafe_math_optimizations"
14493   rtx op0 = gen_reg_rtx (XFmode);
14494   rtx op1 = gen_reg_rtx (XFmode);
14496   if (optimize_insn_for_size_p ())
14497     FAIL;
14499   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14500   emit_insn (gen_asinxf2 (op0, op1));
14501   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14502   DONE;
14505 (define_expand "acosxf2"
14506   [(set (match_dup 2)
14507         (mult:XF (match_operand:XF 1 "register_operand")
14508                  (match_dup 1)))
14509    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14510    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14511    (parallel [(set (match_operand:XF 0 "register_operand")
14512                    (unspec:XF [(match_dup 1) (match_dup 5)]
14513                               UNSPEC_FPATAN))
14514               (clobber (match_scratch:XF 6))])]
14515   "TARGET_USE_FANCY_MATH_387
14516    && flag_unsafe_math_optimizations"
14518   int i;
14520   if (optimize_insn_for_size_p ())
14521     FAIL;
14523   for (i = 2; i < 6; i++)
14524     operands[i] = gen_reg_rtx (XFmode);
14526   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14529 (define_expand "acos<mode>2"
14530   [(use (match_operand:MODEF 0 "register_operand"))
14531    (use (match_operand:MODEF 1 "general_operand"))]
14532  "TARGET_USE_FANCY_MATH_387
14533    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14534        || TARGET_MIX_SSE_I387)
14535    && flag_unsafe_math_optimizations"
14537   rtx op0 = gen_reg_rtx (XFmode);
14538   rtx op1 = gen_reg_rtx (XFmode);
14540   if (optimize_insn_for_size_p ())
14541     FAIL;
14543   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14544   emit_insn (gen_acosxf2 (op0, op1));
14545   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14546   DONE;
14549 (define_insn "fyl2xxf3_i387"
14550   [(set (match_operand:XF 0 "register_operand" "=f")
14551         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14552                     (match_operand:XF 2 "register_operand" "u")]
14553                    UNSPEC_FYL2X))
14554    (clobber (match_scratch:XF 3 "=2"))]
14555   "TARGET_USE_FANCY_MATH_387
14556    && flag_unsafe_math_optimizations"
14557   "fyl2x"
14558   [(set_attr "type" "fpspc")
14559    (set_attr "mode" "XF")])
14561 (define_insn "fyl2x_extend<mode>xf3_i387"
14562   [(set (match_operand:XF 0 "register_operand" "=f")
14563         (unspec:XF [(float_extend:XF
14564                       (match_operand:MODEF 1 "register_operand" "0"))
14565                     (match_operand:XF 2 "register_operand" "u")]
14566                    UNSPEC_FYL2X))
14567    (clobber (match_scratch:XF 3 "=2"))]
14568   "TARGET_USE_FANCY_MATH_387
14569    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14570        || TARGET_MIX_SSE_I387)
14571    && flag_unsafe_math_optimizations"
14572   "fyl2x"
14573   [(set_attr "type" "fpspc")
14574    (set_attr "mode" "XF")])
14576 (define_expand "logxf2"
14577   [(parallel [(set (match_operand:XF 0 "register_operand")
14578                    (unspec:XF [(match_operand:XF 1 "register_operand")
14579                                (match_dup 2)] UNSPEC_FYL2X))
14580               (clobber (match_scratch:XF 3))])]
14581   "TARGET_USE_FANCY_MATH_387
14582    && flag_unsafe_math_optimizations"
14584   operands[2] = gen_reg_rtx (XFmode);
14585   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14588 (define_expand "log<mode>2"
14589   [(use (match_operand:MODEF 0 "register_operand"))
14590    (use (match_operand:MODEF 1 "register_operand"))]
14591   "TARGET_USE_FANCY_MATH_387
14592    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14593        || TARGET_MIX_SSE_I387)
14594    && flag_unsafe_math_optimizations"
14596   rtx op0 = gen_reg_rtx (XFmode);
14598   rtx op2 = gen_reg_rtx (XFmode);
14599   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14601   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14602   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14603   DONE;
14606 (define_expand "log10xf2"
14607   [(parallel [(set (match_operand:XF 0 "register_operand")
14608                    (unspec:XF [(match_operand:XF 1 "register_operand")
14609                                (match_dup 2)] UNSPEC_FYL2X))
14610               (clobber (match_scratch:XF 3))])]
14611   "TARGET_USE_FANCY_MATH_387
14612    && flag_unsafe_math_optimizations"
14614   operands[2] = gen_reg_rtx (XFmode);
14615   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14618 (define_expand "log10<mode>2"
14619   [(use (match_operand:MODEF 0 "register_operand"))
14620    (use (match_operand:MODEF 1 "register_operand"))]
14621   "TARGET_USE_FANCY_MATH_387
14622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14623        || TARGET_MIX_SSE_I387)
14624    && flag_unsafe_math_optimizations"
14626   rtx op0 = gen_reg_rtx (XFmode);
14628   rtx op2 = gen_reg_rtx (XFmode);
14629   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14631   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14632   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14633   DONE;
14636 (define_expand "log2xf2"
14637   [(parallel [(set (match_operand:XF 0 "register_operand")
14638                    (unspec:XF [(match_operand:XF 1 "register_operand")
14639                                (match_dup 2)] UNSPEC_FYL2X))
14640               (clobber (match_scratch:XF 3))])]
14641   "TARGET_USE_FANCY_MATH_387
14642    && flag_unsafe_math_optimizations"
14644   operands[2] = gen_reg_rtx (XFmode);
14645   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14648 (define_expand "log2<mode>2"
14649   [(use (match_operand:MODEF 0 "register_operand"))
14650    (use (match_operand:MODEF 1 "register_operand"))]
14651   "TARGET_USE_FANCY_MATH_387
14652    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14653        || TARGET_MIX_SSE_I387)
14654    && flag_unsafe_math_optimizations"
14656   rtx op0 = gen_reg_rtx (XFmode);
14658   rtx op2 = gen_reg_rtx (XFmode);
14659   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14661   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14662   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14663   DONE;
14666 (define_insn "fyl2xp1xf3_i387"
14667   [(set (match_operand:XF 0 "register_operand" "=f")
14668         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14669                     (match_operand:XF 2 "register_operand" "u")]
14670                    UNSPEC_FYL2XP1))
14671    (clobber (match_scratch:XF 3 "=2"))]
14672   "TARGET_USE_FANCY_MATH_387
14673    && flag_unsafe_math_optimizations"
14674   "fyl2xp1"
14675   [(set_attr "type" "fpspc")
14676    (set_attr "mode" "XF")])
14678 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14679   [(set (match_operand:XF 0 "register_operand" "=f")
14680         (unspec:XF [(float_extend:XF
14681                       (match_operand:MODEF 1 "register_operand" "0"))
14682                     (match_operand:XF 2 "register_operand" "u")]
14683                    UNSPEC_FYL2XP1))
14684    (clobber (match_scratch:XF 3 "=2"))]
14685   "TARGET_USE_FANCY_MATH_387
14686    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14687        || TARGET_MIX_SSE_I387)
14688    && flag_unsafe_math_optimizations"
14689   "fyl2xp1"
14690   [(set_attr "type" "fpspc")
14691    (set_attr "mode" "XF")])
14693 (define_expand "log1pxf2"
14694   [(use (match_operand:XF 0 "register_operand"))
14695    (use (match_operand:XF 1 "register_operand"))]
14696   "TARGET_USE_FANCY_MATH_387
14697    && flag_unsafe_math_optimizations"
14699   if (optimize_insn_for_size_p ())
14700     FAIL;
14702   ix86_emit_i387_log1p (operands[0], operands[1]);
14703   DONE;
14706 (define_expand "log1p<mode>2"
14707   [(use (match_operand:MODEF 0 "register_operand"))
14708    (use (match_operand:MODEF 1 "register_operand"))]
14709   "TARGET_USE_FANCY_MATH_387
14710    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14711        || TARGET_MIX_SSE_I387)
14712    && flag_unsafe_math_optimizations"
14714   rtx op0;
14716   if (optimize_insn_for_size_p ())
14717     FAIL;
14719   op0 = gen_reg_rtx (XFmode);
14721   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14723   ix86_emit_i387_log1p (op0, operands[1]);
14724   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14725   DONE;
14728 (define_insn "fxtractxf3_i387"
14729   [(set (match_operand:XF 0 "register_operand" "=f")
14730         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14731                    UNSPEC_XTRACT_FRACT))
14732    (set (match_operand:XF 1 "register_operand" "=u")
14733         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14734   "TARGET_USE_FANCY_MATH_387
14735    && flag_unsafe_math_optimizations"
14736   "fxtract"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "XF")])
14740 (define_insn "fxtract_extend<mode>xf3_i387"
14741   [(set (match_operand:XF 0 "register_operand" "=f")
14742         (unspec:XF [(float_extend:XF
14743                       (match_operand:MODEF 2 "register_operand" "0"))]
14744                    UNSPEC_XTRACT_FRACT))
14745    (set (match_operand:XF 1 "register_operand" "=u")
14746         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14747   "TARGET_USE_FANCY_MATH_387
14748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14749        || TARGET_MIX_SSE_I387)
14750    && flag_unsafe_math_optimizations"
14751   "fxtract"
14752   [(set_attr "type" "fpspc")
14753    (set_attr "mode" "XF")])
14755 (define_expand "logbxf2"
14756   [(parallel [(set (match_dup 2)
14757                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14758                               UNSPEC_XTRACT_FRACT))
14759               (set (match_operand:XF 0 "register_operand")
14760                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14761   "TARGET_USE_FANCY_MATH_387
14762    && flag_unsafe_math_optimizations"
14763   "operands[2] = gen_reg_rtx (XFmode);")
14765 (define_expand "logb<mode>2"
14766   [(use (match_operand:MODEF 0 "register_operand"))
14767    (use (match_operand:MODEF 1 "register_operand"))]
14768   "TARGET_USE_FANCY_MATH_387
14769    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14770        || TARGET_MIX_SSE_I387)
14771    && flag_unsafe_math_optimizations"
14773   rtx op0 = gen_reg_rtx (XFmode);
14774   rtx op1 = gen_reg_rtx (XFmode);
14776   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14777   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14778   DONE;
14781 (define_expand "ilogbxf2"
14782   [(use (match_operand:SI 0 "register_operand"))
14783    (use (match_operand:XF 1 "register_operand"))]
14784   "TARGET_USE_FANCY_MATH_387
14785    && flag_unsafe_math_optimizations"
14787   rtx op0, op1;
14789   if (optimize_insn_for_size_p ())
14790     FAIL;
14792   op0 = gen_reg_rtx (XFmode);
14793   op1 = gen_reg_rtx (XFmode);
14795   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14796   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14797   DONE;
14800 (define_expand "ilogb<mode>2"
14801   [(use (match_operand:SI 0 "register_operand"))
14802    (use (match_operand:MODEF 1 "register_operand"))]
14803   "TARGET_USE_FANCY_MATH_387
14804    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14805        || TARGET_MIX_SSE_I387)
14806    && flag_unsafe_math_optimizations"
14808   rtx op0, op1;
14810   if (optimize_insn_for_size_p ())
14811     FAIL;
14813   op0 = gen_reg_rtx (XFmode);
14814   op1 = gen_reg_rtx (XFmode);
14816   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14817   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14818   DONE;
14821 (define_insn "*f2xm1xf2_i387"
14822   [(set (match_operand:XF 0 "register_operand" "=f")
14823         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14824                    UNSPEC_F2XM1))]
14825   "TARGET_USE_FANCY_MATH_387
14826    && flag_unsafe_math_optimizations"
14827   "f2xm1"
14828   [(set_attr "type" "fpspc")
14829    (set_attr "mode" "XF")])
14831 (define_insn "fscalexf4_i387"
14832   [(set (match_operand:XF 0 "register_operand" "=f")
14833         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14834                     (match_operand:XF 3 "register_operand" "1")]
14835                    UNSPEC_FSCALE_FRACT))
14836    (set (match_operand:XF 1 "register_operand" "=u")
14837         (unspec:XF [(match_dup 2) (match_dup 3)]
14838                    UNSPEC_FSCALE_EXP))]
14839   "TARGET_USE_FANCY_MATH_387
14840    && flag_unsafe_math_optimizations"
14841   "fscale"
14842   [(set_attr "type" "fpspc")
14843    (set_attr "mode" "XF")])
14845 (define_expand "expNcorexf3"
14846   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14847                                (match_operand:XF 2 "register_operand")))
14848    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14849    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14850    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14851    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14852    (parallel [(set (match_operand:XF 0 "register_operand")
14853                    (unspec:XF [(match_dup 8) (match_dup 4)]
14854                               UNSPEC_FSCALE_FRACT))
14855               (set (match_dup 9)
14856                    (unspec:XF [(match_dup 8) (match_dup 4)]
14857                               UNSPEC_FSCALE_EXP))])]
14858   "TARGET_USE_FANCY_MATH_387
14859    && flag_unsafe_math_optimizations"
14861   int i;
14863   if (optimize_insn_for_size_p ())
14864     FAIL;
14866   for (i = 3; i < 10; i++)
14867     operands[i] = gen_reg_rtx (XFmode);
14869   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14872 (define_expand "expxf2"
14873   [(use (match_operand:XF 0 "register_operand"))
14874    (use (match_operand:XF 1 "register_operand"))]
14875   "TARGET_USE_FANCY_MATH_387
14876    && flag_unsafe_math_optimizations"
14878   rtx op2;
14880   if (optimize_insn_for_size_p ())
14881     FAIL;
14883   op2 = gen_reg_rtx (XFmode);
14884   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14886   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14887   DONE;
14890 (define_expand "exp<mode>2"
14891   [(use (match_operand:MODEF 0 "register_operand"))
14892    (use (match_operand:MODEF 1 "general_operand"))]
14893  "TARGET_USE_FANCY_MATH_387
14894    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14895        || TARGET_MIX_SSE_I387)
14896    && flag_unsafe_math_optimizations"
14898   rtx op0, op1;
14900   if (optimize_insn_for_size_p ())
14901     FAIL;
14903   op0 = gen_reg_rtx (XFmode);
14904   op1 = gen_reg_rtx (XFmode);
14906   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14907   emit_insn (gen_expxf2 (op0, op1));
14908   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14909   DONE;
14912 (define_expand "exp10xf2"
14913   [(use (match_operand:XF 0 "register_operand"))
14914    (use (match_operand:XF 1 "register_operand"))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14918   rtx op2;
14920   if (optimize_insn_for_size_p ())
14921     FAIL;
14923   op2 = gen_reg_rtx (XFmode);
14924   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14926   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14927   DONE;
14930 (define_expand "exp10<mode>2"
14931   [(use (match_operand:MODEF 0 "register_operand"))
14932    (use (match_operand:MODEF 1 "general_operand"))]
14933  "TARGET_USE_FANCY_MATH_387
14934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14935        || TARGET_MIX_SSE_I387)
14936    && flag_unsafe_math_optimizations"
14938   rtx op0, op1;
14940   if (optimize_insn_for_size_p ())
14941     FAIL;
14943   op0 = gen_reg_rtx (XFmode);
14944   op1 = gen_reg_rtx (XFmode);
14946   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14947   emit_insn (gen_exp10xf2 (op0, op1));
14948   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949   DONE;
14952 (define_expand "exp2xf2"
14953   [(use (match_operand:XF 0 "register_operand"))
14954    (use (match_operand:XF 1 "register_operand"))]
14955   "TARGET_USE_FANCY_MATH_387
14956    && flag_unsafe_math_optimizations"
14958   rtx op2;
14960   if (optimize_insn_for_size_p ())
14961     FAIL;
14963   op2 = gen_reg_rtx (XFmode);
14964   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14966   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14967   DONE;
14970 (define_expand "exp2<mode>2"
14971   [(use (match_operand:MODEF 0 "register_operand"))
14972    (use (match_operand:MODEF 1 "general_operand"))]
14973  "TARGET_USE_FANCY_MATH_387
14974    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14975        || TARGET_MIX_SSE_I387)
14976    && flag_unsafe_math_optimizations"
14978   rtx op0, op1;
14980   if (optimize_insn_for_size_p ())
14981     FAIL;
14983   op0 = gen_reg_rtx (XFmode);
14984   op1 = gen_reg_rtx (XFmode);
14986   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14987   emit_insn (gen_exp2xf2 (op0, op1));
14988   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14989   DONE;
14992 (define_expand "expm1xf2"
14993   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14994                                (match_dup 2)))
14995    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14996    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14997    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14998    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14999    (parallel [(set (match_dup 7)
15000                    (unspec:XF [(match_dup 6) (match_dup 4)]
15001                               UNSPEC_FSCALE_FRACT))
15002               (set (match_dup 8)
15003                    (unspec:XF [(match_dup 6) (match_dup 4)]
15004                               UNSPEC_FSCALE_EXP))])
15005    (parallel [(set (match_dup 10)
15006                    (unspec:XF [(match_dup 9) (match_dup 8)]
15007                               UNSPEC_FSCALE_FRACT))
15008               (set (match_dup 11)
15009                    (unspec:XF [(match_dup 9) (match_dup 8)]
15010                               UNSPEC_FSCALE_EXP))])
15011    (set (match_dup 12) (minus:XF (match_dup 10)
15012                                  (float_extend:XF (match_dup 13))))
15013    (set (match_operand:XF 0 "register_operand")
15014         (plus:XF (match_dup 12) (match_dup 7)))]
15015   "TARGET_USE_FANCY_MATH_387
15016    && flag_unsafe_math_optimizations"
15018   int i;
15020   if (optimize_insn_for_size_p ())
15021     FAIL;
15023   for (i = 2; i < 13; i++)
15024     operands[i] = gen_reg_rtx (XFmode);
15026   operands[13]
15027     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15029   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15032 (define_expand "expm1<mode>2"
15033   [(use (match_operand:MODEF 0 "register_operand"))
15034    (use (match_operand:MODEF 1 "general_operand"))]
15035  "TARGET_USE_FANCY_MATH_387
15036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15037        || TARGET_MIX_SSE_I387)
15038    && flag_unsafe_math_optimizations"
15040   rtx op0, op1;
15042   if (optimize_insn_for_size_p ())
15043     FAIL;
15045   op0 = gen_reg_rtx (XFmode);
15046   op1 = gen_reg_rtx (XFmode);
15048   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15049   emit_insn (gen_expm1xf2 (op0, op1));
15050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15051   DONE;
15054 (define_expand "ldexpxf3"
15055   [(match_operand:XF 0 "register_operand")
15056    (match_operand:XF 1 "register_operand")
15057    (match_operand:SI 2 "register_operand")]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations"
15061   rtx tmp1, tmp2;
15062   if (optimize_insn_for_size_p ())
15063     FAIL;
15065   tmp1 = gen_reg_rtx (XFmode);
15066   tmp2 = gen_reg_rtx (XFmode);
15068   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15069   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15070                                  operands[1], tmp1));
15071   DONE;
15074 (define_expand "ldexp<mode>3"
15075   [(use (match_operand:MODEF 0 "register_operand"))
15076    (use (match_operand:MODEF 1 "general_operand"))
15077    (use (match_operand:SI 2 "register_operand"))]
15078  "TARGET_USE_FANCY_MATH_387
15079    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15080        || TARGET_MIX_SSE_I387)
15081    && flag_unsafe_math_optimizations"
15083   rtx op0, op1;
15085   if (optimize_insn_for_size_p ())
15086     FAIL;
15088   op0 = gen_reg_rtx (XFmode);
15089   op1 = gen_reg_rtx (XFmode);
15091   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15092   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15093   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15094   DONE;
15097 (define_expand "scalbxf3"
15098   [(parallel [(set (match_operand:XF 0 " register_operand")
15099                    (unspec:XF [(match_operand:XF 1 "register_operand")
15100                                (match_operand:XF 2 "register_operand")]
15101                               UNSPEC_FSCALE_FRACT))
15102               (set (match_dup 3)
15103                    (unspec:XF [(match_dup 1) (match_dup 2)]
15104                               UNSPEC_FSCALE_EXP))])]
15105   "TARGET_USE_FANCY_MATH_387
15106    && flag_unsafe_math_optimizations"
15108   if (optimize_insn_for_size_p ())
15109     FAIL;
15111   operands[3] = gen_reg_rtx (XFmode);
15114 (define_expand "scalb<mode>3"
15115   [(use (match_operand:MODEF 0 "register_operand"))
15116    (use (match_operand:MODEF 1 "general_operand"))
15117    (use (match_operand:MODEF 2 "general_operand"))]
15118  "TARGET_USE_FANCY_MATH_387
15119    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15120        || TARGET_MIX_SSE_I387)
15121    && flag_unsafe_math_optimizations"
15123   rtx op0, op1, op2;
15125   if (optimize_insn_for_size_p ())
15126     FAIL;
15128   op0 = gen_reg_rtx (XFmode);
15129   op1 = gen_reg_rtx (XFmode);
15130   op2 = gen_reg_rtx (XFmode);
15132   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15133   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15134   emit_insn (gen_scalbxf3 (op0, op1, op2));
15135   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15136   DONE;
15139 (define_expand "significandxf2"
15140   [(parallel [(set (match_operand:XF 0 "register_operand")
15141                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15142                               UNSPEC_XTRACT_FRACT))
15143               (set (match_dup 2)
15144                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15145   "TARGET_USE_FANCY_MATH_387
15146    && flag_unsafe_math_optimizations"
15147   "operands[2] = gen_reg_rtx (XFmode);")
15149 (define_expand "significand<mode>2"
15150   [(use (match_operand:MODEF 0 "register_operand"))
15151    (use (match_operand:MODEF 1 "register_operand"))]
15152   "TARGET_USE_FANCY_MATH_387
15153    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15154        || TARGET_MIX_SSE_I387)
15155    && flag_unsafe_math_optimizations"
15157   rtx op0 = gen_reg_rtx (XFmode);
15158   rtx op1 = gen_reg_rtx (XFmode);
15160   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15162   DONE;
15166 (define_insn "sse4_1_round<mode>2"
15167   [(set (match_operand:MODEF 0 "register_operand" "=x")
15168         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15169                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15170                       UNSPEC_ROUND))]
15171   "TARGET_ROUND"
15172   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15173   [(set_attr "type" "ssecvt")
15174    (set_attr "prefix_extra" "1")
15175    (set_attr "prefix" "maybe_vex")
15176    (set_attr "mode" "<MODE>")])
15178 (define_insn "rintxf2"
15179   [(set (match_operand:XF 0 "register_operand" "=f")
15180         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15181                    UNSPEC_FRNDINT))]
15182   "TARGET_USE_FANCY_MATH_387
15183    && flag_unsafe_math_optimizations"
15184   "frndint"
15185   [(set_attr "type" "fpspc")
15186    (set_attr "mode" "XF")])
15188 (define_expand "rint<mode>2"
15189   [(use (match_operand:MODEF 0 "register_operand"))
15190    (use (match_operand:MODEF 1 "register_operand"))]
15191   "(TARGET_USE_FANCY_MATH_387
15192     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15193         || TARGET_MIX_SSE_I387)
15194     && flag_unsafe_math_optimizations)
15195    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15196        && !flag_trapping_math)"
15198   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15199       && !flag_trapping_math)
15200     {
15201       if (TARGET_ROUND)
15202         emit_insn (gen_sse4_1_round<mode>2
15203                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15204       else if (optimize_insn_for_size_p ())
15205         FAIL;
15206       else
15207         ix86_expand_rint (operands[0], operands[1]);
15208     }
15209   else
15210     {
15211       rtx op0 = gen_reg_rtx (XFmode);
15212       rtx op1 = gen_reg_rtx (XFmode);
15214       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15215       emit_insn (gen_rintxf2 (op0, op1));
15217       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15218     }
15219   DONE;
15222 (define_expand "round<mode>2"
15223   [(match_operand:X87MODEF 0 "register_operand")
15224    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15225   "(TARGET_USE_FANCY_MATH_387
15226     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15227         || TARGET_MIX_SSE_I387)
15228     && flag_unsafe_math_optimizations)
15229    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15230        && !flag_trapping_math && !flag_rounding_math)"
15232   if (optimize_insn_for_size_p ())
15233     FAIL;
15235   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15236       && !flag_trapping_math && !flag_rounding_math)
15237     {
15238       if (TARGET_ROUND)
15239         {
15240           operands[1] = force_reg (<MODE>mode, operands[1]);
15241           ix86_expand_round_sse4 (operands[0], operands[1]);
15242         }
15243       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15244         ix86_expand_round (operands[0], operands[1]);
15245       else
15246         ix86_expand_rounddf_32 (operands[0], operands[1]);
15247     }
15248   else
15249     {
15250       operands[1] = force_reg (<MODE>mode, operands[1]);
15251       ix86_emit_i387_round (operands[0], operands[1]);
15252     }
15253   DONE;
15256 (define_insn_and_split "*fistdi2_1"
15257   [(set (match_operand:DI 0 "nonimmediate_operand")
15258         (unspec:DI [(match_operand:XF 1 "register_operand")]
15259                    UNSPEC_FIST))]
15260   "TARGET_USE_FANCY_MATH_387
15261    && can_create_pseudo_p ()"
15262   "#"
15263   "&& 1"
15264   [(const_int 0)]
15266   if (memory_operand (operands[0], VOIDmode))
15267     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15268   else
15269     {
15270       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15271       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15272                                          operands[2]));
15273     }
15274   DONE;
15276   [(set_attr "type" "fpspc")
15277    (set_attr "mode" "DI")])
15279 (define_insn "fistdi2"
15280   [(set (match_operand:DI 0 "memory_operand" "=m")
15281         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15282                    UNSPEC_FIST))
15283    (clobber (match_scratch:XF 2 "=&1f"))]
15284   "TARGET_USE_FANCY_MATH_387"
15285   "* return output_fix_trunc (insn, operands, false);"
15286   [(set_attr "type" "fpspc")
15287    (set_attr "mode" "DI")])
15289 (define_insn "fistdi2_with_temp"
15290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15291         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15292                    UNSPEC_FIST))
15293    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15294    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15295   "TARGET_USE_FANCY_MATH_387"
15296   "#"
15297   [(set_attr "type" "fpspc")
15298    (set_attr "mode" "DI")])
15300 (define_split
15301   [(set (match_operand:DI 0 "register_operand")
15302         (unspec:DI [(match_operand:XF 1 "register_operand")]
15303                    UNSPEC_FIST))
15304    (clobber (match_operand:DI 2 "memory_operand"))
15305    (clobber (match_scratch 3))]
15306   "reload_completed"
15307   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15308               (clobber (match_dup 3))])
15309    (set (match_dup 0) (match_dup 2))])
15311 (define_split
15312   [(set (match_operand:DI 0 "memory_operand")
15313         (unspec:DI [(match_operand:XF 1 "register_operand")]
15314                    UNSPEC_FIST))
15315    (clobber (match_operand:DI 2 "memory_operand"))
15316    (clobber (match_scratch 3))]
15317   "reload_completed"
15318   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15319               (clobber (match_dup 3))])])
15321 (define_insn_and_split "*fist<mode>2_1"
15322   [(set (match_operand:SWI24 0 "register_operand")
15323         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15324                       UNSPEC_FIST))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && can_create_pseudo_p ()"
15327   "#"
15328   "&& 1"
15329   [(const_int 0)]
15331   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15332   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15333                                         operands[2]));
15334   DONE;
15336   [(set_attr "type" "fpspc")
15337    (set_attr "mode" "<MODE>")])
15339 (define_insn "fist<mode>2"
15340   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15341         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15342                       UNSPEC_FIST))]
15343   "TARGET_USE_FANCY_MATH_387"
15344   "* return output_fix_trunc (insn, operands, false);"
15345   [(set_attr "type" "fpspc")
15346    (set_attr "mode" "<MODE>")])
15348 (define_insn "fist<mode>2_with_temp"
15349   [(set (match_operand:SWI24 0 "register_operand" "=r")
15350         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15351                       UNSPEC_FIST))
15352    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15353   "TARGET_USE_FANCY_MATH_387"
15354   "#"
15355   [(set_attr "type" "fpspc")
15356    (set_attr "mode" "<MODE>")])
15358 (define_split
15359   [(set (match_operand:SWI24 0 "register_operand")
15360         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15361                       UNSPEC_FIST))
15362    (clobber (match_operand:SWI24 2 "memory_operand"))]
15363   "reload_completed"
15364   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15365    (set (match_dup 0) (match_dup 2))])
15367 (define_split
15368   [(set (match_operand:SWI24 0 "memory_operand")
15369         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15370                       UNSPEC_FIST))
15371    (clobber (match_operand:SWI24 2 "memory_operand"))]
15372   "reload_completed"
15373   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15375 (define_expand "lrintxf<mode>2"
15376   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15377      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15378                      UNSPEC_FIST))]
15379   "TARGET_USE_FANCY_MATH_387")
15381 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15382   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15383      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15384                    UNSPEC_FIX_NOTRUNC))]
15385   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15387 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15388   [(match_operand:SWI248x 0 "nonimmediate_operand")
15389    (match_operand:X87MODEF 1 "register_operand")]
15390   "(TARGET_USE_FANCY_MATH_387
15391     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15392         || TARGET_MIX_SSE_I387)
15393     && flag_unsafe_math_optimizations)
15394    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15395        && <SWI248x:MODE>mode != HImode 
15396        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15397        && !flag_trapping_math && !flag_rounding_math)"
15399   if (optimize_insn_for_size_p ())
15400     FAIL;
15402   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15403       && <SWI248x:MODE>mode != HImode
15404       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15405       && !flag_trapping_math && !flag_rounding_math)
15406     ix86_expand_lround (operands[0], operands[1]);
15407   else
15408     ix86_emit_i387_round (operands[0], operands[1]);
15409   DONE;
15412 (define_int_iterator FRNDINT_ROUNDING
15413         [UNSPEC_FRNDINT_FLOOR
15414          UNSPEC_FRNDINT_CEIL
15415          UNSPEC_FRNDINT_TRUNC])
15417 (define_int_iterator FIST_ROUNDING
15418         [UNSPEC_FIST_FLOOR
15419          UNSPEC_FIST_CEIL])
15421 ;; Base name for define_insn
15422 (define_int_attr rounding_insn
15423         [(UNSPEC_FRNDINT_FLOOR "floor")
15424          (UNSPEC_FRNDINT_CEIL "ceil")
15425          (UNSPEC_FRNDINT_TRUNC "btrunc")
15426          (UNSPEC_FIST_FLOOR "floor")
15427          (UNSPEC_FIST_CEIL "ceil")])
15429 (define_int_attr rounding
15430         [(UNSPEC_FRNDINT_FLOOR "floor")
15431          (UNSPEC_FRNDINT_CEIL "ceil")
15432          (UNSPEC_FRNDINT_TRUNC "trunc")
15433          (UNSPEC_FIST_FLOOR "floor")
15434          (UNSPEC_FIST_CEIL "ceil")])
15436 (define_int_attr ROUNDING
15437         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15438          (UNSPEC_FRNDINT_CEIL "CEIL")
15439          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15440          (UNSPEC_FIST_FLOOR "FLOOR")
15441          (UNSPEC_FIST_CEIL "CEIL")])
15443 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15444 (define_insn_and_split "frndintxf2_<rounding>"
15445   [(set (match_operand:XF 0 "register_operand")
15446         (unspec:XF [(match_operand:XF 1 "register_operand")]
15447                    FRNDINT_ROUNDING))
15448    (clobber (reg:CC FLAGS_REG))]
15449   "TARGET_USE_FANCY_MATH_387
15450    && flag_unsafe_math_optimizations
15451    && can_create_pseudo_p ()"
15452   "#"
15453   "&& 1"
15454   [(const_int 0)]
15456   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15458   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15459   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15461   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15462                                              operands[2], operands[3]));
15463   DONE;
15465   [(set_attr "type" "frndint")
15466    (set_attr "i387_cw" "<rounding>")
15467    (set_attr "mode" "XF")])
15469 (define_insn "frndintxf2_<rounding>_i387"
15470   [(set (match_operand:XF 0 "register_operand" "=f")
15471         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15472                    FRNDINT_ROUNDING))
15473    (use (match_operand:HI 2 "memory_operand" "m"))
15474    (use (match_operand:HI 3 "memory_operand" "m"))]
15475   "TARGET_USE_FANCY_MATH_387
15476    && flag_unsafe_math_optimizations"
15477   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15478   [(set_attr "type" "frndint")
15479    (set_attr "i387_cw" "<rounding>")
15480    (set_attr "mode" "XF")])
15482 (define_expand "<rounding_insn>xf2"
15483   [(parallel [(set (match_operand:XF 0 "register_operand")
15484                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15485                               FRNDINT_ROUNDING))
15486               (clobber (reg:CC FLAGS_REG))])]
15487   "TARGET_USE_FANCY_MATH_387
15488    && flag_unsafe_math_optimizations
15489    && !optimize_insn_for_size_p ()")
15491 (define_expand "<rounding_insn><mode>2"
15492   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15493                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15494                                  FRNDINT_ROUNDING))
15495               (clobber (reg:CC FLAGS_REG))])]
15496   "(TARGET_USE_FANCY_MATH_387
15497     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15498         || TARGET_MIX_SSE_I387)
15499     && flag_unsafe_math_optimizations)
15500    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15501        && !flag_trapping_math)"
15503   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15504       && !flag_trapping_math)
15505     {
15506       if (TARGET_ROUND)
15507         emit_insn (gen_sse4_1_round<mode>2
15508                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15509       else if (optimize_insn_for_size_p ())
15510         FAIL;
15511       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15512         {
15513           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15514             ix86_expand_floorceil (operands[0], operands[1], true);
15515           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15516             ix86_expand_floorceil (operands[0], operands[1], false);
15517           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15518             ix86_expand_trunc (operands[0], operands[1]);
15519           else
15520             gcc_unreachable ();
15521         }
15522       else
15523         {
15524           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15525             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15526           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15527             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15528           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15529             ix86_expand_truncdf_32 (operands[0], operands[1]);
15530           else
15531             gcc_unreachable ();
15532         }
15533     }
15534   else
15535     {
15536       rtx op0, op1;
15538       if (optimize_insn_for_size_p ())
15539         FAIL;
15541       op0 = gen_reg_rtx (XFmode);
15542       op1 = gen_reg_rtx (XFmode);
15543       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15544       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15546       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15547     }
15548   DONE;
15551 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15552 (define_insn_and_split "frndintxf2_mask_pm"
15553   [(set (match_operand:XF 0 "register_operand")
15554         (unspec:XF [(match_operand:XF 1 "register_operand")]
15555                    UNSPEC_FRNDINT_MASK_PM))
15556    (clobber (reg:CC FLAGS_REG))]
15557   "TARGET_USE_FANCY_MATH_387
15558    && flag_unsafe_math_optimizations
15559    && can_create_pseudo_p ()"
15560   "#"
15561   "&& 1"
15562   [(const_int 0)]
15564   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15566   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15567   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15569   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15570                                           operands[2], operands[3]));
15571   DONE;
15573   [(set_attr "type" "frndint")
15574    (set_attr "i387_cw" "mask_pm")
15575    (set_attr "mode" "XF")])
15577 (define_insn "frndintxf2_mask_pm_i387"
15578   [(set (match_operand:XF 0 "register_operand" "=f")
15579         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15580                    UNSPEC_FRNDINT_MASK_PM))
15581    (use (match_operand:HI 2 "memory_operand" "m"))
15582    (use (match_operand:HI 3 "memory_operand" "m"))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && flag_unsafe_math_optimizations"
15585   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15586   [(set_attr "type" "frndint")
15587    (set_attr "i387_cw" "mask_pm")
15588    (set_attr "mode" "XF")])
15590 (define_expand "nearbyintxf2"
15591   [(parallel [(set (match_operand:XF 0 "register_operand")
15592                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15593                               UNSPEC_FRNDINT_MASK_PM))
15594               (clobber (reg:CC FLAGS_REG))])]
15595   "TARGET_USE_FANCY_MATH_387
15596    && flag_unsafe_math_optimizations")
15598 (define_expand "nearbyint<mode>2"
15599   [(use (match_operand:MODEF 0 "register_operand"))
15600    (use (match_operand:MODEF 1 "register_operand"))]
15601   "TARGET_USE_FANCY_MATH_387
15602    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15603        || TARGET_MIX_SSE_I387)
15604    && flag_unsafe_math_optimizations"
15606   rtx op0 = gen_reg_rtx (XFmode);
15607   rtx op1 = gen_reg_rtx (XFmode);
15609   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15610   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15612   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15613   DONE;
15616 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15617 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15618   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15619         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15620                         FIST_ROUNDING))
15621    (clobber (reg:CC FLAGS_REG))]
15622   "TARGET_USE_FANCY_MATH_387
15623    && flag_unsafe_math_optimizations
15624    && can_create_pseudo_p ()"
15625   "#"
15626   "&& 1"
15627   [(const_int 0)]
15629   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15631   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15632   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15633   if (memory_operand (operands[0], VOIDmode))
15634     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15635                                            operands[2], operands[3]));
15636   else
15637     {
15638       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15639       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15640                   (operands[0], operands[1], operands[2],
15641                    operands[3], operands[4]));
15642     }
15643   DONE;
15645   [(set_attr "type" "fistp")
15646    (set_attr "i387_cw" "<rounding>")
15647    (set_attr "mode" "<MODE>")])
15649 (define_insn "fistdi2_<rounding>"
15650   [(set (match_operand:DI 0 "memory_operand" "=m")
15651         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15652                    FIST_ROUNDING))
15653    (use (match_operand:HI 2 "memory_operand" "m"))
15654    (use (match_operand:HI 3 "memory_operand" "m"))
15655    (clobber (match_scratch:XF 4 "=&1f"))]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_unsafe_math_optimizations"
15658   "* return output_fix_trunc (insn, operands, false);"
15659   [(set_attr "type" "fistp")
15660    (set_attr "i387_cw" "<rounding>")
15661    (set_attr "mode" "DI")])
15663 (define_insn "fistdi2_<rounding>_with_temp"
15664   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15665         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15666                    FIST_ROUNDING))
15667    (use (match_operand:HI 2 "memory_operand" "m,m"))
15668    (use (match_operand:HI 3 "memory_operand" "m,m"))
15669    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15670    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15671   "TARGET_USE_FANCY_MATH_387
15672    && flag_unsafe_math_optimizations"
15673   "#"
15674   [(set_attr "type" "fistp")
15675    (set_attr "i387_cw" "<rounding>")
15676    (set_attr "mode" "DI")])
15678 (define_split
15679   [(set (match_operand:DI 0 "register_operand")
15680         (unspec:DI [(match_operand:XF 1 "register_operand")]
15681                    FIST_ROUNDING))
15682    (use (match_operand:HI 2 "memory_operand"))
15683    (use (match_operand:HI 3 "memory_operand"))
15684    (clobber (match_operand:DI 4 "memory_operand"))
15685    (clobber (match_scratch 5))]
15686   "reload_completed"
15687   [(parallel [(set (match_dup 4)
15688                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15689               (use (match_dup 2))
15690               (use (match_dup 3))
15691               (clobber (match_dup 5))])
15692    (set (match_dup 0) (match_dup 4))])
15694 (define_split
15695   [(set (match_operand:DI 0 "memory_operand")
15696         (unspec:DI [(match_operand:XF 1 "register_operand")]
15697                    FIST_ROUNDING))
15698    (use (match_operand:HI 2 "memory_operand"))
15699    (use (match_operand:HI 3 "memory_operand"))
15700    (clobber (match_operand:DI 4 "memory_operand"))
15701    (clobber (match_scratch 5))]
15702   "reload_completed"
15703   [(parallel [(set (match_dup 0)
15704                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15705               (use (match_dup 2))
15706               (use (match_dup 3))
15707               (clobber (match_dup 5))])])
15709 (define_insn "fist<mode>2_<rounding>"
15710   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15711         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15712                       FIST_ROUNDING))
15713    (use (match_operand:HI 2 "memory_operand" "m"))
15714    (use (match_operand:HI 3 "memory_operand" "m"))]
15715   "TARGET_USE_FANCY_MATH_387
15716    && flag_unsafe_math_optimizations"
15717   "* return output_fix_trunc (insn, operands, false);"
15718   [(set_attr "type" "fistp")
15719    (set_attr "i387_cw" "<rounding>")
15720    (set_attr "mode" "<MODE>")])
15722 (define_insn "fist<mode>2_<rounding>_with_temp"
15723   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15724         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15725                       FIST_ROUNDING))
15726    (use (match_operand:HI 2 "memory_operand" "m,m"))
15727    (use (match_operand:HI 3 "memory_operand" "m,m"))
15728    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15729   "TARGET_USE_FANCY_MATH_387
15730    && flag_unsafe_math_optimizations"
15731   "#"
15732   [(set_attr "type" "fistp")
15733    (set_attr "i387_cw" "<rounding>")
15734    (set_attr "mode" "<MODE>")])
15736 (define_split
15737   [(set (match_operand:SWI24 0 "register_operand")
15738         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15739                       FIST_ROUNDING))
15740    (use (match_operand:HI 2 "memory_operand"))
15741    (use (match_operand:HI 3 "memory_operand"))
15742    (clobber (match_operand:SWI24 4 "memory_operand"))]
15743   "reload_completed"
15744   [(parallel [(set (match_dup 4)
15745                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15746               (use (match_dup 2))
15747               (use (match_dup 3))])
15748    (set (match_dup 0) (match_dup 4))])
15750 (define_split
15751   [(set (match_operand:SWI24 0 "memory_operand")
15752         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15753                       FIST_ROUNDING))
15754    (use (match_operand:HI 2 "memory_operand"))
15755    (use (match_operand:HI 3 "memory_operand"))
15756    (clobber (match_operand:SWI24 4 "memory_operand"))]
15757   "reload_completed"
15758   [(parallel [(set (match_dup 0)
15759                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15760               (use (match_dup 2))
15761               (use (match_dup 3))])])
15763 (define_expand "l<rounding_insn>xf<mode>2"
15764   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15765                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15766                                    FIST_ROUNDING))
15767               (clobber (reg:CC FLAGS_REG))])]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15770    && flag_unsafe_math_optimizations")
15772 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15773   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15774                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15775                                  FIST_ROUNDING))
15776               (clobber (reg:CC FLAGS_REG))])]
15777   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15778    && !flag_trapping_math"
15780   if (TARGET_64BIT && optimize_insn_for_size_p ())
15781     FAIL;
15783   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15784     ix86_expand_lfloorceil (operands[0], operands[1], true);
15785   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15786     ix86_expand_lfloorceil (operands[0], operands[1], false);
15787   else
15788     gcc_unreachable ();
15790   DONE;
15793 (define_insn "fxam<mode>2_i387"
15794   [(set (match_operand:HI 0 "register_operand" "=a")
15795         (unspec:HI
15796           [(match_operand:X87MODEF 1 "register_operand" "f")]
15797           UNSPEC_FXAM))]
15798   "TARGET_USE_FANCY_MATH_387"
15799   "fxam\n\tfnstsw\t%0"
15800   [(set_attr "type" "multi")
15801    (set_attr "length" "4")
15802    (set_attr "unit" "i387")
15803    (set_attr "mode" "<MODE>")])
15805 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15806   [(set (match_operand:HI 0 "register_operand")
15807         (unspec:HI
15808           [(match_operand:MODEF 1 "memory_operand")]
15809           UNSPEC_FXAM_MEM))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && can_create_pseudo_p ()"
15812   "#"
15813   "&& 1"
15814   [(set (match_dup 2)(match_dup 1))
15815    (set (match_dup 0)
15816         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15818   operands[2] = gen_reg_rtx (<MODE>mode);
15820   MEM_VOLATILE_P (operands[1]) = 1;
15822   [(set_attr "type" "multi")
15823    (set_attr "unit" "i387")
15824    (set_attr "mode" "<MODE>")])
15826 (define_expand "isinfxf2"
15827   [(use (match_operand:SI 0 "register_operand"))
15828    (use (match_operand:XF 1 "register_operand"))]
15829   "TARGET_USE_FANCY_MATH_387
15830    && ix86_libc_has_function (function_c99_misc)"
15832   rtx mask = GEN_INT (0x45);
15833   rtx val = GEN_INT (0x05);
15835   rtx cond;
15837   rtx scratch = gen_reg_rtx (HImode);
15838   rtx res = gen_reg_rtx (QImode);
15840   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15842   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15843   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15844   cond = gen_rtx_fmt_ee (EQ, QImode,
15845                          gen_rtx_REG (CCmode, FLAGS_REG),
15846                          const0_rtx);
15847   emit_insn (gen_rtx_SET (res, cond));
15848   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15849   DONE;
15852 (define_expand "isinf<mode>2"
15853   [(use (match_operand:SI 0 "register_operand"))
15854    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15855   "TARGET_USE_FANCY_MATH_387
15856    && ix86_libc_has_function (function_c99_misc)
15857    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15859   rtx mask = GEN_INT (0x45);
15860   rtx val = GEN_INT (0x05);
15862   rtx cond;
15864   rtx scratch = gen_reg_rtx (HImode);
15865   rtx res = gen_reg_rtx (QImode);
15867   /* Remove excess precision by forcing value through memory. */
15868   if (memory_operand (operands[1], VOIDmode))
15869     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15870   else
15871     {
15872       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15874       emit_move_insn (temp, operands[1]);
15875       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15876     }
15878   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15879   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15880   cond = gen_rtx_fmt_ee (EQ, QImode,
15881                          gen_rtx_REG (CCmode, FLAGS_REG),
15882                          const0_rtx);
15883   emit_insn (gen_rtx_SET (res, cond));
15884   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15885   DONE;
15888 (define_expand "signbitxf2"
15889   [(use (match_operand:SI 0 "register_operand"))
15890    (use (match_operand:XF 1 "register_operand"))]
15891   "TARGET_USE_FANCY_MATH_387"
15893   rtx scratch = gen_reg_rtx (HImode);
15895   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15896   emit_insn (gen_andsi3 (operands[0],
15897              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15898   DONE;
15901 (define_insn "movmsk_df"
15902   [(set (match_operand:SI 0 "register_operand" "=r")
15903         (unspec:SI
15904           [(match_operand:DF 1 "register_operand" "x")]
15905           UNSPEC_MOVMSK))]
15906   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15907   "%vmovmskpd\t{%1, %0|%0, %1}"
15908   [(set_attr "type" "ssemov")
15909    (set_attr "prefix" "maybe_vex")
15910    (set_attr "mode" "DF")])
15912 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15913 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15914 (define_expand "signbitdf2"
15915   [(use (match_operand:SI 0 "register_operand"))
15916    (use (match_operand:DF 1 "register_operand"))]
15917   "TARGET_USE_FANCY_MATH_387
15918    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15920   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15921     {
15922       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15923       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15924     }
15925   else
15926     {
15927       rtx scratch = gen_reg_rtx (HImode);
15929       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15930       emit_insn (gen_andsi3 (operands[0],
15931                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15932     }
15933   DONE;
15936 (define_expand "signbitsf2"
15937   [(use (match_operand:SI 0 "register_operand"))
15938    (use (match_operand:SF 1 "register_operand"))]
15939   "TARGET_USE_FANCY_MATH_387
15940    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15942   rtx scratch = gen_reg_rtx (HImode);
15944   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15945   emit_insn (gen_andsi3 (operands[0],
15946              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15947   DONE;
15950 ;; Block operation instructions
15952 (define_insn "cld"
15953   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15954   ""
15955   "cld"
15956   [(set_attr "length" "1")
15957    (set_attr "length_immediate" "0")
15958    (set_attr "modrm" "0")])
15960 (define_expand "movmem<mode>"
15961   [(use (match_operand:BLK 0 "memory_operand"))
15962    (use (match_operand:BLK 1 "memory_operand"))
15963    (use (match_operand:SWI48 2 "nonmemory_operand"))
15964    (use (match_operand:SWI48 3 "const_int_operand"))
15965    (use (match_operand:SI 4 "const_int_operand"))
15966    (use (match_operand:SI 5 "const_int_operand"))
15967    (use (match_operand:SI 6 ""))
15968    (use (match_operand:SI 7 ""))
15969    (use (match_operand:SI 8 ""))]
15970   ""
15972  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15973                                 operands[2], NULL, operands[3],
15974                                 operands[4], operands[5],
15975                                 operands[6], operands[7],
15976                                 operands[8], false))
15977    DONE;
15978  else
15979    FAIL;
15982 ;; Most CPUs don't like single string operations
15983 ;; Handle this case here to simplify previous expander.
15985 (define_expand "strmov"
15986   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15987    (set (match_operand 1 "memory_operand") (match_dup 4))
15988    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15989               (clobber (reg:CC FLAGS_REG))])
15990    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15991               (clobber (reg:CC FLAGS_REG))])]
15992   ""
15994   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15996   /* If .md ever supports :P for Pmode, these can be directly
15997      in the pattern above.  */
15998   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15999   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16001   /* Can't use this if the user has appropriated esi or edi.  */
16002   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16003       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16004     {
16005       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16006                                       operands[2], operands[3],
16007                                       operands[5], operands[6]));
16008       DONE;
16009     }
16011   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16014 (define_expand "strmov_singleop"
16015   [(parallel [(set (match_operand 1 "memory_operand")
16016                    (match_operand 3 "memory_operand"))
16017               (set (match_operand 0 "register_operand")
16018                    (match_operand 4))
16019               (set (match_operand 2 "register_operand")
16020                    (match_operand 5))])]
16021   ""
16022   "ix86_current_function_needs_cld = 1;")
16024 (define_insn "*strmovdi_rex_1"
16025   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16026         (mem:DI (match_operand:P 3 "register_operand" "1")))
16027    (set (match_operand:P 0 "register_operand" "=D")
16028         (plus:P (match_dup 2)
16029                 (const_int 8)))
16030    (set (match_operand:P 1 "register_operand" "=S")
16031         (plus:P (match_dup 3)
16032                 (const_int 8)))]
16033   "TARGET_64BIT
16034    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16035   "%^movsq"
16036   [(set_attr "type" "str")
16037    (set_attr "memory" "both")
16038    (set_attr "mode" "DI")])
16040 (define_insn "*strmovsi_1"
16041   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16042         (mem:SI (match_operand:P 3 "register_operand" "1")))
16043    (set (match_operand:P 0 "register_operand" "=D")
16044         (plus:P (match_dup 2)
16045                 (const_int 4)))
16046    (set (match_operand:P 1 "register_operand" "=S")
16047         (plus:P (match_dup 3)
16048                 (const_int 4)))]
16049   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16050   "%^movs{l|d}"
16051   [(set_attr "type" "str")
16052    (set_attr "memory" "both")
16053    (set_attr "mode" "SI")])
16055 (define_insn "*strmovhi_1"
16056   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16057         (mem:HI (match_operand:P 3 "register_operand" "1")))
16058    (set (match_operand:P 0 "register_operand" "=D")
16059         (plus:P (match_dup 2)
16060                 (const_int 2)))
16061    (set (match_operand:P 1 "register_operand" "=S")
16062         (plus:P (match_dup 3)
16063                 (const_int 2)))]
16064   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16065   "%^movsw"
16066   [(set_attr "type" "str")
16067    (set_attr "memory" "both")
16068    (set_attr "mode" "HI")])
16070 (define_insn "*strmovqi_1"
16071   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16072         (mem:QI (match_operand:P 3 "register_operand" "1")))
16073    (set (match_operand:P 0 "register_operand" "=D")
16074         (plus:P (match_dup 2)
16075                 (const_int 1)))
16076    (set (match_operand:P 1 "register_operand" "=S")
16077         (plus:P (match_dup 3)
16078                 (const_int 1)))]
16079   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16080   "%^movsb"
16081   [(set_attr "type" "str")
16082    (set_attr "memory" "both")
16083    (set (attr "prefix_rex")
16084         (if_then_else
16085           (match_test "<P:MODE>mode == DImode")
16086           (const_string "0")
16087           (const_string "*")))
16088    (set_attr "mode" "QI")])
16090 (define_expand "rep_mov"
16091   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16092               (set (match_operand 0 "register_operand")
16093                    (match_operand 5))
16094               (set (match_operand 2 "register_operand")
16095                    (match_operand 6))
16096               (set (match_operand 1 "memory_operand")
16097                    (match_operand 3 "memory_operand"))
16098               (use (match_dup 4))])]
16099   ""
16100   "ix86_current_function_needs_cld = 1;")
16102 (define_insn "*rep_movdi_rex64"
16103   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16104    (set (match_operand:P 0 "register_operand" "=D")
16105         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16106                           (const_int 3))
16107                 (match_operand:P 3 "register_operand" "0")))
16108    (set (match_operand:P 1 "register_operand" "=S")
16109         (plus:P (ashift:P (match_dup 5) (const_int 3))
16110                 (match_operand:P 4 "register_operand" "1")))
16111    (set (mem:BLK (match_dup 3))
16112         (mem:BLK (match_dup 4)))
16113    (use (match_dup 5))]
16114   "TARGET_64BIT
16115    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16116   "%^rep{%;} movsq"
16117   [(set_attr "type" "str")
16118    (set_attr "prefix_rep" "1")
16119    (set_attr "memory" "both")
16120    (set_attr "mode" "DI")])
16122 (define_insn "*rep_movsi"
16123   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16124    (set (match_operand:P 0 "register_operand" "=D")
16125         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16126                           (const_int 2))
16127                  (match_operand:P 3 "register_operand" "0")))
16128    (set (match_operand:P 1 "register_operand" "=S")
16129         (plus:P (ashift:P (match_dup 5) (const_int 2))
16130                 (match_operand:P 4 "register_operand" "1")))
16131    (set (mem:BLK (match_dup 3))
16132         (mem:BLK (match_dup 4)))
16133    (use (match_dup 5))]
16134   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16135   "%^rep{%;} movs{l|d}"
16136   [(set_attr "type" "str")
16137    (set_attr "prefix_rep" "1")
16138    (set_attr "memory" "both")
16139    (set_attr "mode" "SI")])
16141 (define_insn "*rep_movqi"
16142   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16143    (set (match_operand:P 0 "register_operand" "=D")
16144         (plus:P (match_operand:P 3 "register_operand" "0")
16145                 (match_operand:P 5 "register_operand" "2")))
16146    (set (match_operand:P 1 "register_operand" "=S")
16147         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16148    (set (mem:BLK (match_dup 3))
16149         (mem:BLK (match_dup 4)))
16150    (use (match_dup 5))]
16151   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16152   "%^rep{%;} movsb"
16153   [(set_attr "type" "str")
16154    (set_attr "prefix_rep" "1")
16155    (set_attr "memory" "both")
16156    (set_attr "mode" "QI")])
16158 (define_expand "setmem<mode>"
16159    [(use (match_operand:BLK 0 "memory_operand"))
16160     (use (match_operand:SWI48 1 "nonmemory_operand"))
16161     (use (match_operand:QI 2 "nonmemory_operand"))
16162     (use (match_operand 3 "const_int_operand"))
16163     (use (match_operand:SI 4 "const_int_operand"))
16164     (use (match_operand:SI 5 "const_int_operand"))
16165     (use (match_operand:SI 6 ""))
16166     (use (match_operand:SI 7 ""))
16167     (use (match_operand:SI 8 ""))]
16168   ""
16170  if (ix86_expand_set_or_movmem (operands[0], NULL,
16171                                 operands[1], operands[2],
16172                                 operands[3], operands[4],
16173                                 operands[5], operands[6],
16174                                 operands[7], operands[8], true))
16175    DONE;
16176  else
16177    FAIL;
16180 ;; Most CPUs don't like single string operations
16181 ;; Handle this case here to simplify previous expander.
16183 (define_expand "strset"
16184   [(set (match_operand 1 "memory_operand")
16185         (match_operand 2 "register_operand"))
16186    (parallel [(set (match_operand 0 "register_operand")
16187                    (match_dup 3))
16188               (clobber (reg:CC FLAGS_REG))])]
16189   ""
16191   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16192     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16194   /* If .md ever supports :P for Pmode, this can be directly
16195      in the pattern above.  */
16196   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16197                               GEN_INT (GET_MODE_SIZE (GET_MODE
16198                                                       (operands[2]))));
16199   /* Can't use this if the user has appropriated eax or edi.  */
16200   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16201       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16202     {
16203       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16204                                       operands[3]));
16205       DONE;
16206     }
16209 (define_expand "strset_singleop"
16210   [(parallel [(set (match_operand 1 "memory_operand")
16211                    (match_operand 2 "register_operand"))
16212               (set (match_operand 0 "register_operand")
16213                    (match_operand 3))
16214               (unspec [(const_int 0)] UNSPEC_STOS)])]
16215   ""
16216   "ix86_current_function_needs_cld = 1;")
16218 (define_insn "*strsetdi_rex_1"
16219   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16220         (match_operand:DI 2 "register_operand" "a"))
16221    (set (match_operand:P 0 "register_operand" "=D")
16222         (plus:P (match_dup 1)
16223                 (const_int 8)))
16224    (unspec [(const_int 0)] UNSPEC_STOS)]
16225   "TARGET_64BIT
16226    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16227   "%^stosq"
16228   [(set_attr "type" "str")
16229    (set_attr "memory" "store")
16230    (set_attr "mode" "DI")])
16232 (define_insn "*strsetsi_1"
16233   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16234         (match_operand:SI 2 "register_operand" "a"))
16235    (set (match_operand:P 0 "register_operand" "=D")
16236         (plus:P (match_dup 1)
16237                 (const_int 4)))
16238    (unspec [(const_int 0)] UNSPEC_STOS)]
16239   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16240   "%^stos{l|d}"
16241   [(set_attr "type" "str")
16242    (set_attr "memory" "store")
16243    (set_attr "mode" "SI")])
16245 (define_insn "*strsethi_1"
16246   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16247         (match_operand:HI 2 "register_operand" "a"))
16248    (set (match_operand:P 0 "register_operand" "=D")
16249         (plus:P (match_dup 1)
16250                 (const_int 2)))
16251    (unspec [(const_int 0)] UNSPEC_STOS)]
16252   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16253   "%^stosw"
16254   [(set_attr "type" "str")
16255    (set_attr "memory" "store")
16256    (set_attr "mode" "HI")])
16258 (define_insn "*strsetqi_1"
16259   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16260         (match_operand:QI 2 "register_operand" "a"))
16261    (set (match_operand:P 0 "register_operand" "=D")
16262         (plus:P (match_dup 1)
16263                 (const_int 1)))
16264    (unspec [(const_int 0)] UNSPEC_STOS)]
16265   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16266   "%^stosb"
16267   [(set_attr "type" "str")
16268    (set_attr "memory" "store")
16269    (set (attr "prefix_rex")
16270         (if_then_else
16271           (match_test "<P:MODE>mode == DImode")
16272           (const_string "0")
16273           (const_string "*")))
16274    (set_attr "mode" "QI")])
16276 (define_expand "rep_stos"
16277   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16278               (set (match_operand 0 "register_operand")
16279                    (match_operand 4))
16280               (set (match_operand 2 "memory_operand") (const_int 0))
16281               (use (match_operand 3 "register_operand"))
16282               (use (match_dup 1))])]
16283   ""
16284   "ix86_current_function_needs_cld = 1;")
16286 (define_insn "*rep_stosdi_rex64"
16287   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16288    (set (match_operand:P 0 "register_operand" "=D")
16289         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16290                           (const_int 3))
16291                  (match_operand:P 3 "register_operand" "0")))
16292    (set (mem:BLK (match_dup 3))
16293         (const_int 0))
16294    (use (match_operand:DI 2 "register_operand" "a"))
16295    (use (match_dup 4))]
16296   "TARGET_64BIT
16297    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16298   "%^rep{%;} stosq"
16299   [(set_attr "type" "str")
16300    (set_attr "prefix_rep" "1")
16301    (set_attr "memory" "store")
16302    (set_attr "mode" "DI")])
16304 (define_insn "*rep_stossi"
16305   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16306    (set (match_operand:P 0 "register_operand" "=D")
16307         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16308                           (const_int 2))
16309                  (match_operand:P 3 "register_operand" "0")))
16310    (set (mem:BLK (match_dup 3))
16311         (const_int 0))
16312    (use (match_operand:SI 2 "register_operand" "a"))
16313    (use (match_dup 4))]
16314   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16315   "%^rep{%;} stos{l|d}"
16316   [(set_attr "type" "str")
16317    (set_attr "prefix_rep" "1")
16318    (set_attr "memory" "store")
16319    (set_attr "mode" "SI")])
16321 (define_insn "*rep_stosqi"
16322   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16323    (set (match_operand:P 0 "register_operand" "=D")
16324         (plus:P (match_operand:P 3 "register_operand" "0")
16325                 (match_operand:P 4 "register_operand" "1")))
16326    (set (mem:BLK (match_dup 3))
16327         (const_int 0))
16328    (use (match_operand:QI 2 "register_operand" "a"))
16329    (use (match_dup 4))]
16330   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16331   "%^rep{%;} stosb"
16332   [(set_attr "type" "str")
16333    (set_attr "prefix_rep" "1")
16334    (set_attr "memory" "store")
16335    (set (attr "prefix_rex")
16336         (if_then_else
16337           (match_test "<P:MODE>mode == DImode")
16338           (const_string "0")
16339           (const_string "*")))
16340    (set_attr "mode" "QI")])
16342 (define_expand "cmpstrnsi"
16343   [(set (match_operand:SI 0 "register_operand")
16344         (compare:SI (match_operand:BLK 1 "general_operand")
16345                     (match_operand:BLK 2 "general_operand")))
16346    (use (match_operand 3 "general_operand"))
16347    (use (match_operand 4 "immediate_operand"))]
16348   ""
16350   rtx addr1, addr2, out, outlow, count, countreg, align;
16352   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16353     FAIL;
16355   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16356   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16357     FAIL;
16359   out = operands[0];
16360   if (!REG_P (out))
16361     out = gen_reg_rtx (SImode);
16363   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16364   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16365   if (addr1 != XEXP (operands[1], 0))
16366     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16367   if (addr2 != XEXP (operands[2], 0))
16368     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16370   count = operands[3];
16371   countreg = ix86_zero_extend_to_Pmode (count);
16373   /* %%% Iff we are testing strict equality, we can use known alignment
16374      to good advantage.  This may be possible with combine, particularly
16375      once cc0 is dead.  */
16376   align = operands[4];
16378   if (CONST_INT_P (count))
16379     {
16380       if (INTVAL (count) == 0)
16381         {
16382           emit_move_insn (operands[0], const0_rtx);
16383           DONE;
16384         }
16385       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16386                                      operands[1], operands[2]));
16387     }
16388   else
16389     {
16390       rtx (*gen_cmp) (rtx, rtx);
16392       gen_cmp = (TARGET_64BIT
16393                  ? gen_cmpdi_1 : gen_cmpsi_1);
16395       emit_insn (gen_cmp (countreg, countreg));
16396       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16397                                   operands[1], operands[2]));
16398     }
16400   outlow = gen_lowpart (QImode, out);
16401   emit_insn (gen_cmpintqi (outlow));
16402   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16404   if (operands[0] != out)
16405     emit_move_insn (operands[0], out);
16407   DONE;
16410 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16412 (define_expand "cmpintqi"
16413   [(set (match_dup 1)
16414         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16415    (set (match_dup 2)
16416         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16417    (parallel [(set (match_operand:QI 0 "register_operand")
16418                    (minus:QI (match_dup 1)
16419                              (match_dup 2)))
16420               (clobber (reg:CC FLAGS_REG))])]
16421   ""
16423   operands[1] = gen_reg_rtx (QImode);
16424   operands[2] = gen_reg_rtx (QImode);
16427 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16428 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16430 (define_expand "cmpstrnqi_nz_1"
16431   [(parallel [(set (reg:CC FLAGS_REG)
16432                    (compare:CC (match_operand 4 "memory_operand")
16433                                (match_operand 5 "memory_operand")))
16434               (use (match_operand 2 "register_operand"))
16435               (use (match_operand:SI 3 "immediate_operand"))
16436               (clobber (match_operand 0 "register_operand"))
16437               (clobber (match_operand 1 "register_operand"))
16438               (clobber (match_dup 2))])]
16439   ""
16440   "ix86_current_function_needs_cld = 1;")
16442 (define_insn "*cmpstrnqi_nz_1"
16443   [(set (reg:CC FLAGS_REG)
16444         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16445                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16446    (use (match_operand:P 6 "register_operand" "2"))
16447    (use (match_operand:SI 3 "immediate_operand" "i"))
16448    (clobber (match_operand:P 0 "register_operand" "=S"))
16449    (clobber (match_operand:P 1 "register_operand" "=D"))
16450    (clobber (match_operand:P 2 "register_operand" "=c"))]
16451   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16452   "%^repz{%;} cmpsb"
16453   [(set_attr "type" "str")
16454    (set_attr "mode" "QI")
16455    (set (attr "prefix_rex")
16456         (if_then_else
16457           (match_test "<P:MODE>mode == DImode")
16458           (const_string "0")
16459           (const_string "*")))
16460    (set_attr "prefix_rep" "1")])
16462 ;; The same, but the count is not known to not be zero.
16464 (define_expand "cmpstrnqi_1"
16465   [(parallel [(set (reg:CC FLAGS_REG)
16466                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16467                                      (const_int 0))
16468                   (compare:CC (match_operand 4 "memory_operand")
16469                               (match_operand 5 "memory_operand"))
16470                   (const_int 0)))
16471               (use (match_operand:SI 3 "immediate_operand"))
16472               (use (reg:CC FLAGS_REG))
16473               (clobber (match_operand 0 "register_operand"))
16474               (clobber (match_operand 1 "register_operand"))
16475               (clobber (match_dup 2))])]
16476   ""
16477   "ix86_current_function_needs_cld = 1;")
16479 (define_insn "*cmpstrnqi_1"
16480   [(set (reg:CC FLAGS_REG)
16481         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16482                              (const_int 0))
16483           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16484                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16485           (const_int 0)))
16486    (use (match_operand:SI 3 "immediate_operand" "i"))
16487    (use (reg:CC FLAGS_REG))
16488    (clobber (match_operand:P 0 "register_operand" "=S"))
16489    (clobber (match_operand:P 1 "register_operand" "=D"))
16490    (clobber (match_operand:P 2 "register_operand" "=c"))]
16491   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16492   "%^repz{%;} cmpsb"
16493   [(set_attr "type" "str")
16494    (set_attr "mode" "QI")
16495    (set (attr "prefix_rex")
16496         (if_then_else
16497           (match_test "<P:MODE>mode == DImode")
16498           (const_string "0")
16499           (const_string "*")))
16500    (set_attr "prefix_rep" "1")])
16502 (define_expand "strlen<mode>"
16503   [(set (match_operand:P 0 "register_operand")
16504         (unspec:P [(match_operand:BLK 1 "general_operand")
16505                    (match_operand:QI 2 "immediate_operand")
16506                    (match_operand 3 "immediate_operand")]
16507                   UNSPEC_SCAS))]
16508   ""
16510  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16511    DONE;
16512  else
16513    FAIL;
16516 (define_expand "strlenqi_1"
16517   [(parallel [(set (match_operand 0 "register_operand")
16518                    (match_operand 2))
16519               (clobber (match_operand 1 "register_operand"))
16520               (clobber (reg:CC FLAGS_REG))])]
16521   ""
16522   "ix86_current_function_needs_cld = 1;")
16524 (define_insn "*strlenqi_1"
16525   [(set (match_operand:P 0 "register_operand" "=&c")
16526         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16527                    (match_operand:QI 2 "register_operand" "a")
16528                    (match_operand:P 3 "immediate_operand" "i")
16529                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16530    (clobber (match_operand:P 1 "register_operand" "=D"))
16531    (clobber (reg:CC FLAGS_REG))]
16532   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16533   "%^repnz{%;} scasb"
16534   [(set_attr "type" "str")
16535    (set_attr "mode" "QI")
16536    (set (attr "prefix_rex")
16537         (if_then_else
16538           (match_test "<P:MODE>mode == DImode")
16539           (const_string "0")
16540           (const_string "*")))
16541    (set_attr "prefix_rep" "1")])
16543 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16544 ;; handled in combine, but it is not currently up to the task.
16545 ;; When used for their truth value, the cmpstrn* expanders generate
16546 ;; code like this:
16548 ;;   repz cmpsb
16549 ;;   seta       %al
16550 ;;   setb       %dl
16551 ;;   cmpb       %al, %dl
16552 ;;   jcc        label
16554 ;; The intermediate three instructions are unnecessary.
16556 ;; This one handles cmpstrn*_nz_1...
16557 (define_peephole2
16558   [(parallel[
16559      (set (reg:CC FLAGS_REG)
16560           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16561                       (mem:BLK (match_operand 5 "register_operand"))))
16562      (use (match_operand 6 "register_operand"))
16563      (use (match_operand:SI 3 "immediate_operand"))
16564      (clobber (match_operand 0 "register_operand"))
16565      (clobber (match_operand 1 "register_operand"))
16566      (clobber (match_operand 2 "register_operand"))])
16567    (set (match_operand:QI 7 "register_operand")
16568         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16569    (set (match_operand:QI 8 "register_operand")
16570         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16571    (set (reg FLAGS_REG)
16572         (compare (match_dup 7) (match_dup 8)))
16573   ]
16574   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16575   [(parallel[
16576      (set (reg:CC FLAGS_REG)
16577           (compare:CC (mem:BLK (match_dup 4))
16578                       (mem:BLK (match_dup 5))))
16579      (use (match_dup 6))
16580      (use (match_dup 3))
16581      (clobber (match_dup 0))
16582      (clobber (match_dup 1))
16583      (clobber (match_dup 2))])])
16585 ;; ...and this one handles cmpstrn*_1.
16586 (define_peephole2
16587   [(parallel[
16588      (set (reg:CC FLAGS_REG)
16589           (if_then_else:CC (ne (match_operand 6 "register_operand")
16590                                (const_int 0))
16591             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16592                         (mem:BLK (match_operand 5 "register_operand")))
16593             (const_int 0)))
16594      (use (match_operand:SI 3 "immediate_operand"))
16595      (use (reg:CC FLAGS_REG))
16596      (clobber (match_operand 0 "register_operand"))
16597      (clobber (match_operand 1 "register_operand"))
16598      (clobber (match_operand 2 "register_operand"))])
16599    (set (match_operand:QI 7 "register_operand")
16600         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16601    (set (match_operand:QI 8 "register_operand")
16602         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16603    (set (reg FLAGS_REG)
16604         (compare (match_dup 7) (match_dup 8)))
16605   ]
16606   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16607   [(parallel[
16608      (set (reg:CC FLAGS_REG)
16609           (if_then_else:CC (ne (match_dup 6)
16610                                (const_int 0))
16611             (compare:CC (mem:BLK (match_dup 4))
16612                         (mem:BLK (match_dup 5)))
16613             (const_int 0)))
16614      (use (match_dup 3))
16615      (use (reg:CC FLAGS_REG))
16616      (clobber (match_dup 0))
16617      (clobber (match_dup 1))
16618      (clobber (match_dup 2))])])
16620 ;; Conditional move instructions.
16622 (define_expand "mov<mode>cc"
16623   [(set (match_operand:SWIM 0 "register_operand")
16624         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16625                            (match_operand:SWIM 2 "<general_operand>")
16626                            (match_operand:SWIM 3 "<general_operand>")))]
16627   ""
16628   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16630 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16631 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16632 ;; So just document what we're doing explicitly.
16634 (define_expand "x86_mov<mode>cc_0_m1"
16635   [(parallel
16636     [(set (match_operand:SWI48 0 "register_operand")
16637           (if_then_else:SWI48
16638             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16639              [(match_operand 1 "flags_reg_operand")
16640               (const_int 0)])
16641             (const_int -1)
16642             (const_int 0)))
16643      (clobber (reg:CC FLAGS_REG))])])
16645 (define_insn "*x86_mov<mode>cc_0_m1"
16646   [(set (match_operand:SWI48 0 "register_operand" "=r")
16647         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16648                              [(reg FLAGS_REG) (const_int 0)])
16649           (const_int -1)
16650           (const_int 0)))
16651    (clobber (reg:CC FLAGS_REG))]
16652   ""
16653   "sbb{<imodesuffix>}\t%0, %0"
16654   ; Since we don't have the proper number of operands for an alu insn,
16655   ; fill in all the blanks.
16656   [(set_attr "type" "alu")
16657    (set_attr "use_carry" "1")
16658    (set_attr "pent_pair" "pu")
16659    (set_attr "memory" "none")
16660    (set_attr "imm_disp" "false")
16661    (set_attr "mode" "<MODE>")
16662    (set_attr "length_immediate" "0")])
16664 (define_insn "*x86_mov<mode>cc_0_m1_se"
16665   [(set (match_operand:SWI48 0 "register_operand" "=r")
16666         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16667                              [(reg FLAGS_REG) (const_int 0)])
16668                             (const_int 1)
16669                             (const_int 0)))
16670    (clobber (reg:CC FLAGS_REG))]
16671   ""
16672   "sbb{<imodesuffix>}\t%0, %0"
16673   [(set_attr "type" "alu")
16674    (set_attr "use_carry" "1")
16675    (set_attr "pent_pair" "pu")
16676    (set_attr "memory" "none")
16677    (set_attr "imm_disp" "false")
16678    (set_attr "mode" "<MODE>")
16679    (set_attr "length_immediate" "0")])
16681 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16682   [(set (match_operand:SWI48 0 "register_operand" "=r")
16683         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16684                     [(reg FLAGS_REG) (const_int 0)])))
16685    (clobber (reg:CC FLAGS_REG))]
16686   ""
16687   "sbb{<imodesuffix>}\t%0, %0"
16688   [(set_attr "type" "alu")
16689    (set_attr "use_carry" "1")
16690    (set_attr "pent_pair" "pu")
16691    (set_attr "memory" "none")
16692    (set_attr "imm_disp" "false")
16693    (set_attr "mode" "<MODE>")
16694    (set_attr "length_immediate" "0")])
16696 (define_insn "*mov<mode>cc_noc"
16697   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16698         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16699                                [(reg FLAGS_REG) (const_int 0)])
16700           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16701           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16702   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16703   "@
16704    cmov%O2%C1\t{%2, %0|%0, %2}
16705    cmov%O2%c1\t{%3, %0|%0, %3}"
16706   [(set_attr "type" "icmov")
16707    (set_attr "mode" "<MODE>")])
16709 ;; Don't do conditional moves with memory inputs.  This splitter helps
16710 ;; register starved x86_32 by forcing inputs into registers before reload.
16711 (define_split
16712   [(set (match_operand:SWI248 0 "register_operand")
16713         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16714                                [(reg FLAGS_REG) (const_int 0)])
16715           (match_operand:SWI248 2 "nonimmediate_operand")
16716           (match_operand:SWI248 3 "nonimmediate_operand")))]
16717   "!TARGET_64BIT && TARGET_CMOVE
16718    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16719    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16720    && can_create_pseudo_p ()
16721    && optimize_insn_for_speed_p ()"
16722   [(set (match_dup 0)
16723         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16725   if (MEM_P (operands[2]))
16726     operands[2] = force_reg (<MODE>mode, operands[2]);
16727   if (MEM_P (operands[3]))
16728     operands[3] = force_reg (<MODE>mode, operands[3]);
16731 (define_insn "*movqicc_noc"
16732   [(set (match_operand:QI 0 "register_operand" "=r,r")
16733         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16734                            [(reg FLAGS_REG) (const_int 0)])
16735                       (match_operand:QI 2 "register_operand" "r,0")
16736                       (match_operand:QI 3 "register_operand" "0,r")))]
16737   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16738   "#"
16739   [(set_attr "type" "icmov")
16740    (set_attr "mode" "QI")])
16742 (define_split
16743   [(set (match_operand:SWI12 0 "register_operand")
16744         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16745                               [(reg FLAGS_REG) (const_int 0)])
16746                       (match_operand:SWI12 2 "register_operand")
16747                       (match_operand:SWI12 3 "register_operand")))]
16748   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16749    && reload_completed"
16750   [(set (match_dup 0)
16751         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16753   operands[0] = gen_lowpart (SImode, operands[0]);
16754   operands[2] = gen_lowpart (SImode, operands[2]);
16755   operands[3] = gen_lowpart (SImode, operands[3]);
16758 ;; Don't do conditional moves with memory inputs
16759 (define_peephole2
16760   [(match_scratch:SWI248 2 "r")
16761    (set (match_operand:SWI248 0 "register_operand")
16762         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16763                                [(reg FLAGS_REG) (const_int 0)])
16764           (match_dup 0)
16765           (match_operand:SWI248 3 "memory_operand")))]
16766   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16767    && optimize_insn_for_speed_p ()"
16768   [(set (match_dup 2) (match_dup 3))
16769    (set (match_dup 0)
16770         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16772 (define_peephole2
16773   [(match_scratch:SWI248 2 "r")
16774    (set (match_operand:SWI248 0 "register_operand")
16775         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16776                                [(reg FLAGS_REG) (const_int 0)])
16777           (match_operand:SWI248 3 "memory_operand")
16778           (match_dup 0)))]
16779   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16780    && optimize_insn_for_speed_p ()"
16781   [(set (match_dup 2) (match_dup 3))
16782    (set (match_dup 0)
16783         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16785 (define_expand "mov<mode>cc"
16786   [(set (match_operand:X87MODEF 0 "register_operand")
16787         (if_then_else:X87MODEF
16788           (match_operand 1 "comparison_operator")
16789           (match_operand:X87MODEF 2 "register_operand")
16790           (match_operand:X87MODEF 3 "register_operand")))]
16791   "(TARGET_80387 && TARGET_CMOVE)
16792    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16793   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16795 (define_insn "*movxfcc_1"
16796   [(set (match_operand:XF 0 "register_operand" "=f,f")
16797         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16798                                 [(reg FLAGS_REG) (const_int 0)])
16799                       (match_operand:XF 2 "register_operand" "f,0")
16800                       (match_operand:XF 3 "register_operand" "0,f")))]
16801   "TARGET_80387 && TARGET_CMOVE"
16802   "@
16803    fcmov%F1\t{%2, %0|%0, %2}
16804    fcmov%f1\t{%3, %0|%0, %3}"
16805   [(set_attr "type" "fcmov")
16806    (set_attr "mode" "XF")])
16808 (define_insn "*movdfcc_1"
16809   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16810         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16811                                 [(reg FLAGS_REG) (const_int 0)])
16812                       (match_operand:DF 2 "nonimmediate_operand"
16813                                                "f ,0,rm,0 ,rm,0")
16814                       (match_operand:DF 3 "nonimmediate_operand"
16815                                                "0 ,f,0 ,rm,0, rm")))]
16816   "TARGET_80387 && TARGET_CMOVE
16817    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16818   "@
16819    fcmov%F1\t{%2, %0|%0, %2}
16820    fcmov%f1\t{%3, %0|%0, %3}
16821    #
16822    #
16823    cmov%O2%C1\t{%2, %0|%0, %2}
16824    cmov%O2%c1\t{%3, %0|%0, %3}"
16825   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16826    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16827    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16829 (define_split
16830   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16831         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16832                                 [(reg FLAGS_REG) (const_int 0)])
16833                       (match_operand:DF 2 "nonimmediate_operand")
16834                       (match_operand:DF 3 "nonimmediate_operand")))]
16835   "!TARGET_64BIT && reload_completed"
16836   [(set (match_dup 2)
16837         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16838    (set (match_dup 3)
16839         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16841   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16842   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16845 (define_insn "*movsfcc_1_387"
16846   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16847         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16848                                 [(reg FLAGS_REG) (const_int 0)])
16849                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16850                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16851   "TARGET_80387 && TARGET_CMOVE
16852    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16853   "@
16854    fcmov%F1\t{%2, %0|%0, %2}
16855    fcmov%f1\t{%3, %0|%0, %3}
16856    cmov%O2%C1\t{%2, %0|%0, %2}
16857    cmov%O2%c1\t{%3, %0|%0, %3}"
16858   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16859    (set_attr "mode" "SF,SF,SI,SI")])
16861 ;; Don't do conditional moves with memory inputs.  This splitter helps
16862 ;; register starved x86_32 by forcing inputs into registers before reload.
16863 (define_split
16864   [(set (match_operand:MODEF 0 "register_operand")
16865         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16866                               [(reg FLAGS_REG) (const_int 0)])
16867           (match_operand:MODEF 2 "nonimmediate_operand")
16868           (match_operand:MODEF 3 "nonimmediate_operand")))]
16869   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16870    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16871    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16872    && can_create_pseudo_p ()
16873    && optimize_insn_for_speed_p ()"
16874   [(set (match_dup 0)
16875         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16877   if (MEM_P (operands[2]))
16878     operands[2] = force_reg (<MODE>mode, operands[2]);
16879   if (MEM_P (operands[3]))
16880     operands[3] = force_reg (<MODE>mode, operands[3]);
16883 ;; Don't do conditional moves with memory inputs
16884 (define_peephole2
16885   [(match_scratch:MODEF 2 "r")
16886    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16887         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16888                               [(reg FLAGS_REG) (const_int 0)])
16889           (match_dup 0)
16890           (match_operand:MODEF 3 "memory_operand")))]
16891   "(<MODE>mode != DFmode || TARGET_64BIT)
16892    && TARGET_80387 && TARGET_CMOVE
16893    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16894    && optimize_insn_for_speed_p ()"
16895   [(set (match_dup 2) (match_dup 3))
16896    (set (match_dup 0)
16897         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16899 (define_peephole2
16900   [(match_scratch:MODEF 2 "r")
16901    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16902         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16903                               [(reg FLAGS_REG) (const_int 0)])
16904           (match_operand:MODEF 3 "memory_operand")
16905           (match_dup 0)))]
16906   "(<MODE>mode != DFmode || TARGET_64BIT)
16907    && TARGET_80387 && TARGET_CMOVE
16908    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16909    && optimize_insn_for_speed_p ()"
16910   [(set (match_dup 2) (match_dup 3))
16911    (set (match_dup 0)
16912         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16914 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16915 ;; the scalar versions to have only XMM registers as operands.
16917 ;; XOP conditional move
16918 (define_insn "*xop_pcmov_<mode>"
16919   [(set (match_operand:MODEF 0 "register_operand" "=x")
16920         (if_then_else:MODEF
16921           (match_operand:MODEF 1 "register_operand" "x")
16922           (match_operand:MODEF 2 "register_operand" "x")
16923           (match_operand:MODEF 3 "register_operand" "x")))]
16924   "TARGET_XOP"
16925   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16926   [(set_attr "type" "sse4arg")])
16928 ;; These versions of the min/max patterns are intentionally ignorant of
16929 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16930 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16931 ;; are undefined in this condition, we're certain this is correct.
16933 (define_insn "<code><mode>3"
16934   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16935         (smaxmin:MODEF
16936           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16937           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16938   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16939   "@
16940    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16941    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16942   [(set_attr "isa" "noavx,avx")
16943    (set_attr "prefix" "orig,vex")
16944    (set_attr "type" "sseadd")
16945    (set_attr "mode" "<MODE>")])
16947 ;; These versions of the min/max patterns implement exactly the operations
16948 ;;   min = (op1 < op2 ? op1 : op2)
16949 ;;   max = (!(op1 < op2) ? op1 : op2)
16950 ;; Their operands are not commutative, and thus they may be used in the
16951 ;; presence of -0.0 and NaN.
16953 (define_int_iterator IEEE_MAXMIN
16954         [UNSPEC_IEEE_MAX
16955          UNSPEC_IEEE_MIN])
16957 (define_int_attr ieee_maxmin
16958         [(UNSPEC_IEEE_MAX "max")
16959          (UNSPEC_IEEE_MIN "min")])
16961 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16962   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16963         (unspec:MODEF
16964           [(match_operand:MODEF 1 "register_operand" "0,v")
16965            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16966           IEEE_MAXMIN))]
16967   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16968   "@
16969    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16970    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16971   [(set_attr "isa" "noavx,avx")
16972    (set_attr "prefix" "orig,maybe_evex")
16973    (set_attr "type" "sseadd")
16974    (set_attr "mode" "<MODE>")])
16976 ;; Make two stack loads independent:
16977 ;;   fld aa              fld aa
16978 ;;   fld %st(0)     ->   fld bb
16979 ;;   fmul bb             fmul %st(1), %st
16981 ;; Actually we only match the last two instructions for simplicity.
16982 (define_peephole2
16983   [(set (match_operand 0 "fp_register_operand")
16984         (match_operand 1 "fp_register_operand"))
16985    (set (match_dup 0)
16986         (match_operator 2 "binary_fp_operator"
16987            [(match_dup 0)
16988             (match_operand 3 "memory_operand")]))]
16989   "REGNO (operands[0]) != REGNO (operands[1])"
16990   [(set (match_dup 0) (match_dup 3))
16991    (set (match_dup 0) (match_dup 4))]
16993   ;; The % modifier is not operational anymore in peephole2's, so we have to
16994   ;; swap the operands manually in the case of addition and multiplication.
16996   rtx op0, op1;
16998   if (COMMUTATIVE_ARITH_P (operands[2]))
16999     op0 = operands[0], op1 = operands[1];
17000   else
17001     op0 = operands[1], op1 = operands[0];
17003   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17004                                 GET_MODE (operands[2]),
17005                                 op0, op1);
17008 ;; Conditional addition patterns
17009 (define_expand "add<mode>cc"
17010   [(match_operand:SWI 0 "register_operand")
17011    (match_operand 1 "ordered_comparison_operator")
17012    (match_operand:SWI 2 "register_operand")
17013    (match_operand:SWI 3 "const_int_operand")]
17014   ""
17015   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17017 ;; Misc patterns (?)
17019 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17020 ;; Otherwise there will be nothing to keep
17022 ;; [(set (reg ebp) (reg esp))]
17023 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17024 ;;  (clobber (eflags)]
17025 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17027 ;; in proper program order.
17029 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17030   [(set (match_operand:P 0 "register_operand" "=r,r")
17031         (plus:P (match_operand:P 1 "register_operand" "0,r")
17032                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17033    (clobber (reg:CC FLAGS_REG))
17034    (clobber (mem:BLK (scratch)))]
17035   ""
17037   switch (get_attr_type (insn))
17038     {
17039     case TYPE_IMOV:
17040       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17042     case TYPE_ALU:
17043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17044       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17045         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17047       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17049     default:
17050       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17051       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17052     }
17054   [(set (attr "type")
17055         (cond [(and (eq_attr "alternative" "0")
17056                     (not (match_test "TARGET_OPT_AGU")))
17057                  (const_string "alu")
17058                (match_operand:<MODE> 2 "const0_operand")
17059                  (const_string "imov")
17060               ]
17061               (const_string "lea")))
17062    (set (attr "length_immediate")
17063         (cond [(eq_attr "type" "imov")
17064                  (const_string "0")
17065                (and (eq_attr "type" "alu")
17066                     (match_operand 2 "const128_operand"))
17067                  (const_string "1")
17068               ]
17069               (const_string "*")))
17070    (set_attr "mode" "<MODE>")])
17072 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17073   [(set (match_operand:P 0 "register_operand" "=r")
17074         (minus:P (match_operand:P 1 "register_operand" "0")
17075                  (match_operand:P 2 "register_operand" "r")))
17076    (clobber (reg:CC FLAGS_REG))
17077    (clobber (mem:BLK (scratch)))]
17078   ""
17079   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17080   [(set_attr "type" "alu")
17081    (set_attr "mode" "<MODE>")])
17083 (define_insn "allocate_stack_worker_probe_<mode>"
17084   [(set (match_operand:P 0 "register_operand" "=a")
17085         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17086                             UNSPECV_STACK_PROBE))
17087    (clobber (reg:CC FLAGS_REG))]
17088   "ix86_target_stack_probe ()"
17089   "call\t___chkstk_ms"
17090   [(set_attr "type" "multi")
17091    (set_attr "length" "5")])
17093 (define_expand "allocate_stack"
17094   [(match_operand 0 "register_operand")
17095    (match_operand 1 "general_operand")]
17096   "ix86_target_stack_probe ()"
17098   rtx x;
17100 #ifndef CHECK_STACK_LIMIT
17101 #define CHECK_STACK_LIMIT 0
17102 #endif
17104   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17105       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17106     x = operands[1];
17107   else
17108     {
17109       rtx (*insn) (rtx, rtx);
17111       x = copy_to_mode_reg (Pmode, operands[1]);
17113       insn = (TARGET_64BIT
17114               ? gen_allocate_stack_worker_probe_di
17115               : gen_allocate_stack_worker_probe_si);
17117       emit_insn (insn (x, x));
17118     }
17120   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17121                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17123   if (x != stack_pointer_rtx)
17124     emit_move_insn (stack_pointer_rtx, x);
17126   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17127   DONE;
17130 ;; Use IOR for stack probes, this is shorter.
17131 (define_expand "probe_stack"
17132   [(match_operand 0 "memory_operand")]
17133   ""
17135   rtx (*gen_ior3) (rtx, rtx, rtx);
17137   gen_ior3 = (GET_MODE (operands[0]) == DImode
17138               ? gen_iordi3 : gen_iorsi3);
17140   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17141   DONE;
17144 (define_insn "adjust_stack_and_probe<mode>"
17145   [(set (match_operand:P 0 "register_operand" "=r")
17146         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17147                             UNSPECV_PROBE_STACK_RANGE))
17148    (set (reg:P SP_REG)
17149         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17150    (clobber (reg:CC FLAGS_REG))
17151    (clobber (mem:BLK (scratch)))]
17152   ""
17153   "* return output_adjust_stack_and_probe (operands[0]);"
17154   [(set_attr "type" "multi")])
17156 (define_insn "probe_stack_range<mode>"
17157   [(set (match_operand:P 0 "register_operand" "=r")
17158         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17159                             (match_operand:P 2 "const_int_operand" "n")]
17160                             UNSPECV_PROBE_STACK_RANGE))
17161    (clobber (reg:CC FLAGS_REG))]
17162   ""
17163   "* return output_probe_stack_range (operands[0], operands[2]);"
17164   [(set_attr "type" "multi")])
17166 (define_expand "builtin_setjmp_receiver"
17167   [(label_ref (match_operand 0))]
17168   "!TARGET_64BIT && flag_pic"
17170 #if TARGET_MACHO
17171   if (TARGET_MACHO)
17172     {
17173       rtx xops[3];
17174       rtx_code_label *label_rtx = gen_label_rtx ();
17175       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17176       xops[0] = xops[1] = pic_offset_table_rtx;
17177       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17178       ix86_expand_binary_operator (MINUS, SImode, xops);
17179     }
17180   else
17181 #endif
17182     emit_insn (gen_set_got (pic_offset_table_rtx));
17183   DONE;
17186 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17187 ;; Do not split instructions with mask registers.
17188 (define_split
17189   [(set (match_operand 0 "general_reg_operand")
17190         (match_operator 3 "promotable_binary_operator"
17191            [(match_operand 1 "general_reg_operand")
17192             (match_operand 2 "aligned_operand")]))
17193    (clobber (reg:CC FLAGS_REG))]
17194   "! TARGET_PARTIAL_REG_STALL && reload_completed
17195    && ((GET_MODE (operands[0]) == HImode
17196         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17197             /* ??? next two lines just !satisfies_constraint_K (...) */
17198             || !CONST_INT_P (operands[2])
17199             || satisfies_constraint_K (operands[2])))
17200        || (GET_MODE (operands[0]) == QImode
17201            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17202   [(parallel [(set (match_dup 0)
17203                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17204               (clobber (reg:CC FLAGS_REG))])]
17206   operands[0] = gen_lowpart (SImode, operands[0]);
17207   operands[1] = gen_lowpart (SImode, operands[1]);
17208   if (GET_CODE (operands[3]) != ASHIFT)
17209     operands[2] = gen_lowpart (SImode, operands[2]);
17210   PUT_MODE (operands[3], SImode);
17213 ; Promote the QImode tests, as i386 has encoding of the AND
17214 ; instruction with 32-bit sign-extended immediate and thus the
17215 ; instruction size is unchanged, except in the %eax case for
17216 ; which it is increased by one byte, hence the ! optimize_size.
17217 (define_split
17218   [(set (match_operand 0 "flags_reg_operand")
17219         (match_operator 2 "compare_operator"
17220           [(and (match_operand 3 "aligned_operand")
17221                 (match_operand 4 "const_int_operand"))
17222            (const_int 0)]))
17223    (set (match_operand 1 "register_operand")
17224         (and (match_dup 3) (match_dup 4)))]
17225   "! TARGET_PARTIAL_REG_STALL && reload_completed
17226    && optimize_insn_for_speed_p ()
17227    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17228        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17229    /* Ensure that the operand will remain sign-extended immediate.  */
17230    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17231   [(parallel [(set (match_dup 0)
17232                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17233                                     (const_int 0)]))
17234               (set (match_dup 1)
17235                    (and:SI (match_dup 3) (match_dup 4)))])]
17237   operands[4]
17238     = gen_int_mode (INTVAL (operands[4])
17239                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17240   operands[1] = gen_lowpart (SImode, operands[1]);
17241   operands[3] = gen_lowpart (SImode, operands[3]);
17244 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17245 ; the TEST instruction with 32-bit sign-extended immediate and thus
17246 ; the instruction size would at least double, which is not what we
17247 ; want even with ! optimize_size.
17248 (define_split
17249   [(set (match_operand 0 "flags_reg_operand")
17250         (match_operator 1 "compare_operator"
17251           [(and (match_operand:HI 2 "aligned_operand")
17252                 (match_operand:HI 3 "const_int_operand"))
17253            (const_int 0)]))]
17254   "! TARGET_PARTIAL_REG_STALL && reload_completed
17255    && ! TARGET_FAST_PREFIX
17256    && optimize_insn_for_speed_p ()
17257    /* Ensure that the operand will remain sign-extended immediate.  */
17258    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17259   [(set (match_dup 0)
17260         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17261                          (const_int 0)]))]
17263   operands[3]
17264     = gen_int_mode (INTVAL (operands[3])
17265                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17266   operands[2] = gen_lowpart (SImode, operands[2]);
17269 (define_split
17270   [(set (match_operand 0 "register_operand")
17271         (neg (match_operand 1 "register_operand")))
17272    (clobber (reg:CC FLAGS_REG))]
17273   "! TARGET_PARTIAL_REG_STALL && reload_completed
17274    && (GET_MODE (operands[0]) == HImode
17275        || (GET_MODE (operands[0]) == QImode
17276            && (TARGET_PROMOTE_QImode
17277                || optimize_insn_for_size_p ())))"
17278   [(parallel [(set (match_dup 0)
17279                    (neg:SI (match_dup 1)))
17280               (clobber (reg:CC FLAGS_REG))])]
17282   operands[0] = gen_lowpart (SImode, operands[0]);
17283   operands[1] = gen_lowpart (SImode, operands[1]);
17286 ;; Do not split instructions with mask regs.
17287 (define_split
17288   [(set (match_operand 0 "general_reg_operand")
17289         (not (match_operand 1 "general_reg_operand")))]
17290   "! TARGET_PARTIAL_REG_STALL && reload_completed
17291    && (GET_MODE (operands[0]) == HImode
17292        || (GET_MODE (operands[0]) == QImode
17293            && (TARGET_PROMOTE_QImode
17294                || optimize_insn_for_size_p ())))"
17295   [(set (match_dup 0)
17296         (not:SI (match_dup 1)))]
17298   operands[0] = gen_lowpart (SImode, operands[0]);
17299   operands[1] = gen_lowpart (SImode, operands[1]);
17302 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17303 ;; transform a complex memory operation into two memory to register operations.
17305 ;; Don't push memory operands
17306 (define_peephole2
17307   [(set (match_operand:SWI 0 "push_operand")
17308         (match_operand:SWI 1 "memory_operand"))
17309    (match_scratch:SWI 2 "<r>")]
17310   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17311    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17312   [(set (match_dup 2) (match_dup 1))
17313    (set (match_dup 0) (match_dup 2))])
17315 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17316 ;; SImode pushes.
17317 (define_peephole2
17318   [(set (match_operand:SF 0 "push_operand")
17319         (match_operand:SF 1 "memory_operand"))
17320    (match_scratch:SF 2 "r")]
17321   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17322    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17323   [(set (match_dup 2) (match_dup 1))
17324    (set (match_dup 0) (match_dup 2))])
17326 ;; Don't move an immediate directly to memory when the instruction
17327 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17328 (define_peephole2
17329   [(match_scratch:SWI124 1 "<r>")
17330    (set (match_operand:SWI124 0 "memory_operand")
17331         (const_int 0))]
17332   "optimize_insn_for_speed_p ()
17333    && ((<MODE>mode == HImode
17334        && TARGET_LCP_STALL)
17335        || (!TARGET_USE_MOV0
17336           && TARGET_SPLIT_LONG_MOVES
17337           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17338    && peep2_regno_dead_p (0, FLAGS_REG)"
17339   [(parallel [(set (match_dup 2) (const_int 0))
17340               (clobber (reg:CC FLAGS_REG))])
17341    (set (match_dup 0) (match_dup 1))]
17342   "operands[2] = gen_lowpart (SImode, operands[1]);")
17344 (define_peephole2
17345   [(match_scratch:SWI124 2 "<r>")
17346    (set (match_operand:SWI124 0 "memory_operand")
17347         (match_operand:SWI124 1 "immediate_operand"))]
17348   "optimize_insn_for_speed_p ()
17349    && ((<MODE>mode == HImode
17350        && TARGET_LCP_STALL)
17351        || (TARGET_SPLIT_LONG_MOVES
17352           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17353   [(set (match_dup 2) (match_dup 1))
17354    (set (match_dup 0) (match_dup 2))])
17356 ;; Don't compare memory with zero, load and use a test instead.
17357 (define_peephole2
17358   [(set (match_operand 0 "flags_reg_operand")
17359         (match_operator 1 "compare_operator"
17360           [(match_operand:SI 2 "memory_operand")
17361            (const_int 0)]))
17362    (match_scratch:SI 3 "r")]
17363   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17364   [(set (match_dup 3) (match_dup 2))
17365    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17367 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17368 ;; Don't split NOTs with a displacement operand, because resulting XOR
17369 ;; will not be pairable anyway.
17371 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17372 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17373 ;; so this split helps here as well.
17375 ;; Note: Can't do this as a regular split because we can't get proper
17376 ;; lifetime information then.
17378 (define_peephole2
17379   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17380         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17381   "optimize_insn_for_speed_p ()
17382    && ((TARGET_NOT_UNPAIRABLE
17383         && (!MEM_P (operands[0])
17384             || !memory_displacement_operand (operands[0], <MODE>mode)))
17385        || (TARGET_NOT_VECTORMODE
17386            && long_memory_operand (operands[0], <MODE>mode)))
17387    && peep2_regno_dead_p (0, FLAGS_REG)"
17388   [(parallel [(set (match_dup 0)
17389                    (xor:SWI124 (match_dup 1) (const_int -1)))
17390               (clobber (reg:CC FLAGS_REG))])])
17392 ;; Non pairable "test imm, reg" instructions can be translated to
17393 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17394 ;; byte opcode instead of two, have a short form for byte operands),
17395 ;; so do it for other CPUs as well.  Given that the value was dead,
17396 ;; this should not create any new dependencies.  Pass on the sub-word
17397 ;; versions if we're concerned about partial register stalls.
17399 (define_peephole2
17400   [(set (match_operand 0 "flags_reg_operand")
17401         (match_operator 1 "compare_operator"
17402           [(and:SI (match_operand:SI 2 "register_operand")
17403                    (match_operand:SI 3 "immediate_operand"))
17404            (const_int 0)]))]
17405   "ix86_match_ccmode (insn, CCNOmode)
17406    && (true_regnum (operands[2]) != AX_REG
17407        || satisfies_constraint_K (operands[3]))
17408    && peep2_reg_dead_p (1, operands[2])"
17409   [(parallel
17410      [(set (match_dup 0)
17411            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17412                             (const_int 0)]))
17413       (set (match_dup 2)
17414            (and:SI (match_dup 2) (match_dup 3)))])])
17416 ;; We don't need to handle HImode case, because it will be promoted to SImode
17417 ;; on ! TARGET_PARTIAL_REG_STALL
17419 (define_peephole2
17420   [(set (match_operand 0 "flags_reg_operand")
17421         (match_operator 1 "compare_operator"
17422           [(and:QI (match_operand:QI 2 "register_operand")
17423                    (match_operand:QI 3 "immediate_operand"))
17424            (const_int 0)]))]
17425   "! TARGET_PARTIAL_REG_STALL
17426    && ix86_match_ccmode (insn, CCNOmode)
17427    && true_regnum (operands[2]) != AX_REG
17428    && peep2_reg_dead_p (1, operands[2])"
17429   [(parallel
17430      [(set (match_dup 0)
17431            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17432                             (const_int 0)]))
17433       (set (match_dup 2)
17434            (and:QI (match_dup 2) (match_dup 3)))])])
17436 (define_peephole2
17437   [(set (match_operand 0 "flags_reg_operand")
17438         (match_operator 1 "compare_operator"
17439           [(and:SI
17440              (zero_extract:SI
17441                (match_operand 2 "QIreg_operand")
17442                (const_int 8)
17443                (const_int 8))
17444              (match_operand 3 "const_int_operand"))
17445            (const_int 0)]))]
17446   "! TARGET_PARTIAL_REG_STALL
17447    && ix86_match_ccmode (insn, CCNOmode)
17448    && true_regnum (operands[2]) != AX_REG
17449    && peep2_reg_dead_p (1, operands[2])"
17450   [(parallel [(set (match_dup 0)
17451                    (match_op_dup 1
17452                      [(and:SI
17453                         (zero_extract:SI
17454                           (match_dup 2)
17455                           (const_int 8)
17456                           (const_int 8))
17457                         (match_dup 3))
17458                       (const_int 0)]))
17459               (set (zero_extract:SI (match_dup 2)
17460                                     (const_int 8)
17461                                     (const_int 8))
17462                    (and:SI
17463                      (zero_extract:SI
17464                        (match_dup 2)
17465                        (const_int 8)
17466                        (const_int 8))
17467                      (match_dup 3)))])])
17469 ;; Don't do logical operations with memory inputs.
17470 (define_peephole2
17471   [(match_scratch:SI 2 "r")
17472    (parallel [(set (match_operand:SI 0 "register_operand")
17473                    (match_operator:SI 3 "arith_or_logical_operator"
17474                      [(match_dup 0)
17475                       (match_operand:SI 1 "memory_operand")]))
17476               (clobber (reg:CC FLAGS_REG))])]
17477   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17478   [(set (match_dup 2) (match_dup 1))
17479    (parallel [(set (match_dup 0)
17480                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17481               (clobber (reg:CC FLAGS_REG))])])
17483 (define_peephole2
17484   [(match_scratch:SI 2 "r")
17485    (parallel [(set (match_operand:SI 0 "register_operand")
17486                    (match_operator:SI 3 "arith_or_logical_operator"
17487                      [(match_operand:SI 1 "memory_operand")
17488                       (match_dup 0)]))
17489               (clobber (reg:CC FLAGS_REG))])]
17490   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17491   [(set (match_dup 2) (match_dup 1))
17492    (parallel [(set (match_dup 0)
17493                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17494               (clobber (reg:CC FLAGS_REG))])])
17496 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17497 ;; refers to the destination of the load!
17499 (define_peephole2
17500   [(set (match_operand:SI 0 "register_operand")
17501         (match_operand:SI 1 "register_operand"))
17502    (parallel [(set (match_dup 0)
17503                    (match_operator:SI 3 "commutative_operator"
17504                      [(match_dup 0)
17505                       (match_operand:SI 2 "memory_operand")]))
17506               (clobber (reg:CC FLAGS_REG))])]
17507   "REGNO (operands[0]) != REGNO (operands[1])
17508    && GENERAL_REGNO_P (REGNO (operands[0]))
17509    && GENERAL_REGNO_P (REGNO (operands[1]))"
17510   [(set (match_dup 0) (match_dup 4))
17511    (parallel [(set (match_dup 0)
17512                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17513               (clobber (reg:CC FLAGS_REG))])]
17514   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17516 (define_peephole2
17517   [(set (match_operand 0 "register_operand")
17518         (match_operand 1 "register_operand"))
17519    (set (match_dup 0)
17520                    (match_operator 3 "commutative_operator"
17521                      [(match_dup 0)
17522                       (match_operand 2 "memory_operand")]))]
17523   "REGNO (operands[0]) != REGNO (operands[1])
17524    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17525        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17526   [(set (match_dup 0) (match_dup 2))
17527    (set (match_dup 0)
17528         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17530 ; Don't do logical operations with memory outputs
17532 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17533 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17534 ; the same decoder scheduling characteristics as the original.
17536 (define_peephole2
17537   [(match_scratch:SI 2 "r")
17538    (parallel [(set (match_operand:SI 0 "memory_operand")
17539                    (match_operator:SI 3 "arith_or_logical_operator"
17540                      [(match_dup 0)
17541                       (match_operand:SI 1 "nonmemory_operand")]))
17542               (clobber (reg:CC FLAGS_REG))])]
17543   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17544    /* Do not split stack checking probes.  */
17545    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17546   [(set (match_dup 2) (match_dup 0))
17547    (parallel [(set (match_dup 2)
17548                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17549               (clobber (reg:CC FLAGS_REG))])
17550    (set (match_dup 0) (match_dup 2))])
17552 (define_peephole2
17553   [(match_scratch:SI 2 "r")
17554    (parallel [(set (match_operand:SI 0 "memory_operand")
17555                    (match_operator:SI 3 "arith_or_logical_operator"
17556                      [(match_operand:SI 1 "nonmemory_operand")
17557                       (match_dup 0)]))
17558               (clobber (reg:CC FLAGS_REG))])]
17559   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17560    /* Do not split stack checking probes.  */
17561    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17562   [(set (match_dup 2) (match_dup 0))
17563    (parallel [(set (match_dup 2)
17564                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17565               (clobber (reg:CC FLAGS_REG))])
17566    (set (match_dup 0) (match_dup 2))])
17568 ;; Attempt to use arith or logical operations with memory outputs with
17569 ;; setting of flags.
17570 (define_peephole2
17571   [(set (match_operand:SWI 0 "register_operand")
17572         (match_operand:SWI 1 "memory_operand"))
17573    (parallel [(set (match_dup 0)
17574                    (match_operator:SWI 3 "plusminuslogic_operator"
17575                      [(match_dup 0)
17576                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17577               (clobber (reg:CC FLAGS_REG))])
17578    (set (match_dup 1) (match_dup 0))
17579    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17580   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17581    && peep2_reg_dead_p (4, operands[0])
17582    && !reg_overlap_mentioned_p (operands[0], operands[1])
17583    && !reg_overlap_mentioned_p (operands[0], operands[2])
17584    && (<MODE>mode != QImode
17585        || immediate_operand (operands[2], QImode)
17586        || any_QIreg_operand (operands[2], QImode))
17587    && ix86_match_ccmode (peep2_next_insn (3),
17588                          (GET_CODE (operands[3]) == PLUS
17589                           || GET_CODE (operands[3]) == MINUS)
17590                          ? CCGOCmode : CCNOmode)"
17591   [(parallel [(set (match_dup 4) (match_dup 5))
17592               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17593                                                   (match_dup 2)]))])]
17595   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17596   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17597                                 copy_rtx (operands[1]),
17598                                 copy_rtx (operands[2]));
17599   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17600                                  operands[5], const0_rtx);
17603 (define_peephole2
17604   [(parallel [(set (match_operand:SWI 0 "register_operand")
17605                    (match_operator:SWI 2 "plusminuslogic_operator"
17606                      [(match_dup 0)
17607                       (match_operand:SWI 1 "memory_operand")]))
17608               (clobber (reg:CC FLAGS_REG))])
17609    (set (match_dup 1) (match_dup 0))
17610    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17611   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17612    && GET_CODE (operands[2]) != MINUS
17613    && peep2_reg_dead_p (3, operands[0])
17614    && !reg_overlap_mentioned_p (operands[0], operands[1])
17615    && ix86_match_ccmode (peep2_next_insn (2),
17616                          GET_CODE (operands[2]) == PLUS
17617                          ? CCGOCmode : CCNOmode)"
17618   [(parallel [(set (match_dup 3) (match_dup 4))
17619               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17620                                                   (match_dup 0)]))])]
17622   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17623   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17624                                 copy_rtx (operands[1]),
17625                                 copy_rtx (operands[0]));
17626   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17627                                  operands[4], const0_rtx);
17630 (define_peephole2
17631   [(set (match_operand:SWI12 0 "register_operand")
17632         (match_operand:SWI12 1 "memory_operand"))
17633    (parallel [(set (match_operand:SI 4 "register_operand")
17634                    (match_operator:SI 3 "plusminuslogic_operator"
17635                      [(match_dup 4)
17636                       (match_operand:SI 2 "nonmemory_operand")]))
17637               (clobber (reg:CC FLAGS_REG))])
17638    (set (match_dup 1) (match_dup 0))
17639    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17640   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17641    && REG_P (operands[0]) && REG_P (operands[4])
17642    && REGNO (operands[0]) == REGNO (operands[4])
17643    && peep2_reg_dead_p (4, operands[0])
17644    && (<MODE>mode != QImode
17645        || immediate_operand (operands[2], SImode)
17646        || any_QIreg_operand (operands[2], SImode))
17647    && !reg_overlap_mentioned_p (operands[0], operands[1])
17648    && !reg_overlap_mentioned_p (operands[0], operands[2])
17649    && ix86_match_ccmode (peep2_next_insn (3),
17650                          (GET_CODE (operands[3]) == PLUS
17651                           || GET_CODE (operands[3]) == MINUS)
17652                          ? CCGOCmode : CCNOmode)"
17653   [(parallel [(set (match_dup 4) (match_dup 5))
17654               (set (match_dup 1) (match_dup 6))])]
17656   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17657   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17658   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17659                                 copy_rtx (operands[1]), operands[2]);
17660   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17661                                  operands[5], const0_rtx);
17662   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17663                                 copy_rtx (operands[1]),
17664                                 copy_rtx (operands[2]));
17667 ;; Attempt to always use XOR for zeroing registers.
17668 (define_peephole2
17669   [(set (match_operand 0 "register_operand")
17670         (match_operand 1 "const0_operand"))]
17671   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17672    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17673    && GENERAL_REG_P (operands[0])
17674    && peep2_regno_dead_p (0, FLAGS_REG)"
17675   [(parallel [(set (match_dup 0) (const_int 0))
17676               (clobber (reg:CC FLAGS_REG))])]
17677   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17679 (define_peephole2
17680   [(set (strict_low_part (match_operand 0 "register_operand"))
17681         (const_int 0))]
17682   "(GET_MODE (operands[0]) == QImode
17683     || GET_MODE (operands[0]) == HImode)
17684    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17685    && peep2_regno_dead_p (0, FLAGS_REG)"
17686   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17687               (clobber (reg:CC FLAGS_REG))])])
17689 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17690 (define_peephole2
17691   [(set (match_operand:SWI248 0 "register_operand")
17692         (const_int -1))]
17693   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17694    && peep2_regno_dead_p (0, FLAGS_REG)"
17695   [(parallel [(set (match_dup 0) (const_int -1))
17696               (clobber (reg:CC FLAGS_REG))])]
17698   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17699     operands[0] = gen_lowpart (SImode, operands[0]);
17702 ;; Attempt to convert simple lea to add/shift.
17703 ;; These can be created by move expanders.
17704 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17705 ;; relevant lea instructions were already split.
17707 (define_peephole2
17708   [(set (match_operand:SWI48 0 "register_operand")
17709         (plus:SWI48 (match_dup 0)
17710                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17711   "!TARGET_OPT_AGU
17712    && peep2_regno_dead_p (0, FLAGS_REG)"
17713   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17714               (clobber (reg:CC FLAGS_REG))])])
17716 (define_peephole2
17717   [(set (match_operand:SWI48 0 "register_operand")
17718         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17719                     (match_dup 0)))]
17720   "!TARGET_OPT_AGU
17721    && peep2_regno_dead_p (0, FLAGS_REG)"
17722   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17723               (clobber (reg:CC FLAGS_REG))])])
17725 (define_peephole2
17726   [(set (match_operand:DI 0 "register_operand")
17727         (zero_extend:DI
17728           (plus:SI (match_operand:SI 1 "register_operand")
17729                    (match_operand:SI 2 "nonmemory_operand"))))]
17730   "TARGET_64BIT && !TARGET_OPT_AGU
17731    && REGNO (operands[0]) == REGNO (operands[1])
17732    && peep2_regno_dead_p (0, FLAGS_REG)"
17733   [(parallel [(set (match_dup 0)
17734                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17735               (clobber (reg:CC FLAGS_REG))])])
17737 (define_peephole2
17738   [(set (match_operand:DI 0 "register_operand")
17739         (zero_extend:DI
17740           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17741                    (match_operand:SI 2 "register_operand"))))]
17742   "TARGET_64BIT && !TARGET_OPT_AGU
17743    && REGNO (operands[0]) == REGNO (operands[2])
17744    && peep2_regno_dead_p (0, FLAGS_REG)"
17745   [(parallel [(set (match_dup 0)
17746                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17747               (clobber (reg:CC FLAGS_REG))])])
17749 (define_peephole2
17750   [(set (match_operand:SWI48 0 "register_operand")
17751         (mult:SWI48 (match_dup 0)
17752                     (match_operand:SWI48 1 "const_int_operand")))]
17753   "exact_log2 (INTVAL (operands[1])) >= 0
17754    && peep2_regno_dead_p (0, FLAGS_REG)"
17755   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17756               (clobber (reg:CC FLAGS_REG))])]
17757   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17759 (define_peephole2
17760   [(set (match_operand:DI 0 "register_operand")
17761         (zero_extend:DI
17762           (mult:SI (match_operand:SI 1 "register_operand")
17763                    (match_operand:SI 2 "const_int_operand"))))]
17764   "TARGET_64BIT
17765    && exact_log2 (INTVAL (operands[2])) >= 0
17766    && REGNO (operands[0]) == REGNO (operands[1])
17767    && peep2_regno_dead_p (0, FLAGS_REG)"
17768   [(parallel [(set (match_dup 0)
17769                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17770               (clobber (reg:CC FLAGS_REG))])]
17771   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17773 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17774 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17775 ;; On many CPUs it is also faster, since special hardware to avoid esp
17776 ;; dependencies is present.
17778 ;; While some of these conversions may be done using splitters, we use
17779 ;; peepholes in order to allow combine_stack_adjustments pass to see
17780 ;; nonobfuscated RTL.
17782 ;; Convert prologue esp subtractions to push.
17783 ;; We need register to push.  In order to keep verify_flow_info happy we have
17784 ;; two choices
17785 ;; - use scratch and clobber it in order to avoid dependencies
17786 ;; - use already live register
17787 ;; We can't use the second way right now, since there is no reliable way how to
17788 ;; verify that given register is live.  First choice will also most likely in
17789 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17790 ;; call clobbered registers are dead.  We may want to use base pointer as an
17791 ;; alternative when no register is available later.
17793 (define_peephole2
17794   [(match_scratch:W 1 "r")
17795    (parallel [(set (reg:P SP_REG)
17796                    (plus:P (reg:P SP_REG)
17797                            (match_operand:P 0 "const_int_operand")))
17798               (clobber (reg:CC FLAGS_REG))
17799               (clobber (mem:BLK (scratch)))])]
17800   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17801    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17802   [(clobber (match_dup 1))
17803    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17804               (clobber (mem:BLK (scratch)))])])
17806 (define_peephole2
17807   [(match_scratch:W 1 "r")
17808    (parallel [(set (reg:P SP_REG)
17809                    (plus:P (reg:P SP_REG)
17810                            (match_operand:P 0 "const_int_operand")))
17811               (clobber (reg:CC FLAGS_REG))
17812               (clobber (mem:BLK (scratch)))])]
17813   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17814    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17815   [(clobber (match_dup 1))
17816    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17817    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17818               (clobber (mem:BLK (scratch)))])])
17820 ;; Convert esp subtractions to push.
17821 (define_peephole2
17822   [(match_scratch:W 1 "r")
17823    (parallel [(set (reg:P SP_REG)
17824                    (plus:P (reg:P SP_REG)
17825                            (match_operand:P 0 "const_int_operand")))
17826               (clobber (reg:CC FLAGS_REG))])]
17827   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17828    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17829   [(clobber (match_dup 1))
17830    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17832 (define_peephole2
17833   [(match_scratch:W 1 "r")
17834    (parallel [(set (reg:P SP_REG)
17835                    (plus:P (reg:P SP_REG)
17836                            (match_operand:P 0 "const_int_operand")))
17837               (clobber (reg:CC FLAGS_REG))])]
17838   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17839    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17840   [(clobber (match_dup 1))
17841    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17842    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17844 ;; Convert epilogue deallocator to pop.
17845 (define_peephole2
17846   [(match_scratch:W 1 "r")
17847    (parallel [(set (reg:P SP_REG)
17848                    (plus:P (reg:P SP_REG)
17849                            (match_operand:P 0 "const_int_operand")))
17850               (clobber (reg:CC FLAGS_REG))
17851               (clobber (mem:BLK (scratch)))])]
17852   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17853    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17854   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17855               (clobber (mem:BLK (scratch)))])])
17857 ;; Two pops case is tricky, since pop causes dependency
17858 ;; on destination register.  We use two registers if available.
17859 (define_peephole2
17860   [(match_scratch:W 1 "r")
17861    (match_scratch:W 2 "r")
17862    (parallel [(set (reg:P SP_REG)
17863                    (plus:P (reg:P SP_REG)
17864                            (match_operand:P 0 "const_int_operand")))
17865               (clobber (reg:CC FLAGS_REG))
17866               (clobber (mem:BLK (scratch)))])]
17867   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17868    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17869   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17870               (clobber (mem:BLK (scratch)))])
17871    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17873 (define_peephole2
17874   [(match_scratch:W 1 "r")
17875    (parallel [(set (reg:P SP_REG)
17876                    (plus:P (reg:P SP_REG)
17877                            (match_operand:P 0 "const_int_operand")))
17878               (clobber (reg:CC FLAGS_REG))
17879               (clobber (mem:BLK (scratch)))])]
17880   "optimize_insn_for_size_p ()
17881    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17882   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17883               (clobber (mem:BLK (scratch)))])
17884    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17886 ;; Convert esp additions to pop.
17887 (define_peephole2
17888   [(match_scratch:W 1 "r")
17889    (parallel [(set (reg:P SP_REG)
17890                    (plus:P (reg:P SP_REG)
17891                            (match_operand:P 0 "const_int_operand")))
17892               (clobber (reg:CC FLAGS_REG))])]
17893   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17894   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17896 ;; Two pops case is tricky, since pop causes dependency
17897 ;; on destination register.  We use two registers if available.
17898 (define_peephole2
17899   [(match_scratch:W 1 "r")
17900    (match_scratch:W 2 "r")
17901    (parallel [(set (reg:P SP_REG)
17902                    (plus:P (reg:P SP_REG)
17903                            (match_operand:P 0 "const_int_operand")))
17904               (clobber (reg:CC FLAGS_REG))])]
17905   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17906   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17907    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17909 (define_peephole2
17910   [(match_scratch:W 1 "r")
17911    (parallel [(set (reg:P SP_REG)
17912                    (plus:P (reg:P SP_REG)
17913                            (match_operand:P 0 "const_int_operand")))
17914               (clobber (reg:CC FLAGS_REG))])]
17915   "optimize_insn_for_size_p ()
17916    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17917   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17918    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17920 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17921 ;; required and register dies.  Similarly for 128 to -128.
17922 (define_peephole2
17923   [(set (match_operand 0 "flags_reg_operand")
17924         (match_operator 1 "compare_operator"
17925           [(match_operand 2 "register_operand")
17926            (match_operand 3 "const_int_operand")]))]
17927   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17928      && incdec_operand (operands[3], GET_MODE (operands[3])))
17929     || (!TARGET_FUSE_CMP_AND_BRANCH
17930         && INTVAL (operands[3]) == 128))
17931    && ix86_match_ccmode (insn, CCGCmode)
17932    && peep2_reg_dead_p (1, operands[2])"
17933   [(parallel [(set (match_dup 0)
17934                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17935               (clobber (match_dup 2))])])
17937 ;; Convert imul by three, five and nine into lea
17938 (define_peephole2
17939   [(parallel
17940     [(set (match_operand:SWI48 0 "register_operand")
17941           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17942                       (match_operand:SWI48 2 "const359_operand")))
17943      (clobber (reg:CC FLAGS_REG))])]
17944   "!TARGET_PARTIAL_REG_STALL
17945    || <MODE>mode == SImode
17946    || optimize_function_for_size_p (cfun)"
17947   [(set (match_dup 0)
17948         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17949                     (match_dup 1)))]
17950   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17952 (define_peephole2
17953   [(parallel
17954     [(set (match_operand:SWI48 0 "register_operand")
17955           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17956                       (match_operand:SWI48 2 "const359_operand")))
17957      (clobber (reg:CC FLAGS_REG))])]
17958   "optimize_insn_for_speed_p ()
17959    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17960   [(set (match_dup 0) (match_dup 1))
17961    (set (match_dup 0)
17962         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17963                     (match_dup 0)))]
17964   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17966 ;; imul $32bit_imm, mem, reg is vector decoded, while
17967 ;; imul $32bit_imm, reg, reg is direct decoded.
17968 (define_peephole2
17969   [(match_scratch:SWI48 3 "r")
17970    (parallel [(set (match_operand:SWI48 0 "register_operand")
17971                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17972                                (match_operand:SWI48 2 "immediate_operand")))
17973               (clobber (reg:CC FLAGS_REG))])]
17974   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17975    && !satisfies_constraint_K (operands[2])"
17976   [(set (match_dup 3) (match_dup 1))
17977    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17978               (clobber (reg:CC FLAGS_REG))])])
17980 (define_peephole2
17981   [(match_scratch:SI 3 "r")
17982    (parallel [(set (match_operand:DI 0 "register_operand")
17983                    (zero_extend:DI
17984                      (mult:SI (match_operand:SI 1 "memory_operand")
17985                               (match_operand:SI 2 "immediate_operand"))))
17986               (clobber (reg:CC FLAGS_REG))])]
17987   "TARGET_64BIT
17988    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17989    && !satisfies_constraint_K (operands[2])"
17990   [(set (match_dup 3) (match_dup 1))
17991    (parallel [(set (match_dup 0)
17992                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17993               (clobber (reg:CC FLAGS_REG))])])
17995 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17996 ;; Convert it into imul reg, reg
17997 ;; It would be better to force assembler to encode instruction using long
17998 ;; immediate, but there is apparently no way to do so.
17999 (define_peephole2
18000   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18001                    (mult:SWI248
18002                     (match_operand:SWI248 1 "nonimmediate_operand")
18003                     (match_operand:SWI248 2 "const_int_operand")))
18004               (clobber (reg:CC FLAGS_REG))])
18005    (match_scratch:SWI248 3 "r")]
18006   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18007    && satisfies_constraint_K (operands[2])"
18008   [(set (match_dup 3) (match_dup 2))
18009    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18010               (clobber (reg:CC FLAGS_REG))])]
18012   if (!rtx_equal_p (operands[0], operands[1]))
18013     emit_move_insn (operands[0], operands[1]);
18016 ;; After splitting up read-modify operations, array accesses with memory
18017 ;; operands might end up in form:
18018 ;;  sall    $2, %eax
18019 ;;  movl    4(%esp), %edx
18020 ;;  addl    %edx, %eax
18021 ;; instead of pre-splitting:
18022 ;;  sall    $2, %eax
18023 ;;  addl    4(%esp), %eax
18024 ;; Turn it into:
18025 ;;  movl    4(%esp), %edx
18026 ;;  leal    (%edx,%eax,4), %eax
18028 (define_peephole2
18029   [(match_scratch:W 5 "r")
18030    (parallel [(set (match_operand 0 "register_operand")
18031                    (ashift (match_operand 1 "register_operand")
18032                            (match_operand 2 "const_int_operand")))
18033                (clobber (reg:CC FLAGS_REG))])
18034    (parallel [(set (match_operand 3 "register_operand")
18035                    (plus (match_dup 0)
18036                          (match_operand 4 "x86_64_general_operand")))
18037                    (clobber (reg:CC FLAGS_REG))])]
18038   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18039    /* Validate MODE for lea.  */
18040    && ((!TARGET_PARTIAL_REG_STALL
18041         && (GET_MODE (operands[0]) == QImode
18042             || GET_MODE (operands[0]) == HImode))
18043        || GET_MODE (operands[0]) == SImode
18044        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18045    && (rtx_equal_p (operands[0], operands[3])
18046        || peep2_reg_dead_p (2, operands[0]))
18047    /* We reorder load and the shift.  */
18048    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18049   [(set (match_dup 5) (match_dup 4))
18050    (set (match_dup 0) (match_dup 1))]
18052   machine_mode op1mode = GET_MODE (operands[1]);
18053   machine_mode mode = op1mode == DImode ? DImode : SImode;
18054   int scale = 1 << INTVAL (operands[2]);
18055   rtx index = gen_lowpart (word_mode, operands[1]);
18056   rtx base = gen_lowpart (word_mode, operands[5]);
18057   rtx dest = gen_lowpart (mode, operands[3]);
18059   operands[1] = gen_rtx_PLUS (word_mode, base,
18060                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18061   operands[5] = base;
18062   if (mode != word_mode)
18063     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18064   if (op1mode != word_mode)
18065     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18066   operands[0] = dest;
18069 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18070 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18071 ;; caught for use by garbage collectors and the like.  Using an insn that
18072 ;; maps to SIGILL makes it more likely the program will rightfully die.
18073 ;; Keeping with tradition, "6" is in honor of #UD.
18074 (define_insn "trap"
18075   [(trap_if (const_int 1) (const_int 6))]
18076   ""
18078 #ifdef HAVE_AS_IX86_UD2
18079   return "ud2";
18080 #else
18081   return ASM_SHORT "0x0b0f";
18082 #endif
18084   [(set_attr "length" "2")])
18086 (define_expand "prefetch"
18087   [(prefetch (match_operand 0 "address_operand")
18088              (match_operand:SI 1 "const_int_operand")
18089              (match_operand:SI 2 "const_int_operand"))]
18090   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18092   bool write = INTVAL (operands[1]) != 0;
18093   int locality = INTVAL (operands[2]);
18095   gcc_assert (IN_RANGE (locality, 0, 3));
18097   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18098      supported by SSE counterpart or the SSE prefetch is not available
18099      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18100      of locality.  */
18101   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18102     operands[2] = const2_rtx;
18103   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18104     operands[2] = GEN_INT (3);
18105   else
18106     operands[1] = const0_rtx;
18109 (define_insn "*prefetch_sse"
18110   [(prefetch (match_operand 0 "address_operand" "p")
18111              (const_int 0)
18112              (match_operand:SI 1 "const_int_operand"))]
18113   "TARGET_PREFETCH_SSE"
18115   static const char * const patterns[4] = {
18116    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18117   };
18119   int locality = INTVAL (operands[1]);
18120   gcc_assert (IN_RANGE (locality, 0, 3));
18122   return patterns[locality];
18124   [(set_attr "type" "sse")
18125    (set_attr "atom_sse_attr" "prefetch")
18126    (set (attr "length_address")
18127         (symbol_ref "memory_address_length (operands[0], false)"))
18128    (set_attr "memory" "none")])
18130 (define_insn "*prefetch_3dnow"
18131   [(prefetch (match_operand 0 "address_operand" "p")
18132              (match_operand:SI 1 "const_int_operand" "n")
18133              (const_int 3))]
18134   "TARGET_PRFCHW"
18136   if (INTVAL (operands[1]) == 0)
18137     return "prefetch\t%a0";
18138   else
18139     return "prefetchw\t%a0";
18141   [(set_attr "type" "mmx")
18142    (set (attr "length_address")
18143         (symbol_ref "memory_address_length (operands[0], false)"))
18144    (set_attr "memory" "none")])
18146 (define_insn "*prefetch_prefetchwt1"
18147   [(prefetch (match_operand 0 "address_operand" "p")
18148              (const_int 1)
18149              (const_int 2))]
18150   "TARGET_PREFETCHWT1"
18151   "prefetchwt1\t%a0";
18152   [(set_attr "type" "sse")
18153    (set (attr "length_address")
18154         (symbol_ref "memory_address_length (operands[0], false)"))
18155    (set_attr "memory" "none")])
18157 (define_expand "stack_protect_set"
18158   [(match_operand 0 "memory_operand")
18159    (match_operand 1 "memory_operand")]
18160   "TARGET_SSP_TLS_GUARD"
18162   rtx (*insn)(rtx, rtx);
18164 #ifdef TARGET_THREAD_SSP_OFFSET
18165   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18166   insn = (TARGET_LP64
18167           ? gen_stack_tls_protect_set_di
18168           : gen_stack_tls_protect_set_si);
18169 #else
18170   insn = (TARGET_LP64
18171           ? gen_stack_protect_set_di
18172           : gen_stack_protect_set_si);
18173 #endif
18175   emit_insn (insn (operands[0], operands[1]));
18176   DONE;
18179 (define_insn "stack_protect_set_<mode>"
18180   [(set (match_operand:PTR 0 "memory_operand" "=m")
18181         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18182                     UNSPEC_SP_SET))
18183    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18184    (clobber (reg:CC FLAGS_REG))]
18185   "TARGET_SSP_TLS_GUARD"
18186   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18187   [(set_attr "type" "multi")])
18189 (define_insn "stack_tls_protect_set_<mode>"
18190   [(set (match_operand:PTR 0 "memory_operand" "=m")
18191         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18192                     UNSPEC_SP_TLS_SET))
18193    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18194    (clobber (reg:CC FLAGS_REG))]
18195   ""
18196   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18197   [(set_attr "type" "multi")])
18199 (define_expand "stack_protect_test"
18200   [(match_operand 0 "memory_operand")
18201    (match_operand 1 "memory_operand")
18202    (match_operand 2)]
18203   "TARGET_SSP_TLS_GUARD"
18205   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18207   rtx (*insn)(rtx, rtx, rtx);
18209 #ifdef TARGET_THREAD_SSP_OFFSET
18210   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18211   insn = (TARGET_LP64
18212           ? gen_stack_tls_protect_test_di
18213           : gen_stack_tls_protect_test_si);
18214 #else
18215   insn = (TARGET_LP64
18216           ? gen_stack_protect_test_di
18217           : gen_stack_protect_test_si);
18218 #endif
18220   emit_insn (insn (flags, operands[0], operands[1]));
18222   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18223                                   flags, const0_rtx, operands[2]));
18224   DONE;
18227 (define_insn "stack_protect_test_<mode>"
18228   [(set (match_operand:CCZ 0 "flags_reg_operand")
18229         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18230                      (match_operand:PTR 2 "memory_operand" "m")]
18231                     UNSPEC_SP_TEST))
18232    (clobber (match_scratch:PTR 3 "=&r"))]
18233   "TARGET_SSP_TLS_GUARD"
18234   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18235   [(set_attr "type" "multi")])
18237 (define_insn "stack_tls_protect_test_<mode>"
18238   [(set (match_operand:CCZ 0 "flags_reg_operand")
18239         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18240                      (match_operand:PTR 2 "const_int_operand" "i")]
18241                     UNSPEC_SP_TLS_TEST))
18242    (clobber (match_scratch:PTR 3 "=r"))]
18243   ""
18244   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18245   [(set_attr "type" "multi")])
18247 (define_insn "sse4_2_crc32<mode>"
18248   [(set (match_operand:SI 0 "register_operand" "=r")
18249         (unspec:SI
18250           [(match_operand:SI 1 "register_operand" "0")
18251            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18252           UNSPEC_CRC32))]
18253   "TARGET_SSE4_2 || TARGET_CRC32"
18254   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18255   [(set_attr "type" "sselog1")
18256    (set_attr "prefix_rep" "1")
18257    (set_attr "prefix_extra" "1")
18258    (set (attr "prefix_data16")
18259      (if_then_else (match_operand:HI 2)
18260        (const_string "1")
18261        (const_string "*")))
18262    (set (attr "prefix_rex")
18263      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18264        (const_string "1")
18265        (const_string "*")))
18266    (set_attr "mode" "SI")])
18268 (define_insn "sse4_2_crc32di"
18269   [(set (match_operand:DI 0 "register_operand" "=r")
18270         (unspec:DI
18271           [(match_operand:DI 1 "register_operand" "0")
18272            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18273           UNSPEC_CRC32))]
18274   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18275   "crc32{q}\t{%2, %0|%0, %2}"
18276   [(set_attr "type" "sselog1")
18277    (set_attr "prefix_rep" "1")
18278    (set_attr "prefix_extra" "1")
18279    (set_attr "mode" "DI")])
18281 (define_insn "rdpmc"
18282   [(set (match_operand:DI 0 "register_operand" "=A")
18283         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18284                             UNSPECV_RDPMC))]
18285   "!TARGET_64BIT"
18286   "rdpmc"
18287   [(set_attr "type" "other")
18288    (set_attr "length" "2")])
18290 (define_insn "rdpmc_rex64"
18291   [(set (match_operand:DI 0 "register_operand" "=a")
18292         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18293                             UNSPECV_RDPMC))
18294    (set (match_operand:DI 1 "register_operand" "=d")
18295         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18296   "TARGET_64BIT"
18297   "rdpmc"
18298   [(set_attr "type" "other")
18299    (set_attr "length" "2")])
18301 (define_insn "rdtsc"
18302   [(set (match_operand:DI 0 "register_operand" "=A")
18303         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18304   "!TARGET_64BIT"
18305   "rdtsc"
18306   [(set_attr "type" "other")
18307    (set_attr "length" "2")])
18309 (define_insn "rdtsc_rex64"
18310   [(set (match_operand:DI 0 "register_operand" "=a")
18311         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18312    (set (match_operand:DI 1 "register_operand" "=d")
18313         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18314   "TARGET_64BIT"
18315   "rdtsc"
18316   [(set_attr "type" "other")
18317    (set_attr "length" "2")])
18319 (define_insn "rdtscp"
18320   [(set (match_operand:DI 0 "register_operand" "=A")
18321         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18322    (set (match_operand:SI 1 "register_operand" "=c")
18323         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18324   "!TARGET_64BIT"
18325   "rdtscp"
18326   [(set_attr "type" "other")
18327    (set_attr "length" "3")])
18329 (define_insn "rdtscp_rex64"
18330   [(set (match_operand:DI 0 "register_operand" "=a")
18331         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18332    (set (match_operand:DI 1 "register_operand" "=d")
18333         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18334    (set (match_operand:SI 2 "register_operand" "=c")
18335         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18336   "TARGET_64BIT"
18337   "rdtscp"
18338   [(set_attr "type" "other")
18339    (set_attr "length" "3")])
18341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18343 ;; FXSR, XSAVE and XSAVEOPT instructions
18345 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18347 (define_insn "fxsave"
18348   [(set (match_operand:BLK 0 "memory_operand" "=m")
18349         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18350   "TARGET_FXSR"
18351   "fxsave\t%0"
18352   [(set_attr "type" "other")
18353    (set_attr "memory" "store")
18354    (set (attr "length")
18355         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18357 (define_insn "fxsave64"
18358   [(set (match_operand:BLK 0 "memory_operand" "=m")
18359         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18360   "TARGET_64BIT && TARGET_FXSR"
18361   "fxsave64\t%0"
18362   [(set_attr "type" "other")
18363    (set_attr "memory" "store")
18364    (set (attr "length")
18365         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18367 (define_insn "fxrstor"
18368   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18369                     UNSPECV_FXRSTOR)]
18370   "TARGET_FXSR"
18371   "fxrstor\t%0"
18372   [(set_attr "type" "other")
18373    (set_attr "memory" "load")
18374    (set (attr "length")
18375         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18377 (define_insn "fxrstor64"
18378   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18379                     UNSPECV_FXRSTOR64)]
18380   "TARGET_64BIT && TARGET_FXSR"
18381   "fxrstor64\t%0"
18382   [(set_attr "type" "other")
18383    (set_attr "memory" "load")
18384    (set (attr "length")
18385         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18387 (define_int_iterator ANY_XSAVE
18388         [UNSPECV_XSAVE
18389          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18390          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18391          (UNSPECV_XSAVES "TARGET_XSAVES")])
18393 (define_int_iterator ANY_XSAVE64
18394         [UNSPECV_XSAVE64
18395          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18396          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18397          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18399 (define_int_attr xsave
18400         [(UNSPECV_XSAVE "xsave")
18401          (UNSPECV_XSAVE64 "xsave64")
18402          (UNSPECV_XSAVEOPT "xsaveopt")
18403          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18404          (UNSPECV_XSAVEC "xsavec")
18405          (UNSPECV_XSAVEC64 "xsavec64")
18406          (UNSPECV_XSAVES "xsaves")
18407          (UNSPECV_XSAVES64 "xsaves64")])
18409 (define_int_iterator ANY_XRSTOR
18410         [UNSPECV_XRSTOR
18411          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18413 (define_int_iterator ANY_XRSTOR64
18414         [UNSPECV_XRSTOR64
18415          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18417 (define_int_attr xrstor
18418         [(UNSPECV_XRSTOR "xrstor")
18419          (UNSPECV_XRSTOR64 "xrstor")
18420          (UNSPECV_XRSTORS "xrstors")
18421          (UNSPECV_XRSTORS64 "xrstors")])
18423 (define_insn "<xsave>"
18424   [(set (match_operand:BLK 0 "memory_operand" "=m")
18425         (unspec_volatile:BLK
18426          [(match_operand:DI 1 "register_operand" "A")]
18427          ANY_XSAVE))]
18428   "!TARGET_64BIT && TARGET_XSAVE"
18429   "<xsave>\t%0"
18430   [(set_attr "type" "other")
18431    (set_attr "memory" "store")
18432    (set (attr "length")
18433         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18435 (define_insn "<xsave>_rex64"
18436   [(set (match_operand:BLK 0 "memory_operand" "=m")
18437         (unspec_volatile:BLK
18438          [(match_operand:SI 1 "register_operand" "a")
18439           (match_operand:SI 2 "register_operand" "d")]
18440          ANY_XSAVE))]
18441   "TARGET_64BIT && TARGET_XSAVE"
18442   "<xsave>\t%0"
18443   [(set_attr "type" "other")
18444    (set_attr "memory" "store")
18445    (set (attr "length")
18446         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18448 (define_insn "<xsave>"
18449   [(set (match_operand:BLK 0 "memory_operand" "=m")
18450         (unspec_volatile:BLK
18451          [(match_operand:SI 1 "register_operand" "a")
18452           (match_operand:SI 2 "register_operand" "d")]
18453          ANY_XSAVE64))]
18454   "TARGET_64BIT && TARGET_XSAVE"
18455   "<xsave>\t%0"
18456   [(set_attr "type" "other")
18457    (set_attr "memory" "store")
18458    (set (attr "length")
18459         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18461 (define_insn "<xrstor>"
18462    [(unspec_volatile:BLK
18463      [(match_operand:BLK 0 "memory_operand" "m")
18464       (match_operand:DI 1 "register_operand" "A")]
18465      ANY_XRSTOR)]
18466   "!TARGET_64BIT && TARGET_XSAVE"
18467   "<xrstor>\t%0"
18468   [(set_attr "type" "other")
18469    (set_attr "memory" "load")
18470    (set (attr "length")
18471         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18473 (define_insn "<xrstor>_rex64"
18474    [(unspec_volatile:BLK
18475      [(match_operand:BLK 0 "memory_operand" "m")
18476       (match_operand:SI 1 "register_operand" "a")
18477       (match_operand:SI 2 "register_operand" "d")]
18478      ANY_XRSTOR)]
18479   "TARGET_64BIT && TARGET_XSAVE"
18480   "<xrstor>\t%0"
18481   [(set_attr "type" "other")
18482    (set_attr "memory" "load")
18483    (set (attr "length")
18484         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18486 (define_insn "<xrstor>64"
18487    [(unspec_volatile:BLK
18488      [(match_operand:BLK 0 "memory_operand" "m")
18489       (match_operand:SI 1 "register_operand" "a")
18490       (match_operand:SI 2 "register_operand" "d")]
18491      ANY_XRSTOR64)]
18492   "TARGET_64BIT && TARGET_XSAVE"
18493   "<xrstor>64\t%0"
18494   [(set_attr "type" "other")
18495    (set_attr "memory" "load")
18496    (set (attr "length")
18497         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18501 ;; Floating-point instructions for atomic compound assignments
18503 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18505 ; Clobber all floating-point registers on environment save and restore
18506 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18507 (define_insn "fnstenv"
18508   [(set (match_operand:BLK 0 "memory_operand" "=m")
18509         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18510    (clobber (reg:HI FPCR_REG))
18511    (clobber (reg:XF ST0_REG))
18512    (clobber (reg:XF ST1_REG))
18513    (clobber (reg:XF ST2_REG))
18514    (clobber (reg:XF ST3_REG))
18515    (clobber (reg:XF ST4_REG))
18516    (clobber (reg:XF ST5_REG))
18517    (clobber (reg:XF ST6_REG))
18518    (clobber (reg:XF ST7_REG))]
18519   "TARGET_80387"
18520   "fnstenv\t%0"
18521   [(set_attr "type" "other")
18522    (set_attr "memory" "store")
18523    (set (attr "length")
18524         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18526 (define_insn "fldenv"
18527   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18528                     UNSPECV_FLDENV)
18529    (clobber (reg:CCFP FPSR_REG))
18530    (clobber (reg:HI FPCR_REG))
18531    (clobber (reg:XF ST0_REG))
18532    (clobber (reg:XF ST1_REG))
18533    (clobber (reg:XF ST2_REG))
18534    (clobber (reg:XF ST3_REG))
18535    (clobber (reg:XF ST4_REG))
18536    (clobber (reg:XF ST5_REG))
18537    (clobber (reg:XF ST6_REG))
18538    (clobber (reg:XF ST7_REG))]
18539   "TARGET_80387"
18540   "fldenv\t%0"
18541   [(set_attr "type" "other")
18542    (set_attr "memory" "load")
18543    (set (attr "length")
18544         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18546 (define_insn "fnstsw"
18547   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18548         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18549   "TARGET_80387"
18550   "fnstsw\t%0"
18551   [(set_attr "type" "other,other")
18552    (set_attr "memory" "none,store")
18553    (set (attr "length")
18554         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18556 (define_insn "fnclex"
18557   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18558   "TARGET_80387"
18559   "fnclex"
18560   [(set_attr "type" "other")
18561    (set_attr "memory" "none")
18562    (set_attr "length" "2")])
18564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18566 ;; LWP instructions
18568 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18570 (define_expand "lwp_llwpcb"
18571   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18572                     UNSPECV_LLWP_INTRINSIC)]
18573   "TARGET_LWP")
18575 (define_insn "*lwp_llwpcb<mode>1"
18576   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18577                     UNSPECV_LLWP_INTRINSIC)]
18578   "TARGET_LWP"
18579   "llwpcb\t%0"
18580   [(set_attr "type" "lwp")
18581    (set_attr "mode" "<MODE>")
18582    (set_attr "length" "5")])
18584 (define_expand "lwp_slwpcb"
18585   [(set (match_operand 0 "register_operand" "=r")
18586         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18587   "TARGET_LWP"
18589   rtx (*insn)(rtx);
18591   insn = (Pmode == DImode
18592           ? gen_lwp_slwpcbdi
18593           : gen_lwp_slwpcbsi);
18595   emit_insn (insn (operands[0]));
18596   DONE;
18599 (define_insn "lwp_slwpcb<mode>"
18600   [(set (match_operand:P 0 "register_operand" "=r")
18601         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18602   "TARGET_LWP"
18603   "slwpcb\t%0"
18604   [(set_attr "type" "lwp")
18605    (set_attr "mode" "<MODE>")
18606    (set_attr "length" "5")])
18608 (define_expand "lwp_lwpval<mode>3"
18609   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18610                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18611                      (match_operand:SI 3 "const_int_operand" "i")]
18612                     UNSPECV_LWPVAL_INTRINSIC)]
18613   "TARGET_LWP"
18614   ;; Avoid unused variable warning.
18615   "(void) operands[0];")
18617 (define_insn "*lwp_lwpval<mode>3_1"
18618   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18619                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18620                      (match_operand:SI 2 "const_int_operand" "i")]
18621                     UNSPECV_LWPVAL_INTRINSIC)]
18622   "TARGET_LWP"
18623   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18624   [(set_attr "type" "lwp")
18625    (set_attr "mode" "<MODE>")
18626    (set (attr "length")
18627         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18629 (define_expand "lwp_lwpins<mode>3"
18630   [(set (reg:CCC FLAGS_REG)
18631         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18632                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18633                               (match_operand:SI 3 "const_int_operand" "i")]
18634                              UNSPECV_LWPINS_INTRINSIC))
18635    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18636         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18637   "TARGET_LWP")
18639 (define_insn "*lwp_lwpins<mode>3_1"
18640   [(set (reg:CCC FLAGS_REG)
18641         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18642                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18643                               (match_operand:SI 2 "const_int_operand" "i")]
18644                              UNSPECV_LWPINS_INTRINSIC))]
18645   "TARGET_LWP"
18646   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18647   [(set_attr "type" "lwp")
18648    (set_attr "mode" "<MODE>")
18649    (set (attr "length")
18650         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18652 (define_int_iterator RDFSGSBASE
18653         [UNSPECV_RDFSBASE
18654          UNSPECV_RDGSBASE])
18656 (define_int_iterator WRFSGSBASE
18657         [UNSPECV_WRFSBASE
18658          UNSPECV_WRGSBASE])
18660 (define_int_attr fsgs
18661         [(UNSPECV_RDFSBASE "fs")
18662          (UNSPECV_RDGSBASE "gs")
18663          (UNSPECV_WRFSBASE "fs")
18664          (UNSPECV_WRGSBASE "gs")])
18666 (define_insn "rd<fsgs>base<mode>"
18667   [(set (match_operand:SWI48 0 "register_operand" "=r")
18668         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18669   "TARGET_64BIT && TARGET_FSGSBASE"
18670   "rd<fsgs>base\t%0"
18671   [(set_attr "type" "other")
18672    (set_attr "prefix_extra" "2")])
18674 (define_insn "wr<fsgs>base<mode>"
18675   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18676                     WRFSGSBASE)]
18677   "TARGET_64BIT && TARGET_FSGSBASE"
18678   "wr<fsgs>base\t%0"
18679   [(set_attr "type" "other")
18680    (set_attr "prefix_extra" "2")])
18682 (define_insn "rdrand<mode>_1"
18683   [(set (match_operand:SWI248 0 "register_operand" "=r")
18684         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18685    (set (reg:CCC FLAGS_REG)
18686         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18687   "TARGET_RDRND"
18688   "rdrand\t%0"
18689   [(set_attr "type" "other")
18690    (set_attr "prefix_extra" "1")])
18692 (define_insn "rdseed<mode>_1"
18693   [(set (match_operand:SWI248 0 "register_operand" "=r")
18694         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18695    (set (reg:CCC FLAGS_REG)
18696         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18697   "TARGET_RDSEED"
18698   "rdseed\t%0"
18699   [(set_attr "type" "other")
18700    (set_attr "prefix_extra" "1")])
18702 (define_expand "pause"
18703   [(set (match_dup 0)
18704         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18705   ""
18707   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18708   MEM_VOLATILE_P (operands[0]) = 1;
18711 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18712 ;; They have the same encoding.
18713 (define_insn "*pause"
18714   [(set (match_operand:BLK 0)
18715         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18716   ""
18717   "rep%; nop"
18718   [(set_attr "length" "2")
18719    (set_attr "memory" "unknown")])
18721 (define_expand "xbegin"
18722   [(set (match_operand:SI 0 "register_operand")
18723         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18724   "TARGET_RTM"
18726   rtx_code_label *label = gen_label_rtx ();
18728   /* xbegin is emitted as jump_insn, so reload won't be able
18729      to reload its operand.  Force the value into AX hard register.  */
18730   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18731   emit_move_insn (ax_reg, constm1_rtx);
18733   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18735   emit_label (label);
18736   LABEL_NUSES (label) = 1;
18738   emit_move_insn (operands[0], ax_reg);
18740   DONE;
18743 (define_insn "xbegin_1"
18744   [(set (pc)
18745         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18746                           (const_int 0))
18747                       (label_ref (match_operand 1))
18748                       (pc)))
18749    (set (match_operand:SI 0 "register_operand" "+a")
18750         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18751   "TARGET_RTM"
18752   "xbegin\t%l1"
18753   [(set_attr "type" "other")
18754    (set_attr "length" "6")])
18756 (define_insn "xend"
18757   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18758   "TARGET_RTM"
18759   "xend"
18760   [(set_attr "type" "other")
18761    (set_attr "length" "3")])
18763 (define_insn "xabort"
18764   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18765                     UNSPECV_XABORT)]
18766   "TARGET_RTM"
18767   "xabort\t%0"
18768   [(set_attr "type" "other")
18769    (set_attr "length" "3")])
18771 (define_expand "xtest"
18772   [(set (match_operand:QI 0 "register_operand")
18773         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18774   "TARGET_RTM"
18776   emit_insn (gen_xtest_1 ());
18778   ix86_expand_setcc (operands[0], NE,
18779                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18780   DONE;
18783 (define_insn "xtest_1"
18784   [(set (reg:CCZ FLAGS_REG)
18785         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18786   "TARGET_RTM"
18787   "xtest"
18788   [(set_attr "type" "other")
18789    (set_attr "length" "3")])
18791 (define_insn "pcommit"
18792   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18793   "TARGET_PCOMMIT"
18794   "pcommit"
18795   [(set_attr "type" "other")
18796    (set_attr "length" "4")])
18798 (define_insn "clwb"
18799   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18800                    UNSPECV_CLWB)]
18801   "TARGET_CLWB"
18802   "clwb\t%a0"
18803   [(set_attr "type" "sse")
18804    (set_attr "atom_sse_attr" "fence")
18805    (set_attr "memory" "unknown")])
18807 (define_insn "clflushopt"
18808   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18809                    UNSPECV_CLFLUSHOPT)]
18810   "TARGET_CLFLUSHOPT"
18811   "clflushopt\t%a0"
18812   [(set_attr "type" "sse")
18813    (set_attr "atom_sse_attr" "fence")
18814    (set_attr "memory" "unknown")])
18816 ;; MPX instructions
18818 (define_expand "<mode>_mk"
18819   [(set (match_operand:BND 0 "register_operand")
18820     (unspec:BND
18821       [(mem:<bnd_ptr>
18822        (match_par_dup 3
18823         [(match_operand:<bnd_ptr> 1 "register_operand")
18824          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18825       UNSPEC_BNDMK))]
18826   "TARGET_MPX"
18828   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18829                                                   operands[2]),
18830                                 UNSPEC_BNDMK_ADDR);
18833 (define_insn "*<mode>_mk"
18834   [(set (match_operand:BND 0 "register_operand" "=w")
18835     (unspec:BND
18836       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18837         [(unspec:<bnd_ptr>
18838            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18839             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18840            UNSPEC_BNDMK_ADDR)])]
18841       UNSPEC_BNDMK))]
18842   "TARGET_MPX"
18843   "bndmk\t{%3, %0|%0, %3}"
18844   [(set_attr "type" "mpxmk")])
18846 (define_expand "mov<mode>"
18847   [(set (match_operand:BND 0 "general_operand")
18848         (match_operand:BND 1 "general_operand"))]
18849   "TARGET_MPX"
18851   ix86_expand_move (<MODE>mode, operands);DONE;
18854 (define_insn "*mov<mode>_internal_mpx"
18855   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18856         (match_operand:BND 1 "general_operand" "wm,w"))]
18857   "TARGET_MPX"
18858   "bndmov\t{%1, %0|%0, %1}"
18859   [(set_attr "type" "mpxmov")])
18861 (define_expand "<mode>_<bndcheck>"
18862   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18863                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18864               (set (match_dup 2)
18865                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18866   "TARGET_MPX"
18868   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18869   MEM_VOLATILE_P (operands[2]) = 1;
18872 (define_insn "*<mode>_<bndcheck>"
18873   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18874                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18875               (set (match_operand:BLK 2 "bnd_mem_operator")
18876                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18877   "TARGET_MPX"
18878   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18879   [(set_attr "type" "mpxchk")])
18881 (define_expand "<mode>_ldx"
18882   [(parallel [(set (match_operand:BND 0 "register_operand")
18883                    (unspec:BND
18884                      [(mem:<bnd_ptr>
18885                        (match_par_dup 3
18886                          [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18887                           (match_operand:<bnd_ptr> 2 "register_operand")]))]
18888                      UNSPEC_BNDLDX))
18889               (use (mem:BLK (match_dup 1)))])]
18890   "TARGET_MPX"
18892   /* Avoid registers which connot be used as index.  */
18893   if (!index_register_operand (operands[2], Pmode))
18894     {
18895       rtx temp = gen_reg_rtx (Pmode);
18896       emit_move_insn (temp, operands[2]);
18897       operands[2] = temp;
18898     }
18900   /* If it was a register originally then it may have
18901      mode other than Pmode.  We need to extend in such
18902      case because bndldx may work only with Pmode regs.  */
18903   if (GET_MODE (operands[2]) != Pmode)
18904     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18906   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18907                                                   operands[2]),
18908                                 UNSPEC_BNDLDX_ADDR);
18911 (define_insn "*<mode>_ldx"
18912   [(parallel [(set (match_operand:BND 0 "register_operand" "=w")
18913                    (unspec:BND
18914                      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18915                        [(unspec:<bnd_ptr>
18916                          [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18917                           (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18918                         UNSPEC_BNDLDX_ADDR)])]
18919                      UNSPEC_BNDLDX))
18920               (use (mem:BLK (match_dup 1)))])]
18921   "TARGET_MPX"
18922   "bndldx\t{%3, %0|%0, %3}"
18923   [(set_attr "type" "mpxld")])
18925 (define_expand "<mode>_stx"
18926   [(parallel [(unspec [(mem:<bnd_ptr>
18927                          (match_par_dup 3
18928                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18929                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18930                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18931               (set (match_dup 4)
18932                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18933   "TARGET_MPX"
18935   /* Avoid registers which connot be used as index.  */
18936   if (!index_register_operand (operands[1], Pmode))
18937     {
18938       rtx temp = gen_reg_rtx (Pmode);
18939       emit_move_insn (temp, operands[1]);
18940       operands[1] = temp;
18941     }
18943   /* If it was a register originally then it may have
18944      mode other than Pmode.  We need to extend in such
18945      case because bndstx may work only with Pmode regs.  */
18946   if (GET_MODE (operands[1]) != Pmode)
18947     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18949   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18950                                                   operands[1]),
18951                                 UNSPEC_BNDLDX_ADDR);
18952   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18953   MEM_VOLATILE_P (operands[4]) = 1;
18956 (define_insn "*<mode>_stx"
18957   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18958                          [(unspec:<bnd_ptr>
18959                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18960                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18961                          UNSPEC_BNDLDX_ADDR)])
18962                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18963               (set (match_operand:BLK 4 "bnd_mem_operator")
18964                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18965   "TARGET_MPX"
18966   "bndstx\t{%2, %3|%3, %2}"
18967   [(set_attr "type" "mpxst")])
18969 (define_insn "move_size_reloc_<mode>"
18970   [(set (match_operand:SWI48 0 "register_operand" "=r")
18971        (unspec:SWI48
18972         [(match_operand:SWI48 1 "symbol_operand")]
18973         UNSPEC_SIZEOF))]
18974   "TARGET_MPX"
18976   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18977     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18978   else
18979     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18981   [(set_attr "type" "imov")
18982    (set_attr "mode" "<MODE>")])
18984 (include "mmx.md")
18985 (include "sse.md")
18986 (include "sync.md")