* config/i386/i386.c: Change GET_CODE (...) == CONST_DOUBLE check
[official-gcc.git] / gcc / config / i386 / i386.md
blob8b0830c7a1b5c004355ffb4902df16dd3ebf40e8
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 (VOIDmode, 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 (VOIDmode, 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   [(const_int 0)]
4903   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4904                                      <MODE>mode, 0);
4905   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4907   emit_insn (gen_sse2_loadld (operands[4],
4908                               CONST0_RTX (V4SImode), operands[1]));
4910   if (<ssevecmode>mode == V4SFmode)
4911     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4912   else
4913     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4914   DONE;
4917 ;; Avoid partial SSE register dependency stalls
4918 (define_split
4919   [(set (match_operand:MODEF 0 "register_operand")
4920         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4921   "TARGET_SSE2 && TARGET_SSE_MATH
4922    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4923    && optimize_function_for_speed_p (cfun)
4924    && reload_completed && SSE_REG_P (operands[0])"
4925   [(const_int 0)]
4927   const machine_mode vmode = <MODEF:ssevecmode>mode;
4928   const machine_mode mode = <MODEF:MODE>mode;
4929   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4931   emit_move_insn (op0, CONST0_RTX (vmode));
4933   t = gen_rtx_FLOAT (mode, operands[1]);
4934   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4935   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4936   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4937   DONE;
4940 ;; Break partial reg stall for cvtsd2ss.
4942 (define_peephole2
4943   [(set (match_operand:SF 0 "register_operand")
4944         (float_truncate:SF
4945           (match_operand:DF 1 "nonimmediate_operand")))]
4946   "TARGET_SSE2 && TARGET_SSE_MATH
4947    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4948    && optimize_function_for_speed_p (cfun)
4949    && SSE_REG_P (operands[0])
4950    && (!SSE_REG_P (operands[1])
4951        || REGNO (operands[0]) != REGNO (operands[1]))
4952    && (!EXT_REX_SSE_REG_P (operands[0])
4953        || TARGET_AVX512VL)"
4954   [(set (match_dup 0)
4955         (vec_merge:V4SF
4956           (vec_duplicate:V4SF
4957             (float_truncate:V2SF
4958               (match_dup 1)))
4959           (match_dup 0)
4960           (const_int 1)))]
4962   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4963                                      SFmode, 0);
4964   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4965                                      DFmode, 0);
4966   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4969 ;; Break partial reg stall for cvtss2sd.
4971 (define_peephole2
4972   [(set (match_operand:DF 0 "register_operand")
4973         (float_extend:DF
4974           (match_operand:SF 1 "nonimmediate_operand")))]
4975   "TARGET_SSE2 && TARGET_SSE_MATH
4976    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4977    && optimize_function_for_speed_p (cfun)
4978    && SSE_REG_P (operands[0])
4979    && (!SSE_REG_P (operands[1])
4980        || REGNO (operands[0]) != REGNO (operands[1]))
4981    && (!EXT_REX_SSE_REG_P (operands[0])
4982        || TARGET_AVX512VL)"
4983   [(set (match_dup 0)
4984         (vec_merge:V2DF
4985           (float_extend:V2DF
4986             (vec_select:V2SF
4987               (match_dup 1)
4988               (parallel [(const_int 0) (const_int 1)])))
4989           (match_dup 0)
4990           (const_int 1)))]
4992   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4993                                      DFmode, 0);
4994   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4995                                      SFmode, 0);
4996   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4999 ;; Avoid store forwarding (partial memory) stall penalty
5000 ;; by passing DImode value through XMM registers.  */
5002 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5003   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5004         (float:X87MODEF
5005           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5006    (clobber (match_scratch:V4SI 3 "=X,x"))
5007    (clobber (match_scratch:V4SI 4 "=X,x"))
5008    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5009   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5010    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5011    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5012   "#"
5013   [(set_attr "type" "multi")
5014    (set_attr "mode" "<X87MODEF:MODE>")
5015    (set_attr "unit" "i387")
5016    (set_attr "fp_int_src" "true")])
5018 (define_split
5019   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5020         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5021    (clobber (match_scratch:V4SI 3))
5022    (clobber (match_scratch:V4SI 4))
5023    (clobber (match_operand:DI 2 "memory_operand"))]
5024   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5025    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5026    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5027    && reload_completed"
5028   [(set (match_dup 2) (match_dup 3))
5029    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5031   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5032      Assemble the 64-bit DImode value in an xmm register.  */
5033   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5034                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5035   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5036                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5037   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5038                                          operands[4]));
5040   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5043 (define_split
5044   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5045         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5046    (clobber (match_scratch:V4SI 3))
5047    (clobber (match_scratch:V4SI 4))
5048    (clobber (match_operand:DI 2 "memory_operand"))]
5049   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5050    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5051    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5052    && reload_completed"
5053   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5055 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5056   [(set (match_operand:MODEF 0 "register_operand")
5057         (unsigned_float:MODEF
5058           (match_operand:SWI12 1 "nonimmediate_operand")))]
5059   "!TARGET_64BIT
5060    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5062   operands[1] = convert_to_mode (SImode, operands[1], 1);
5063   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5064   DONE;
5067 ;; Avoid store forwarding (partial memory) stall penalty by extending
5068 ;; SImode value to DImode through XMM register instead of pushing two
5069 ;; SImode values to stack. Also note that fild loads from memory only.
5071 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5072   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5073         (unsigned_float:X87MODEF
5074           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5075    (clobber (match_scratch:DI 3 "=x"))
5076    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5077   "!TARGET_64BIT
5078    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5079    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5080   "#"
5081   "&& reload_completed"
5082   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5083    (set (match_dup 2) (match_dup 3))
5084    (set (match_dup 0)
5085         (float:X87MODEF (match_dup 2)))]
5086   ""
5087   [(set_attr "type" "multi")
5088    (set_attr "mode" "<MODE>")])
5090 (define_expand "floatunssi<mode>2"
5091   [(parallel
5092      [(set (match_operand:X87MODEF 0 "register_operand")
5093            (unsigned_float:X87MODEF
5094              (match_operand:SI 1 "nonimmediate_operand")))
5095       (clobber (match_scratch:DI 3))
5096       (clobber (match_dup 2))])]
5097   "!TARGET_64BIT
5098    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5099         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5100        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5102   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5103     {
5104       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5105       DONE;
5106     }
5107   else
5108     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5111 (define_expand "floatunsdisf2"
5112   [(use (match_operand:SF 0 "register_operand"))
5113    (use (match_operand:DI 1 "nonimmediate_operand"))]
5114   "TARGET_64BIT && TARGET_SSE_MATH"
5115   "x86_emit_floatuns (operands); DONE;")
5117 (define_expand "floatunsdidf2"
5118   [(use (match_operand:DF 0 "register_operand"))
5119    (use (match_operand:DI 1 "nonimmediate_operand"))]
5120   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5121    && TARGET_SSE2 && TARGET_SSE_MATH"
5123   if (TARGET_64BIT)
5124     x86_emit_floatuns (operands);
5125   else
5126     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5127   DONE;
5130 ;; Load effective address instructions
5132 (define_insn_and_split "*lea<mode>"
5133   [(set (match_operand:SWI48 0 "register_operand" "=r")
5134         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5135   ""
5137   if (SImode_address_operand (operands[1], VOIDmode))
5138     {
5139       gcc_assert (TARGET_64BIT);
5140       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5141     }
5142   else 
5143     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5145   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5146   [(const_int 0)]
5148   machine_mode mode = <MODE>mode;
5149   rtx pat;
5151   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5152      change operands[] array behind our back.  */
5153   pat = PATTERN (curr_insn);
5155   operands[0] = SET_DEST (pat);
5156   operands[1] = SET_SRC (pat);
5158   /* Emit all operations in SImode for zero-extended addresses.  */
5159   if (SImode_address_operand (operands[1], VOIDmode))
5160     mode = SImode;
5162   ix86_split_lea_for_addr (curr_insn, operands, mode);
5164   /* Zero-extend return register to DImode for zero-extended addresses.  */
5165   if (mode != <MODE>mode)
5166     emit_insn (gen_zero_extendsidi2
5167                (operands[0], gen_lowpart (mode, operands[0])));
5169   DONE;
5171   [(set_attr "type" "lea")
5172    (set (attr "mode")
5173      (if_then_else
5174        (match_operand 1 "SImode_address_operand")
5175        (const_string "SI")
5176        (const_string "<MODE>")))])
5178 ;; Add instructions
5180 (define_expand "add<mode>3"
5181   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5182         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5183                     (match_operand:SDWIM 2 "<general_operand>")))]
5184   ""
5185   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5187 (define_insn_and_split "*add<dwi>3_doubleword"
5188   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5189         (plus:<DWI>
5190           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5191           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5192    (clobber (reg:CC FLAGS_REG))]
5193   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5194   "#"
5195   "reload_completed"
5196   [(parallel [(set (reg:CC FLAGS_REG)
5197                    (unspec:CC [(match_dup 1) (match_dup 2)]
5198                               UNSPEC_ADD_CARRY))
5199               (set (match_dup 0)
5200                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5201    (parallel [(set (match_dup 3)
5202                    (plus:DWIH
5203                      (match_dup 4)
5204                      (plus:DWIH
5205                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5206                        (match_dup 5))))
5207               (clobber (reg:CC FLAGS_REG))])]
5208   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5210 (define_insn "*add<mode>3_cc"
5211   [(set (reg:CC FLAGS_REG)
5212         (unspec:CC
5213           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5214            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5215           UNSPEC_ADD_CARRY))
5216    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5217         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5218   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5219   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5220   [(set_attr "type" "alu")
5221    (set_attr "mode" "<MODE>")])
5223 (define_insn "addqi3_cc"
5224   [(set (reg:CC FLAGS_REG)
5225         (unspec:CC
5226           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5227            (match_operand:QI 2 "general_operand" "qn,qm")]
5228           UNSPEC_ADD_CARRY))
5229    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5230         (plus:QI (match_dup 1) (match_dup 2)))]
5231   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5232   "add{b}\t{%2, %0|%0, %2}"
5233   [(set_attr "type" "alu")
5234    (set_attr "mode" "QI")])
5236 (define_insn "*add<mode>_1"
5237   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5238         (plus:SWI48
5239           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5240           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5241    (clobber (reg:CC FLAGS_REG))]
5242   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5244   switch (get_attr_type (insn))
5245     {
5246     case TYPE_LEA:
5247       return "#";
5249     case TYPE_INCDEC:
5250       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251       if (operands[2] == const1_rtx)
5252         return "inc{<imodesuffix>}\t%0";
5253       else
5254         {
5255           gcc_assert (operands[2] == constm1_rtx);
5256           return "dec{<imodesuffix>}\t%0";
5257         }
5259     default:
5260       /* For most processors, ADD is faster than LEA.  This alternative
5261          was added to use ADD as much as possible.  */
5262       if (which_alternative == 2)
5263         std::swap (operands[1], operands[2]);
5264         
5265       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5267         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5269       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5270     }
5272   [(set (attr "type")
5273      (cond [(eq_attr "alternative" "3")
5274               (const_string "lea")
5275             (match_operand:SWI48 2 "incdec_operand")
5276               (const_string "incdec")
5277            ]
5278            (const_string "alu")))
5279    (set (attr "length_immediate")
5280       (if_then_else
5281         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5282         (const_string "1")
5283         (const_string "*")))
5284    (set_attr "mode" "<MODE>")])
5286 ;; It may seem that nonimmediate operand is proper one for operand 1.
5287 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5288 ;; we take care in ix86_binary_operator_ok to not allow two memory
5289 ;; operands so proper swapping will be done in reload.  This allow
5290 ;; patterns constructed from addsi_1 to match.
5292 (define_insn "addsi_1_zext"
5293   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5294         (zero_extend:DI
5295           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5296                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5297    (clobber (reg:CC FLAGS_REG))]
5298   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5300   switch (get_attr_type (insn))
5301     {
5302     case TYPE_LEA:
5303       return "#";
5305     case TYPE_INCDEC:
5306       if (operands[2] == const1_rtx)
5307         return "inc{l}\t%k0";
5308       else
5309         {
5310           gcc_assert (operands[2] == constm1_rtx);
5311           return "dec{l}\t%k0";
5312         }
5314     default:
5315       /* For most processors, ADD is faster than LEA.  This alternative
5316          was added to use ADD as much as possible.  */
5317       if (which_alternative == 1)
5318         std::swap (operands[1], operands[2]);
5320       if (x86_maybe_negate_const_int (&operands[2], SImode))
5321         return "sub{l}\t{%2, %k0|%k0, %2}";
5323       return "add{l}\t{%2, %k0|%k0, %2}";
5324     }
5326   [(set (attr "type")
5327      (cond [(eq_attr "alternative" "2")
5328               (const_string "lea")
5329             (match_operand:SI 2 "incdec_operand")
5330               (const_string "incdec")
5331            ]
5332            (const_string "alu")))
5333    (set (attr "length_immediate")
5334       (if_then_else
5335         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5336         (const_string "1")
5337         (const_string "*")))
5338    (set_attr "mode" "SI")])
5340 (define_insn "*addhi_1"
5341   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5342         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5343                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5344    (clobber (reg:CC FLAGS_REG))]
5345   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5347   switch (get_attr_type (insn))
5348     {
5349     case TYPE_LEA:
5350       return "#";
5352     case TYPE_INCDEC:
5353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5354       if (operands[2] == const1_rtx)
5355         return "inc{w}\t%0";
5356       else
5357         {
5358           gcc_assert (operands[2] == constm1_rtx);
5359           return "dec{w}\t%0";
5360         }
5362     default:
5363       /* For most processors, ADD is faster than LEA.  This alternative
5364          was added to use ADD as much as possible.  */
5365       if (which_alternative == 2)
5366         std::swap (operands[1], operands[2]);
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369       if (x86_maybe_negate_const_int (&operands[2], HImode))
5370         return "sub{w}\t{%2, %0|%0, %2}";
5372       return "add{w}\t{%2, %0|%0, %2}";
5373     }
5375   [(set (attr "type")
5376      (cond [(eq_attr "alternative" "3")
5377               (const_string "lea")
5378             (match_operand:HI 2 "incdec_operand")
5379               (const_string "incdec")
5380            ]
5381            (const_string "alu")))
5382    (set (attr "length_immediate")
5383       (if_then_else
5384         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5385         (const_string "1")
5386         (const_string "*")))
5387    (set_attr "mode" "HI,HI,HI,SI")])
5389 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5390 (define_insn "*addqi_1"
5391   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5392         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5393                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5394    (clobber (reg:CC FLAGS_REG))]
5395   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5397   bool widen = (which_alternative == 3 || which_alternative == 4);
5399   switch (get_attr_type (insn))
5400     {
5401     case TYPE_LEA:
5402       return "#";
5404     case TYPE_INCDEC:
5405       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5406       if (operands[2] == const1_rtx)
5407         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5408       else
5409         {
5410           gcc_assert (operands[2] == constm1_rtx);
5411           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5412         }
5414     default:
5415       /* For most processors, ADD is faster than LEA.  These alternatives
5416          were added to use ADD as much as possible.  */
5417       if (which_alternative == 2 || which_alternative == 4)
5418         std::swap (operands[1], operands[2]);
5420       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5421       if (x86_maybe_negate_const_int (&operands[2], QImode))
5422         {
5423           if (widen)
5424             return "sub{l}\t{%2, %k0|%k0, %2}";
5425           else
5426             return "sub{b}\t{%2, %0|%0, %2}";
5427         }
5428       if (widen)
5429         return "add{l}\t{%k2, %k0|%k0, %k2}";
5430       else
5431         return "add{b}\t{%2, %0|%0, %2}";
5432     }
5434   [(set (attr "type")
5435      (cond [(eq_attr "alternative" "5")
5436               (const_string "lea")
5437             (match_operand:QI 2 "incdec_operand")
5438               (const_string "incdec")
5439            ]
5440            (const_string "alu")))
5441    (set (attr "length_immediate")
5442       (if_then_else
5443         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5444         (const_string "1")
5445         (const_string "*")))
5446    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5448 (define_insn "*addqi_1_slp"
5449   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5450         (plus:QI (match_dup 0)
5451                  (match_operand:QI 1 "general_operand" "qn,qm")))
5452    (clobber (reg:CC FLAGS_REG))]
5453   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       if (operands[1] == const1_rtx)
5460         return "inc{b}\t%0";
5461       else
5462         {
5463           gcc_assert (operands[1] == constm1_rtx);
5464           return "dec{b}\t%0";
5465         }
5467     default:
5468       if (x86_maybe_negate_const_int (&operands[1], QImode))
5469         return "sub{b}\t{%1, %0|%0, %1}";
5471       return "add{b}\t{%1, %0|%0, %1}";
5472     }
5474   [(set (attr "type")
5475      (if_then_else (match_operand:QI 1 "incdec_operand")
5476         (const_string "incdec")
5477         (const_string "alu1")))
5478    (set (attr "memory")
5479      (if_then_else (match_operand 1 "memory_operand")
5480         (const_string "load")
5481         (const_string "none")))
5482    (set_attr "mode" "QI")])
5484 ;; Split non destructive adds if we cannot use lea.
5485 (define_split
5486   [(set (match_operand:SWI48 0 "register_operand")
5487         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5488                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5489    (clobber (reg:CC FLAGS_REG))]
5490   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5491   [(set (match_dup 0) (match_dup 1))
5492    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5493               (clobber (reg:CC FLAGS_REG))])])
5495 ;; Convert add to the lea pattern to avoid flags dependency.
5496 (define_split
5497   [(set (match_operand:SWI 0 "register_operand")
5498         (plus:SWI (match_operand:SWI 1 "register_operand")
5499                   (match_operand:SWI 2 "<nonmemory_operand>")))
5500    (clobber (reg:CC FLAGS_REG))]
5501   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5502   [(const_int 0)]
5504   machine_mode mode = <MODE>mode;
5505   rtx pat;
5507   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5508     { 
5509       mode = SImode; 
5510       operands[0] = gen_lowpart (mode, operands[0]);
5511       operands[1] = gen_lowpart (mode, operands[1]);
5512       operands[2] = gen_lowpart (mode, operands[2]);
5513     }
5515   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5517   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5518   DONE;
5521 ;; Split non destructive adds if we cannot use lea.
5522 (define_split
5523   [(set (match_operand:DI 0 "register_operand")
5524         (zero_extend:DI
5525           (plus:SI (match_operand:SI 1 "register_operand")
5526                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5527    (clobber (reg:CC FLAGS_REG))]
5528   "TARGET_64BIT
5529    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5530   [(set (match_dup 3) (match_dup 1))
5531    (parallel [(set (match_dup 0)
5532                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5533               (clobber (reg:CC FLAGS_REG))])]
5534   "operands[3] = gen_lowpart (SImode, operands[0]);")
5536 ;; Convert add to the lea pattern to avoid flags dependency.
5537 (define_split
5538   [(set (match_operand:DI 0 "register_operand")
5539         (zero_extend:DI
5540           (plus:SI (match_operand:SI 1 "register_operand")
5541                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5542    (clobber (reg:CC FLAGS_REG))]
5543   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5544   [(set (match_dup 0)
5545         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5547 (define_insn "*add<mode>_2"
5548   [(set (reg FLAGS_REG)
5549         (compare
5550           (plus:SWI
5551             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5552             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5553           (const_int 0)))
5554    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5555         (plus:SWI (match_dup 1) (match_dup 2)))]
5556   "ix86_match_ccmode (insn, CCGOCmode)
5557    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       if (operands[2] == const1_rtx)
5563         return "inc{<imodesuffix>}\t%0";
5564       else
5565         {
5566           gcc_assert (operands[2] == constm1_rtx);
5567           return "dec{<imodesuffix>}\t%0";
5568         }
5570     default:
5571       if (which_alternative == 2)
5572         std::swap (operands[1], operands[2]);
5573         
5574       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5575       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5576         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5578       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5579     }
5581   [(set (attr "type")
5582      (if_then_else (match_operand:SWI 2 "incdec_operand")
5583         (const_string "incdec")
5584         (const_string "alu")))
5585    (set (attr "length_immediate")
5586       (if_then_else
5587         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5588         (const_string "1")
5589         (const_string "*")))
5590    (set_attr "mode" "<MODE>")])
5592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5593 (define_insn "*addsi_2_zext"
5594   [(set (reg FLAGS_REG)
5595         (compare
5596           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5597                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5598           (const_int 0)))
5599    (set (match_operand:DI 0 "register_operand" "=r,r")
5600         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5601   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5602    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5604   switch (get_attr_type (insn))
5605     {
5606     case TYPE_INCDEC:
5607       if (operands[2] == const1_rtx)
5608         return "inc{l}\t%k0";
5609       else
5610         {
5611           gcc_assert (operands[2] == constm1_rtx);
5612           return "dec{l}\t%k0";
5613         }
5615     default:
5616       if (which_alternative == 1)
5617         std::swap (operands[1], operands[2]);
5619       if (x86_maybe_negate_const_int (&operands[2], SImode))
5620         return "sub{l}\t{%2, %k0|%k0, %2}";
5622       return "add{l}\t{%2, %k0|%k0, %2}";
5623     }
5625   [(set (attr "type")
5626      (if_then_else (match_operand:SI 2 "incdec_operand")
5627         (const_string "incdec")
5628         (const_string "alu")))
5629    (set (attr "length_immediate")
5630       (if_then_else
5631         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5632         (const_string "1")
5633         (const_string "*")))
5634    (set_attr "mode" "SI")])
5636 (define_insn "*add<mode>_3"
5637   [(set (reg FLAGS_REG)
5638         (compare
5639           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5640           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5641    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5642   "ix86_match_ccmode (insn, CCZmode)
5643    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5645   switch (get_attr_type (insn))
5646     {
5647     case TYPE_INCDEC:
5648       if (operands[2] == const1_rtx)
5649         return "inc{<imodesuffix>}\t%0";
5650       else
5651         {
5652           gcc_assert (operands[2] == constm1_rtx);
5653           return "dec{<imodesuffix>}\t%0";
5654         }
5656     default:
5657       if (which_alternative == 1)
5658         std::swap (operands[1], operands[2]);
5660       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5661       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5662         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5664       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5665     }
5667   [(set (attr "type")
5668      (if_then_else (match_operand:SWI 2 "incdec_operand")
5669         (const_string "incdec")
5670         (const_string "alu")))
5671    (set (attr "length_immediate")
5672       (if_then_else
5673         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5674         (const_string "1")
5675         (const_string "*")))
5676    (set_attr "mode" "<MODE>")])
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680   [(set (reg FLAGS_REG)
5681         (compare
5682           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5683           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5684    (set (match_operand:DI 0 "register_operand" "=r,r")
5685         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5686   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5687    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5689   switch (get_attr_type (insn))
5690     {
5691     case TYPE_INCDEC:
5692       if (operands[2] == const1_rtx)
5693         return "inc{l}\t%k0";
5694       else
5695         {
5696           gcc_assert (operands[2] == constm1_rtx);
5697           return "dec{l}\t%k0";
5698         }
5700     default:
5701       if (which_alternative == 1)
5702         std::swap (operands[1], operands[2]);
5704       if (x86_maybe_negate_const_int (&operands[2], SImode))
5705         return "sub{l}\t{%2, %k0|%k0, %2}";
5707       return "add{l}\t{%2, %k0|%k0, %2}";
5708     }
5710   [(set (attr "type")
5711      (if_then_else (match_operand:SI 2 "incdec_operand")
5712         (const_string "incdec")
5713         (const_string "alu")))
5714    (set (attr "length_immediate")
5715       (if_then_else
5716         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5717         (const_string "1")
5718         (const_string "*")))
5719    (set_attr "mode" "SI")])
5721 ; For comparisons against 1, -1 and 128, we may generate better code
5722 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5723 ; is matched then.  We can't accept general immediate, because for
5724 ; case of overflows,  the result is messed up.
5725 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5726 ; only for comparisons not depending on it.
5728 (define_insn "*adddi_4"
5729   [(set (reg FLAGS_REG)
5730         (compare
5731           (match_operand:DI 1 "nonimmediate_operand" "0")
5732           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5733    (clobber (match_scratch:DI 0 "=rm"))]
5734   "TARGET_64BIT
5735    && ix86_match_ccmode (insn, CCGCmode)"
5737   switch (get_attr_type (insn))
5738     {
5739     case TYPE_INCDEC:
5740       if (operands[2] == constm1_rtx)
5741         return "inc{q}\t%0";
5742       else
5743         {
5744           gcc_assert (operands[2] == const1_rtx);
5745           return "dec{q}\t%0";
5746         }
5748     default:
5749       if (x86_maybe_negate_const_int (&operands[2], DImode))
5750         return "add{q}\t{%2, %0|%0, %2}";
5752       return "sub{q}\t{%2, %0|%0, %2}";
5753     }
5755   [(set (attr "type")
5756      (if_then_else (match_operand:DI 2 "incdec_operand")
5757         (const_string "incdec")
5758         (const_string "alu")))
5759    (set (attr "length_immediate")
5760       (if_then_else
5761         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5762         (const_string "1")
5763         (const_string "*")))
5764    (set_attr "mode" "DI")])
5766 ; For comparisons against 1, -1 and 128, we may generate better code
5767 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5768 ; is matched then.  We can't accept general immediate, because for
5769 ; case of overflows,  the result is messed up.
5770 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5771 ; only for comparisons not depending on it.
5773 (define_insn "*add<mode>_4"
5774   [(set (reg FLAGS_REG)
5775         (compare
5776           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5777           (match_operand:SWI124 2 "const_int_operand" "n")))
5778    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5779   "ix86_match_ccmode (insn, CCGCmode)"
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_INCDEC:
5784       if (operands[2] == constm1_rtx)
5785         return "inc{<imodesuffix>}\t%0";
5786       else
5787         {
5788           gcc_assert (operands[2] == const1_rtx);
5789           return "dec{<imodesuffix>}\t%0";
5790         }
5792     default:
5793       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5794         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5796       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5797     }
5799   [(set (attr "type")
5800      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5801         (const_string "incdec")
5802         (const_string "alu")))
5803    (set (attr "length_immediate")
5804       (if_then_else
5805         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5806         (const_string "1")
5807         (const_string "*")))
5808    (set_attr "mode" "<MODE>")])
5810 (define_insn "*add<mode>_5"
5811   [(set (reg FLAGS_REG)
5812         (compare
5813           (plus:SWI
5814             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5815             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5816           (const_int 0)))
5817    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5818   "ix86_match_ccmode (insn, CCGOCmode)
5819    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5821   switch (get_attr_type (insn))
5822     {
5823     case TYPE_INCDEC:
5824       if (operands[2] == const1_rtx)
5825         return "inc{<imodesuffix>}\t%0";
5826       else
5827         {
5828           gcc_assert (operands[2] == constm1_rtx);
5829           return "dec{<imodesuffix>}\t%0";
5830         }
5832     default:
5833       if (which_alternative == 1)
5834         std::swap (operands[1], operands[2]);
5836       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5838         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5840       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5841     }
5843   [(set (attr "type")
5844      (if_then_else (match_operand:SWI 2 "incdec_operand")
5845         (const_string "incdec")
5846         (const_string "alu")))
5847    (set (attr "length_immediate")
5848       (if_then_else
5849         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5850         (const_string "1")
5851         (const_string "*")))
5852    (set_attr "mode" "<MODE>")])
5854 (define_insn "addqi_ext_1"
5855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5856                          (const_int 8)
5857                          (const_int 8))
5858         (plus:SI
5859           (zero_extract:SI
5860             (match_operand 1 "ext_register_operand" "0,0")
5861             (const_int 8)
5862             (const_int 8))
5863           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5864    (clobber (reg:CC FLAGS_REG))]
5865   ""
5867   switch (get_attr_type (insn))
5868     {
5869     case TYPE_INCDEC:
5870       if (operands[2] == const1_rtx)
5871         return "inc{b}\t%h0";
5872       else
5873         {
5874           gcc_assert (operands[2] == constm1_rtx);
5875           return "dec{b}\t%h0";
5876         }
5878     default:
5879       return "add{b}\t{%2, %h0|%h0, %2}";
5880     }
5882   [(set_attr "isa" "*,nox64")
5883    (set (attr "type")
5884      (if_then_else (match_operand:QI 2 "incdec_operand")
5885         (const_string "incdec")
5886         (const_string "alu")))
5887    (set_attr "modrm" "1")
5888    (set_attr "mode" "QI")])
5890 (define_insn "*addqi_ext_2"
5891   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5892                          (const_int 8)
5893                          (const_int 8))
5894         (plus:SI
5895           (zero_extract:SI
5896             (match_operand 1 "ext_register_operand" "%0")
5897             (const_int 8)
5898             (const_int 8))
5899           (zero_extract:SI
5900             (match_operand 2 "ext_register_operand" "Q")
5901             (const_int 8)
5902             (const_int 8))))
5903    (clobber (reg:CC FLAGS_REG))]
5904   ""
5905   "add{b}\t{%h2, %h0|%h0, %h2}"
5906   [(set_attr "type" "alu")
5907    (set_attr "mode" "QI")])
5909 ;; Add with jump on overflow.
5910 (define_expand "addv<mode>4"
5911   [(parallel [(set (reg:CCO FLAGS_REG)
5912                    (eq:CCO (plus:<DWI>
5913                               (sign_extend:<DWI>
5914                                  (match_operand:SWI 1 "nonimmediate_operand"))
5915                               (match_dup 4))
5916                            (sign_extend:<DWI>
5917                               (plus:SWI (match_dup 1)
5918                                         (match_operand:SWI 2
5919                                            "<general_operand>")))))
5920               (set (match_operand:SWI 0 "register_operand")
5921                    (plus:SWI (match_dup 1) (match_dup 2)))])
5922    (set (pc) (if_then_else
5923                (eq (reg:CCO FLAGS_REG) (const_int 0))
5924                (label_ref (match_operand 3))
5925                (pc)))]
5926   ""
5928   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5929   if (CONST_INT_P (operands[2]))
5930     operands[4] = operands[2];
5931   else
5932     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5935 (define_insn "*addv<mode>4"
5936   [(set (reg:CCO FLAGS_REG)
5937         (eq:CCO (plus:<DWI>
5938                    (sign_extend:<DWI>
5939                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5940                    (sign_extend:<DWI>
5941                       (match_operand:SWI 2 "<general_sext_operand>"
5942                                            "<r>mWe,<r>We")))
5943                 (sign_extend:<DWI>
5944                    (plus:SWI (match_dup 1) (match_dup 2)))))
5945    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5946         (plus:SWI (match_dup 1) (match_dup 2)))]
5947   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5948   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5949   [(set_attr "type" "alu")
5950    (set_attr "mode" "<MODE>")])
5952 (define_insn "*addv<mode>4_1"
5953   [(set (reg:CCO FLAGS_REG)
5954         (eq:CCO (plus:<DWI>
5955                    (sign_extend:<DWI>
5956                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5957                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5958                 (sign_extend:<DWI>
5959                    (plus:SWI (match_dup 1)
5960                              (match_operand:SWI 2 "x86_64_immediate_operand"
5961                                                   "<i>")))))
5962    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5963         (plus:SWI (match_dup 1) (match_dup 2)))]
5964   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5965    && CONST_INT_P (operands[2])
5966    && INTVAL (operands[2]) == INTVAL (operands[3])"
5967   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5968   [(set_attr "type" "alu")
5969    (set_attr "mode" "<MODE>")
5970    (set (attr "length_immediate")
5971         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5972                   (const_string "1")
5973                (match_test "<MODE_SIZE> == 8")
5974                   (const_string "4")]
5975               (const_string "<MODE_SIZE>")))])
5977 ;; The lea patterns for modes less than 32 bits need to be matched by
5978 ;; several insns converted to real lea by splitters.
5980 (define_insn_and_split "*lea_general_1"
5981   [(set (match_operand 0 "register_operand" "=r")
5982         (plus (plus (match_operand 1 "index_register_operand" "l")
5983                     (match_operand 2 "register_operand" "r"))
5984               (match_operand 3 "immediate_operand" "i")))]
5985   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5986    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5987    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5988    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5989    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5990        || GET_MODE (operands[3]) == VOIDmode)"
5991   "#"
5992   "&& reload_completed"
5993   [(const_int 0)]
5995   machine_mode mode = SImode;
5996   rtx pat;
5998   operands[0] = gen_lowpart (mode, operands[0]);
5999   operands[1] = gen_lowpart (mode, operands[1]);
6000   operands[2] = gen_lowpart (mode, operands[2]);
6001   operands[3] = gen_lowpart (mode, operands[3]);
6003   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6004                       operands[3]);
6006   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6007   DONE;
6009   [(set_attr "type" "lea")
6010    (set_attr "mode" "SI")])
6012 (define_insn_and_split "*lea_general_2"
6013   [(set (match_operand 0 "register_operand" "=r")
6014         (plus (mult (match_operand 1 "index_register_operand" "l")
6015                     (match_operand 2 "const248_operand" "n"))
6016               (match_operand 3 "nonmemory_operand" "ri")))]
6017   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6018    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021        || GET_MODE (operands[3]) == VOIDmode)"
6022   "#"
6023   "&& reload_completed"
6024   [(const_int 0)]
6026   machine_mode mode = SImode;
6027   rtx pat;
6029   operands[0] = gen_lowpart (mode, operands[0]);
6030   operands[1] = gen_lowpart (mode, operands[1]);
6031   operands[3] = gen_lowpart (mode, operands[3]);
6033   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6034                       operands[3]);
6036   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6037   DONE;
6039   [(set_attr "type" "lea")
6040    (set_attr "mode" "SI")])
6042 (define_insn_and_split "*lea_general_3"
6043   [(set (match_operand 0 "register_operand" "=r")
6044         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6045                           (match_operand 2 "const248_operand" "n"))
6046                     (match_operand 3 "register_operand" "r"))
6047               (match_operand 4 "immediate_operand" "i")))]
6048   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6049    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6050    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6051    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6052   "#"
6053   "&& reload_completed"
6054   [(const_int 0)]
6056   machine_mode mode = SImode;
6057   rtx pat;
6059   operands[0] = gen_lowpart (mode, operands[0]);
6060   operands[1] = gen_lowpart (mode, operands[1]);
6061   operands[3] = gen_lowpart (mode, operands[3]);
6062   operands[4] = gen_lowpart (mode, operands[4]);
6064   pat = gen_rtx_PLUS (mode,
6065                       gen_rtx_PLUS (mode,
6066                                     gen_rtx_MULT (mode, operands[1],
6067                                                         operands[2]),
6068                                     operands[3]),
6069                       operands[4]);
6071   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6072   DONE;
6074   [(set_attr "type" "lea")
6075    (set_attr "mode" "SI")])
6077 (define_insn_and_split "*lea_general_4"
6078   [(set (match_operand 0 "register_operand" "=r")
6079         (any_or (ashift
6080                   (match_operand 1 "index_register_operand" "l")
6081                   (match_operand 2 "const_int_operand" "n"))
6082                 (match_operand 3 "const_int_operand" "n")))]
6083   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6084       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6085     || GET_MODE (operands[0]) == SImode
6086     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6087    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6088    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6089    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6090        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6091   "#"
6092   "&& reload_completed"
6093   [(const_int 0)]
6095   machine_mode mode = GET_MODE (operands[0]);
6096   rtx pat;
6098   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6099     { 
6100       mode = SImode; 
6101       operands[0] = gen_lowpart (mode, operands[0]);
6102       operands[1] = gen_lowpart (mode, operands[1]);
6103     }
6105   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6107   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6108                        INTVAL (operands[3]));
6110   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6111   DONE;
6113   [(set_attr "type" "lea")
6114    (set (attr "mode")
6115       (if_then_else (match_operand:DI 0)
6116         (const_string "DI")
6117         (const_string "SI")))])
6119 ;; Subtract instructions
6121 (define_expand "sub<mode>3"
6122   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6123         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6124                      (match_operand:SDWIM 2 "<general_operand>")))]
6125   ""
6126   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6128 (define_insn_and_split "*sub<dwi>3_doubleword"
6129   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6130         (minus:<DWI>
6131           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6132           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6133    (clobber (reg:CC FLAGS_REG))]
6134   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6135   "#"
6136   "reload_completed"
6137   [(parallel [(set (reg:CC FLAGS_REG)
6138                    (compare:CC (match_dup 1) (match_dup 2)))
6139               (set (match_dup 0)
6140                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6141    (parallel [(set (match_dup 3)
6142                    (minus:DWIH
6143                      (match_dup 4)
6144                      (plus:DWIH
6145                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6146                        (match_dup 5))))
6147               (clobber (reg:CC FLAGS_REG))])]
6148   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6150 (define_insn "*sub<mode>_1"
6151   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6152         (minus:SWI
6153           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6154           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6155    (clobber (reg:CC FLAGS_REG))]
6156   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6157   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6158   [(set_attr "type" "alu")
6159    (set_attr "mode" "<MODE>")])
6161 (define_insn "*subsi_1_zext"
6162   [(set (match_operand:DI 0 "register_operand" "=r")
6163         (zero_extend:DI
6164           (minus:SI (match_operand:SI 1 "register_operand" "0")
6165                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6166    (clobber (reg:CC FLAGS_REG))]
6167   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6168   "sub{l}\t{%2, %k0|%k0, %2}"
6169   [(set_attr "type" "alu")
6170    (set_attr "mode" "SI")])
6172 (define_insn "*subqi_1_slp"
6173   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6174         (minus:QI (match_dup 0)
6175                   (match_operand:QI 1 "general_operand" "qn,qm")))
6176    (clobber (reg:CC FLAGS_REG))]
6177   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6178    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6179   "sub{b}\t{%1, %0|%0, %1}"
6180   [(set_attr "type" "alu1")
6181    (set_attr "mode" "QI")])
6183 (define_insn "*sub<mode>_2"
6184   [(set (reg FLAGS_REG)
6185         (compare
6186           (minus:SWI
6187             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6188             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6189           (const_int 0)))
6190    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6191         (minus:SWI (match_dup 1) (match_dup 2)))]
6192   "ix86_match_ccmode (insn, CCGOCmode)
6193    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6194   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6195   [(set_attr "type" "alu")
6196    (set_attr "mode" "<MODE>")])
6198 (define_insn "*subsi_2_zext"
6199   [(set (reg FLAGS_REG)
6200         (compare
6201           (minus:SI (match_operand:SI 1 "register_operand" "0")
6202                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6203           (const_int 0)))
6204    (set (match_operand:DI 0 "register_operand" "=r")
6205         (zero_extend:DI
6206           (minus:SI (match_dup 1)
6207                     (match_dup 2))))]
6208   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6209    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6210   "sub{l}\t{%2, %k0|%k0, %2}"
6211   [(set_attr "type" "alu")
6212    (set_attr "mode" "SI")])
6214 ;; Subtract with jump on overflow.
6215 (define_expand "subv<mode>4"
6216   [(parallel [(set (reg:CCO FLAGS_REG)
6217                    (eq:CCO (minus:<DWI>
6218                               (sign_extend:<DWI>
6219                                  (match_operand:SWI 1 "nonimmediate_operand"))
6220                               (match_dup 4))
6221                            (sign_extend:<DWI>
6222                               (minus:SWI (match_dup 1)
6223                                          (match_operand:SWI 2
6224                                             "<general_operand>")))))
6225               (set (match_operand:SWI 0 "register_operand")
6226                    (minus:SWI (match_dup 1) (match_dup 2)))])
6227    (set (pc) (if_then_else
6228                (eq (reg:CCO FLAGS_REG) (const_int 0))
6229                (label_ref (match_operand 3))
6230                (pc)))]
6231   ""
6233   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6234   if (CONST_INT_P (operands[2]))
6235     operands[4] = operands[2];
6236   else
6237     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6240 (define_insn "*subv<mode>4"
6241   [(set (reg:CCO FLAGS_REG)
6242         (eq:CCO (minus:<DWI>
6243                    (sign_extend:<DWI>
6244                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6245                    (sign_extend:<DWI>
6246                       (match_operand:SWI 2 "<general_sext_operand>"
6247                                            "<r>We,<r>m")))
6248                 (sign_extend:<DWI>
6249                    (minus:SWI (match_dup 1) (match_dup 2)))))
6250    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6251         (minus:SWI (match_dup 1) (match_dup 2)))]
6252   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6253   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6254   [(set_attr "type" "alu")
6255    (set_attr "mode" "<MODE>")])
6257 (define_insn "*subv<mode>4_1"
6258   [(set (reg:CCO FLAGS_REG)
6259         (eq:CCO (minus:<DWI>
6260                    (sign_extend:<DWI>
6261                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6262                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6263                 (sign_extend:<DWI>
6264                    (minus:SWI (match_dup 1)
6265                               (match_operand:SWI 2 "x86_64_immediate_operand"
6266                                                    "<i>")))))
6267    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6268         (minus:SWI (match_dup 1) (match_dup 2)))]
6269   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6270    && CONST_INT_P (operands[2])
6271    && INTVAL (operands[2]) == INTVAL (operands[3])"
6272   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6273   [(set_attr "type" "alu")
6274    (set_attr "mode" "<MODE>")
6275    (set (attr "length_immediate")
6276         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6277                   (const_string "1")
6278                (match_test "<MODE_SIZE> == 8")
6279                   (const_string "4")]
6280               (const_string "<MODE_SIZE>")))])
6282 (define_insn "*sub<mode>_3"
6283   [(set (reg FLAGS_REG)
6284         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6285                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6286    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6287         (minus:SWI (match_dup 1) (match_dup 2)))]
6288   "ix86_match_ccmode (insn, CCmode)
6289    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6290   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6291   [(set_attr "type" "alu")
6292    (set_attr "mode" "<MODE>")])
6294 (define_insn "*subsi_3_zext"
6295   [(set (reg FLAGS_REG)
6296         (compare (match_operand:SI 1 "register_operand" "0")
6297                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6298    (set (match_operand:DI 0 "register_operand" "=r")
6299         (zero_extend:DI
6300           (minus:SI (match_dup 1)
6301                     (match_dup 2))))]
6302   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6303    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6304   "sub{l}\t{%2, %1|%1, %2}"
6305   [(set_attr "type" "alu")
6306    (set_attr "mode" "SI")])
6308 ;; Add with carry and subtract with borrow
6310 (define_expand "<plusminus_insn><mode>3_carry"
6311   [(parallel
6312     [(set (match_operand:SWI 0 "nonimmediate_operand")
6313           (plusminus:SWI
6314             (match_operand:SWI 1 "nonimmediate_operand")
6315             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6316                        [(match_operand 3 "flags_reg_operand")
6317                         (const_int 0)])
6318                       (match_operand:SWI 2 "<general_operand>"))))
6319      (clobber (reg:CC FLAGS_REG))])]
6320   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6322 (define_insn "*<plusminus_insn><mode>3_carry"
6323   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6324         (plusminus:SWI
6325           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6326           (plus:SWI
6327             (match_operator 3 "ix86_carry_flag_operator"
6328              [(reg FLAGS_REG) (const_int 0)])
6329             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6330    (clobber (reg:CC FLAGS_REG))]
6331   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6332   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6333   [(set_attr "type" "alu")
6334    (set_attr "use_carry" "1")
6335    (set_attr "pent_pair" "pu")
6336    (set_attr "mode" "<MODE>")])
6338 (define_insn "*addsi3_carry_zext"
6339   [(set (match_operand:DI 0 "register_operand" "=r")
6340         (zero_extend:DI
6341           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6342                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6343                              [(reg FLAGS_REG) (const_int 0)])
6344                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6345    (clobber (reg:CC FLAGS_REG))]
6346   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6347   "adc{l}\t{%2, %k0|%k0, %2}"
6348   [(set_attr "type" "alu")
6349    (set_attr "use_carry" "1")
6350    (set_attr "pent_pair" "pu")
6351    (set_attr "mode" "SI")])
6353 (define_insn "*subsi3_carry_zext"
6354   [(set (match_operand:DI 0 "register_operand" "=r")
6355         (zero_extend:DI
6356           (minus:SI (match_operand:SI 1 "register_operand" "0")
6357                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6358                               [(reg FLAGS_REG) (const_int 0)])
6359                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6360    (clobber (reg:CC FLAGS_REG))]
6361   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6362   "sbb{l}\t{%2, %k0|%k0, %2}"
6363   [(set_attr "type" "alu")
6364    (set_attr "pent_pair" "pu")
6365    (set_attr "mode" "SI")])
6367 ;; ADCX instruction
6369 (define_insn "adcx<mode>3"
6370   [(set (reg:CCC FLAGS_REG)
6371         (compare:CCC
6372           (plus:SWI48
6373             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6374             (plus:SWI48
6375               (match_operator 4 "ix86_carry_flag_operator"
6376                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6377               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6378           (const_int 0)))
6379    (set (match_operand:SWI48 0 "register_operand" "=r")
6380         (plus:SWI48 (match_dup 1)
6381                     (plus:SWI48 (match_op_dup 4
6382                                  [(match_dup 3) (const_int 0)])
6383                                 (match_dup 2))))]
6384   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6385   "adcx\t{%2, %0|%0, %2}"
6386   [(set_attr "type" "alu")
6387    (set_attr "use_carry" "1")
6388    (set_attr "mode" "<MODE>")])
6390 ;; Overflow setting add instructions
6392 (define_insn "*add<mode>3_cconly_overflow"
6393   [(set (reg:CCC FLAGS_REG)
6394         (compare:CCC
6395           (plus:SWI
6396             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6397             (match_operand:SWI 2 "<general_operand>" "<g>"))
6398           (match_dup 1)))
6399    (clobber (match_scratch:SWI 0 "=<r>"))]
6400   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6401   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6402   [(set_attr "type" "alu")
6403    (set_attr "mode" "<MODE>")])
6405 (define_insn "*add<mode>3_cc_overflow"
6406   [(set (reg:CCC FLAGS_REG)
6407         (compare:CCC
6408             (plus:SWI
6409                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6410                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6411             (match_dup 1)))
6412    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6413         (plus:SWI (match_dup 1) (match_dup 2)))]
6414   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6415   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6416   [(set_attr "type" "alu")
6417    (set_attr "mode" "<MODE>")])
6419 (define_insn "*addsi3_zext_cc_overflow"
6420   [(set (reg:CCC FLAGS_REG)
6421         (compare:CCC
6422           (plus:SI
6423             (match_operand:SI 1 "nonimmediate_operand" "%0")
6424             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6425           (match_dup 1)))
6426    (set (match_operand:DI 0 "register_operand" "=r")
6427         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6428   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6429   "add{l}\t{%2, %k0|%k0, %2}"
6430   [(set_attr "type" "alu")
6431    (set_attr "mode" "SI")])
6433 ;; The patterns that match these are at the end of this file.
6435 (define_expand "<plusminus_insn>xf3"
6436   [(set (match_operand:XF 0 "register_operand")
6437         (plusminus:XF
6438           (match_operand:XF 1 "register_operand")
6439           (match_operand:XF 2 "register_operand")))]
6440   "TARGET_80387")
6442 (define_expand "<plusminus_insn><mode>3"
6443   [(set (match_operand:MODEF 0 "register_operand")
6444         (plusminus:MODEF
6445           (match_operand:MODEF 1 "register_operand")
6446           (match_operand:MODEF 2 "nonimmediate_operand")))]
6447   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6448     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6450 ;; Multiply instructions
6452 (define_expand "mul<mode>3"
6453   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6454                    (mult:SWIM248
6455                      (match_operand:SWIM248 1 "register_operand")
6456                      (match_operand:SWIM248 2 "<general_operand>")))
6457               (clobber (reg:CC FLAGS_REG))])])
6459 (define_expand "mulqi3"
6460   [(parallel [(set (match_operand:QI 0 "register_operand")
6461                    (mult:QI
6462                      (match_operand:QI 1 "register_operand")
6463                      (match_operand:QI 2 "nonimmediate_operand")))
6464               (clobber (reg:CC FLAGS_REG))])]
6465   "TARGET_QIMODE_MATH")
6467 ;; On AMDFAM10
6468 ;; IMUL reg32/64, reg32/64, imm8        Direct
6469 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6470 ;; IMUL reg32/64, reg32/64, imm32       Direct
6471 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6472 ;; IMUL reg32/64, reg32/64              Direct
6473 ;; IMUL reg32/64, mem32/64              Direct
6475 ;; On BDVER1, all above IMULs use DirectPath
6477 (define_insn "*mul<mode>3_1"
6478   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6479         (mult:SWI48
6480           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6481           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6482    (clobber (reg:CC FLAGS_REG))]
6483   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6484   "@
6485    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6486    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6487    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6488   [(set_attr "type" "imul")
6489    (set_attr "prefix_0f" "0,0,1")
6490    (set (attr "athlon_decode")
6491         (cond [(eq_attr "cpu" "athlon")
6492                   (const_string "vector")
6493                (eq_attr "alternative" "1")
6494                   (const_string "vector")
6495                (and (eq_attr "alternative" "2")
6496                     (match_operand 1 "memory_operand"))
6497                   (const_string "vector")]
6498               (const_string "direct")))
6499    (set (attr "amdfam10_decode")
6500         (cond [(and (eq_attr "alternative" "0,1")
6501                     (match_operand 1 "memory_operand"))
6502                   (const_string "vector")]
6503               (const_string "direct")))
6504    (set_attr "bdver1_decode" "direct")
6505    (set_attr "mode" "<MODE>")])
6507 (define_insn "*mulsi3_1_zext"
6508   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6509         (zero_extend:DI
6510           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6511                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6512    (clobber (reg:CC FLAGS_REG))]
6513   "TARGET_64BIT
6514    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6515   "@
6516    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6517    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6518    imul{l}\t{%2, %k0|%k0, %2}"
6519   [(set_attr "type" "imul")
6520    (set_attr "prefix_0f" "0,0,1")
6521    (set (attr "athlon_decode")
6522         (cond [(eq_attr "cpu" "athlon")
6523                   (const_string "vector")
6524                (eq_attr "alternative" "1")
6525                   (const_string "vector")
6526                (and (eq_attr "alternative" "2")
6527                     (match_operand 1 "memory_operand"))
6528                   (const_string "vector")]
6529               (const_string "direct")))
6530    (set (attr "amdfam10_decode")
6531         (cond [(and (eq_attr "alternative" "0,1")
6532                     (match_operand 1 "memory_operand"))
6533                   (const_string "vector")]
6534               (const_string "direct")))
6535    (set_attr "bdver1_decode" "direct")
6536    (set_attr "mode" "SI")])
6538 ;; On AMDFAM10
6539 ;; IMUL reg16, reg16, imm8      VectorPath
6540 ;; IMUL reg16, mem16, imm8      VectorPath
6541 ;; IMUL reg16, reg16, imm16     VectorPath
6542 ;; IMUL reg16, mem16, imm16     VectorPath
6543 ;; IMUL reg16, reg16            Direct
6544 ;; IMUL reg16, mem16            Direct
6546 ;; On BDVER1, all HI MULs use DoublePath
6548 (define_insn "*mulhi3_1"
6549   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6550         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6551                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6552    (clobber (reg:CC FLAGS_REG))]
6553   "TARGET_HIMODE_MATH
6554    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6555   "@
6556    imul{w}\t{%2, %1, %0|%0, %1, %2}
6557    imul{w}\t{%2, %1, %0|%0, %1, %2}
6558    imul{w}\t{%2, %0|%0, %2}"
6559   [(set_attr "type" "imul")
6560    (set_attr "prefix_0f" "0,0,1")
6561    (set (attr "athlon_decode")
6562         (cond [(eq_attr "cpu" "athlon")
6563                   (const_string "vector")
6564                (eq_attr "alternative" "1,2")
6565                   (const_string "vector")]
6566               (const_string "direct")))
6567    (set (attr "amdfam10_decode")
6568         (cond [(eq_attr "alternative" "0,1")
6569                   (const_string "vector")]
6570               (const_string "direct")))
6571    (set_attr "bdver1_decode" "double")
6572    (set_attr "mode" "HI")])
6574 ;;On AMDFAM10 and BDVER1
6575 ;; MUL reg8     Direct
6576 ;; MUL mem8     Direct
6578 (define_insn "*mulqi3_1"
6579   [(set (match_operand:QI 0 "register_operand" "=a")
6580         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6581                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6582    (clobber (reg:CC FLAGS_REG))]
6583   "TARGET_QIMODE_MATH
6584    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6585   "mul{b}\t%2"
6586   [(set_attr "type" "imul")
6587    (set_attr "length_immediate" "0")
6588    (set (attr "athlon_decode")
6589      (if_then_else (eq_attr "cpu" "athlon")
6590         (const_string "vector")
6591         (const_string "direct")))
6592    (set_attr "amdfam10_decode" "direct")
6593    (set_attr "bdver1_decode" "direct")
6594    (set_attr "mode" "QI")])
6596 ;; Multiply with jump on overflow.
6597 (define_expand "mulv<mode>4"
6598   [(parallel [(set (reg:CCO FLAGS_REG)
6599                    (eq:CCO (mult:<DWI>
6600                               (sign_extend:<DWI>
6601                                  (match_operand:SWI48 1 "register_operand"))
6602                               (match_dup 4))
6603                            (sign_extend:<DWI>
6604                               (mult:SWI48 (match_dup 1)
6605                                           (match_operand:SWI48 2
6606                                              "<general_operand>")))))
6607               (set (match_operand:SWI48 0 "register_operand")
6608                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6609    (set (pc) (if_then_else
6610                (eq (reg:CCO FLAGS_REG) (const_int 0))
6611                (label_ref (match_operand 3))
6612                (pc)))]
6613   ""
6615   if (CONST_INT_P (operands[2]))
6616     operands[4] = operands[2];
6617   else
6618     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6621 (define_insn "*mulv<mode>4"
6622   [(set (reg:CCO FLAGS_REG)
6623         (eq:CCO (mult:<DWI>
6624                    (sign_extend:<DWI>
6625                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6626                    (sign_extend:<DWI>
6627                       (match_operand:SWI48 2 "<general_sext_operand>"
6628                                              "We,mr")))
6629                 (sign_extend:<DWI>
6630                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6631    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6632         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6633   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6634   "@
6635    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6636    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6637   [(set_attr "type" "imul")
6638    (set_attr "prefix_0f" "0,1")
6639    (set (attr "athlon_decode")
6640         (cond [(eq_attr "cpu" "athlon")
6641                   (const_string "vector")
6642                (eq_attr "alternative" "0")
6643                   (const_string "vector")
6644                (and (eq_attr "alternative" "1")
6645                     (match_operand 1 "memory_operand"))
6646                   (const_string "vector")]
6647               (const_string "direct")))
6648    (set (attr "amdfam10_decode")
6649         (cond [(and (eq_attr "alternative" "1")
6650                     (match_operand 1 "memory_operand"))
6651                   (const_string "vector")]
6652               (const_string "direct")))
6653    (set_attr "bdver1_decode" "direct")
6654    (set_attr "mode" "<MODE>")])
6656 (define_insn "*mulv<mode>4_1"
6657   [(set (reg:CCO FLAGS_REG)
6658         (eq:CCO (mult:<DWI>
6659                    (sign_extend:<DWI>
6660                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6661                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6662                 (sign_extend:<DWI>
6663                    (mult:SWI48 (match_dup 1)
6664                                (match_operand:SWI 2 "x86_64_immediate_operand"
6665                                                     "K,<i>")))))
6666    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6667         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6668   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6669    && CONST_INT_P (operands[2])
6670    && INTVAL (operands[2]) == INTVAL (operands[3])"
6671   "@
6672    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6673    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6674   [(set_attr "type" "imul")
6675    (set (attr "athlon_decode")
6676         (cond [(eq_attr "cpu" "athlon")
6677                   (const_string "vector")
6678                (eq_attr "alternative" "1")
6679                   (const_string "vector")]
6680               (const_string "direct")))
6681    (set (attr "amdfam10_decode")
6682         (cond [(match_operand 1 "memory_operand")
6683                   (const_string "vector")]
6684               (const_string "direct")))
6685    (set_attr "bdver1_decode" "direct")
6686    (set_attr "mode" "<MODE>")
6687    (set (attr "length_immediate")
6688         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6689                   (const_string "1")
6690                (match_test "<MODE_SIZE> == 8")
6691                   (const_string "4")]
6692               (const_string "<MODE_SIZE>")))])
6694 (define_expand "umulv<mode>4"
6695   [(parallel [(set (reg:CCO FLAGS_REG)
6696                    (eq:CCO (mult:<DWI>
6697                               (zero_extend:<DWI>
6698                                  (match_operand:SWI48 1
6699                                                       "nonimmediate_operand"))
6700                               (zero_extend:<DWI>
6701                                  (match_operand:SWI48 2
6702                                                       "nonimmediate_operand")))
6703                            (zero_extend:<DWI>
6704                               (mult:SWI48 (match_dup 1) (match_dup 2)))))
6705               (set (match_operand:SWI48 0 "register_operand")
6706                    (mult:SWI48 (match_dup 1) (match_dup 2)))
6707               (clobber (match_scratch:SWI48 4))])
6708    (set (pc) (if_then_else
6709                (eq (reg:CCO FLAGS_REG) (const_int 0))
6710                (label_ref (match_operand 3))
6711                (pc)))]
6712   ""
6714   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6715     operands[1] = force_reg (<MODE>mode, operands[1]);
6718 (define_insn "*umulv<mode>4"
6719   [(set (reg:CCO FLAGS_REG)
6720         (eq:CCO (mult:<DWI>
6721                    (zero_extend:<DWI>
6722                       (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6723                    (zero_extend:<DWI>
6724                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6725                 (zero_extend:<DWI>
6726                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6727    (set (match_operand:SWI48 0 "register_operand" "=a")
6728         (mult:SWI48 (match_dup 1) (match_dup 2)))
6729    (clobber (match_scratch:SWI48 3 "=d"))]
6730   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6731   "mul{<imodesuffix>}\t%2"
6732   [(set_attr "type" "imul")
6733    (set_attr "length_immediate" "0")
6734    (set (attr "athlon_decode")
6735      (if_then_else (eq_attr "cpu" "athlon")
6736        (const_string "vector")
6737        (const_string "double")))
6738    (set_attr "amdfam10_decode" "double")
6739    (set_attr "bdver1_decode" "direct")
6740    (set_attr "mode" "<MODE>")])
6742 (define_expand "<u>mulvqi4"
6743   [(parallel [(set (reg:CCO FLAGS_REG)
6744                    (eq:CCO (mult:HI
6745                               (any_extend:HI
6746                                  (match_operand:QI 1 "nonimmediate_operand"))
6747                               (any_extend:HI
6748                                  (match_operand:QI 2 "nonimmediate_operand")))
6749                            (any_extend:HI
6750                               (mult:QI (match_dup 1) (match_dup 2)))))
6751               (set (match_operand:QI 0 "register_operand")
6752                    (mult:QI (match_dup 1) (match_dup 2)))])
6753    (set (pc) (if_then_else
6754                (eq (reg:CCO FLAGS_REG) (const_int 0))
6755                (label_ref (match_operand 3))
6756                (pc)))]
6757   "TARGET_QIMODE_MATH"
6759   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6760     operands[1] = force_reg (QImode, operands[1]);
6763 (define_insn "*<u>mulvqi4"
6764   [(set (reg:CCO FLAGS_REG)
6765         (eq:CCO (mult:HI
6766                    (any_extend:HI
6767                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
6768                    (any_extend:HI
6769                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
6770                 (any_extend:HI
6771                    (mult:QI (match_dup 1) (match_dup 2)))))
6772    (set (match_operand:QI 0 "register_operand" "=a")
6773         (mult:QI (match_dup 1) (match_dup 2)))]
6774   "TARGET_QIMODE_MATH
6775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776   "<sgnprefix>mul{b}\t%2"
6777   [(set_attr "type" "imul")
6778    (set_attr "length_immediate" "0")
6779    (set (attr "athlon_decode")
6780      (if_then_else (eq_attr "cpu" "athlon")
6781         (const_string "vector")
6782         (const_string "direct")))
6783    (set_attr "amdfam10_decode" "direct")
6784    (set_attr "bdver1_decode" "direct")
6785    (set_attr "mode" "QI")])
6787 (define_expand "<u>mul<mode><dwi>3"
6788   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6789                    (mult:<DWI>
6790                      (any_extend:<DWI>
6791                        (match_operand:DWIH 1 "nonimmediate_operand"))
6792                      (any_extend:<DWI>
6793                        (match_operand:DWIH 2 "register_operand"))))
6794               (clobber (reg:CC FLAGS_REG))])])
6796 (define_expand "<u>mulqihi3"
6797   [(parallel [(set (match_operand:HI 0 "register_operand")
6798                    (mult:HI
6799                      (any_extend:HI
6800                        (match_operand:QI 1 "nonimmediate_operand"))
6801                      (any_extend:HI
6802                        (match_operand:QI 2 "register_operand"))))
6803               (clobber (reg:CC FLAGS_REG))])]
6804   "TARGET_QIMODE_MATH")
6806 (define_insn "*bmi2_umul<mode><dwi>3_1"
6807   [(set (match_operand:DWIH 0 "register_operand" "=r")
6808         (mult:DWIH
6809           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6810           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6811    (set (match_operand:DWIH 1 "register_operand" "=r")
6812         (truncate:DWIH
6813           (lshiftrt:<DWI>
6814             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6815                         (zero_extend:<DWI> (match_dup 3)))
6816             (match_operand:QI 4 "const_int_operand" "n"))))]
6817   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6818    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6819   "mulx\t{%3, %0, %1|%1, %0, %3}"
6820   [(set_attr "type" "imulx")
6821    (set_attr "prefix" "vex")
6822    (set_attr "mode" "<MODE>")])
6824 (define_insn "*umul<mode><dwi>3_1"
6825   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6826         (mult:<DWI>
6827           (zero_extend:<DWI>
6828             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6829           (zero_extend:<DWI>
6830             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6831    (clobber (reg:CC FLAGS_REG))]
6832   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6833   "@
6834    #
6835    mul{<imodesuffix>}\t%2"
6836   [(set_attr "isa" "bmi2,*")
6837    (set_attr "type" "imulx,imul")
6838    (set_attr "length_immediate" "*,0")
6839    (set (attr "athlon_decode")
6840         (cond [(eq_attr "alternative" "1")
6841                  (if_then_else (eq_attr "cpu" "athlon")
6842                    (const_string "vector")
6843                    (const_string "double"))]
6844               (const_string "*")))
6845    (set_attr "amdfam10_decode" "*,double")
6846    (set_attr "bdver1_decode" "*,direct")
6847    (set_attr "prefix" "vex,orig")
6848    (set_attr "mode" "<MODE>")])
6850 ;; Convert mul to the mulx pattern to avoid flags dependency.
6851 (define_split
6852  [(set (match_operand:<DWI> 0 "register_operand")
6853        (mult:<DWI>
6854          (zero_extend:<DWI>
6855            (match_operand:DWIH 1 "register_operand"))
6856          (zero_extend:<DWI>
6857            (match_operand:DWIH 2 "nonimmediate_operand"))))
6858   (clobber (reg:CC FLAGS_REG))]
6859  "TARGET_BMI2 && reload_completed
6860   && true_regnum (operands[1]) == DX_REG"
6861   [(parallel [(set (match_dup 3)
6862                    (mult:DWIH (match_dup 1) (match_dup 2)))
6863               (set (match_dup 4)
6864                    (truncate:DWIH
6865                      (lshiftrt:<DWI>
6866                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6867                                    (zero_extend:<DWI> (match_dup 2)))
6868                        (match_dup 5))))])]
6870   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6872   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6875 (define_insn "*mul<mode><dwi>3_1"
6876   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6877         (mult:<DWI>
6878           (sign_extend:<DWI>
6879             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6880           (sign_extend:<DWI>
6881             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6882    (clobber (reg:CC FLAGS_REG))]
6883   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6884   "imul{<imodesuffix>}\t%2"
6885   [(set_attr "type" "imul")
6886    (set_attr "length_immediate" "0")
6887    (set (attr "athlon_decode")
6888      (if_then_else (eq_attr "cpu" "athlon")
6889         (const_string "vector")
6890         (const_string "double")))
6891    (set_attr "amdfam10_decode" "double")
6892    (set_attr "bdver1_decode" "direct")
6893    (set_attr "mode" "<MODE>")])
6895 (define_insn "*<u>mulqihi3_1"
6896   [(set (match_operand:HI 0 "register_operand" "=a")
6897         (mult:HI
6898           (any_extend:HI
6899             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6900           (any_extend:HI
6901             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6902    (clobber (reg:CC FLAGS_REG))]
6903   "TARGET_QIMODE_MATH
6904    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6905   "<sgnprefix>mul{b}\t%2"
6906   [(set_attr "type" "imul")
6907    (set_attr "length_immediate" "0")
6908    (set (attr "athlon_decode")
6909      (if_then_else (eq_attr "cpu" "athlon")
6910         (const_string "vector")
6911         (const_string "direct")))
6912    (set_attr "amdfam10_decode" "direct")
6913    (set_attr "bdver1_decode" "direct")
6914    (set_attr "mode" "QI")])
6916 (define_expand "<s>mul<mode>3_highpart"
6917   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6918                    (truncate:SWI48
6919                      (lshiftrt:<DWI>
6920                        (mult:<DWI>
6921                          (any_extend:<DWI>
6922                            (match_operand:SWI48 1 "nonimmediate_operand"))
6923                          (any_extend:<DWI>
6924                            (match_operand:SWI48 2 "register_operand")))
6925                        (match_dup 4))))
6926               (clobber (match_scratch:SWI48 3))
6927               (clobber (reg:CC FLAGS_REG))])]
6928   ""
6929   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6931 (define_insn "*<s>muldi3_highpart_1"
6932   [(set (match_operand:DI 0 "register_operand" "=d")
6933         (truncate:DI
6934           (lshiftrt:TI
6935             (mult:TI
6936               (any_extend:TI
6937                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6938               (any_extend:TI
6939                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6940             (const_int 64))))
6941    (clobber (match_scratch:DI 3 "=1"))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "TARGET_64BIT
6944    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945   "<sgnprefix>mul{q}\t%2"
6946   [(set_attr "type" "imul")
6947    (set_attr "length_immediate" "0")
6948    (set (attr "athlon_decode")
6949      (if_then_else (eq_attr "cpu" "athlon")
6950         (const_string "vector")
6951         (const_string "double")))
6952    (set_attr "amdfam10_decode" "double")
6953    (set_attr "bdver1_decode" "direct")
6954    (set_attr "mode" "DI")])
6956 (define_insn "*<s>mulsi3_highpart_1"
6957   [(set (match_operand:SI 0 "register_operand" "=d")
6958         (truncate:SI
6959           (lshiftrt:DI
6960             (mult:DI
6961               (any_extend:DI
6962                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6963               (any_extend:DI
6964                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6965             (const_int 32))))
6966    (clobber (match_scratch:SI 3 "=1"))
6967    (clobber (reg:CC FLAGS_REG))]
6968   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6969   "<sgnprefix>mul{l}\t%2"
6970   [(set_attr "type" "imul")
6971    (set_attr "length_immediate" "0")
6972    (set (attr "athlon_decode")
6973      (if_then_else (eq_attr "cpu" "athlon")
6974         (const_string "vector")
6975         (const_string "double")))
6976    (set_attr "amdfam10_decode" "double")
6977    (set_attr "bdver1_decode" "direct")
6978    (set_attr "mode" "SI")])
6980 (define_insn "*<s>mulsi3_highpart_zext"
6981   [(set (match_operand:DI 0 "register_operand" "=d")
6982         (zero_extend:DI (truncate:SI
6983           (lshiftrt:DI
6984             (mult:DI (any_extend:DI
6985                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6986                      (any_extend:DI
6987                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6988             (const_int 32)))))
6989    (clobber (match_scratch:SI 3 "=1"))
6990    (clobber (reg:CC FLAGS_REG))]
6991   "TARGET_64BIT
6992    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6993   "<sgnprefix>mul{l}\t%2"
6994   [(set_attr "type" "imul")
6995    (set_attr "length_immediate" "0")
6996    (set (attr "athlon_decode")
6997      (if_then_else (eq_attr "cpu" "athlon")
6998         (const_string "vector")
6999         (const_string "double")))
7000    (set_attr "amdfam10_decode" "double")
7001    (set_attr "bdver1_decode" "direct")
7002    (set_attr "mode" "SI")])
7004 ;; The patterns that match these are at the end of this file.
7006 (define_expand "mulxf3"
7007   [(set (match_operand:XF 0 "register_operand")
7008         (mult:XF (match_operand:XF 1 "register_operand")
7009                  (match_operand:XF 2 "register_operand")))]
7010   "TARGET_80387")
7012 (define_expand "mul<mode>3"
7013   [(set (match_operand:MODEF 0 "register_operand")
7014         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7015                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7016   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7017     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7019 ;; Divide instructions
7021 ;; The patterns that match these are at the end of this file.
7023 (define_expand "divxf3"
7024   [(set (match_operand:XF 0 "register_operand")
7025         (div:XF (match_operand:XF 1 "register_operand")
7026                 (match_operand:XF 2 "register_operand")))]
7027   "TARGET_80387")
7029 (define_expand "divdf3"
7030   [(set (match_operand:DF 0 "register_operand")
7031         (div:DF (match_operand:DF 1 "register_operand")
7032                 (match_operand:DF 2 "nonimmediate_operand")))]
7033    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7034     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7036 (define_expand "divsf3"
7037   [(set (match_operand:SF 0 "register_operand")
7038         (div:SF (match_operand:SF 1 "register_operand")
7039                 (match_operand:SF 2 "nonimmediate_operand")))]
7040   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7041     || TARGET_SSE_MATH"
7043   if (TARGET_SSE_MATH
7044       && TARGET_RECIP_DIV
7045       && optimize_insn_for_speed_p ()
7046       && flag_finite_math_only && !flag_trapping_math
7047       && flag_unsafe_math_optimizations)
7048     {
7049       ix86_emit_swdivsf (operands[0], operands[1],
7050                          operands[2], SFmode);
7051       DONE;
7052     }
7055 ;; Divmod instructions.
7057 (define_expand "divmod<mode>4"
7058   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7059                    (div:SWIM248
7060                      (match_operand:SWIM248 1 "register_operand")
7061                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7062               (set (match_operand:SWIM248 3 "register_operand")
7063                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7064               (clobber (reg:CC FLAGS_REG))])])
7066 ;; Split with 8bit unsigned divide:
7067 ;;      if (dividend an divisor are in [0-255])
7068 ;;         use 8bit unsigned integer divide
7069 ;;       else
7070 ;;         use original integer divide
7071 (define_split
7072   [(set (match_operand:SWI48 0 "register_operand")
7073         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7074                     (match_operand:SWI48 3 "nonimmediate_operand")))
7075    (set (match_operand:SWI48 1 "register_operand")
7076         (mod:SWI48 (match_dup 2) (match_dup 3)))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "TARGET_USE_8BIT_IDIV
7079    && TARGET_QIMODE_MATH
7080    && can_create_pseudo_p ()
7081    && !optimize_insn_for_size_p ()"
7082   [(const_int 0)]
7083   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7085 (define_insn_and_split "divmod<mode>4_1"
7086   [(set (match_operand:SWI48 0 "register_operand" "=a")
7087         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7088                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7089    (set (match_operand:SWI48 1 "register_operand" "=&d")
7090         (mod:SWI48 (match_dup 2) (match_dup 3)))
7091    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7092    (clobber (reg:CC FLAGS_REG))]
7093   ""
7094   "#"
7095   "reload_completed"
7096   [(parallel [(set (match_dup 1)
7097                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7098               (clobber (reg:CC FLAGS_REG))])
7099    (parallel [(set (match_dup 0)
7100                    (div:SWI48 (match_dup 2) (match_dup 3)))
7101               (set (match_dup 1)
7102                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7103               (use (match_dup 1))
7104               (clobber (reg:CC FLAGS_REG))])]
7106   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7108   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7109     operands[4] = operands[2];
7110   else
7111     {
7112       /* Avoid use of cltd in favor of a mov+shift.  */
7113       emit_move_insn (operands[1], operands[2]);
7114       operands[4] = operands[1];
7115     }
7117   [(set_attr "type" "multi")
7118    (set_attr "mode" "<MODE>")])
7120 (define_insn_and_split "*divmod<mode>4"
7121   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7122         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7123                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7124    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7125         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7126    (clobber (reg:CC FLAGS_REG))]
7127   ""
7128   "#"
7129   "reload_completed"
7130   [(parallel [(set (match_dup 1)
7131                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7132               (clobber (reg:CC FLAGS_REG))])
7133    (parallel [(set (match_dup 0)
7134                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7135               (set (match_dup 1)
7136                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7137               (use (match_dup 1))
7138               (clobber (reg:CC FLAGS_REG))])]
7140   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7142   if (<MODE>mode != HImode
7143       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7144     operands[4] = operands[2];
7145   else
7146     {
7147       /* Avoid use of cltd in favor of a mov+shift.  */
7148       emit_move_insn (operands[1], operands[2]);
7149       operands[4] = operands[1];
7150     }
7152   [(set_attr "type" "multi")
7153    (set_attr "mode" "<MODE>")])
7155 (define_insn "*divmod<mode>4_noext"
7156   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7157         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7158                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7159    (set (match_operand:SWIM248 1 "register_operand" "=d")
7160         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7161    (use (match_operand:SWIM248 4 "register_operand" "1"))
7162    (clobber (reg:CC FLAGS_REG))]
7163   ""
7164   "idiv{<imodesuffix>}\t%3"
7165   [(set_attr "type" "idiv")
7166    (set_attr "mode" "<MODE>")])
7168 (define_expand "divmodqi4"
7169   [(parallel [(set (match_operand:QI 0 "register_operand")
7170                    (div:QI
7171                      (match_operand:QI 1 "register_operand")
7172                      (match_operand:QI 2 "nonimmediate_operand")))
7173               (set (match_operand:QI 3 "register_operand")
7174                    (mod:QI (match_dup 1) (match_dup 2)))
7175               (clobber (reg:CC FLAGS_REG))])]
7176   "TARGET_QIMODE_MATH"
7178   rtx div, mod, insn;
7179   rtx tmp0, tmp1;
7180   
7181   tmp0 = gen_reg_rtx (HImode);
7182   tmp1 = gen_reg_rtx (HImode);
7184   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7185      in AX.  */
7186   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7187   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7189   /* Extract remainder from AH.  */
7190   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7191   insn = emit_move_insn (operands[3], tmp1);
7193   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7194   set_unique_reg_note (insn, REG_EQUAL, mod);
7196   /* Extract quotient from AL.  */
7197   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7199   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7200   set_unique_reg_note (insn, REG_EQUAL, div);
7202   DONE;
7205 ;; Divide AX by r/m8, with result stored in
7206 ;; AL <- Quotient
7207 ;; AH <- Remainder
7208 ;; Change div/mod to HImode and extend the second argument to HImode
7209 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7210 ;; combine may fail.
7211 (define_insn "divmodhiqi3"
7212   [(set (match_operand:HI 0 "register_operand" "=a")
7213         (ior:HI
7214           (ashift:HI
7215             (zero_extend:HI
7216               (truncate:QI
7217                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7218                         (sign_extend:HI
7219                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7220             (const_int 8))
7221           (zero_extend:HI
7222             (truncate:QI
7223               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7224    (clobber (reg:CC FLAGS_REG))]
7225   "TARGET_QIMODE_MATH"
7226   "idiv{b}\t%2"
7227   [(set_attr "type" "idiv")
7228    (set_attr "mode" "QI")])
7230 (define_expand "udivmod<mode>4"
7231   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7232                    (udiv:SWIM248
7233                      (match_operand:SWIM248 1 "register_operand")
7234                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7235               (set (match_operand:SWIM248 3 "register_operand")
7236                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7237               (clobber (reg:CC FLAGS_REG))])])
7239 ;; Split with 8bit unsigned divide:
7240 ;;      if (dividend an divisor are in [0-255])
7241 ;;         use 8bit unsigned integer divide
7242 ;;       else
7243 ;;         use original integer divide
7244 (define_split
7245   [(set (match_operand:SWI48 0 "register_operand")
7246         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7247                     (match_operand:SWI48 3 "nonimmediate_operand")))
7248    (set (match_operand:SWI48 1 "register_operand")
7249         (umod:SWI48 (match_dup 2) (match_dup 3)))
7250    (clobber (reg:CC FLAGS_REG))]
7251   "TARGET_USE_8BIT_IDIV
7252    && TARGET_QIMODE_MATH
7253    && can_create_pseudo_p ()
7254    && !optimize_insn_for_size_p ()"
7255   [(const_int 0)]
7256   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7258 (define_insn_and_split "udivmod<mode>4_1"
7259   [(set (match_operand:SWI48 0 "register_operand" "=a")
7260         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7261                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7262    (set (match_operand:SWI48 1 "register_operand" "=&d")
7263         (umod:SWI48 (match_dup 2) (match_dup 3)))
7264    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7265    (clobber (reg:CC FLAGS_REG))]
7266   ""
7267   "#"
7268   "reload_completed"
7269   [(set (match_dup 1) (const_int 0))
7270    (parallel [(set (match_dup 0)
7271                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7272               (set (match_dup 1)
7273                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7274               (use (match_dup 1))
7275               (clobber (reg:CC FLAGS_REG))])]
7276   ""
7277   [(set_attr "type" "multi")
7278    (set_attr "mode" "<MODE>")])
7280 (define_insn_and_split "*udivmod<mode>4"
7281   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7282         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7283                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7284    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7285         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7286    (clobber (reg:CC FLAGS_REG))]
7287   ""
7288   "#"
7289   "reload_completed"
7290   [(set (match_dup 1) (const_int 0))
7291    (parallel [(set (match_dup 0)
7292                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7293               (set (match_dup 1)
7294                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7295               (use (match_dup 1))
7296               (clobber (reg:CC FLAGS_REG))])]
7297   ""
7298   [(set_attr "type" "multi")
7299    (set_attr "mode" "<MODE>")])
7301 ;; Optimize division or modulo by constant power of 2, if the constant
7302 ;; materializes only after expansion.
7303 (define_insn_and_split "*udivmod<mode>4_pow2"
7304   [(set (match_operand:SWI48 0 "register_operand" "=r")
7305         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7306                     (match_operand:SWI48 3 "const_int_operand" "n")))
7307    (set (match_operand:SWI48 1 "register_operand" "=r")
7308         (umod:SWI48 (match_dup 2) (match_dup 3)))
7309    (clobber (reg:CC FLAGS_REG))]
7310   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7311    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7312   "#"
7313   "&& 1"
7314   [(set (match_dup 1) (match_dup 2))
7315    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7316               (clobber (reg:CC FLAGS_REG))])
7317    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7318               (clobber (reg:CC FLAGS_REG))])]
7320   int v = exact_log2 (UINTVAL (operands[3]));
7321   operands[4] = GEN_INT (v);
7322   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7324   [(set_attr "type" "multi")
7325    (set_attr "mode" "<MODE>")])
7327 (define_insn "*udivmod<mode>4_noext"
7328   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7329         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7330                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7331    (set (match_operand:SWIM248 1 "register_operand" "=d")
7332         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7333    (use (match_operand:SWIM248 4 "register_operand" "1"))
7334    (clobber (reg:CC FLAGS_REG))]
7335   ""
7336   "div{<imodesuffix>}\t%3"
7337   [(set_attr "type" "idiv")
7338    (set_attr "mode" "<MODE>")])
7340 (define_expand "udivmodqi4"
7341   [(parallel [(set (match_operand:QI 0 "register_operand")
7342                    (udiv:QI
7343                      (match_operand:QI 1 "register_operand")
7344                      (match_operand:QI 2 "nonimmediate_operand")))
7345               (set (match_operand:QI 3 "register_operand")
7346                    (umod:QI (match_dup 1) (match_dup 2)))
7347               (clobber (reg:CC FLAGS_REG))])]
7348   "TARGET_QIMODE_MATH"
7350   rtx div, mod, insn;
7351   rtx tmp0, tmp1;
7352   
7353   tmp0 = gen_reg_rtx (HImode);
7354   tmp1 = gen_reg_rtx (HImode);
7356   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7357      in AX.  */
7358   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7359   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7361   /* Extract remainder from AH.  */
7362   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7363   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7364   insn = emit_move_insn (operands[3], tmp1);
7366   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7367   set_unique_reg_note (insn, REG_EQUAL, mod);
7369   /* Extract quotient from AL.  */
7370   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7372   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7373   set_unique_reg_note (insn, REG_EQUAL, div);
7375   DONE;
7378 (define_insn "udivmodhiqi3"
7379   [(set (match_operand:HI 0 "register_operand" "=a")
7380         (ior:HI
7381           (ashift:HI
7382             (zero_extend:HI
7383               (truncate:QI
7384                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7385                         (zero_extend:HI
7386                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7387             (const_int 8))
7388           (zero_extend:HI
7389             (truncate:QI
7390               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "TARGET_QIMODE_MATH"
7393   "div{b}\t%2"
7394   [(set_attr "type" "idiv")
7395    (set_attr "mode" "QI")])
7397 ;; We cannot use div/idiv for double division, because it causes
7398 ;; "division by zero" on the overflow and that's not what we expect
7399 ;; from truncate.  Because true (non truncating) double division is
7400 ;; never generated, we can't create this insn anyway.
7402 ;(define_insn ""
7403 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7404 ;       (truncate:SI
7405 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7406 ;                  (zero_extend:DI
7407 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7408 ;   (set (match_operand:SI 3 "register_operand" "=d")
7409 ;       (truncate:SI
7410 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7411 ;   (clobber (reg:CC FLAGS_REG))]
7412 ;  ""
7413 ;  "div{l}\t{%2, %0|%0, %2}"
7414 ;  [(set_attr "type" "idiv")])
7416 ;;- Logical AND instructions
7418 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7419 ;; Note that this excludes ah.
7421 (define_expand "testsi_ccno_1"
7422   [(set (reg:CCNO FLAGS_REG)
7423         (compare:CCNO
7424           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7425                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7426           (const_int 0)))])
7428 (define_expand "testqi_ccz_1"
7429   [(set (reg:CCZ FLAGS_REG)
7430         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7431                              (match_operand:QI 1 "nonmemory_operand"))
7432                  (const_int 0)))])
7434 (define_expand "testdi_ccno_1"
7435   [(set (reg:CCNO FLAGS_REG)
7436         (compare:CCNO
7437           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7438                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7439           (const_int 0)))]
7440   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7442 (define_insn "*testdi_1"
7443   [(set (reg FLAGS_REG)
7444         (compare
7445          (and:DI
7446           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7447           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7448          (const_int 0)))]
7449   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7450    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7451   "@
7452    test{l}\t{%k1, %k0|%k0, %k1}
7453    test{l}\t{%k1, %k0|%k0, %k1}
7454    test{q}\t{%1, %0|%0, %1}
7455    test{q}\t{%1, %0|%0, %1}
7456    test{q}\t{%1, %0|%0, %1}"
7457   [(set_attr "type" "test")
7458    (set_attr "modrm" "0,1,0,1,1")
7459    (set_attr "mode" "SI,SI,DI,DI,DI")])
7461 (define_insn "*testqi_1_maybe_si"
7462   [(set (reg FLAGS_REG)
7463         (compare
7464           (and:QI
7465             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7466             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7467           (const_int 0)))]
7468    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7469     && ix86_match_ccmode (insn,
7470                          CONST_INT_P (operands[1])
7471                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7473   if (which_alternative == 3)
7474     {
7475       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7476         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7477       return "test{l}\t{%1, %k0|%k0, %1}";
7478     }
7479   return "test{b}\t{%1, %0|%0, %1}";
7481   [(set_attr "type" "test")
7482    (set_attr "modrm" "0,1,1,1")
7483    (set_attr "mode" "QI,QI,QI,SI")
7484    (set_attr "pent_pair" "uv,np,uv,np")])
7486 (define_insn "*test<mode>_1"
7487   [(set (reg FLAGS_REG)
7488         (compare
7489          (and:SWI124
7490           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7491           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7492          (const_int 0)))]
7493   "ix86_match_ccmode (insn, CCNOmode)
7494    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7495   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7496   [(set_attr "type" "test")
7497    (set_attr "modrm" "0,1,1")
7498    (set_attr "mode" "<MODE>")
7499    (set_attr "pent_pair" "uv,np,uv")])
7501 (define_expand "testqi_ext_ccno_0"
7502   [(set (reg:CCNO FLAGS_REG)
7503         (compare:CCNO
7504           (and:SI
7505             (zero_extract:SI
7506               (match_operand 0 "ext_register_operand")
7507               (const_int 8)
7508               (const_int 8))
7509             (match_operand 1 "const_int_operand"))
7510           (const_int 0)))])
7512 (define_insn "*testqi_ext_0"
7513   [(set (reg FLAGS_REG)
7514         (compare
7515           (and:SI
7516             (zero_extract:SI
7517               (match_operand 0 "ext_register_operand" "Q")
7518               (const_int 8)
7519               (const_int 8))
7520             (match_operand 1 "const_int_operand" "n"))
7521           (const_int 0)))]
7522   "ix86_match_ccmode (insn, CCNOmode)"
7523   "test{b}\t{%1, %h0|%h0, %1}"
7524   [(set_attr "type" "test")
7525    (set_attr "mode" "QI")
7526    (set_attr "length_immediate" "1")
7527    (set_attr "modrm" "1")
7528    (set_attr "pent_pair" "np")])
7530 (define_insn "*testqi_ext_1"
7531   [(set (reg FLAGS_REG)
7532         (compare
7533           (and:SI
7534             (zero_extract:SI
7535               (match_operand 0 "ext_register_operand" "Q,Q")
7536               (const_int 8)
7537               (const_int 8))
7538             (zero_extend:SI
7539               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7540           (const_int 0)))]
7541   "ix86_match_ccmode (insn, CCNOmode)"
7542   "test{b}\t{%1, %h0|%h0, %1}"
7543   [(set_attr "isa" "*,nox64")
7544    (set_attr "type" "test")
7545    (set_attr "mode" "QI")])
7547 (define_insn "*testqi_ext_2"
7548   [(set (reg FLAGS_REG)
7549         (compare
7550           (and:SI
7551             (zero_extract:SI
7552               (match_operand 0 "ext_register_operand" "Q")
7553               (const_int 8)
7554               (const_int 8))
7555             (zero_extract:SI
7556               (match_operand 1 "ext_register_operand" "Q")
7557               (const_int 8)
7558               (const_int 8)))
7559           (const_int 0)))]
7560   "ix86_match_ccmode (insn, CCNOmode)"
7561   "test{b}\t{%h1, %h0|%h0, %h1}"
7562   [(set_attr "type" "test")
7563    (set_attr "mode" "QI")])
7565 ;; Combine likes to form bit extractions for some tests.  Humor it.
7566 (define_insn "*testqi_ext_3"
7567   [(set (reg FLAGS_REG)
7568         (compare (zero_extract:SWI48
7569                    (match_operand 0 "nonimmediate_operand" "rm")
7570                    (match_operand:SWI48 1 "const_int_operand")
7571                    (match_operand:SWI48 2 "const_int_operand"))
7572                  (const_int 0)))]
7573   "ix86_match_ccmode (insn, CCNOmode)
7574    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7575        || GET_MODE (operands[0]) == SImode
7576        || GET_MODE (operands[0]) == HImode
7577        || GET_MODE (operands[0]) == QImode)
7578    /* Ensure that resulting mask is zero or sign extended operand.  */
7579    && INTVAL (operands[2]) >= 0
7580    && ((INTVAL (operands[1]) > 0
7581         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7582        || (<MODE>mode == DImode
7583            && INTVAL (operands[1]) > 32
7584            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7585   "#")
7587 (define_split
7588   [(set (match_operand 0 "flags_reg_operand")
7589         (match_operator 1 "compare_operator"
7590           [(zero_extract
7591              (match_operand 2 "nonimmediate_operand")
7592              (match_operand 3 "const_int_operand")
7593              (match_operand 4 "const_int_operand"))
7594            (const_int 0)]))]
7595   "ix86_match_ccmode (insn, CCNOmode)"
7596   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7598   rtx val = operands[2];
7599   HOST_WIDE_INT len = INTVAL (operands[3]);
7600   HOST_WIDE_INT pos = INTVAL (operands[4]);
7601   HOST_WIDE_INT mask;
7602   machine_mode mode, submode;
7604   mode = GET_MODE (val);
7605   if (MEM_P (val))
7606     {
7607       /* ??? Combine likes to put non-volatile mem extractions in QImode
7608          no matter the size of the test.  So find a mode that works.  */
7609       if (! MEM_VOLATILE_P (val))
7610         {
7611           mode = smallest_mode_for_size (pos + len, MODE_INT);
7612           val = adjust_address (val, mode, 0);
7613         }
7614     }
7615   else if (GET_CODE (val) == SUBREG
7616            && (submode = GET_MODE (SUBREG_REG (val)),
7617                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7618            && pos + len <= GET_MODE_BITSIZE (submode)
7619            && GET_MODE_CLASS (submode) == MODE_INT)
7620     {
7621       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7622       mode = submode;
7623       val = SUBREG_REG (val);
7624     }
7625   else if (mode == HImode && pos + len <= 8)
7626     {
7627       /* Small HImode tests can be converted to QImode.  */
7628       mode = QImode;
7629       val = gen_lowpart (QImode, val);
7630     }
7632   if (len == HOST_BITS_PER_WIDE_INT)
7633     mask = -1;
7634   else
7635     mask = ((HOST_WIDE_INT)1 << len) - 1;
7636   mask <<= pos;
7638   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7641 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7642 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7643 ;; this is relatively important trick.
7644 ;; Do the conversion only post-reload to avoid limiting of the register class
7645 ;; to QI regs.
7646 (define_split
7647   [(set (match_operand 0 "flags_reg_operand")
7648         (match_operator 1 "compare_operator"
7649           [(and (match_operand 2 "QIreg_operand")
7650                 (match_operand 3 "const_int_operand"))
7651            (const_int 0)]))]
7652    "reload_completed
7653     && GET_MODE (operands[2]) != QImode
7654     && ((ix86_match_ccmode (insn, CCZmode)
7655          && !(INTVAL (operands[3]) & ~(255 << 8)))
7656         || (ix86_match_ccmode (insn, CCNOmode)
7657             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7658   [(set (match_dup 0)
7659         (match_op_dup 1
7660           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7661                    (match_dup 3))
7662            (const_int 0)]))]
7664   operands[2] = gen_lowpart (SImode, operands[2]);
7665   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7668 (define_split
7669   [(set (match_operand 0 "flags_reg_operand")
7670         (match_operator 1 "compare_operator"
7671           [(and (match_operand 2 "nonimmediate_operand")
7672                 (match_operand 3 "const_int_operand"))
7673            (const_int 0)]))]
7674    "reload_completed
7675     && GET_MODE (operands[2]) != QImode
7676     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7677     && ((ix86_match_ccmode (insn, CCZmode)
7678          && !(INTVAL (operands[3]) & ~255))
7679         || (ix86_match_ccmode (insn, CCNOmode)
7680             && !(INTVAL (operands[3]) & ~127)))"
7681   [(set (match_dup 0)
7682         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7683                          (const_int 0)]))]
7685   operands[2] = gen_lowpart (QImode, operands[2]);
7686   operands[3] = gen_lowpart (QImode, operands[3]);
7689 (define_split
7690   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7691         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7692                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7693    (clobber (reg:CC FLAGS_REG))]
7694   "TARGET_AVX512F && reload_completed"
7695   [(set (match_dup 0)
7696         (any_logic:SWI1248x (match_dup 1)
7697                             (match_dup 2)))])
7699 (define_insn "*k<logic><mode>"
7700   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7701         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7702                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7703   "TARGET_AVX512F"
7704   {
7705     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7706       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7707     else
7708       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7709   }
7710   [(set_attr "mode" "<MODE>")
7711    (set_attr "type" "msklog")
7712    (set_attr "prefix" "vex")])
7714 ;; %%% This used to optimize known byte-wide and operations to memory,
7715 ;; and sometimes to QImode registers.  If this is considered useful,
7716 ;; it should be done with splitters.
7718 (define_expand "and<mode>3"
7719   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7720         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7721                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7722   ""
7724   machine_mode mode = <MODE>mode;
7725   rtx (*insn) (rtx, rtx);
7727   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7728     {
7729       HOST_WIDE_INT ival = INTVAL (operands[2]);
7731       if (ival == (HOST_WIDE_INT) 0xffffffff)
7732         mode = SImode;
7733       else if (ival == 0xffff)
7734         mode = HImode;
7735       else if (ival == 0xff)
7736         mode = QImode;
7737       }
7739   if (mode == <MODE>mode)
7740     {
7741       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7742       DONE;
7743     }
7745   if (<MODE>mode == DImode)
7746     insn = (mode == SImode)
7747            ? gen_zero_extendsidi2
7748            : (mode == HImode)
7749            ? gen_zero_extendhidi2
7750            : gen_zero_extendqidi2;
7751   else if (<MODE>mode == SImode)
7752     insn = (mode == HImode)
7753            ? gen_zero_extendhisi2
7754            : gen_zero_extendqisi2;
7755   else if (<MODE>mode == HImode)
7756     insn = gen_zero_extendqihi2;
7757   else
7758     gcc_unreachable ();
7760   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7761   DONE;
7764 (define_insn "*anddi_1"
7765   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7766         (and:DI
7767          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7768          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7769    (clobber (reg:CC FLAGS_REG))]
7770   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7772   switch (get_attr_type (insn))
7773     {
7774     case TYPE_IMOVX:
7775       return "#";
7777     case TYPE_MSKLOG:
7778       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7780     default:
7781       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7782       if (get_attr_mode (insn) == MODE_SI)
7783         return "and{l}\t{%k2, %k0|%k0, %k2}";
7784       else
7785         return "and{q}\t{%2, %0|%0, %2}";
7786     }
7788   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7789    (set_attr "length_immediate" "*,*,*,0,0")
7790    (set (attr "prefix_rex")
7791      (if_then_else
7792        (and (eq_attr "type" "imovx")
7793             (and (match_test "INTVAL (operands[2]) == 0xff")
7794                  (match_operand 1 "ext_QIreg_operand")))
7795        (const_string "1")
7796        (const_string "*")))
7797    (set_attr "mode" "SI,DI,DI,SI,DI")])
7799 (define_insn "*andsi_1"
7800   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7801         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7802                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7803    (clobber (reg:CC FLAGS_REG))]
7804   "ix86_binary_operator_ok (AND, SImode, operands)"
7806   switch (get_attr_type (insn))
7807     {
7808     case TYPE_IMOVX:
7809       return "#";
7811     case TYPE_MSKLOG:
7812       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7814     default:
7815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816       return "and{l}\t{%2, %0|%0, %2}";
7817     }
7819   [(set_attr "type" "alu,alu,imovx,msklog")
7820    (set (attr "prefix_rex")
7821      (if_then_else
7822        (and (eq_attr "type" "imovx")
7823             (and (match_test "INTVAL (operands[2]) == 0xff")
7824                  (match_operand 1 "ext_QIreg_operand")))
7825        (const_string "1")
7826        (const_string "*")))
7827    (set_attr "length_immediate" "*,*,0,0")
7828    (set_attr "mode" "SI")])
7830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7831 (define_insn "*andsi_1_zext"
7832   [(set (match_operand:DI 0 "register_operand" "=r")
7833         (zero_extend:DI
7834           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7835                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7836    (clobber (reg:CC FLAGS_REG))]
7837   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7838   "and{l}\t{%2, %k0|%k0, %2}"
7839   [(set_attr "type" "alu")
7840    (set_attr "mode" "SI")])
7842 (define_insn "*andhi_1"
7843   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7844         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7845                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7846    (clobber (reg:CC FLAGS_REG))]
7847   "ix86_binary_operator_ok (AND, HImode, operands)"
7849   switch (get_attr_type (insn))
7850     {
7851     case TYPE_IMOVX:
7852       return "#";
7854     case TYPE_MSKLOG:
7855       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7857     default:
7858       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7859       return "and{w}\t{%2, %0|%0, %2}";
7860     }
7862   [(set_attr "type" "alu,alu,imovx,msklog")
7863    (set_attr "length_immediate" "*,*,0,*")
7864    (set (attr "prefix_rex")
7865      (if_then_else
7866        (and (eq_attr "type" "imovx")
7867             (match_operand 1 "ext_QIreg_operand"))
7868        (const_string "1")
7869        (const_string "*")))
7870    (set_attr "mode" "HI,HI,SI,HI")])
7872 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7873 (define_insn "*andqi_1"
7874   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7875         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7876                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7877    (clobber (reg:CC FLAGS_REG))]
7878   "ix86_binary_operator_ok (AND, QImode, operands)"
7880   switch (which_alternative)
7881     {
7882     case 0:
7883     case 1:
7884       return "and{b}\t{%2, %0|%0, %2}";
7885     case 2:
7886       return "and{l}\t{%k2, %k0|%k0, %k2}";
7887     case 3:
7888       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7889                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7890     default:
7891       gcc_unreachable ();
7892     }
7894   [(set_attr "type" "alu,alu,alu,msklog")
7895    (set_attr "mode" "QI,QI,SI,HI")])
7897 (define_insn "*andqi_1_slp"
7898   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7899         (and:QI (match_dup 0)
7900                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7901    (clobber (reg:CC FLAGS_REG))]
7902   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7904   "and{b}\t{%1, %0|%0, %1}"
7905   [(set_attr "type" "alu1")
7906    (set_attr "mode" "QI")])
7908 (define_insn "kandn<mode>"
7909   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7910         (and:SWI12
7911           (not:SWI12
7912             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7913           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7914    (clobber (reg:CC FLAGS_REG))]
7915   "TARGET_AVX512F"
7917   switch (which_alternative)
7918     {
7919     case 0:
7920       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7921     case 1:
7922       return "#";
7923     case 2:
7924       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7925         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7926       else
7927         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7928     default:
7929       gcc_unreachable ();
7930     }
7932   [(set_attr "isa" "bmi,*,avx512f")
7933    (set_attr "type" "bitmanip,*,msklog")
7934    (set_attr "prefix" "*,*,vex")
7935    (set_attr "btver2_decode" "direct,*,*")
7936    (set_attr "mode" "<MODE>")])
7938 (define_split
7939   [(set (match_operand:SWI12 0 "general_reg_operand")
7940         (and:SWI12
7941           (not:SWI12
7942             (match_dup 0))
7943           (match_operand:SWI12 1 "general_reg_operand")))
7944    (clobber (reg:CC FLAGS_REG))]
7945   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7946   [(set (match_dup 0)
7947         (not:HI (match_dup 0)))
7948    (parallel [(set (match_dup 0)
7949                    (and:HI (match_dup 0)
7950                            (match_dup 1)))
7951               (clobber (reg:CC FLAGS_REG))])])
7953 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7954 (define_split
7955   [(set (match_operand:DI 0 "register_operand")
7956         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7957                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7958    (clobber (reg:CC FLAGS_REG))]
7959   "TARGET_64BIT"
7960   [(parallel [(set (match_dup 0)
7961                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7962               (clobber (reg:CC FLAGS_REG))])]
7963   "operands[2] = gen_lowpart (SImode, operands[2]);")
7965 (define_split
7966   [(set (match_operand:SWI248 0 "register_operand")
7967         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7968                     (match_operand:SWI248 2 "const_int_operand")))
7969    (clobber (reg:CC FLAGS_REG))]
7970   "reload_completed
7971    && true_regnum (operands[0]) != true_regnum (operands[1])"
7972   [(const_int 0)]
7974   HOST_WIDE_INT ival = INTVAL (operands[2]);
7975   machine_mode mode;
7976   rtx (*insn) (rtx, rtx);
7978   if (ival == (HOST_WIDE_INT) 0xffffffff)
7979     mode = SImode;
7980   else if (ival == 0xffff)
7981     mode = HImode;
7982   else
7983     {
7984       gcc_assert (ival == 0xff);
7985       mode = QImode;
7986     }
7988   if (<MODE>mode == DImode)
7989     insn = (mode == SImode)
7990            ? gen_zero_extendsidi2
7991            : (mode == HImode)
7992            ? gen_zero_extendhidi2
7993            : gen_zero_extendqidi2;
7994   else
7995     {
7996       if (<MODE>mode != SImode)
7997         /* Zero extend to SImode to avoid partial register stalls.  */
7998         operands[0] = gen_lowpart (SImode, operands[0]);
8000       insn = (mode == HImode)
8001              ? gen_zero_extendhisi2
8002              : gen_zero_extendqisi2;
8003     }
8004   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8005   DONE;
8008 (define_split
8009   [(set (match_operand:SWI48 0 "register_operand")
8010         (and:SWI48 (match_dup 0)
8011                    (const_int -65536)))
8012    (clobber (reg:CC FLAGS_REG))]
8013   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8014     || optimize_function_for_size_p (cfun)"
8015   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8016   "operands[1] = gen_lowpart (HImode, operands[0]);")
8018 (define_split
8019   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8020         (and:SWI248 (match_dup 0)
8021                     (const_int -256)))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8024    && reload_completed"
8025   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8026   "operands[1] = gen_lowpart (QImode, operands[0]);")
8028 (define_split
8029   [(set (match_operand:SWI248 0 "QIreg_operand")
8030         (and:SWI248 (match_dup 0)
8031                     (const_int -65281)))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8034    && reload_completed"
8035   [(parallel [(set (zero_extract:SI (match_dup 0)
8036                                     (const_int 8)
8037                                     (const_int 8))
8038                    (xor:SI
8039                      (zero_extract:SI (match_dup 0)
8040                                       (const_int 8)
8041                                       (const_int 8))
8042                      (zero_extract:SI (match_dup 0)
8043                                       (const_int 8)
8044                                       (const_int 8))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "operands[0] = gen_lowpart (SImode, operands[0]);")
8048 (define_insn "*anddi_2"
8049   [(set (reg FLAGS_REG)
8050         (compare
8051          (and:DI
8052           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8054          (const_int 0)))
8055    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056         (and:DI (match_dup 1) (match_dup 2)))]
8057   "TARGET_64BIT
8058    && ix86_match_ccmode
8059         (insn,
8060          /* If we are going to emit andl instead of andq, and the operands[2]
8061             constant might have the SImode sign bit set, make sure the sign
8062             flag isn't tested, because the instruction will set the sign flag
8063             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8064             conservatively assume it might have bit 31 set.  */
8065          (satisfies_constraint_Z (operands[2])
8066           && (!CONST_INT_P (operands[2])
8067               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8068          ? CCZmode : CCNOmode)
8069    && ix86_binary_operator_ok (AND, DImode, operands)"
8070   "@
8071    and{l}\t{%k2, %k0|%k0, %k2}
8072    and{q}\t{%2, %0|%0, %2}
8073    and{q}\t{%2, %0|%0, %2}"
8074   [(set_attr "type" "alu")
8075    (set_attr "mode" "SI,DI,DI")])
8077 (define_insn "*andqi_2_maybe_si"
8078   [(set (reg FLAGS_REG)
8079         (compare (and:QI
8080                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8081                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8082                  (const_int 0)))
8083    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8084         (and:QI (match_dup 1) (match_dup 2)))]
8085   "ix86_binary_operator_ok (AND, QImode, operands)
8086    && ix86_match_ccmode (insn,
8087                          CONST_INT_P (operands[2])
8088                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8090   if (which_alternative == 2)
8091     {
8092       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8093         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8094       return "and{l}\t{%2, %k0|%k0, %2}";
8095     }
8096   return "and{b}\t{%2, %0|%0, %2}";
8098   [(set_attr "type" "alu")
8099    (set_attr "mode" "QI,QI,SI")])
8101 (define_insn "*and<mode>_2"
8102   [(set (reg FLAGS_REG)
8103         (compare (and:SWI124
8104                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8105                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8106                  (const_int 0)))
8107    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8108         (and:SWI124 (match_dup 1) (match_dup 2)))]
8109   "ix86_match_ccmode (insn, CCNOmode)
8110    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8111   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8112   [(set_attr "type" "alu")
8113    (set_attr "mode" "<MODE>")])
8115 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8116 (define_insn "*andsi_2_zext"
8117   [(set (reg FLAGS_REG)
8118         (compare (and:SI
8119                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8120                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8121                  (const_int 0)))
8122    (set (match_operand:DI 0 "register_operand" "=r")
8123         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8124   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8125    && ix86_binary_operator_ok (AND, SImode, operands)"
8126   "and{l}\t{%2, %k0|%k0, %2}"
8127   [(set_attr "type" "alu")
8128    (set_attr "mode" "SI")])
8130 (define_insn "*andqi_2_slp"
8131   [(set (reg FLAGS_REG)
8132         (compare (and:QI
8133                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8134                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8135                  (const_int 0)))
8136    (set (strict_low_part (match_dup 0))
8137         (and:QI (match_dup 0) (match_dup 1)))]
8138   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8139    && ix86_match_ccmode (insn, CCNOmode)
8140    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8141   "and{b}\t{%1, %0|%0, %1}"
8142   [(set_attr "type" "alu1")
8143    (set_attr "mode" "QI")])
8145 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8146 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8147 ;; for a QImode operand, which of course failed.
8148 (define_insn "andqi_ext_0"
8149   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8150                          (const_int 8)
8151                          (const_int 8))
8152         (and:SI
8153           (zero_extract:SI
8154             (match_operand 1 "ext_register_operand" "0")
8155             (const_int 8)
8156             (const_int 8))
8157           (match_operand 2 "const_int_operand" "n")))
8158    (clobber (reg:CC FLAGS_REG))]
8159   ""
8160   "and{b}\t{%2, %h0|%h0, %2}"
8161   [(set_attr "type" "alu")
8162    (set_attr "length_immediate" "1")
8163    (set_attr "modrm" "1")
8164    (set_attr "mode" "QI")])
8166 ;; Generated by peephole translating test to and.  This shows up
8167 ;; often in fp comparisons.
8168 (define_insn "*andqi_ext_0_cc"
8169   [(set (reg FLAGS_REG)
8170         (compare
8171           (and:SI
8172             (zero_extract:SI
8173               (match_operand 1 "ext_register_operand" "0")
8174               (const_int 8)
8175               (const_int 8))
8176             (match_operand 2 "const_int_operand" "n"))
8177           (const_int 0)))
8178    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8179                          (const_int 8)
8180                          (const_int 8))
8181         (and:SI
8182           (zero_extract:SI
8183             (match_dup 1)
8184             (const_int 8)
8185             (const_int 8))
8186           (match_dup 2)))]
8187   "ix86_match_ccmode (insn, CCNOmode)"
8188   "and{b}\t{%2, %h0|%h0, %2}"
8189   [(set_attr "type" "alu")
8190    (set_attr "length_immediate" "1")
8191    (set_attr "modrm" "1")
8192    (set_attr "mode" "QI")])
8194 (define_insn "*andqi_ext_1"
8195   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8196                          (const_int 8)
8197                          (const_int 8))
8198         (and:SI
8199           (zero_extract:SI
8200             (match_operand 1 "ext_register_operand" "0,0")
8201             (const_int 8)
8202             (const_int 8))
8203           (zero_extend:SI
8204             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8205    (clobber (reg:CC FLAGS_REG))]
8206   ""
8207   "and{b}\t{%2, %h0|%h0, %2}"
8208   [(set_attr "isa" "*,nox64")
8209    (set_attr "type" "alu")
8210    (set_attr "length_immediate" "0")
8211    (set_attr "mode" "QI")])
8213 (define_insn "*andqi_ext_2"
8214   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8215                          (const_int 8)
8216                          (const_int 8))
8217         (and:SI
8218           (zero_extract:SI
8219             (match_operand 1 "ext_register_operand" "%0")
8220             (const_int 8)
8221             (const_int 8))
8222           (zero_extract:SI
8223             (match_operand 2 "ext_register_operand" "Q")
8224             (const_int 8)
8225             (const_int 8))))
8226    (clobber (reg:CC FLAGS_REG))]
8227   ""
8228   "and{b}\t{%h2, %h0|%h0, %h2}"
8229   [(set_attr "type" "alu")
8230    (set_attr "length_immediate" "0")
8231    (set_attr "mode" "QI")])
8233 ;; Convert wide AND instructions with immediate operand to shorter QImode
8234 ;; equivalents when possible.
8235 ;; Don't do the splitting with memory operands, since it introduces risk
8236 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8237 ;; for size, but that can (should?) be handled by generic code instead.
8238 (define_split
8239   [(set (match_operand 0 "QIreg_operand")
8240         (and (match_operand 1 "register_operand")
8241              (match_operand 2 "const_int_operand")))
8242    (clobber (reg:CC FLAGS_REG))]
8243    "reload_completed
8244     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8245     && !(~INTVAL (operands[2]) & ~(255 << 8))
8246     && GET_MODE (operands[0]) != QImode"
8247   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8248                    (and:SI (zero_extract:SI (match_dup 1)
8249                                             (const_int 8) (const_int 8))
8250                            (match_dup 2)))
8251               (clobber (reg:CC FLAGS_REG))])]
8253   operands[0] = gen_lowpart (SImode, operands[0]);
8254   operands[1] = gen_lowpart (SImode, operands[1]);
8255   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8258 ;; Since AND can be encoded with sign extended immediate, this is only
8259 ;; profitable when 7th bit is not set.
8260 (define_split
8261   [(set (match_operand 0 "any_QIreg_operand")
8262         (and (match_operand 1 "general_operand")
8263              (match_operand 2 "const_int_operand")))
8264    (clobber (reg:CC FLAGS_REG))]
8265    "reload_completed
8266     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8267     && !(~INTVAL (operands[2]) & ~255)
8268     && !(INTVAL (operands[2]) & 128)
8269     && GET_MODE (operands[0]) != QImode"
8270   [(parallel [(set (strict_low_part (match_dup 0))
8271                    (and:QI (match_dup 1)
8272                            (match_dup 2)))
8273               (clobber (reg:CC FLAGS_REG))])]
8275   operands[0] = gen_lowpart (QImode, operands[0]);
8276   operands[1] = gen_lowpart (QImode, operands[1]);
8277   operands[2] = gen_lowpart (QImode, operands[2]);
8280 ;; Logical inclusive and exclusive OR instructions
8282 ;; %%% This used to optimize known byte-wide and operations to memory.
8283 ;; If this is considered useful, it should be done with splitters.
8285 (define_expand "<code><mode>3"
8286   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8287         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8288                      (match_operand:SWIM 2 "<general_operand>")))]
8289   ""
8290   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8292 (define_insn "*<code><mode>_1"
8293   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8294         (any_or:SWI48
8295          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8296          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8297    (clobber (reg:CC FLAGS_REG))]
8298   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8299   "@
8300    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8301    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8302    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8303   [(set_attr "type" "alu,alu,msklog")
8304    (set_attr "mode" "<MODE>")])
8306 (define_insn "*<code>hi_1"
8307   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8308         (any_or:HI
8309          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8310          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8311    (clobber (reg:CC FLAGS_REG))]
8312   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8313   "@
8314   <logic>{w}\t{%2, %0|%0, %2}
8315   <logic>{w}\t{%2, %0|%0, %2}
8316   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8317   [(set_attr "type" "alu,alu,msklog")
8318    (set_attr "mode" "HI")])
8320 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8321 (define_insn "*<code>qi_1"
8322   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8323         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8324                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8327   "@
8328    <logic>{b}\t{%2, %0|%0, %2}
8329    <logic>{b}\t{%2, %0|%0, %2}
8330    <logic>{l}\t{%k2, %k0|%k0, %k2}
8331    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8332   [(set_attr "type" "alu,alu,alu,msklog")
8333    (set_attr "mode" "QI,QI,SI,HI")])
8335 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8336 (define_insn "*<code>si_1_zext"
8337   [(set (match_operand:DI 0 "register_operand" "=r")
8338         (zero_extend:DI
8339          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8340                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8341    (clobber (reg:CC FLAGS_REG))]
8342   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8343   "<logic>{l}\t{%2, %k0|%k0, %2}"
8344   [(set_attr "type" "alu")
8345    (set_attr "mode" "SI")])
8347 (define_insn "*<code>si_1_zext_imm"
8348   [(set (match_operand:DI 0 "register_operand" "=r")
8349         (any_or:DI
8350          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8351          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8354   "<logic>{l}\t{%2, %k0|%k0, %2}"
8355   [(set_attr "type" "alu")
8356    (set_attr "mode" "SI")])
8358 (define_insn "*<code>qi_1_slp"
8359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8360         (any_or:QI (match_dup 0)
8361                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8365   "<logic>{b}\t{%1, %0|%0, %1}"
8366   [(set_attr "type" "alu1")
8367    (set_attr "mode" "QI")])
8369 (define_insn "*<code><mode>_2"
8370   [(set (reg FLAGS_REG)
8371         (compare (any_or:SWI
8372                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8373                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8374                  (const_int 0)))
8375    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8376         (any_or:SWI (match_dup 1) (match_dup 2)))]
8377   "ix86_match_ccmode (insn, CCNOmode)
8378    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8379   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8380   [(set_attr "type" "alu")
8381    (set_attr "mode" "<MODE>")])
8383 (define_insn "kxnor<mode>"
8384   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8385         (not:SWI12
8386           (xor:SWI12
8387             (match_operand:SWI12 1 "register_operand" "0,k")
8388             (match_operand:SWI12 2 "register_operand" "r,k"))))
8389    (clobber (reg:CC FLAGS_REG))]
8390   "TARGET_AVX512F"
8392   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8393     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8394   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8396   [(set_attr "type" "*,msklog")
8397    (set_attr "prefix" "*,vex")
8398    (set_attr "mode" "<MODE>")])
8400 (define_insn "kxnor<mode>"
8401   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8402         (not:SWI48x
8403           (xor:SWI48x
8404             (match_operand:SWI48x 1 "register_operand" "0,k")
8405             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8406    (clobber (reg:CC FLAGS_REG))]
8407   "TARGET_AVX512BW"
8408   "@
8409    #
8410    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8411   [(set_attr "type" "*,msklog")
8412    (set_attr "prefix" "*,vex")
8413    (set_attr "mode" "<MODE>")])
8415 (define_split
8416   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8417         (not:SWI1248x
8418           (xor:SWI1248x
8419             (match_dup 0)
8420             (match_operand:SWI1248x 1 "general_reg_operand"))))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "TARGET_AVX512F && reload_completed"
8423    [(parallel [(set (match_dup 0)
8424                     (xor:HI (match_dup 0)
8425                             (match_dup 1)))
8426                (clobber (reg:CC FLAGS_REG))])
8427     (set (match_dup 0)
8428          (not:HI (match_dup 0)))])
8430 ;;There are kortrest[bdq] but no intrinsics for them.
8431 ;;We probably don't need to implement them.
8432 (define_insn "kortestzhi"
8433   [(set (reg:CCZ FLAGS_REG)
8434         (compare:CCZ
8435           (ior:HI
8436             (match_operand:HI 0 "register_operand" "k")
8437             (match_operand:HI 1 "register_operand" "k"))
8438           (const_int 0)))]
8439   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8440   "kortestw\t{%1, %0|%0, %1}"
8441   [(set_attr "mode" "HI")
8442    (set_attr "type" "msklog")
8443    (set_attr "prefix" "vex")])
8445 (define_insn "kortestchi"
8446   [(set (reg:CCC FLAGS_REG)
8447         (compare:CCC
8448           (ior:HI
8449             (match_operand:HI 0 "register_operand" "k")
8450             (match_operand:HI 1 "register_operand" "k"))
8451           (const_int -1)))]
8452   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8453   "kortestw\t{%1, %0|%0, %1}"
8454   [(set_attr "mode" "HI")
8455    (set_attr "type" "msklog")
8456    (set_attr "prefix" "vex")])
8458 (define_insn "kunpckhi"
8459   [(set (match_operand:HI 0 "register_operand" "=k")
8460         (ior:HI
8461           (ashift:HI
8462             (match_operand:HI 1 "register_operand" "k")
8463             (const_int 8))
8464           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8465   "TARGET_AVX512F"
8466   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8467   [(set_attr "mode" "HI")
8468    (set_attr "type" "msklog")
8469    (set_attr "prefix" "vex")])
8471 (define_insn "kunpcksi"
8472   [(set (match_operand:SI 0 "register_operand" "=k")
8473         (ior:SI
8474           (ashift:SI
8475             (match_operand:SI 1 "register_operand" "k")
8476             (const_int 16))
8477           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8478   "TARGET_AVX512BW"
8479   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8480   [(set_attr "mode" "SI")])
8482 (define_insn "kunpckdi"
8483   [(set (match_operand:DI 0 "register_operand" "=k")
8484         (ior:DI
8485           (ashift:DI
8486             (match_operand:DI 1 "register_operand" "k")
8487             (const_int 32))
8488           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8489   "TARGET_AVX512BW"
8490   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8491   [(set_attr "mode" "DI")])
8493 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8494 ;; ??? Special case for immediate operand is missing - it is tricky.
8495 (define_insn "*<code>si_2_zext"
8496   [(set (reg FLAGS_REG)
8497         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8498                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8499                  (const_int 0)))
8500    (set (match_operand:DI 0 "register_operand" "=r")
8501         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8502   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8503    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8504   "<logic>{l}\t{%2, %k0|%k0, %2}"
8505   [(set_attr "type" "alu")
8506    (set_attr "mode" "SI")])
8508 (define_insn "*<code>si_2_zext_imm"
8509   [(set (reg FLAGS_REG)
8510         (compare (any_or:SI
8511                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8512                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8513                  (const_int 0)))
8514    (set (match_operand:DI 0 "register_operand" "=r")
8515         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8516   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8517    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8518   "<logic>{l}\t{%2, %k0|%k0, %2}"
8519   [(set_attr "type" "alu")
8520    (set_attr "mode" "SI")])
8522 (define_insn "*<code>qi_2_slp"
8523   [(set (reg FLAGS_REG)
8524         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8525                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8526                  (const_int 0)))
8527    (set (strict_low_part (match_dup 0))
8528         (any_or:QI (match_dup 0) (match_dup 1)))]
8529   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8530    && ix86_match_ccmode (insn, CCNOmode)
8531    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8532   "<logic>{b}\t{%1, %0|%0, %1}"
8533   [(set_attr "type" "alu1")
8534    (set_attr "mode" "QI")])
8536 (define_insn "*<code><mode>_3"
8537   [(set (reg FLAGS_REG)
8538         (compare (any_or:SWI
8539                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8540                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8541                  (const_int 0)))
8542    (clobber (match_scratch:SWI 0 "=<r>"))]
8543   "ix86_match_ccmode (insn, CCNOmode)
8544    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8545   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8546   [(set_attr "type" "alu")
8547    (set_attr "mode" "<MODE>")])
8549 (define_insn "*<code>qi_ext_0"
8550   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8551                          (const_int 8)
8552                          (const_int 8))
8553         (any_or:SI
8554           (zero_extract:SI
8555             (match_operand 1 "ext_register_operand" "0")
8556             (const_int 8)
8557             (const_int 8))
8558           (match_operand 2 "const_int_operand" "n")))
8559    (clobber (reg:CC FLAGS_REG))]
8560   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8561   "<logic>{b}\t{%2, %h0|%h0, %2}"
8562   [(set_attr "type" "alu")
8563    (set_attr "length_immediate" "1")
8564    (set_attr "modrm" "1")
8565    (set_attr "mode" "QI")])
8567 (define_insn "*<code>qi_ext_1"
8568   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8569                          (const_int 8)
8570                          (const_int 8))
8571         (any_or:SI
8572           (zero_extract:SI
8573             (match_operand 1 "ext_register_operand" "0,0")
8574             (const_int 8)
8575             (const_int 8))
8576           (zero_extend:SI
8577             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8578    (clobber (reg:CC FLAGS_REG))]
8579   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8580   "<logic>{b}\t{%2, %h0|%h0, %2}"
8581   [(set_attr "isa" "*,nox64")
8582    (set_attr "type" "alu")
8583    (set_attr "length_immediate" "0")
8584    (set_attr "mode" "QI")])
8586 (define_insn "*<code>qi_ext_2"
8587   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8588                          (const_int 8)
8589                          (const_int 8))
8590         (any_or:SI
8591           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8592                            (const_int 8)
8593                            (const_int 8))
8594           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8595                            (const_int 8)
8596                            (const_int 8))))
8597    (clobber (reg:CC FLAGS_REG))]
8598   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8599   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8600   [(set_attr "type" "alu")
8601    (set_attr "length_immediate" "0")
8602    (set_attr "mode" "QI")])
8604 (define_split
8605   [(set (match_operand 0 "QIreg_operand")
8606         (any_or (match_operand 1 "register_operand")
8607                 (match_operand 2 "const_int_operand")))
8608    (clobber (reg:CC FLAGS_REG))]
8609    "reload_completed
8610     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8611     && !(INTVAL (operands[2]) & ~(255 << 8))
8612     && GET_MODE (operands[0]) != QImode"
8613   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8614                    (any_or:SI (zero_extract:SI (match_dup 1)
8615                                                (const_int 8) (const_int 8))
8616                               (match_dup 2)))
8617               (clobber (reg:CC FLAGS_REG))])]
8619   operands[0] = gen_lowpart (SImode, operands[0]);
8620   operands[1] = gen_lowpart (SImode, operands[1]);
8621   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8624 ;; Since OR can be encoded with sign extended immediate, this is only
8625 ;; profitable when 7th bit is set.
8626 (define_split
8627   [(set (match_operand 0 "any_QIreg_operand")
8628         (any_or (match_operand 1 "general_operand")
8629                 (match_operand 2 "const_int_operand")))
8630    (clobber (reg:CC FLAGS_REG))]
8631    "reload_completed
8632     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8633     && !(INTVAL (operands[2]) & ~255)
8634     && (INTVAL (operands[2]) & 128)
8635     && GET_MODE (operands[0]) != QImode"
8636   [(parallel [(set (strict_low_part (match_dup 0))
8637                    (any_or:QI (match_dup 1)
8638                               (match_dup 2)))
8639               (clobber (reg:CC FLAGS_REG))])]
8641   operands[0] = gen_lowpart (QImode, operands[0]);
8642   operands[1] = gen_lowpart (QImode, operands[1]);
8643   operands[2] = gen_lowpart (QImode, operands[2]);
8646 (define_expand "xorqi_cc_ext_1"
8647   [(parallel [
8648      (set (reg:CCNO FLAGS_REG)
8649           (compare:CCNO
8650             (xor:SI
8651               (zero_extract:SI
8652                 (match_operand 1 "ext_register_operand")
8653                 (const_int 8)
8654                 (const_int 8))
8655               (match_operand:QI 2 "const_int_operand"))
8656             (const_int 0)))
8657      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8658                            (const_int 8)
8659                            (const_int 8))
8660           (xor:SI
8661             (zero_extract:SI
8662              (match_dup 1)
8663              (const_int 8)
8664              (const_int 8))
8665             (match_dup 2)))])])
8667 (define_insn "*xorqi_cc_ext_1"
8668   [(set (reg FLAGS_REG)
8669         (compare
8670           (xor:SI
8671             (zero_extract:SI
8672               (match_operand 1 "ext_register_operand" "0,0")
8673               (const_int 8)
8674               (const_int 8))
8675             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8676           (const_int 0)))
8677    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8678                          (const_int 8)
8679                          (const_int 8))
8680         (xor:SI
8681           (zero_extract:SI
8682            (match_dup 1)
8683            (const_int 8)
8684            (const_int 8))
8685           (match_dup 2)))]
8686   "ix86_match_ccmode (insn, CCNOmode)"
8687   "xor{b}\t{%2, %h0|%h0, %2}"
8688   [(set_attr "isa" "*,nox64")
8689    (set_attr "type" "alu")
8690    (set_attr "modrm" "1")
8691    (set_attr "mode" "QI")])
8693 ;; Negation instructions
8695 (define_expand "neg<mode>2"
8696   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8697         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8698   ""
8699   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8701 (define_insn_and_split "*neg<dwi>2_doubleword"
8702   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8703         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8704    (clobber (reg:CC FLAGS_REG))]
8705   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8706   "#"
8707   "reload_completed"
8708   [(parallel
8709     [(set (reg:CCZ FLAGS_REG)
8710           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8711      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8712    (parallel
8713     [(set (match_dup 2)
8714           (plus:DWIH (match_dup 3)
8715                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8716                                 (const_int 0))))
8717      (clobber (reg:CC FLAGS_REG))])
8718    (parallel
8719     [(set (match_dup 2)
8720           (neg:DWIH (match_dup 2)))
8721      (clobber (reg:CC FLAGS_REG))])]
8722   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8724 (define_insn "*neg<mode>2_1"
8725   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8726         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8729   "neg{<imodesuffix>}\t%0"
8730   [(set_attr "type" "negnot")
8731    (set_attr "mode" "<MODE>")])
8733 ;; Combine is quite creative about this pattern.
8734 (define_insn "*negsi2_1_zext"
8735   [(set (match_operand:DI 0 "register_operand" "=r")
8736         (lshiftrt:DI
8737           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8738                              (const_int 32)))
8739         (const_int 32)))
8740    (clobber (reg:CC FLAGS_REG))]
8741   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8742   "neg{l}\t%k0"
8743   [(set_attr "type" "negnot")
8744    (set_attr "mode" "SI")])
8746 ;; The problem with neg is that it does not perform (compare x 0),
8747 ;; it really performs (compare 0 x), which leaves us with the zero
8748 ;; flag being the only useful item.
8750 (define_insn "*neg<mode>2_cmpz"
8751   [(set (reg:CCZ FLAGS_REG)
8752         (compare:CCZ
8753           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8754                    (const_int 0)))
8755    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8756         (neg:SWI (match_dup 1)))]
8757   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8758   "neg{<imodesuffix>}\t%0"
8759   [(set_attr "type" "negnot")
8760    (set_attr "mode" "<MODE>")])
8762 (define_insn "*negsi2_cmpz_zext"
8763   [(set (reg:CCZ FLAGS_REG)
8764         (compare:CCZ
8765           (lshiftrt:DI
8766             (neg:DI (ashift:DI
8767                       (match_operand:DI 1 "register_operand" "0")
8768                       (const_int 32)))
8769             (const_int 32))
8770           (const_int 0)))
8771    (set (match_operand:DI 0 "register_operand" "=r")
8772         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8773                                         (const_int 32)))
8774                      (const_int 32)))]
8775   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8776   "neg{l}\t%k0"
8777   [(set_attr "type" "negnot")
8778    (set_attr "mode" "SI")])
8780 ;; Negate with jump on overflow.
8781 (define_expand "negv<mode>3"
8782   [(parallel [(set (reg:CCO FLAGS_REG)
8783                    (ne:CCO (match_operand:SWI 1 "register_operand")
8784                            (match_dup 3)))
8785               (set (match_operand:SWI 0 "register_operand")
8786                    (neg:SWI (match_dup 1)))])
8787    (set (pc) (if_then_else
8788                (eq (reg:CCO FLAGS_REG) (const_int 0))
8789                (label_ref (match_operand 2))
8790                (pc)))]
8791   ""
8793   operands[3]
8794     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8795                     <MODE>mode);
8798 (define_insn "*negv<mode>3"
8799   [(set (reg:CCO FLAGS_REG)
8800         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8801                 (match_operand:SWI 2 "const_int_operand")))
8802    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8803         (neg:SWI (match_dup 1)))]
8804   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8805    && mode_signbit_p (<MODE>mode, operands[2])"
8806   "neg{<imodesuffix>}\t%0"
8807   [(set_attr "type" "negnot")
8808    (set_attr "mode" "<MODE>")])
8810 ;; Changing of sign for FP values is doable using integer unit too.
8812 (define_expand "<code><mode>2"
8813   [(set (match_operand:X87MODEF 0 "register_operand")
8814         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8815   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8816   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8818 (define_insn "*absneg<mode>2_mixed"
8819   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8820         (match_operator:MODEF 3 "absneg_operator"
8821           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8822    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8823    (clobber (reg:CC FLAGS_REG))]
8824   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8825   "#"
8826   [(set (attr "enabled")
8827      (cond [(eq_attr "alternative" "2")
8828               (symbol_ref "TARGET_MIX_SSE_I387")
8829            ]
8830            (symbol_ref "true")))])
8832 (define_insn "*absneg<mode>2_i387"
8833   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8834         (match_operator:X87MODEF 3 "absneg_operator"
8835           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8836    (use (match_operand 2))
8837    (clobber (reg:CC FLAGS_REG))]
8838   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8839   "#")
8841 (define_expand "<code>tf2"
8842   [(set (match_operand:TF 0 "register_operand")
8843         (absneg:TF (match_operand:TF 1 "register_operand")))]
8844   "TARGET_SSE"
8845   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8847 (define_insn "*absnegtf2_sse"
8848   [(set (match_operand:TF 0 "register_operand" "=x,x")
8849         (match_operator:TF 3 "absneg_operator"
8850           [(match_operand:TF 1 "register_operand" "0,x")]))
8851    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8852    (clobber (reg:CC FLAGS_REG))]
8853   "TARGET_SSE"
8854   "#")
8856 ;; Splitters for fp abs and neg.
8858 (define_split
8859   [(set (match_operand 0 "fp_register_operand")
8860         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8861    (use (match_operand 2))
8862    (clobber (reg:CC FLAGS_REG))]
8863   "reload_completed"
8864   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8866 (define_split
8867   [(set (match_operand 0 "register_operand")
8868         (match_operator 3 "absneg_operator"
8869           [(match_operand 1 "register_operand")]))
8870    (use (match_operand 2 "nonimmediate_operand"))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "reload_completed && SSE_REG_P (operands[0])"
8873   [(set (match_dup 0) (match_dup 3))]
8875   machine_mode mode = GET_MODE (operands[0]);
8876   machine_mode vmode = GET_MODE (operands[2]);
8877   rtx tmp;
8879   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8880   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8881   if (operands_match_p (operands[0], operands[2]))
8882     std::swap (operands[1], operands[2]);
8883   if (GET_CODE (operands[3]) == ABS)
8884     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8885   else
8886     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8887   operands[3] = tmp;
8890 (define_split
8891   [(set (match_operand:SF 0 "register_operand")
8892         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8893    (use (match_operand:V4SF 2))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "reload_completed"
8896   [(parallel [(set (match_dup 0) (match_dup 1))
8897               (clobber (reg:CC FLAGS_REG))])]
8899   rtx tmp;
8900   operands[0] = gen_lowpart (SImode, operands[0]);
8901   if (GET_CODE (operands[1]) == ABS)
8902     {
8903       tmp = gen_int_mode (0x7fffffff, SImode);
8904       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8905     }
8906   else
8907     {
8908       tmp = gen_int_mode (0x80000000, SImode);
8909       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8910     }
8911   operands[1] = tmp;
8914 (define_split
8915   [(set (match_operand:DF 0 "register_operand")
8916         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8917    (use (match_operand 2))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "reload_completed"
8920   [(parallel [(set (match_dup 0) (match_dup 1))
8921               (clobber (reg:CC FLAGS_REG))])]
8923   rtx tmp;
8924   if (TARGET_64BIT)
8925     {
8926       tmp = gen_lowpart (DImode, operands[0]);
8927       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8928       operands[0] = tmp;
8930       if (GET_CODE (operands[1]) == ABS)
8931         tmp = const0_rtx;
8932       else
8933         tmp = gen_rtx_NOT (DImode, tmp);
8934     }
8935   else
8936     {
8937       operands[0] = gen_highpart (SImode, operands[0]);
8938       if (GET_CODE (operands[1]) == ABS)
8939         {
8940           tmp = gen_int_mode (0x7fffffff, SImode);
8941           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8942         }
8943       else
8944         {
8945           tmp = gen_int_mode (0x80000000, SImode);
8946           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8947         }
8948     }
8949   operands[1] = tmp;
8952 (define_split
8953   [(set (match_operand:XF 0 "register_operand")
8954         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8955    (use (match_operand 2))
8956    (clobber (reg:CC FLAGS_REG))]
8957   "reload_completed"
8958   [(parallel [(set (match_dup 0) (match_dup 1))
8959               (clobber (reg:CC FLAGS_REG))])]
8961   rtx tmp;
8962   operands[0] = gen_rtx_REG (SImode,
8963                              true_regnum (operands[0])
8964                              + (TARGET_64BIT ? 1 : 2));
8965   if (GET_CODE (operands[1]) == ABS)
8966     {
8967       tmp = GEN_INT (0x7fff);
8968       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8969     }
8970   else
8971     {
8972       tmp = GEN_INT (0x8000);
8973       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8974     }
8975   operands[1] = tmp;
8978 ;; Conditionalize these after reload. If they match before reload, we
8979 ;; lose the clobber and ability to use integer instructions.
8981 (define_insn "*<code><mode>2_1"
8982   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8983         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8984   "TARGET_80387
8985    && (reload_completed
8986        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8987   "f<absneg_mnemonic>"
8988   [(set_attr "type" "fsgn")
8989    (set_attr "mode" "<MODE>")])
8991 (define_insn "*<code>extendsfdf2"
8992   [(set (match_operand:DF 0 "register_operand" "=f")
8993         (absneg:DF (float_extend:DF
8994                      (match_operand:SF 1 "register_operand" "0"))))]
8995   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8996   "f<absneg_mnemonic>"
8997   [(set_attr "type" "fsgn")
8998    (set_attr "mode" "DF")])
9000 (define_insn "*<code>extendsfxf2"
9001   [(set (match_operand:XF 0 "register_operand" "=f")
9002         (absneg:XF (float_extend:XF
9003                      (match_operand:SF 1 "register_operand" "0"))))]
9004   "TARGET_80387"
9005   "f<absneg_mnemonic>"
9006   [(set_attr "type" "fsgn")
9007    (set_attr "mode" "XF")])
9009 (define_insn "*<code>extenddfxf2"
9010   [(set (match_operand:XF 0 "register_operand" "=f")
9011         (absneg:XF (float_extend:XF
9012                      (match_operand:DF 1 "register_operand" "0"))))]
9013   "TARGET_80387"
9014   "f<absneg_mnemonic>"
9015   [(set_attr "type" "fsgn")
9016    (set_attr "mode" "XF")])
9018 ;; Copysign instructions
9020 (define_mode_iterator CSGNMODE [SF DF TF])
9021 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9023 (define_expand "copysign<mode>3"
9024   [(match_operand:CSGNMODE 0 "register_operand")
9025    (match_operand:CSGNMODE 1 "nonmemory_operand")
9026    (match_operand:CSGNMODE 2 "register_operand")]
9027   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9028    || (TARGET_SSE && (<MODE>mode == TFmode))"
9029   "ix86_expand_copysign (operands); DONE;")
9031 (define_insn_and_split "copysign<mode>3_const"
9032   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9033         (unspec:CSGNMODE
9034           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9035            (match_operand:CSGNMODE 2 "register_operand" "0")
9036            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9037           UNSPEC_COPYSIGN))]
9038   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9039    || (TARGET_SSE && (<MODE>mode == TFmode))"
9040   "#"
9041   "&& reload_completed"
9042   [(const_int 0)]
9043   "ix86_split_copysign_const (operands); DONE;")
9045 (define_insn "copysign<mode>3_var"
9046   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9047         (unspec:CSGNMODE
9048           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9049            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9050            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9051            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9052           UNSPEC_COPYSIGN))
9053    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9054   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9055    || (TARGET_SSE && (<MODE>mode == TFmode))"
9056   "#")
9058 (define_split
9059   [(set (match_operand:CSGNMODE 0 "register_operand")
9060         (unspec:CSGNMODE
9061           [(match_operand:CSGNMODE 2 "register_operand")
9062            (match_operand:CSGNMODE 3 "register_operand")
9063            (match_operand:<CSGNVMODE> 4)
9064            (match_operand:<CSGNVMODE> 5)]
9065           UNSPEC_COPYSIGN))
9066    (clobber (match_scratch:<CSGNVMODE> 1))]
9067   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9068     || (TARGET_SSE && (<MODE>mode == TFmode)))
9069    && reload_completed"
9070   [(const_int 0)]
9071   "ix86_split_copysign_var (operands); DONE;")
9073 ;; One complement instructions
9075 (define_expand "one_cmpl<mode>2"
9076   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9077         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9078   ""
9079   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9081 (define_insn "*one_cmpl<mode>2_1"
9082   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9083         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9084   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9085   "@
9086    not{<imodesuffix>}\t%0
9087    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9088   [(set_attr "isa" "*,avx512bw")
9089    (set_attr "type" "negnot,msklog")
9090    (set_attr "prefix" "*,vex")
9091    (set_attr "mode" "<MODE>")])
9093 (define_insn "*one_cmplhi2_1"
9094   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9095         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9096   "ix86_unary_operator_ok (NOT, HImode, operands)"
9097   "@
9098    not{w}\t%0
9099    knotw\t{%1, %0|%0, %1}"
9100   [(set_attr "isa" "*,avx512f")
9101    (set_attr "type" "negnot,msklog")
9102    (set_attr "prefix" "*,vex")
9103    (set_attr "mode" "HI")])
9105 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9106 (define_insn "*one_cmplqi2_1"
9107   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9108         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9109   "ix86_unary_operator_ok (NOT, QImode, operands)"
9111   switch (which_alternative)
9112     {
9113     case 0:
9114       return "not{b}\t%0";
9115     case 1:
9116       return "not{l}\t%k0";
9117     case 2:
9118       if (TARGET_AVX512DQ)
9119         return "knotb\t{%1, %0|%0, %1}";
9120       return "knotw\t{%1, %0|%0, %1}";
9121     default:
9122       gcc_unreachable ();
9123     }
9125   [(set_attr "isa" "*,*,avx512f")
9126    (set_attr "type" "negnot,negnot,msklog")
9127    (set_attr "prefix" "*,*,vex")
9128    (set_attr "mode" "QI,SI,QI")])
9130 ;; ??? Currently never generated - xor is used instead.
9131 (define_insn "*one_cmplsi2_1_zext"
9132   [(set (match_operand:DI 0 "register_operand" "=r")
9133         (zero_extend:DI
9134           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9135   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9136   "not{l}\t%k0"
9137   [(set_attr "type" "negnot")
9138    (set_attr "mode" "SI")])
9140 (define_insn "*one_cmpl<mode>2_2"
9141   [(set (reg FLAGS_REG)
9142         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9143                  (const_int 0)))
9144    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9145         (not:SWI (match_dup 1)))]
9146   "ix86_match_ccmode (insn, CCNOmode)
9147    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9148   "#"
9149   [(set_attr "type" "alu1")
9150    (set_attr "mode" "<MODE>")])
9152 (define_split
9153   [(set (match_operand 0 "flags_reg_operand")
9154         (match_operator 2 "compare_operator"
9155           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9156            (const_int 0)]))
9157    (set (match_operand:SWI 1 "nonimmediate_operand")
9158         (not:SWI (match_dup 3)))]
9159   "ix86_match_ccmode (insn, CCNOmode)"
9160   [(parallel [(set (match_dup 0)
9161                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9162                                     (const_int 0)]))
9163               (set (match_dup 1)
9164                    (xor:SWI (match_dup 3) (const_int -1)))])])
9166 ;; ??? Currently never generated - xor is used instead.
9167 (define_insn "*one_cmplsi2_2_zext"
9168   [(set (reg FLAGS_REG)
9169         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9170                  (const_int 0)))
9171    (set (match_operand:DI 0 "register_operand" "=r")
9172         (zero_extend:DI (not:SI (match_dup 1))))]
9173   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9174    && ix86_unary_operator_ok (NOT, SImode, operands)"
9175   "#"
9176   [(set_attr "type" "alu1")
9177    (set_attr "mode" "SI")])
9179 (define_split
9180   [(set (match_operand 0 "flags_reg_operand")
9181         (match_operator 2 "compare_operator"
9182           [(not:SI (match_operand:SI 3 "register_operand"))
9183            (const_int 0)]))
9184    (set (match_operand:DI 1 "register_operand")
9185         (zero_extend:DI (not:SI (match_dup 3))))]
9186   "ix86_match_ccmode (insn, CCNOmode)"
9187   [(parallel [(set (match_dup 0)
9188                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9189                                     (const_int 0)]))
9190               (set (match_dup 1)
9191                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9193 ;; Shift instructions
9195 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9196 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9197 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9198 ;; from the assembler input.
9200 ;; This instruction shifts the target reg/mem as usual, but instead of
9201 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9202 ;; is a left shift double, bits are taken from the high order bits of
9203 ;; reg, else if the insn is a shift right double, bits are taken from the
9204 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9205 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9207 ;; Since sh[lr]d does not change the `reg' operand, that is done
9208 ;; separately, making all shifts emit pairs of shift double and normal
9209 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9210 ;; support a 63 bit shift, each shift where the count is in a reg expands
9211 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9213 ;; If the shift count is a constant, we need never emit more than one
9214 ;; shift pair, instead using moves and sign extension for counts greater
9215 ;; than 31.
9217 (define_expand "ashl<mode>3"
9218   [(set (match_operand:SDWIM 0 "<shift_operand>")
9219         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9220                       (match_operand:QI 2 "nonmemory_operand")))]
9221   ""
9222   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9224 (define_insn "*ashl<mode>3_doubleword"
9225   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9226         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9227                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9228    (clobber (reg:CC FLAGS_REG))]
9229   ""
9230   "#"
9231   [(set_attr "type" "multi")])
9233 (define_split
9234   [(set (match_operand:DWI 0 "register_operand")
9235         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9236                     (match_operand:QI 2 "nonmemory_operand")))
9237    (clobber (reg:CC FLAGS_REG))]
9238   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9239   [(const_int 0)]
9240   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9242 ;; By default we don't ask for a scratch register, because when DWImode
9243 ;; values are manipulated, registers are already at a premium.  But if
9244 ;; we have one handy, we won't turn it away.
9246 (define_peephole2
9247   [(match_scratch:DWIH 3 "r")
9248    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9249                    (ashift:<DWI>
9250                      (match_operand:<DWI> 1 "nonmemory_operand")
9251                      (match_operand:QI 2 "nonmemory_operand")))
9252               (clobber (reg:CC FLAGS_REG))])
9253    (match_dup 3)]
9254   "TARGET_CMOVE"
9255   [(const_int 0)]
9256   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9258 (define_insn "x86_64_shld"
9259   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9260         (ior:DI (ashift:DI (match_dup 0)
9261                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9262                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9263                   (minus:QI (const_int 64) (match_dup 2)))))
9264    (clobber (reg:CC FLAGS_REG))]
9265   "TARGET_64BIT"
9266   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9267   [(set_attr "type" "ishift")
9268    (set_attr "prefix_0f" "1")
9269    (set_attr "mode" "DI")
9270    (set_attr "athlon_decode" "vector")
9271    (set_attr "amdfam10_decode" "vector")
9272    (set_attr "bdver1_decode" "vector")])
9274 (define_insn "x86_shld"
9275   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9276         (ior:SI (ashift:SI (match_dup 0)
9277                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9278                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9279                   (minus:QI (const_int 32) (match_dup 2)))))
9280    (clobber (reg:CC FLAGS_REG))]
9281   ""
9282   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9283   [(set_attr "type" "ishift")
9284    (set_attr "prefix_0f" "1")
9285    (set_attr "mode" "SI")
9286    (set_attr "pent_pair" "np")
9287    (set_attr "athlon_decode" "vector")
9288    (set_attr "amdfam10_decode" "vector")
9289    (set_attr "bdver1_decode" "vector")])
9291 (define_expand "x86_shift<mode>_adj_1"
9292   [(set (reg:CCZ FLAGS_REG)
9293         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9294                              (match_dup 4))
9295                      (const_int 0)))
9296    (set (match_operand:SWI48 0 "register_operand")
9297         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9298                             (match_operand:SWI48 1 "register_operand")
9299                             (match_dup 0)))
9300    (set (match_dup 1)
9301         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9302                             (match_operand:SWI48 3 "register_operand")
9303                             (match_dup 1)))]
9304   "TARGET_CMOVE"
9305   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9307 (define_expand "x86_shift<mode>_adj_2"
9308   [(use (match_operand:SWI48 0 "register_operand"))
9309    (use (match_operand:SWI48 1 "register_operand"))
9310    (use (match_operand:QI 2 "register_operand"))]
9311   ""
9313   rtx_code_label *label = gen_label_rtx ();
9314   rtx tmp;
9316   emit_insn (gen_testqi_ccz_1 (operands[2],
9317                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9319   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9320   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9321   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9322                               gen_rtx_LABEL_REF (VOIDmode, label),
9323                               pc_rtx);
9324   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9325   JUMP_LABEL (tmp) = label;
9327   emit_move_insn (operands[0], operands[1]);
9328   ix86_expand_clear (operands[1]);
9330   emit_label (label);
9331   LABEL_NUSES (label) = 1;
9333   DONE;
9336 ;; Avoid useless masking of count operand.
9337 (define_insn "*ashl<mode>3_mask"
9338   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9339         (ashift:SWI48
9340           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9341           (subreg:QI
9342             (and:SI
9343               (match_operand:SI 2 "register_operand" "c")
9344               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9347    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9348       == GET_MODE_BITSIZE (<MODE>mode)-1"
9350   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9352   [(set_attr "type" "ishift")
9353    (set_attr "mode" "<MODE>")])
9355 (define_insn "*bmi2_ashl<mode>3_1"
9356   [(set (match_operand:SWI48 0 "register_operand" "=r")
9357         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9358                       (match_operand:SWI48 2 "register_operand" "r")))]
9359   "TARGET_BMI2"
9360   "shlx\t{%2, %1, %0|%0, %1, %2}"
9361   [(set_attr "type" "ishiftx")
9362    (set_attr "mode" "<MODE>")])
9364 (define_insn "*ashl<mode>3_1"
9365   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9366         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9367                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9371   switch (get_attr_type (insn))
9372     {
9373     case TYPE_LEA:
9374     case TYPE_ISHIFTX:
9375       return "#";
9377     case TYPE_ALU:
9378       gcc_assert (operands[2] == const1_rtx);
9379       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9380       return "add{<imodesuffix>}\t%0, %0";
9382     default:
9383       if (operands[2] == const1_rtx
9384           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9385         return "sal{<imodesuffix>}\t%0";
9386       else
9387         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9388     }
9390   [(set_attr "isa" "*,*,bmi2")
9391    (set (attr "type")
9392      (cond [(eq_attr "alternative" "1")
9393               (const_string "lea")
9394             (eq_attr "alternative" "2")
9395               (const_string "ishiftx")
9396             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9397                       (match_operand 0 "register_operand"))
9398                  (match_operand 2 "const1_operand"))
9399               (const_string "alu")
9400            ]
9401            (const_string "ishift")))
9402    (set (attr "length_immediate")
9403      (if_then_else
9404        (ior (eq_attr "type" "alu")
9405             (and (eq_attr "type" "ishift")
9406                  (and (match_operand 2 "const1_operand")
9407                       (ior (match_test "TARGET_SHIFT1")
9408                            (match_test "optimize_function_for_size_p (cfun)")))))
9409        (const_string "0")
9410        (const_string "*")))
9411    (set_attr "mode" "<MODE>")])
9413 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9414 (define_split
9415   [(set (match_operand:SWI48 0 "register_operand")
9416         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9417                       (match_operand:QI 2 "register_operand")))
9418    (clobber (reg:CC FLAGS_REG))]
9419   "TARGET_BMI2 && reload_completed"
9420   [(set (match_dup 0)
9421         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9422   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9424 (define_insn "*bmi2_ashlsi3_1_zext"
9425   [(set (match_operand:DI 0 "register_operand" "=r")
9426         (zero_extend:DI
9427           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9428                      (match_operand:SI 2 "register_operand" "r"))))]
9429   "TARGET_64BIT && TARGET_BMI2"
9430   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9431   [(set_attr "type" "ishiftx")
9432    (set_attr "mode" "SI")])
9434 (define_insn "*ashlsi3_1_zext"
9435   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9436         (zero_extend:DI
9437           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9438                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9439    (clobber (reg:CC FLAGS_REG))]
9440   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9442   switch (get_attr_type (insn))
9443     {
9444     case TYPE_LEA:
9445     case TYPE_ISHIFTX:
9446       return "#";
9448     case TYPE_ALU:
9449       gcc_assert (operands[2] == const1_rtx);
9450       return "add{l}\t%k0, %k0";
9452     default:
9453       if (operands[2] == const1_rtx
9454           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9455         return "sal{l}\t%k0";
9456       else
9457         return "sal{l}\t{%2, %k0|%k0, %2}";
9458     }
9460   [(set_attr "isa" "*,*,bmi2")
9461    (set (attr "type")
9462      (cond [(eq_attr "alternative" "1")
9463               (const_string "lea")
9464             (eq_attr "alternative" "2")
9465               (const_string "ishiftx")
9466             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9467                  (match_operand 2 "const1_operand"))
9468               (const_string "alu")
9469            ]
9470            (const_string "ishift")))
9471    (set (attr "length_immediate")
9472      (if_then_else
9473        (ior (eq_attr "type" "alu")
9474             (and (eq_attr "type" "ishift")
9475                  (and (match_operand 2 "const1_operand")
9476                       (ior (match_test "TARGET_SHIFT1")
9477                            (match_test "optimize_function_for_size_p (cfun)")))))
9478        (const_string "0")
9479        (const_string "*")))
9480    (set_attr "mode" "SI")])
9482 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9483 (define_split
9484   [(set (match_operand:DI 0 "register_operand")
9485         (zero_extend:DI
9486           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9487                      (match_operand:QI 2 "register_operand"))))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9490   [(set (match_dup 0)
9491         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9492   "operands[2] = gen_lowpart (SImode, operands[2]);")
9494 (define_insn "*ashlhi3_1"
9495   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9496         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9497                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9498    (clobber (reg:CC FLAGS_REG))]
9499   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9501   switch (get_attr_type (insn))
9502     {
9503     case TYPE_LEA:
9504       return "#";
9506     case TYPE_ALU:
9507       gcc_assert (operands[2] == const1_rtx);
9508       return "add{w}\t%0, %0";
9510     default:
9511       if (operands[2] == const1_rtx
9512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513         return "sal{w}\t%0";
9514       else
9515         return "sal{w}\t{%2, %0|%0, %2}";
9516     }
9518   [(set (attr "type")
9519      (cond [(eq_attr "alternative" "1")
9520               (const_string "lea")
9521             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9522                       (match_operand 0 "register_operand"))
9523                  (match_operand 2 "const1_operand"))
9524               (const_string "alu")
9525            ]
9526            (const_string "ishift")))
9527    (set (attr "length_immediate")
9528      (if_then_else
9529        (ior (eq_attr "type" "alu")
9530             (and (eq_attr "type" "ishift")
9531                  (and (match_operand 2 "const1_operand")
9532                       (ior (match_test "TARGET_SHIFT1")
9533                            (match_test "optimize_function_for_size_p (cfun)")))))
9534        (const_string "0")
9535        (const_string "*")))
9536    (set_attr "mode" "HI,SI")])
9538 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9539 (define_insn "*ashlqi3_1"
9540   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9541         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9542                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9546   switch (get_attr_type (insn))
9547     {
9548     case TYPE_LEA:
9549       return "#";
9551     case TYPE_ALU:
9552       gcc_assert (operands[2] == const1_rtx);
9553       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9554         return "add{l}\t%k0, %k0";
9555       else
9556         return "add{b}\t%0, %0";
9558     default:
9559       if (operands[2] == const1_rtx
9560           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9561         {
9562           if (get_attr_mode (insn) == MODE_SI)
9563             return "sal{l}\t%k0";
9564           else
9565             return "sal{b}\t%0";
9566         }
9567       else
9568         {
9569           if (get_attr_mode (insn) == MODE_SI)
9570             return "sal{l}\t{%2, %k0|%k0, %2}";
9571           else
9572             return "sal{b}\t{%2, %0|%0, %2}";
9573         }
9574     }
9576   [(set (attr "type")
9577      (cond [(eq_attr "alternative" "2")
9578               (const_string "lea")
9579             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9580                       (match_operand 0 "register_operand"))
9581                  (match_operand 2 "const1_operand"))
9582               (const_string "alu")
9583            ]
9584            (const_string "ishift")))
9585    (set (attr "length_immediate")
9586      (if_then_else
9587        (ior (eq_attr "type" "alu")
9588             (and (eq_attr "type" "ishift")
9589                  (and (match_operand 2 "const1_operand")
9590                       (ior (match_test "TARGET_SHIFT1")
9591                            (match_test "optimize_function_for_size_p (cfun)")))))
9592        (const_string "0")
9593        (const_string "*")))
9594    (set_attr "mode" "QI,SI,SI")])
9596 (define_insn "*ashlqi3_1_slp"
9597   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9598         (ashift:QI (match_dup 0)
9599                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "(optimize_function_for_size_p (cfun)
9602     || !TARGET_PARTIAL_FLAG_REG_STALL
9603     || (operands[1] == const1_rtx
9604         && (TARGET_SHIFT1
9605             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9607   switch (get_attr_type (insn))
9608     {
9609     case TYPE_ALU:
9610       gcc_assert (operands[1] == const1_rtx);
9611       return "add{b}\t%0, %0";
9613     default:
9614       if (operands[1] == const1_rtx
9615           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9616         return "sal{b}\t%0";
9617       else
9618         return "sal{b}\t{%1, %0|%0, %1}";
9619     }
9621   [(set (attr "type")
9622      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9623                       (match_operand 0 "register_operand"))
9624                  (match_operand 1 "const1_operand"))
9625               (const_string "alu")
9626            ]
9627            (const_string "ishift1")))
9628    (set (attr "length_immediate")
9629      (if_then_else
9630        (ior (eq_attr "type" "alu")
9631             (and (eq_attr "type" "ishift1")
9632                  (and (match_operand 1 "const1_operand")
9633                       (ior (match_test "TARGET_SHIFT1")
9634                            (match_test "optimize_function_for_size_p (cfun)")))))
9635        (const_string "0")
9636        (const_string "*")))
9637    (set_attr "mode" "QI")])
9639 ;; Convert ashift to the lea pattern to avoid flags dependency.
9640 (define_split
9641   [(set (match_operand 0 "register_operand")
9642         (ashift (match_operand 1 "index_register_operand")
9643                 (match_operand:QI 2 "const_int_operand")))
9644    (clobber (reg:CC FLAGS_REG))]
9645   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9646    && reload_completed
9647    && true_regnum (operands[0]) != true_regnum (operands[1])"
9648   [(const_int 0)]
9650   machine_mode mode = GET_MODE (operands[0]);
9651   rtx pat;
9653   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9654     { 
9655       mode = SImode; 
9656       operands[0] = gen_lowpart (mode, operands[0]);
9657       operands[1] = gen_lowpart (mode, operands[1]);
9658     }
9660   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9662   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9664   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9665   DONE;
9668 ;; Convert ashift to the lea pattern to avoid flags dependency.
9669 (define_split
9670   [(set (match_operand:DI 0 "register_operand")
9671         (zero_extend:DI
9672           (ashift:SI (match_operand:SI 1 "index_register_operand")
9673                      (match_operand:QI 2 "const_int_operand"))))
9674    (clobber (reg:CC FLAGS_REG))]
9675   "TARGET_64BIT && reload_completed
9676    && true_regnum (operands[0]) != true_regnum (operands[1])"
9677   [(set (match_dup 0)
9678         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9680   operands[1] = gen_lowpart (SImode, operands[1]);
9681   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9684 ;; This pattern can't accept a variable shift count, since shifts by
9685 ;; zero don't affect the flags.  We assume that shifts by constant
9686 ;; zero are optimized away.
9687 (define_insn "*ashl<mode>3_cmp"
9688   [(set (reg FLAGS_REG)
9689         (compare
9690           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9691                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9692           (const_int 0)))
9693    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9694         (ashift:SWI (match_dup 1) (match_dup 2)))]
9695   "(optimize_function_for_size_p (cfun)
9696     || !TARGET_PARTIAL_FLAG_REG_STALL
9697     || (operands[2] == const1_rtx
9698         && (TARGET_SHIFT1
9699             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9700    && ix86_match_ccmode (insn, CCGOCmode)
9701    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9703   switch (get_attr_type (insn))
9704     {
9705     case TYPE_ALU:
9706       gcc_assert (operands[2] == const1_rtx);
9707       return "add{<imodesuffix>}\t%0, %0";
9709     default:
9710       if (operands[2] == const1_rtx
9711           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9712         return "sal{<imodesuffix>}\t%0";
9713       else
9714         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9715     }
9717   [(set (attr "type")
9718      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9719                       (match_operand 0 "register_operand"))
9720                  (match_operand 2 "const1_operand"))
9721               (const_string "alu")
9722            ]
9723            (const_string "ishift")))
9724    (set (attr "length_immediate")
9725      (if_then_else
9726        (ior (eq_attr "type" "alu")
9727             (and (eq_attr "type" "ishift")
9728                  (and (match_operand 2 "const1_operand")
9729                       (ior (match_test "TARGET_SHIFT1")
9730                            (match_test "optimize_function_for_size_p (cfun)")))))
9731        (const_string "0")
9732        (const_string "*")))
9733    (set_attr "mode" "<MODE>")])
9735 (define_insn "*ashlsi3_cmp_zext"
9736   [(set (reg FLAGS_REG)
9737         (compare
9738           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9739                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9740           (const_int 0)))
9741    (set (match_operand:DI 0 "register_operand" "=r")
9742         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9743   "TARGET_64BIT
9744    && (optimize_function_for_size_p (cfun)
9745        || !TARGET_PARTIAL_FLAG_REG_STALL
9746        || (operands[2] == const1_rtx
9747            && (TARGET_SHIFT1
9748                || TARGET_DOUBLE_WITH_ADD)))
9749    && ix86_match_ccmode (insn, CCGOCmode)
9750    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9752   switch (get_attr_type (insn))
9753     {
9754     case TYPE_ALU:
9755       gcc_assert (operands[2] == const1_rtx);
9756       return "add{l}\t%k0, %k0";
9758     default:
9759       if (operands[2] == const1_rtx
9760           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9761         return "sal{l}\t%k0";
9762       else
9763         return "sal{l}\t{%2, %k0|%k0, %2}";
9764     }
9766   [(set (attr "type")
9767      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9768                  (match_operand 2 "const1_operand"))
9769               (const_string "alu")
9770            ]
9771            (const_string "ishift")))
9772    (set (attr "length_immediate")
9773      (if_then_else
9774        (ior (eq_attr "type" "alu")
9775             (and (eq_attr "type" "ishift")
9776                  (and (match_operand 2 "const1_operand")
9777                       (ior (match_test "TARGET_SHIFT1")
9778                            (match_test "optimize_function_for_size_p (cfun)")))))
9779        (const_string "0")
9780        (const_string "*")))
9781    (set_attr "mode" "SI")])
9783 (define_insn "*ashl<mode>3_cconly"
9784   [(set (reg FLAGS_REG)
9785         (compare
9786           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9787                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9788           (const_int 0)))
9789    (clobber (match_scratch:SWI 0 "=<r>"))]
9790   "(optimize_function_for_size_p (cfun)
9791     || !TARGET_PARTIAL_FLAG_REG_STALL
9792     || (operands[2] == const1_rtx
9793         && (TARGET_SHIFT1
9794             || TARGET_DOUBLE_WITH_ADD)))
9795    && ix86_match_ccmode (insn, CCGOCmode)"
9797   switch (get_attr_type (insn))
9798     {
9799     case TYPE_ALU:
9800       gcc_assert (operands[2] == const1_rtx);
9801       return "add{<imodesuffix>}\t%0, %0";
9803     default:
9804       if (operands[2] == const1_rtx
9805           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9806         return "sal{<imodesuffix>}\t%0";
9807       else
9808         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9809     }
9811   [(set (attr "type")
9812      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9813                       (match_operand 0 "register_operand"))
9814                  (match_operand 2 "const1_operand"))
9815               (const_string "alu")
9816            ]
9817            (const_string "ishift")))
9818    (set (attr "length_immediate")
9819      (if_then_else
9820        (ior (eq_attr "type" "alu")
9821             (and (eq_attr "type" "ishift")
9822                  (and (match_operand 2 "const1_operand")
9823                       (ior (match_test "TARGET_SHIFT1")
9824                            (match_test "optimize_function_for_size_p (cfun)")))))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "<MODE>")])
9829 ;; See comment above `ashl<mode>3' about how this works.
9831 (define_expand "<shift_insn><mode>3"
9832   [(set (match_operand:SDWIM 0 "<shift_operand>")
9833         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9834                            (match_operand:QI 2 "nonmemory_operand")))]
9835   ""
9836   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9838 ;; Avoid useless masking of count operand.
9839 (define_insn "*<shift_insn><mode>3_mask"
9840   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9841         (any_shiftrt:SWI48
9842           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9843           (subreg:QI
9844             (and:SI
9845               (match_operand:SI 2 "register_operand" "c")
9846               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9847    (clobber (reg:CC FLAGS_REG))]
9848   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9849    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9850       == GET_MODE_BITSIZE (<MODE>mode)-1"
9852   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9854   [(set_attr "type" "ishift")
9855    (set_attr "mode" "<MODE>")])
9857 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9858   [(set (match_operand:DWI 0 "register_operand" "=r")
9859         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9860                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   ""
9863   "#"
9864   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9865   [(const_int 0)]
9866   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9867   [(set_attr "type" "multi")])
9869 ;; By default we don't ask for a scratch register, because when DWImode
9870 ;; values are manipulated, registers are already at a premium.  But if
9871 ;; we have one handy, we won't turn it away.
9873 (define_peephole2
9874   [(match_scratch:DWIH 3 "r")
9875    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9876                    (any_shiftrt:<DWI>
9877                      (match_operand:<DWI> 1 "register_operand")
9878                      (match_operand:QI 2 "nonmemory_operand")))
9879               (clobber (reg:CC FLAGS_REG))])
9880    (match_dup 3)]
9881   "TARGET_CMOVE"
9882   [(const_int 0)]
9883   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9885 (define_insn "x86_64_shrd"
9886   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9887         (ior:DI (lshiftrt:DI (match_dup 0)
9888                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9889                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9890                   (minus:QI (const_int 64) (match_dup 2)))))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_64BIT"
9893   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9894   [(set_attr "type" "ishift")
9895    (set_attr "prefix_0f" "1")
9896    (set_attr "mode" "DI")
9897    (set_attr "athlon_decode" "vector")
9898    (set_attr "amdfam10_decode" "vector")
9899    (set_attr "bdver1_decode" "vector")])
9901 (define_insn "x86_shrd"
9902   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9903         (ior:SI (lshiftrt:SI (match_dup 0)
9904                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9905                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9906                   (minus:QI (const_int 32) (match_dup 2)))))
9907    (clobber (reg:CC FLAGS_REG))]
9908   ""
9909   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9910   [(set_attr "type" "ishift")
9911    (set_attr "prefix_0f" "1")
9912    (set_attr "mode" "SI")
9913    (set_attr "pent_pair" "np")
9914    (set_attr "athlon_decode" "vector")
9915    (set_attr "amdfam10_decode" "vector")
9916    (set_attr "bdver1_decode" "vector")])
9918 (define_insn "ashrdi3_cvt"
9919   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9920         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9921                      (match_operand:QI 2 "const_int_operand")))
9922    (clobber (reg:CC FLAGS_REG))]
9923   "TARGET_64BIT && INTVAL (operands[2]) == 63
9924    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9925    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9926   "@
9927    {cqto|cqo}
9928    sar{q}\t{%2, %0|%0, %2}"
9929   [(set_attr "type" "imovx,ishift")
9930    (set_attr "prefix_0f" "0,*")
9931    (set_attr "length_immediate" "0,*")
9932    (set_attr "modrm" "0,1")
9933    (set_attr "mode" "DI")])
9935 (define_insn "ashrsi3_cvt"
9936   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9937         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9938                      (match_operand:QI 2 "const_int_operand")))
9939    (clobber (reg:CC FLAGS_REG))]
9940   "INTVAL (operands[2]) == 31
9941    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9942    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9943   "@
9944    {cltd|cdq}
9945    sar{l}\t{%2, %0|%0, %2}"
9946   [(set_attr "type" "imovx,ishift")
9947    (set_attr "prefix_0f" "0,*")
9948    (set_attr "length_immediate" "0,*")
9949    (set_attr "modrm" "0,1")
9950    (set_attr "mode" "SI")])
9952 (define_insn "*ashrsi3_cvt_zext"
9953   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9954         (zero_extend:DI
9955           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9956                        (match_operand:QI 2 "const_int_operand"))))
9957    (clobber (reg:CC FLAGS_REG))]
9958   "TARGET_64BIT && INTVAL (operands[2]) == 31
9959    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9960    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9961   "@
9962    {cltd|cdq}
9963    sar{l}\t{%2, %k0|%k0, %2}"
9964   [(set_attr "type" "imovx,ishift")
9965    (set_attr "prefix_0f" "0,*")
9966    (set_attr "length_immediate" "0,*")
9967    (set_attr "modrm" "0,1")
9968    (set_attr "mode" "SI")])
9970 (define_expand "x86_shift<mode>_adj_3"
9971   [(use (match_operand:SWI48 0 "register_operand"))
9972    (use (match_operand:SWI48 1 "register_operand"))
9973    (use (match_operand:QI 2 "register_operand"))]
9974   ""
9976   rtx_code_label *label = gen_label_rtx ();
9977   rtx tmp;
9979   emit_insn (gen_testqi_ccz_1 (operands[2],
9980                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9982   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9983   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9984   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9985                               gen_rtx_LABEL_REF (VOIDmode, label),
9986                               pc_rtx);
9987   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9988   JUMP_LABEL (tmp) = label;
9990   emit_move_insn (operands[0], operands[1]);
9991   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9992                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9993   emit_label (label);
9994   LABEL_NUSES (label) = 1;
9996   DONE;
9999 (define_insn "*bmi2_<shift_insn><mode>3_1"
10000   [(set (match_operand:SWI48 0 "register_operand" "=r")
10001         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10002                            (match_operand:SWI48 2 "register_operand" "r")))]
10003   "TARGET_BMI2"
10004   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10005   [(set_attr "type" "ishiftx")
10006    (set_attr "mode" "<MODE>")])
10008 (define_insn "*<shift_insn><mode>3_1"
10009   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10010         (any_shiftrt:SWI48
10011           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10012           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10016   switch (get_attr_type (insn))
10017     {
10018     case TYPE_ISHIFTX:
10019       return "#";
10021     default:
10022       if (operands[2] == const1_rtx
10023           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10024         return "<shift>{<imodesuffix>}\t%0";
10025       else
10026         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10027     }
10029   [(set_attr "isa" "*,bmi2")
10030    (set_attr "type" "ishift,ishiftx")
10031    (set (attr "length_immediate")
10032      (if_then_else
10033        (and (match_operand 2 "const1_operand")
10034             (ior (match_test "TARGET_SHIFT1")
10035                  (match_test "optimize_function_for_size_p (cfun)")))
10036        (const_string "0")
10037        (const_string "*")))
10038    (set_attr "mode" "<MODE>")])
10040 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10041 (define_split
10042   [(set (match_operand:SWI48 0 "register_operand")
10043         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10044                            (match_operand:QI 2 "register_operand")))
10045    (clobber (reg:CC FLAGS_REG))]
10046   "TARGET_BMI2 && reload_completed"
10047   [(set (match_dup 0)
10048         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10049   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10051 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10052   [(set (match_operand:DI 0 "register_operand" "=r")
10053         (zero_extend:DI
10054           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10055                           (match_operand:SI 2 "register_operand" "r"))))]
10056   "TARGET_64BIT && TARGET_BMI2"
10057   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10058   [(set_attr "type" "ishiftx")
10059    (set_attr "mode" "SI")])
10061 (define_insn "*<shift_insn>si3_1_zext"
10062   [(set (match_operand:DI 0 "register_operand" "=r,r")
10063         (zero_extend:DI
10064           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10065                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10066    (clobber (reg:CC FLAGS_REG))]
10067   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10069   switch (get_attr_type (insn))
10070     {
10071     case TYPE_ISHIFTX:
10072       return "#";
10074     default:
10075       if (operands[2] == const1_rtx
10076           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10077         return "<shift>{l}\t%k0";
10078       else
10079         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10080     }
10082   [(set_attr "isa" "*,bmi2")
10083    (set_attr "type" "ishift,ishiftx")
10084    (set (attr "length_immediate")
10085      (if_then_else
10086        (and (match_operand 2 "const1_operand")
10087             (ior (match_test "TARGET_SHIFT1")
10088                  (match_test "optimize_function_for_size_p (cfun)")))
10089        (const_string "0")
10090        (const_string "*")))
10091    (set_attr "mode" "SI")])
10093 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10094 (define_split
10095   [(set (match_operand:DI 0 "register_operand")
10096         (zero_extend:DI
10097           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10098                           (match_operand:QI 2 "register_operand"))))
10099    (clobber (reg:CC FLAGS_REG))]
10100   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10101   [(set (match_dup 0)
10102         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10103   "operands[2] = gen_lowpart (SImode, operands[2]);")
10105 (define_insn "*<shift_insn><mode>3_1"
10106   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10107         (any_shiftrt:SWI12
10108           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10109           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10110    (clobber (reg:CC FLAGS_REG))]
10111   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113   if (operands[2] == const1_rtx
10114       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10115     return "<shift>{<imodesuffix>}\t%0";
10116   else
10117     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10119   [(set_attr "type" "ishift")
10120    (set (attr "length_immediate")
10121      (if_then_else
10122        (and (match_operand 2 "const1_operand")
10123             (ior (match_test "TARGET_SHIFT1")
10124                  (match_test "optimize_function_for_size_p (cfun)")))
10125        (const_string "0")
10126        (const_string "*")))
10127    (set_attr "mode" "<MODE>")])
10129 (define_insn "*<shift_insn>qi3_1_slp"
10130   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10131         (any_shiftrt:QI (match_dup 0)
10132                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "(optimize_function_for_size_p (cfun)
10135     || !TARGET_PARTIAL_REG_STALL
10136     || (operands[1] == const1_rtx
10137         && TARGET_SHIFT1))"
10139   if (operands[1] == const1_rtx
10140       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10141     return "<shift>{b}\t%0";
10142   else
10143     return "<shift>{b}\t{%1, %0|%0, %1}";
10145   [(set_attr "type" "ishift1")
10146    (set (attr "length_immediate")
10147      (if_then_else
10148        (and (match_operand 1 "const1_operand")
10149             (ior (match_test "TARGET_SHIFT1")
10150                  (match_test "optimize_function_for_size_p (cfun)")))
10151        (const_string "0")
10152        (const_string "*")))
10153    (set_attr "mode" "QI")])
10155 ;; This pattern can't accept a variable shift count, since shifts by
10156 ;; zero don't affect the flags.  We assume that shifts by constant
10157 ;; zero are optimized away.
10158 (define_insn "*<shift_insn><mode>3_cmp"
10159   [(set (reg FLAGS_REG)
10160         (compare
10161           (any_shiftrt:SWI
10162             (match_operand:SWI 1 "nonimmediate_operand" "0")
10163             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10164           (const_int 0)))
10165    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10166         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10167   "(optimize_function_for_size_p (cfun)
10168     || !TARGET_PARTIAL_FLAG_REG_STALL
10169     || (operands[2] == const1_rtx
10170         && TARGET_SHIFT1))
10171    && ix86_match_ccmode (insn, CCGOCmode)
10172    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10174   if (operands[2] == const1_rtx
10175       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10176     return "<shift>{<imodesuffix>}\t%0";
10177   else
10178     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10180   [(set_attr "type" "ishift")
10181    (set (attr "length_immediate")
10182      (if_then_else
10183        (and (match_operand 2 "const1_operand")
10184             (ior (match_test "TARGET_SHIFT1")
10185                  (match_test "optimize_function_for_size_p (cfun)")))
10186        (const_string "0")
10187        (const_string "*")))
10188    (set_attr "mode" "<MODE>")])
10190 (define_insn "*<shift_insn>si3_cmp_zext"
10191   [(set (reg FLAGS_REG)
10192         (compare
10193           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10194                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10195           (const_int 0)))
10196    (set (match_operand:DI 0 "register_operand" "=r")
10197         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10198   "TARGET_64BIT
10199    && (optimize_function_for_size_p (cfun)
10200        || !TARGET_PARTIAL_FLAG_REG_STALL
10201        || (operands[2] == const1_rtx
10202            && TARGET_SHIFT1))
10203    && ix86_match_ccmode (insn, CCGOCmode)
10204    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10206   if (operands[2] == const1_rtx
10207       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10208     return "<shift>{l}\t%k0";
10209   else
10210     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10212   [(set_attr "type" "ishift")
10213    (set (attr "length_immediate")
10214      (if_then_else
10215        (and (match_operand 2 "const1_operand")
10216             (ior (match_test "TARGET_SHIFT1")
10217                  (match_test "optimize_function_for_size_p (cfun)")))
10218        (const_string "0")
10219        (const_string "*")))
10220    (set_attr "mode" "SI")])
10222 (define_insn "*<shift_insn><mode>3_cconly"
10223   [(set (reg FLAGS_REG)
10224         (compare
10225           (any_shiftrt:SWI
10226             (match_operand:SWI 1 "register_operand" "0")
10227             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10228           (const_int 0)))
10229    (clobber (match_scratch:SWI 0 "=<r>"))]
10230   "(optimize_function_for_size_p (cfun)
10231     || !TARGET_PARTIAL_FLAG_REG_STALL
10232     || (operands[2] == const1_rtx
10233         && TARGET_SHIFT1))
10234    && ix86_match_ccmode (insn, CCGOCmode)"
10236   if (operands[2] == const1_rtx
10237       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238     return "<shift>{<imodesuffix>}\t%0";
10239   else
10240     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242   [(set_attr "type" "ishift")
10243    (set (attr "length_immediate")
10244      (if_then_else
10245        (and (match_operand 2 "const1_operand")
10246             (ior (match_test "TARGET_SHIFT1")
10247                  (match_test "optimize_function_for_size_p (cfun)")))
10248        (const_string "0")
10249        (const_string "*")))
10250    (set_attr "mode" "<MODE>")])
10252 ;; Rotate instructions
10254 (define_expand "<rotate_insn>ti3"
10255   [(set (match_operand:TI 0 "register_operand")
10256         (any_rotate:TI (match_operand:TI 1 "register_operand")
10257                        (match_operand:QI 2 "nonmemory_operand")))]
10258   "TARGET_64BIT"
10260   if (const_1_to_63_operand (operands[2], VOIDmode))
10261     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10262                 (operands[0], operands[1], operands[2]));
10263   else
10264     FAIL;
10266   DONE;
10269 (define_expand "<rotate_insn>di3"
10270   [(set (match_operand:DI 0 "shiftdi_operand")
10271         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10272                        (match_operand:QI 2 "nonmemory_operand")))]
10273  ""
10275   if (TARGET_64BIT)
10276     ix86_expand_binary_operator (<CODE>, DImode, operands);
10277   else if (const_1_to_31_operand (operands[2], VOIDmode))
10278     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10279                 (operands[0], operands[1], operands[2]));
10280   else
10281     FAIL;
10283   DONE;
10286 (define_expand "<rotate_insn><mode>3"
10287   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10288         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10289                             (match_operand:QI 2 "nonmemory_operand")))]
10290   ""
10291   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10293 ;; Avoid useless masking of count operand.
10294 (define_insn "*<rotate_insn><mode>3_mask"
10295   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10296         (any_rotate:SWI48
10297           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10298           (subreg:QI
10299             (and:SI
10300               (match_operand:SI 2 "register_operand" "c")
10301               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10304    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10305       == GET_MODE_BITSIZE (<MODE>mode)-1"
10307   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10309   [(set_attr "type" "rotate")
10310    (set_attr "mode" "<MODE>")])
10312 ;; Implement rotation using two double-precision
10313 ;; shift instructions and a scratch register.
10315 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10316  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10317        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10318                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10319   (clobber (reg:CC FLAGS_REG))
10320   (clobber (match_scratch:DWIH 3 "=&r"))]
10321  ""
10322  "#"
10323  "reload_completed"
10324  [(set (match_dup 3) (match_dup 4))
10325   (parallel
10326    [(set (match_dup 4)
10327          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10328                    (lshiftrt:DWIH (match_dup 5)
10329                                   (minus:QI (match_dup 6) (match_dup 2)))))
10330     (clobber (reg:CC FLAGS_REG))])
10331   (parallel
10332    [(set (match_dup 5)
10333          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10334                    (lshiftrt:DWIH (match_dup 3)
10335                                   (minus:QI (match_dup 6) (match_dup 2)))))
10336     (clobber (reg:CC FLAGS_REG))])]
10338   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10340   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10343 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10344  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10345        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10346                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10347   (clobber (reg:CC FLAGS_REG))
10348   (clobber (match_scratch:DWIH 3 "=&r"))]
10349  ""
10350  "#"
10351  "reload_completed"
10352  [(set (match_dup 3) (match_dup 4))
10353   (parallel
10354    [(set (match_dup 4)
10355          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10356                    (ashift:DWIH (match_dup 5)
10357                                 (minus:QI (match_dup 6) (match_dup 2)))))
10358     (clobber (reg:CC FLAGS_REG))])
10359   (parallel
10360    [(set (match_dup 5)
10361          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10362                    (ashift:DWIH (match_dup 3)
10363                                 (minus:QI (match_dup 6) (match_dup 2)))))
10364     (clobber (reg:CC FLAGS_REG))])]
10366   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10368   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10371 (define_insn "*bmi2_rorx<mode>3_1"
10372   [(set (match_operand:SWI48 0 "register_operand" "=r")
10373         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10374                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10375   "TARGET_BMI2"
10376   "rorx\t{%2, %1, %0|%0, %1, %2}"
10377   [(set_attr "type" "rotatex")
10378    (set_attr "mode" "<MODE>")])
10380 (define_insn "*<rotate_insn><mode>3_1"
10381   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10382         (any_rotate:SWI48
10383           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10384           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10385    (clobber (reg:CC FLAGS_REG))]
10386   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10388   switch (get_attr_type (insn))
10389     {
10390     case TYPE_ROTATEX:
10391       return "#";
10393     default:
10394       if (operands[2] == const1_rtx
10395           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10396         return "<rotate>{<imodesuffix>}\t%0";
10397       else
10398         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10399     }
10401   [(set_attr "isa" "*,bmi2")
10402    (set_attr "type" "rotate,rotatex")
10403    (set (attr "length_immediate")
10404      (if_then_else
10405        (and (eq_attr "type" "rotate")
10406             (and (match_operand 2 "const1_operand")
10407                  (ior (match_test "TARGET_SHIFT1")
10408                       (match_test "optimize_function_for_size_p (cfun)"))))
10409        (const_string "0")
10410        (const_string "*")))
10411    (set_attr "mode" "<MODE>")])
10413 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10414 (define_split
10415   [(set (match_operand:SWI48 0 "register_operand")
10416         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10417                       (match_operand:QI 2 "immediate_operand")))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "TARGET_BMI2 && reload_completed"
10420   [(set (match_dup 0)
10421         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10423   operands[2]
10424     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10427 (define_split
10428   [(set (match_operand:SWI48 0 "register_operand")
10429         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10430                         (match_operand:QI 2 "immediate_operand")))
10431    (clobber (reg:CC FLAGS_REG))]
10432   "TARGET_BMI2 && reload_completed"
10433   [(set (match_dup 0)
10434         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10436 (define_insn "*bmi2_rorxsi3_1_zext"
10437   [(set (match_operand:DI 0 "register_operand" "=r")
10438         (zero_extend:DI
10439           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10440                        (match_operand:QI 2 "immediate_operand" "I"))))]
10441   "TARGET_64BIT && TARGET_BMI2"
10442   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10443   [(set_attr "type" "rotatex")
10444    (set_attr "mode" "SI")])
10446 (define_insn "*<rotate_insn>si3_1_zext"
10447   [(set (match_operand:DI 0 "register_operand" "=r,r")
10448         (zero_extend:DI
10449           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10450                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10451    (clobber (reg:CC FLAGS_REG))]
10452   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10454   switch (get_attr_type (insn))
10455     {
10456     case TYPE_ROTATEX:
10457       return "#";
10459     default:
10460       if (operands[2] == const1_rtx
10461           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10462         return "<rotate>{l}\t%k0";
10463       else
10464         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10465     }
10467   [(set_attr "isa" "*,bmi2")
10468    (set_attr "type" "rotate,rotatex")
10469    (set (attr "length_immediate")
10470      (if_then_else
10471        (and (eq_attr "type" "rotate")
10472             (and (match_operand 2 "const1_operand")
10473                  (ior (match_test "TARGET_SHIFT1")
10474                       (match_test "optimize_function_for_size_p (cfun)"))))
10475        (const_string "0")
10476        (const_string "*")))
10477    (set_attr "mode" "SI")])
10479 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10480 (define_split
10481   [(set (match_operand:DI 0 "register_operand")
10482         (zero_extend:DI
10483           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10484                      (match_operand:QI 2 "immediate_operand"))))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10487   [(set (match_dup 0)
10488         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10490   operands[2]
10491     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10494 (define_split
10495   [(set (match_operand:DI 0 "register_operand")
10496         (zero_extend:DI
10497           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10498                        (match_operand:QI 2 "immediate_operand"))))
10499    (clobber (reg:CC FLAGS_REG))]
10500   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10501   [(set (match_dup 0)
10502         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10504 (define_insn "*<rotate_insn><mode>3_1"
10505   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10506         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10507                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10508    (clobber (reg:CC FLAGS_REG))]
10509   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10511   if (operands[2] == const1_rtx
10512       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10513     return "<rotate>{<imodesuffix>}\t%0";
10514   else
10515     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10517   [(set_attr "type" "rotate")
10518    (set (attr "length_immediate")
10519      (if_then_else
10520        (and (match_operand 2 "const1_operand")
10521             (ior (match_test "TARGET_SHIFT1")
10522                  (match_test "optimize_function_for_size_p (cfun)")))
10523        (const_string "0")
10524        (const_string "*")))
10525    (set_attr "mode" "<MODE>")])
10527 (define_insn "*<rotate_insn>qi3_1_slp"
10528   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10529         (any_rotate:QI (match_dup 0)
10530                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10531    (clobber (reg:CC FLAGS_REG))]
10532   "(optimize_function_for_size_p (cfun)
10533     || !TARGET_PARTIAL_REG_STALL
10534     || (operands[1] == const1_rtx
10535         && TARGET_SHIFT1))"
10537   if (operands[1] == const1_rtx
10538       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10539     return "<rotate>{b}\t%0";
10540   else
10541     return "<rotate>{b}\t{%1, %0|%0, %1}";
10543   [(set_attr "type" "rotate1")
10544    (set (attr "length_immediate")
10545      (if_then_else
10546        (and (match_operand 1 "const1_operand")
10547             (ior (match_test "TARGET_SHIFT1")
10548                  (match_test "optimize_function_for_size_p (cfun)")))
10549        (const_string "0")
10550        (const_string "*")))
10551    (set_attr "mode" "QI")])
10553 (define_split
10554  [(set (match_operand:HI 0 "register_operand")
10555        (any_rotate:HI (match_dup 0) (const_int 8)))
10556   (clobber (reg:CC FLAGS_REG))]
10557  "reload_completed
10558   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10559  [(parallel [(set (strict_low_part (match_dup 0))
10560                   (bswap:HI (match_dup 0)))
10561              (clobber (reg:CC FLAGS_REG))])])
10563 ;; Bit set / bit test instructions
10565 (define_expand "extv"
10566   [(set (match_operand:SI 0 "register_operand")
10567         (sign_extract:SI (match_operand:SI 1 "register_operand")
10568                          (match_operand:SI 2 "const8_operand")
10569                          (match_operand:SI 3 "const8_operand")))]
10570   ""
10572   /* Handle extractions from %ah et al.  */
10573   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10574     FAIL;
10576   /* From mips.md: extract_bit_field doesn't verify that our source
10577      matches the predicate, so check it again here.  */
10578   if (! ext_register_operand (operands[1], VOIDmode))
10579     FAIL;
10582 (define_expand "extzv"
10583   [(set (match_operand:SI 0 "register_operand")
10584         (zero_extract:SI (match_operand 1 "ext_register_operand")
10585                          (match_operand:SI 2 "const8_operand")
10586                          (match_operand:SI 3 "const8_operand")))]
10587   ""
10589   /* Handle extractions from %ah et al.  */
10590   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10591     FAIL;
10593   /* From mips.md: extract_bit_field doesn't verify that our source
10594      matches the predicate, so check it again here.  */
10595   if (! ext_register_operand (operands[1], VOIDmode))
10596     FAIL;
10599 (define_expand "insv"
10600   [(set (zero_extract (match_operand 0 "register_operand")
10601                       (match_operand 1 "const_int_operand")
10602                       (match_operand 2 "const_int_operand"))
10603         (match_operand 3 "register_operand"))]
10604   ""
10606   rtx (*gen_mov_insv_1) (rtx, rtx);
10608   if (ix86_expand_pinsr (operands))
10609     DONE;
10611   /* Handle insertions to %ah et al.  */
10612   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10613     FAIL;
10615   /* From mips.md: insert_bit_field doesn't verify that our source
10616      matches the predicate, so check it again here.  */
10617   if (! ext_register_operand (operands[0], VOIDmode))
10618     FAIL;
10620   gen_mov_insv_1 = (TARGET_64BIT
10621                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10623   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10624   DONE;
10627 ;; %%% bts, btr, btc, bt.
10628 ;; In general these instructions are *slow* when applied to memory,
10629 ;; since they enforce atomic operation.  When applied to registers,
10630 ;; it depends on the cpu implementation.  They're never faster than
10631 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10632 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10633 ;; within the instruction itself, so operating on bits in the high
10634 ;; 32-bits of a register becomes easier.
10636 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10637 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10638 ;; negdf respectively, so they can never be disabled entirely.
10640 (define_insn "*btsq"
10641   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10642                          (const_int 1)
10643                          (match_operand:DI 1 "const_0_to_63_operand"))
10644         (const_int 1))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10647   "bts{q}\t{%1, %0|%0, %1}"
10648   [(set_attr "type" "alu1")
10649    (set_attr "prefix_0f" "1")
10650    (set_attr "mode" "DI")])
10652 (define_insn "*btrq"
10653   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10654                          (const_int 1)
10655                          (match_operand:DI 1 "const_0_to_63_operand"))
10656         (const_int 0))
10657    (clobber (reg:CC FLAGS_REG))]
10658   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10659   "btr{q}\t{%1, %0|%0, %1}"
10660   [(set_attr "type" "alu1")
10661    (set_attr "prefix_0f" "1")
10662    (set_attr "mode" "DI")])
10664 (define_insn "*btcq"
10665   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10666                          (const_int 1)
10667                          (match_operand:DI 1 "const_0_to_63_operand"))
10668         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10669    (clobber (reg:CC FLAGS_REG))]
10670   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10671   "btc{q}\t{%1, %0|%0, %1}"
10672   [(set_attr "type" "alu1")
10673    (set_attr "prefix_0f" "1")
10674    (set_attr "mode" "DI")])
10676 ;; Allow Nocona to avoid these instructions if a register is available.
10678 (define_peephole2
10679   [(match_scratch:DI 2 "r")
10680    (parallel [(set (zero_extract:DI
10681                      (match_operand:DI 0 "register_operand")
10682                      (const_int 1)
10683                      (match_operand:DI 1 "const_0_to_63_operand"))
10684                    (const_int 1))
10685               (clobber (reg:CC FLAGS_REG))])]
10686   "TARGET_64BIT && !TARGET_USE_BT"
10687   [(const_int 0)]
10689   int i = INTVAL (operands[1]);
10691   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10693   if (i >= 31)
10694     {
10695       emit_move_insn (operands[2], op1);
10696       op1 = operands[2];
10697     }
10699   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10700   DONE;
10703 (define_peephole2
10704   [(match_scratch:DI 2 "r")
10705    (parallel [(set (zero_extract:DI
10706                      (match_operand:DI 0 "register_operand")
10707                      (const_int 1)
10708                      (match_operand:DI 1 "const_0_to_63_operand"))
10709                    (const_int 0))
10710               (clobber (reg:CC FLAGS_REG))])]
10711   "TARGET_64BIT && !TARGET_USE_BT"
10712   [(const_int 0)]
10714   int i = INTVAL (operands[1]);
10716   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10718   if (i >= 32)
10719     {
10720       emit_move_insn (operands[2], op1);
10721       op1 = operands[2];
10722     }
10724   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10725   DONE;
10728 (define_peephole2
10729   [(match_scratch:DI 2 "r")
10730    (parallel [(set (zero_extract:DI
10731                      (match_operand:DI 0 "register_operand")
10732                      (const_int 1)
10733                      (match_operand:DI 1 "const_0_to_63_operand"))
10734               (not:DI (zero_extract:DI
10735                         (match_dup 0) (const_int 1) (match_dup 1))))
10736               (clobber (reg:CC FLAGS_REG))])]
10737   "TARGET_64BIT && !TARGET_USE_BT"
10738   [(const_int 0)]
10740   int i = INTVAL (operands[1]);
10742   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10744   if (i >= 31)
10745     {
10746       emit_move_insn (operands[2], op1);
10747       op1 = operands[2];
10748     }
10750   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10751   DONE;
10754 (define_insn "*bt<mode>"
10755   [(set (reg:CCC FLAGS_REG)
10756         (compare:CCC
10757           (zero_extract:SWI48
10758             (match_operand:SWI48 0 "register_operand" "r")
10759             (const_int 1)
10760             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10761           (const_int 0)))]
10762   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10763   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10764   [(set_attr "type" "alu1")
10765    (set_attr "prefix_0f" "1")
10766    (set_attr "mode" "<MODE>")])
10768 ;; Store-flag instructions.
10770 ;; For all sCOND expanders, also expand the compare or test insn that
10771 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10773 (define_insn_and_split "*setcc_di_1"
10774   [(set (match_operand:DI 0 "register_operand" "=q")
10775         (match_operator:DI 1 "ix86_comparison_operator"
10776           [(reg FLAGS_REG) (const_int 0)]))]
10777   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10778   "#"
10779   "&& reload_completed"
10780   [(set (match_dup 2) (match_dup 1))
10781    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10783   PUT_MODE (operands[1], QImode);
10784   operands[2] = gen_lowpart (QImode, operands[0]);
10787 (define_insn_and_split "*setcc_si_1_and"
10788   [(set (match_operand:SI 0 "register_operand" "=q")
10789         (match_operator:SI 1 "ix86_comparison_operator"
10790           [(reg FLAGS_REG) (const_int 0)]))
10791    (clobber (reg:CC FLAGS_REG))]
10792   "!TARGET_PARTIAL_REG_STALL
10793    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10794   "#"
10795   "&& reload_completed"
10796   [(set (match_dup 2) (match_dup 1))
10797    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10798               (clobber (reg:CC FLAGS_REG))])]
10800   PUT_MODE (operands[1], QImode);
10801   operands[2] = gen_lowpart (QImode, operands[0]);
10804 (define_insn_and_split "*setcc_si_1_movzbl"
10805   [(set (match_operand:SI 0 "register_operand" "=q")
10806         (match_operator:SI 1 "ix86_comparison_operator"
10807           [(reg FLAGS_REG) (const_int 0)]))]
10808   "!TARGET_PARTIAL_REG_STALL
10809    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10810   "#"
10811   "&& reload_completed"
10812   [(set (match_dup 2) (match_dup 1))
10813    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10815   PUT_MODE (operands[1], QImode);
10816   operands[2] = gen_lowpart (QImode, operands[0]);
10819 (define_insn "*setcc_qi"
10820   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10821         (match_operator:QI 1 "ix86_comparison_operator"
10822           [(reg FLAGS_REG) (const_int 0)]))]
10823   ""
10824   "set%C1\t%0"
10825   [(set_attr "type" "setcc")
10826    (set_attr "mode" "QI")])
10828 (define_insn "*setcc_qi_slp"
10829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10830         (match_operator:QI 1 "ix86_comparison_operator"
10831           [(reg FLAGS_REG) (const_int 0)]))]
10832   ""
10833   "set%C1\t%0"
10834   [(set_attr "type" "setcc")
10835    (set_attr "mode" "QI")])
10837 ;; In general it is not safe to assume too much about CCmode registers,
10838 ;; so simplify-rtx stops when it sees a second one.  Under certain
10839 ;; conditions this is safe on x86, so help combine not create
10841 ;;      seta    %al
10842 ;;      testb   %al, %al
10843 ;;      sete    %al
10845 (define_split
10846   [(set (match_operand:QI 0 "nonimmediate_operand")
10847         (ne:QI (match_operator 1 "ix86_comparison_operator"
10848                  [(reg FLAGS_REG) (const_int 0)])
10849             (const_int 0)))]
10850   ""
10851   [(set (match_dup 0) (match_dup 1))]
10852   "PUT_MODE (operands[1], QImode);")
10854 (define_split
10855   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10856         (ne:QI (match_operator 1 "ix86_comparison_operator"
10857                  [(reg FLAGS_REG) (const_int 0)])
10858             (const_int 0)))]
10859   ""
10860   [(set (match_dup 0) (match_dup 1))]
10861   "PUT_MODE (operands[1], QImode);")
10863 (define_split
10864   [(set (match_operand:QI 0 "nonimmediate_operand")
10865         (eq:QI (match_operator 1 "ix86_comparison_operator"
10866                  [(reg FLAGS_REG) (const_int 0)])
10867             (const_int 0)))]
10868   ""
10869   [(set (match_dup 0) (match_dup 1))]
10871   rtx new_op1 = copy_rtx (operands[1]);
10872   operands[1] = new_op1;
10873   PUT_MODE (new_op1, QImode);
10874   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10875                                              GET_MODE (XEXP (new_op1, 0))));
10877   /* Make sure that (a) the CCmode we have for the flags is strong
10878      enough for the reversed compare or (b) we have a valid FP compare.  */
10879   if (! ix86_comparison_operator (new_op1, VOIDmode))
10880     FAIL;
10883 (define_split
10884   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10885         (eq:QI (match_operator 1 "ix86_comparison_operator"
10886                  [(reg FLAGS_REG) (const_int 0)])
10887             (const_int 0)))]
10888   ""
10889   [(set (match_dup 0) (match_dup 1))]
10891   rtx new_op1 = copy_rtx (operands[1]);
10892   operands[1] = new_op1;
10893   PUT_MODE (new_op1, QImode);
10894   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10895                                              GET_MODE (XEXP (new_op1, 0))));
10897   /* Make sure that (a) the CCmode we have for the flags is strong
10898      enough for the reversed compare or (b) we have a valid FP compare.  */
10899   if (! ix86_comparison_operator (new_op1, VOIDmode))
10900     FAIL;
10903 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10904 ;; subsequent logical operations are used to imitate conditional moves.
10905 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10906 ;; it directly.
10908 (define_insn "setcc_<mode>_sse"
10909   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10910         (match_operator:MODEF 3 "sse_comparison_operator"
10911           [(match_operand:MODEF 1 "register_operand" "0,x")
10912            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10913   "SSE_FLOAT_MODE_P (<MODE>mode)"
10914   "@
10915    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10916    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10917   [(set_attr "isa" "noavx,avx")
10918    (set_attr "type" "ssecmp")
10919    (set_attr "length_immediate" "1")
10920    (set_attr "prefix" "orig,vex")
10921    (set_attr "mode" "<MODE>")])
10923 ;; Basic conditional jump instructions.
10924 ;; We ignore the overflow flag for signed branch instructions.
10926 (define_insn "*jcc_1_bnd"
10927   [(set (pc)
10928         (if_then_else (match_operator 1 "ix86_comparison_operator"
10929                                       [(reg FLAGS_REG) (const_int 0)])
10930                       (label_ref (match_operand 0))
10931                       (pc)))]
10932   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10933   "bnd %+j%C1\t%l0"
10934   [(set_attr "type" "ibr")
10935    (set_attr "modrm" "0")
10936    (set (attr "length")
10937            (if_then_else (and (ge (minus (match_dup 0) (pc))
10938                                   (const_int -126))
10939                               (lt (minus (match_dup 0) (pc))
10940                                   (const_int 128)))
10941              (const_int 3)
10942              (const_int 7)))])
10944 (define_insn "*jcc_1"
10945   [(set (pc)
10946         (if_then_else (match_operator 1 "ix86_comparison_operator"
10947                                       [(reg FLAGS_REG) (const_int 0)])
10948                       (label_ref (match_operand 0))
10949                       (pc)))]
10950   ""
10951   "%+j%C1\t%l0"
10952   [(set_attr "type" "ibr")
10953    (set_attr "modrm" "0")
10954    (set (attr "length")
10955            (if_then_else (and (ge (minus (match_dup 0) (pc))
10956                                   (const_int -126))
10957                               (lt (minus (match_dup 0) (pc))
10958                                   (const_int 128)))
10959              (const_int 2)
10960              (const_int 6)))])
10962 (define_insn "*jcc_2_bnd"
10963   [(set (pc)
10964         (if_then_else (match_operator 1 "ix86_comparison_operator"
10965                                       [(reg FLAGS_REG) (const_int 0)])
10966                       (pc)
10967                       (label_ref (match_operand 0))))]
10968   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
10969   "bnd %+j%c1\t%l0"
10970   [(set_attr "type" "ibr")
10971    (set_attr "modrm" "0")
10972    (set (attr "length")
10973            (if_then_else (and (ge (minus (match_dup 0) (pc))
10974                                   (const_int -126))
10975                               (lt (minus (match_dup 0) (pc))
10976                                   (const_int 128)))
10977              (const_int 3)
10978              (const_int 7)))])
10980 (define_insn "*jcc_2"
10981   [(set (pc)
10982         (if_then_else (match_operator 1 "ix86_comparison_operator"
10983                                       [(reg FLAGS_REG) (const_int 0)])
10984                       (pc)
10985                       (label_ref (match_operand 0))))]
10986   ""
10987   "%+j%c1\t%l0"
10988   [(set_attr "type" "ibr")
10989    (set_attr "modrm" "0")
10990    (set (attr "length")
10991            (if_then_else (and (ge (minus (match_dup 0) (pc))
10992                                   (const_int -126))
10993                               (lt (minus (match_dup 0) (pc))
10994                                   (const_int 128)))
10995              (const_int 2)
10996              (const_int 6)))])
10998 ;; In general it is not safe to assume too much about CCmode registers,
10999 ;; so simplify-rtx stops when it sees a second one.  Under certain
11000 ;; conditions this is safe on x86, so help combine not create
11002 ;;      seta    %al
11003 ;;      testb   %al, %al
11004 ;;      je      Lfoo
11006 (define_split
11007   [(set (pc)
11008         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11009                                       [(reg FLAGS_REG) (const_int 0)])
11010                           (const_int 0))
11011                       (label_ref (match_operand 1))
11012                       (pc)))]
11013   ""
11014   [(set (pc)
11015         (if_then_else (match_dup 0)
11016                       (label_ref (match_dup 1))
11017                       (pc)))]
11018   "PUT_MODE (operands[0], VOIDmode);")
11020 (define_split
11021   [(set (pc)
11022         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11023                                       [(reg FLAGS_REG) (const_int 0)])
11024                           (const_int 0))
11025                       (label_ref (match_operand 1))
11026                       (pc)))]
11027   ""
11028   [(set (pc)
11029         (if_then_else (match_dup 0)
11030                       (label_ref (match_dup 1))
11031                       (pc)))]
11033   rtx new_op0 = copy_rtx (operands[0]);
11034   operands[0] = new_op0;
11035   PUT_MODE (new_op0, VOIDmode);
11036   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11037                                              GET_MODE (XEXP (new_op0, 0))));
11039   /* Make sure that (a) the CCmode we have for the flags is strong
11040      enough for the reversed compare or (b) we have a valid FP compare.  */
11041   if (! ix86_comparison_operator (new_op0, VOIDmode))
11042     FAIL;
11045 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11046 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11047 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11048 ;; appropriate modulo of the bit offset value.
11050 (define_insn_and_split "*jcc_bt<mode>"
11051   [(set (pc)
11052         (if_then_else (match_operator 0 "bt_comparison_operator"
11053                         [(zero_extract:SWI48
11054                            (match_operand:SWI48 1 "register_operand" "r")
11055                            (const_int 1)
11056                            (zero_extend:SI
11057                              (match_operand:QI 2 "register_operand" "r")))
11058                          (const_int 0)])
11059                       (label_ref (match_operand 3))
11060                       (pc)))
11061    (clobber (reg:CC FLAGS_REG))]
11062   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11063   "#"
11064   "&& 1"
11065   [(set (reg:CCC FLAGS_REG)
11066         (compare:CCC
11067           (zero_extract:SWI48
11068             (match_dup 1)
11069             (const_int 1)
11070             (match_dup 2))
11071           (const_int 0)))
11072    (set (pc)
11073         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11074                       (label_ref (match_dup 3))
11075                       (pc)))]
11077   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11079   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11082 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11083 ;; zero extended to SImode.
11084 (define_insn_and_split "*jcc_bt<mode>_1"
11085   [(set (pc)
11086         (if_then_else (match_operator 0 "bt_comparison_operator"
11087                         [(zero_extract:SWI48
11088                            (match_operand:SWI48 1 "register_operand" "r")
11089                            (const_int 1)
11090                            (match_operand:SI 2 "register_operand" "r"))
11091                          (const_int 0)])
11092                       (label_ref (match_operand 3))
11093                       (pc)))
11094    (clobber (reg:CC FLAGS_REG))]
11095   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11096   "#"
11097   "&& 1"
11098   [(set (reg:CCC FLAGS_REG)
11099         (compare:CCC
11100           (zero_extract:SWI48
11101             (match_dup 1)
11102             (const_int 1)
11103             (match_dup 2))
11104           (const_int 0)))
11105    (set (pc)
11106         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11107                       (label_ref (match_dup 3))
11108                       (pc)))]
11110   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11112   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11115 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11116 ;; also for DImode, this is what combine produces.
11117 (define_insn_and_split "*jcc_bt<mode>_mask"
11118   [(set (pc)
11119         (if_then_else (match_operator 0 "bt_comparison_operator"
11120                         [(zero_extract:SWI48
11121                            (match_operand:SWI48 1 "register_operand" "r")
11122                            (const_int 1)
11123                            (and:SI
11124                              (match_operand:SI 2 "register_operand" "r")
11125                              (match_operand:SI 3 "const_int_operand" "n")))])
11126                       (label_ref (match_operand 4))
11127                       (pc)))
11128    (clobber (reg:CC FLAGS_REG))]
11129   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11130    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11131       == GET_MODE_BITSIZE (<MODE>mode)-1"
11132   "#"
11133   "&& 1"
11134   [(set (reg:CCC FLAGS_REG)
11135         (compare:CCC
11136           (zero_extract:SWI48
11137             (match_dup 1)
11138             (const_int 1)
11139             (match_dup 2))
11140           (const_int 0)))
11141    (set (pc)
11142         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11143                       (label_ref (match_dup 4))
11144                       (pc)))]
11146   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11148   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11151 (define_insn_and_split "*jcc_btsi_1"
11152   [(set (pc)
11153         (if_then_else (match_operator 0 "bt_comparison_operator"
11154                         [(and:SI
11155                            (lshiftrt:SI
11156                              (match_operand:SI 1 "register_operand" "r")
11157                              (match_operand:QI 2 "register_operand" "r"))
11158                            (const_int 1))
11159                          (const_int 0)])
11160                       (label_ref (match_operand 3))
11161                       (pc)))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11164   "#"
11165   "&& 1"
11166   [(set (reg:CCC FLAGS_REG)
11167         (compare:CCC
11168           (zero_extract:SI
11169             (match_dup 1)
11170             (const_int 1)
11171             (match_dup 2))
11172           (const_int 0)))
11173    (set (pc)
11174         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11175                       (label_ref (match_dup 3))
11176                       (pc)))]
11178   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11180   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11183 ;; avoid useless masking of bit offset operand
11184 (define_insn_and_split "*jcc_btsi_mask_1"
11185   [(set (pc)
11186         (if_then_else
11187           (match_operator 0 "bt_comparison_operator"
11188             [(and:SI
11189                (lshiftrt:SI
11190                  (match_operand:SI 1 "register_operand" "r")
11191                  (subreg:QI
11192                    (and:SI
11193                      (match_operand:SI 2 "register_operand" "r")
11194                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11195                (const_int 1))
11196              (const_int 0)])
11197           (label_ref (match_operand 4))
11198           (pc)))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11201    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11202   "#"
11203   "&& 1"
11204   [(set (reg:CCC FLAGS_REG)
11205         (compare:CCC
11206           (zero_extract:SI
11207             (match_dup 1)
11208             (const_int 1)
11209             (match_dup 2))
11210           (const_int 0)))
11211    (set (pc)
11212         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11213                       (label_ref (match_dup 4))
11214                       (pc)))]
11215   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11217 ;; Define combination compare-and-branch fp compare instructions to help
11218 ;; combine.
11220 (define_insn "*jcc<mode>_0_i387"
11221   [(set (pc)
11222         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11223                         [(match_operand:X87MODEF 1 "register_operand" "f")
11224                          (match_operand:X87MODEF 2 "const0_operand")])
11225           (label_ref (match_operand 3))
11226           (pc)))
11227    (clobber (reg:CCFP FPSR_REG))
11228    (clobber (reg:CCFP FLAGS_REG))
11229    (clobber (match_scratch:HI 4 "=a"))]
11230   "TARGET_80387 && !TARGET_CMOVE"
11231   "#")
11233 (define_insn "*jcc<mode>_0_r_i387"
11234   [(set (pc)
11235         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11236                         [(match_operand:X87MODEF 1 "register_operand" "f")
11237                          (match_operand:X87MODEF 2 "const0_operand")])
11238           (pc)
11239           (label_ref (match_operand 3))))
11240    (clobber (reg:CCFP FPSR_REG))
11241    (clobber (reg:CCFP FLAGS_REG))
11242    (clobber (match_scratch:HI 4 "=a"))]
11243   "TARGET_80387 && !TARGET_CMOVE"
11244   "#")
11246 (define_insn "*jccxf_i387"
11247   [(set (pc)
11248         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11249                         [(match_operand:XF 1 "register_operand" "f")
11250                          (match_operand:XF 2 "register_operand" "f")])
11251           (label_ref (match_operand 3))
11252           (pc)))
11253    (clobber (reg:CCFP FPSR_REG))
11254    (clobber (reg:CCFP FLAGS_REG))
11255    (clobber (match_scratch:HI 4 "=a"))]
11256   "TARGET_80387 && !TARGET_CMOVE"
11257   "#")
11259 (define_insn "*jccxf_r_i387"
11260   [(set (pc)
11261         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11262                         [(match_operand:XF 1 "register_operand" "f")
11263                          (match_operand:XF 2 "register_operand" "f")])
11264           (pc)
11265           (label_ref (match_operand 3))))
11266    (clobber (reg:CCFP FPSR_REG))
11267    (clobber (reg:CCFP FLAGS_REG))
11268    (clobber (match_scratch:HI 4 "=a"))]
11269   "TARGET_80387 && !TARGET_CMOVE"
11270   "#")
11272 (define_insn "*jcc<mode>_i387"
11273   [(set (pc)
11274         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11275                         [(match_operand:MODEF 1 "register_operand" "f")
11276                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11277           (label_ref (match_operand 3))
11278           (pc)))
11279    (clobber (reg:CCFP FPSR_REG))
11280    (clobber (reg:CCFP FLAGS_REG))
11281    (clobber (match_scratch:HI 4 "=a"))]
11282   "TARGET_80387 && !TARGET_CMOVE"
11283   "#")
11285 (define_insn "*jcc<mode>_r_i387"
11286   [(set (pc)
11287         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11288                         [(match_operand:MODEF 1 "register_operand" "f")
11289                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11290           (pc)
11291           (label_ref (match_operand 3))))
11292    (clobber (reg:CCFP FPSR_REG))
11293    (clobber (reg:CCFP FLAGS_REG))
11294    (clobber (match_scratch:HI 4 "=a"))]
11295   "TARGET_80387 && !TARGET_CMOVE"
11296   "#")
11298 (define_insn "*jccu<mode>_i387"
11299   [(set (pc)
11300         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11301                         [(match_operand:X87MODEF 1 "register_operand" "f")
11302                          (match_operand:X87MODEF 2 "register_operand" "f")])
11303           (label_ref (match_operand 3))
11304           (pc)))
11305    (clobber (reg:CCFP FPSR_REG))
11306    (clobber (reg:CCFP FLAGS_REG))
11307    (clobber (match_scratch:HI 4 "=a"))]
11308   "TARGET_80387 && !TARGET_CMOVE"
11309   "#")
11311 (define_insn "*jccu<mode>_r_i387"
11312   [(set (pc)
11313         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11314                         [(match_operand:X87MODEF 1 "register_operand" "f")
11315                          (match_operand:X87MODEF 2 "register_operand" "f")])
11316           (pc)
11317           (label_ref (match_operand 3))))
11318    (clobber (reg:CCFP FPSR_REG))
11319    (clobber (reg:CCFP FLAGS_REG))
11320    (clobber (match_scratch:HI 4 "=a"))]
11321   "TARGET_80387 && !TARGET_CMOVE"
11322   "#")
11324 (define_split
11325   [(set (pc)
11326         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11327                         [(match_operand:X87MODEF 1 "register_operand")
11328                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11329           (match_operand 3)
11330           (match_operand 4)))
11331    (clobber (reg:CCFP FPSR_REG))
11332    (clobber (reg:CCFP FLAGS_REG))]
11333   "TARGET_80387 && !TARGET_CMOVE
11334    && reload_completed"
11335   [(const_int 0)]
11337   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11338                         operands[3], operands[4], NULL_RTX);
11339   DONE;
11342 (define_split
11343   [(set (pc)
11344         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11345                         [(match_operand:X87MODEF 1 "register_operand")
11346                          (match_operand:X87MODEF 2 "general_operand")])
11347           (match_operand 3)
11348           (match_operand 4)))
11349    (clobber (reg:CCFP FPSR_REG))
11350    (clobber (reg:CCFP FLAGS_REG))
11351    (clobber (match_scratch:HI 5))]
11352   "TARGET_80387 && !TARGET_CMOVE
11353    && reload_completed"
11354   [(const_int 0)]
11356   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11357                         operands[3], operands[4], operands[5]);
11358   DONE;
11361 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11362 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11363 ;; with a precedence over other operators and is always put in the first
11364 ;; place. Swap condition and operands to match ficom instruction.
11366 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11367   [(set (pc)
11368         (if_then_else
11369           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11370             [(match_operator:X87MODEF 1 "float_operator"
11371               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11372              (match_operand:X87MODEF 3 "register_operand" "f")])
11373           (label_ref (match_operand 4))
11374           (pc)))
11375    (clobber (reg:CCFP FPSR_REG))
11376    (clobber (reg:CCFP FLAGS_REG))
11377    (clobber (match_scratch:HI 5 "=a"))]
11378   "TARGET_80387 && !TARGET_CMOVE
11379    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11380        || optimize_function_for_size_p (cfun))"
11381   "#")
11383 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11384   [(set (pc)
11385         (if_then_else
11386           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11387             [(match_operator:X87MODEF 1 "float_operator"
11388               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11389              (match_operand:X87MODEF 3 "register_operand" "f")])
11390           (pc)
11391           (label_ref (match_operand 4))))
11392    (clobber (reg:CCFP FPSR_REG))
11393    (clobber (reg:CCFP FLAGS_REG))
11394    (clobber (match_scratch:HI 5 "=a"))]
11395   "TARGET_80387 && !TARGET_CMOVE
11396    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11397        || optimize_function_for_size_p (cfun))"
11398   "#")
11400 (define_split
11401   [(set (pc)
11402         (if_then_else
11403           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11404             [(match_operator:X87MODEF 1 "float_operator"
11405               [(match_operand:SWI24 2 "memory_operand")])
11406              (match_operand:X87MODEF 3 "register_operand")])
11407           (match_operand 4)
11408           (match_operand 5)))
11409    (clobber (reg:CCFP FPSR_REG))
11410    (clobber (reg:CCFP FLAGS_REG))
11411    (clobber (match_scratch:HI 6))]
11412   "TARGET_80387 && !TARGET_CMOVE
11413    && reload_completed"
11414   [(const_int 0)]
11416   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11417                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11418                         operands[4], operands[5], operands[6]);
11419   DONE;
11422 ;; Unconditional and other jump instructions
11424 (define_insn "jump_bnd"
11425   [(set (pc)
11426         (label_ref (match_operand 0)))]
11427   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11428   "bnd jmp\t%l0"
11429   [(set_attr "type" "ibr")
11430    (set (attr "length")
11431            (if_then_else (and (ge (minus (match_dup 0) (pc))
11432                                   (const_int -126))
11433                               (lt (minus (match_dup 0) (pc))
11434                                   (const_int 128)))
11435              (const_int 3)
11436              (const_int 6)))
11437    (set_attr "modrm" "0")])
11439 (define_insn "jump"
11440   [(set (pc)
11441         (label_ref (match_operand 0)))]
11442   ""
11443   "jmp\t%l0"
11444   [(set_attr "type" "ibr")
11445    (set (attr "length")
11446            (if_then_else (and (ge (minus (match_dup 0) (pc))
11447                                   (const_int -126))
11448                               (lt (minus (match_dup 0) (pc))
11449                                   (const_int 128)))
11450              (const_int 2)
11451              (const_int 5)))
11452    (set_attr "modrm" "0")])
11454 (define_expand "indirect_jump"
11455   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11456   ""
11458   if (TARGET_X32)
11459     operands[0] = convert_memory_address (word_mode, operands[0]);
11462 (define_insn "*indirect_jump"
11463   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11464   ""
11465   "%!jmp\t%A0"
11466   [(set_attr "type" "ibr")
11467    (set_attr "length_immediate" "0")])
11469 (define_expand "tablejump"
11470   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11471               (use (label_ref (match_operand 1)))])]
11472   ""
11474   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11475      relative.  Convert the relative address to an absolute address.  */
11476   if (flag_pic)
11477     {
11478       rtx op0, op1;
11479       enum rtx_code code;
11481       /* We can't use @GOTOFF for text labels on VxWorks;
11482          see gotoff_operand.  */
11483       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11484         {
11485           code = PLUS;
11486           op0 = operands[0];
11487           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11488         }
11489       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11490         {
11491           code = PLUS;
11492           op0 = operands[0];
11493           op1 = pic_offset_table_rtx;
11494         }
11495       else
11496         {
11497           code = MINUS;
11498           op0 = pic_offset_table_rtx;
11499           op1 = operands[0];
11500         }
11502       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11503                                          OPTAB_DIRECT);
11504     }
11506   if (TARGET_X32)
11507     operands[0] = convert_memory_address (word_mode, operands[0]);
11510 (define_insn "*tablejump_1"
11511   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11512    (use (label_ref (match_operand 1)))]
11513   ""
11514   "%!jmp\t%A0"
11515   [(set_attr "type" "ibr")
11516    (set_attr "length_immediate" "0")])
11518 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11520 (define_peephole2
11521   [(set (reg FLAGS_REG) (match_operand 0))
11522    (set (match_operand:QI 1 "register_operand")
11523         (match_operator:QI 2 "ix86_comparison_operator"
11524           [(reg FLAGS_REG) (const_int 0)]))
11525    (set (match_operand 3 "any_QIreg_operand")
11526         (zero_extend (match_dup 1)))]
11527   "(peep2_reg_dead_p (3, operands[1])
11528     || operands_match_p (operands[1], operands[3]))
11529    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11530   [(set (match_dup 4) (match_dup 0))
11531    (set (strict_low_part (match_dup 5))
11532         (match_dup 2))]
11534   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11535   operands[5] = gen_lowpart (QImode, operands[3]);
11536   ix86_expand_clear (operands[3]);
11539 (define_peephole2
11540   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11541               (match_operand 4)])
11542    (set (match_operand:QI 1 "register_operand")
11543         (match_operator:QI 2 "ix86_comparison_operator"
11544           [(reg FLAGS_REG) (const_int 0)]))
11545    (set (match_operand 3 "any_QIreg_operand")
11546         (zero_extend (match_dup 1)))]
11547   "(peep2_reg_dead_p (3, operands[1])
11548     || operands_match_p (operands[1], operands[3]))
11549    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11550    && ! (GET_CODE (operands[4]) == CLOBBER
11551          && reg_mentioned_p (operands[3], operands[4]))"
11552   [(parallel [(set (match_dup 5) (match_dup 0))
11553               (match_dup 4)])
11554    (set (strict_low_part (match_dup 6))
11555         (match_dup 2))]
11557   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11558   operands[6] = gen_lowpart (QImode, operands[3]);
11559   ix86_expand_clear (operands[3]);
11562 ;; Similar, but match zero extend with andsi3.
11564 (define_peephole2
11565   [(set (reg FLAGS_REG) (match_operand 0))
11566    (set (match_operand:QI 1 "register_operand")
11567         (match_operator:QI 2 "ix86_comparison_operator"
11568           [(reg FLAGS_REG) (const_int 0)]))
11569    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11570                    (and:SI (match_dup 3) (const_int 255)))
11571               (clobber (reg:CC FLAGS_REG))])]
11572   "REGNO (operands[1]) == REGNO (operands[3])
11573    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11574   [(set (match_dup 4) (match_dup 0))
11575    (set (strict_low_part (match_dup 5))
11576         (match_dup 2))]
11578   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11579   operands[5] = gen_lowpart (QImode, operands[3]);
11580   ix86_expand_clear (operands[3]);
11583 (define_peephole2
11584   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11585               (match_operand 4)])
11586    (set (match_operand:QI 1 "register_operand")
11587         (match_operator:QI 2 "ix86_comparison_operator"
11588           [(reg FLAGS_REG) (const_int 0)]))
11589    (parallel [(set (match_operand 3 "any_QIreg_operand")
11590                    (zero_extend (match_dup 1)))
11591               (clobber (reg:CC FLAGS_REG))])]
11592   "(peep2_reg_dead_p (3, operands[1])
11593     || operands_match_p (operands[1], operands[3]))
11594    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11595    && ! (GET_CODE (operands[4]) == CLOBBER
11596          && reg_mentioned_p (operands[3], operands[4]))"
11597   [(parallel [(set (match_dup 5) (match_dup 0))
11598               (match_dup 4)])
11599    (set (strict_low_part (match_dup 6))
11600         (match_dup 2))]
11602   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11603   operands[6] = gen_lowpart (QImode, operands[3]);
11604   ix86_expand_clear (operands[3]);
11607 ;; Call instructions.
11609 ;; The predicates normally associated with named expanders are not properly
11610 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11611 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11613 ;; P6 processors will jump to the address after the decrement when %esp
11614 ;; is used as a call operand, so they will execute return address as a code.
11615 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11617 ;; Register constraint for call instruction.
11618 (define_mode_attr c [(SI "l") (DI "r")])
11620 ;; Call subroutine returning no value.
11622 (define_expand "call"
11623   [(call (match_operand:QI 0)
11624          (match_operand 1))
11625    (use (match_operand 2))]
11626   ""
11628   ix86_expand_call (NULL, operands[0], operands[1],
11629                     operands[2], NULL, false);
11630   DONE;
11633 (define_expand "sibcall"
11634   [(call (match_operand:QI 0)
11635          (match_operand 1))
11636    (use (match_operand 2))]
11637   ""
11639   ix86_expand_call (NULL, operands[0], operands[1],
11640                     operands[2], NULL, true);
11641   DONE;
11644 (define_insn "*call"
11645   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11646          (match_operand 1))]
11647   "!SIBLING_CALL_P (insn)"
11648   "* return ix86_output_call_insn (insn, operands[0]);"
11649   [(set_attr "type" "call")])
11651 (define_insn "*sibcall"
11652   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11653          (match_operand 1))]
11654   "SIBLING_CALL_P (insn)"
11655   "* return ix86_output_call_insn (insn, operands[0]);"
11656   [(set_attr "type" "call")])
11658 (define_insn "*sibcall_memory"
11659   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11660          (match_operand 1))
11661    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11662   "!TARGET_X32"
11663   "* return ix86_output_call_insn (insn, operands[0]);"
11664   [(set_attr "type" "call")])
11666 (define_peephole2
11667   [(set (match_operand:W 0 "register_operand")
11668         (match_operand:W 1 "memory_operand"))
11669    (call (mem:QI (match_dup 0))
11670          (match_operand 3))]
11671   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11672    && peep2_reg_dead_p (2, operands[0])"
11673   [(parallel [(call (mem:QI (match_dup 1))
11674                     (match_dup 3))
11675               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11677 (define_peephole2
11678   [(set (match_operand:W 0 "register_operand")
11679         (match_operand:W 1 "memory_operand"))
11680    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11681    (call (mem:QI (match_dup 0))
11682          (match_operand 3))]
11683   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11684    && peep2_reg_dead_p (3, operands[0])"
11685   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11686    (parallel [(call (mem:QI (match_dup 1))
11687                     (match_dup 3))
11688               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11690 (define_expand "call_pop"
11691   [(parallel [(call (match_operand:QI 0)
11692                     (match_operand:SI 1))
11693               (set (reg:SI SP_REG)
11694                    (plus:SI (reg:SI SP_REG)
11695                             (match_operand:SI 3)))])]
11696   "!TARGET_64BIT"
11698   ix86_expand_call (NULL, operands[0], operands[1],
11699                     operands[2], operands[3], false);
11700   DONE;
11703 (define_insn "*call_pop"
11704   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11705          (match_operand 1))
11706    (set (reg:SI SP_REG)
11707         (plus:SI (reg:SI SP_REG)
11708                  (match_operand:SI 2 "immediate_operand" "i")))]
11709   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11710   "* return ix86_output_call_insn (insn, operands[0]);"
11711   [(set_attr "type" "call")])
11713 (define_insn "*sibcall_pop"
11714   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11715          (match_operand 1))
11716    (set (reg:SI SP_REG)
11717         (plus:SI (reg:SI SP_REG)
11718                  (match_operand:SI 2 "immediate_operand" "i")))]
11719   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11720   "* return ix86_output_call_insn (insn, operands[0]);"
11721   [(set_attr "type" "call")])
11723 (define_insn "*sibcall_pop_memory"
11724   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11725          (match_operand 1))
11726    (set (reg:SI SP_REG)
11727         (plus:SI (reg:SI SP_REG)
11728                  (match_operand:SI 2 "immediate_operand" "i")))
11729    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11730   "!TARGET_64BIT"
11731   "* return ix86_output_call_insn (insn, operands[0]);"
11732   [(set_attr "type" "call")])
11734 (define_peephole2
11735   [(set (match_operand:SI 0 "register_operand")
11736         (match_operand:SI 1 "memory_operand"))
11737    (parallel [(call (mem:QI (match_dup 0))
11738                     (match_operand 3))
11739               (set (reg:SI SP_REG)
11740                    (plus:SI (reg:SI SP_REG)
11741                             (match_operand:SI 4 "immediate_operand")))])]
11742   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11743    && peep2_reg_dead_p (2, operands[0])"
11744   [(parallel [(call (mem:QI (match_dup 1))
11745                     (match_dup 3))
11746               (set (reg:SI SP_REG)
11747                    (plus:SI (reg:SI SP_REG)
11748                             (match_dup 4)))
11749               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11751 (define_peephole2
11752   [(set (match_operand:SI 0 "register_operand")
11753         (match_operand:SI 1 "memory_operand"))
11754    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11755    (parallel [(call (mem:QI (match_dup 0))
11756                     (match_operand 3))
11757               (set (reg:SI SP_REG)
11758                    (plus:SI (reg:SI SP_REG)
11759                             (match_operand:SI 4 "immediate_operand")))])]
11760   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11761    && peep2_reg_dead_p (3, operands[0])"
11762   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11763    (parallel [(call (mem:QI (match_dup 1))
11764                     (match_dup 3))
11765               (set (reg:SI SP_REG)
11766                    (plus:SI (reg:SI SP_REG)
11767                             (match_dup 4)))
11768               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11770 ;; Combining simple memory jump instruction
11772 (define_peephole2
11773   [(set (match_operand:W 0 "register_operand")
11774         (match_operand:W 1 "memory_operand"))
11775    (set (pc) (match_dup 0))]
11776   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11777   [(set (pc) (match_dup 1))])
11779 ;; Call subroutine, returning value in operand 0
11781 (define_expand "call_value"
11782   [(set (match_operand 0)
11783         (call (match_operand:QI 1)
11784               (match_operand 2)))
11785    (use (match_operand 3))]
11786   ""
11788   ix86_expand_call (operands[0], operands[1], operands[2],
11789                     operands[3], NULL, false);
11790   DONE;
11793 (define_expand "sibcall_value"
11794   [(set (match_operand 0)
11795         (call (match_operand:QI 1)
11796               (match_operand 2)))
11797    (use (match_operand 3))]
11798   ""
11800   ix86_expand_call (operands[0], operands[1], operands[2],
11801                     operands[3], NULL, true);
11802   DONE;
11805 (define_insn "*call_value"
11806   [(set (match_operand 0)
11807         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11808               (match_operand 2)))]
11809   "!SIBLING_CALL_P (insn)"
11810   "* return ix86_output_call_insn (insn, operands[1]);"
11811   [(set_attr "type" "callv")])
11813 (define_insn "*sibcall_value"
11814   [(set (match_operand 0)
11815         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11816               (match_operand 2)))]
11817   "SIBLING_CALL_P (insn)"
11818   "* return ix86_output_call_insn (insn, operands[1]);"
11819   [(set_attr "type" "callv")])
11821 (define_insn "*sibcall_value_memory"
11822   [(set (match_operand 0)
11823         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11824               (match_operand 2)))
11825    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11826   "!TARGET_X32"
11827   "* return ix86_output_call_insn (insn, operands[1]);"
11828   [(set_attr "type" "callv")])
11830 (define_peephole2
11831   [(set (match_operand:W 0 "register_operand")
11832         (match_operand:W 1 "memory_operand"))
11833    (set (match_operand 2)
11834    (call (mem:QI (match_dup 0))
11835                  (match_operand 3)))]
11836   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11837    && peep2_reg_dead_p (2, operands[0])"
11838   [(parallel [(set (match_dup 2)
11839                    (call (mem:QI (match_dup 1))
11840                          (match_dup 3)))
11841               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11843 (define_peephole2
11844   [(set (match_operand:W 0 "register_operand")
11845         (match_operand:W 1 "memory_operand"))
11846    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11847    (set (match_operand 2)
11848         (call (mem:QI (match_dup 0))
11849               (match_operand 3)))]
11850   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11851    && peep2_reg_dead_p (3, operands[0])"
11852   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11853    (parallel [(set (match_dup 2)
11854                    (call (mem:QI (match_dup 1))
11855                          (match_dup 3)))
11856               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11858 (define_expand "call_value_pop"
11859   [(parallel [(set (match_operand 0)
11860                    (call (match_operand:QI 1)
11861                          (match_operand:SI 2)))
11862               (set (reg:SI SP_REG)
11863                    (plus:SI (reg:SI SP_REG)
11864                             (match_operand:SI 4)))])]
11865   "!TARGET_64BIT"
11867   ix86_expand_call (operands[0], operands[1], operands[2],
11868                     operands[3], operands[4], false);
11869   DONE;
11872 (define_insn "*call_value_pop"
11873   [(set (match_operand 0)
11874         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11875               (match_operand 2)))
11876    (set (reg:SI SP_REG)
11877         (plus:SI (reg:SI SP_REG)
11878                  (match_operand:SI 3 "immediate_operand" "i")))]
11879   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11880   "* return ix86_output_call_insn (insn, operands[1]);"
11881   [(set_attr "type" "callv")])
11883 (define_insn "*sibcall_value_pop"
11884   [(set (match_operand 0)
11885         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11886               (match_operand 2)))
11887    (set (reg:SI SP_REG)
11888         (plus:SI (reg:SI SP_REG)
11889                  (match_operand:SI 3 "immediate_operand" "i")))]
11890   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11891   "* return ix86_output_call_insn (insn, operands[1]);"
11892   [(set_attr "type" "callv")])
11894 (define_insn "*sibcall_value_pop_memory"
11895   [(set (match_operand 0)
11896         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11897               (match_operand 2)))
11898    (set (reg:SI SP_REG)
11899         (plus:SI (reg:SI SP_REG)
11900                  (match_operand:SI 3 "immediate_operand" "i")))
11901    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11902   "!TARGET_64BIT"
11903   "* return ix86_output_call_insn (insn, operands[1]);"
11904   [(set_attr "type" "callv")])
11906 (define_peephole2
11907   [(set (match_operand:SI 0 "register_operand")
11908         (match_operand:SI 1 "memory_operand"))
11909    (parallel [(set (match_operand 2)
11910                    (call (mem:QI (match_dup 0))
11911                          (match_operand 3)))
11912               (set (reg:SI SP_REG)
11913                    (plus:SI (reg:SI SP_REG)
11914                             (match_operand:SI 4 "immediate_operand")))])]
11915   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11916    && peep2_reg_dead_p (2, operands[0])"
11917   [(parallel [(set (match_dup 2)
11918                    (call (mem:QI (match_dup 1))
11919                          (match_dup 3)))
11920               (set (reg:SI SP_REG)
11921                    (plus:SI (reg:SI SP_REG)
11922                             (match_dup 4)))
11923               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11925 (define_peephole2
11926   [(set (match_operand:SI 0 "register_operand")
11927         (match_operand:SI 1 "memory_operand"))
11928    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11929    (parallel [(set (match_operand 2)
11930                    (call (mem:QI (match_dup 0))
11931                          (match_operand 3)))
11932               (set (reg:SI SP_REG)
11933                    (plus:SI (reg:SI SP_REG)
11934                             (match_operand:SI 4 "immediate_operand")))])]
11935   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11936    && peep2_reg_dead_p (3, operands[0])"
11937   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11938    (parallel [(set (match_dup 2)
11939                    (call (mem:QI (match_dup 1))
11940                          (match_dup 3)))
11941               (set (reg:SI SP_REG)
11942                    (plus:SI (reg:SI SP_REG)
11943                             (match_dup 4)))
11944               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11946 ;; Call subroutine returning any type.
11948 (define_expand "untyped_call"
11949   [(parallel [(call (match_operand 0)
11950                     (const_int 0))
11951               (match_operand 1)
11952               (match_operand 2)])]
11953   ""
11955   int i;
11957   /* In order to give reg-stack an easier job in validating two
11958      coprocessor registers as containing a possible return value,
11959      simply pretend the untyped call returns a complex long double
11960      value. 
11962      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11963      and should have the default ABI.  */
11965   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11966                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11967                     operands[0], const0_rtx,
11968                     GEN_INT ((TARGET_64BIT
11969                               ? (ix86_abi == SYSV_ABI
11970                                  ? X86_64_SSE_REGPARM_MAX
11971                                  : X86_64_MS_SSE_REGPARM_MAX)
11972                               : X86_32_SSE_REGPARM_MAX)
11973                              - 1),
11974                     NULL, false);
11976   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11977     {
11978       rtx set = XVECEXP (operands[2], 0, i);
11979       emit_move_insn (SET_DEST (set), SET_SRC (set));
11980     }
11982   /* The optimizer does not know that the call sets the function value
11983      registers we stored in the result block.  We avoid problems by
11984      claiming that all hard registers are used and clobbered at this
11985      point.  */
11986   emit_insn (gen_blockage ());
11988   DONE;
11991 ;; Prologue and epilogue instructions
11993 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11994 ;; all of memory.  This blocks insns from being moved across this point.
11996 (define_insn "blockage"
11997   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11998   ""
11999   ""
12000   [(set_attr "length" "0")])
12002 ;; Do not schedule instructions accessing memory across this point.
12004 (define_expand "memory_blockage"
12005   [(set (match_dup 0)
12006         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12007   ""
12009   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12010   MEM_VOLATILE_P (operands[0]) = 1;
12013 (define_insn "*memory_blockage"
12014   [(set (match_operand:BLK 0)
12015         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12016   ""
12017   ""
12018   [(set_attr "length" "0")])
12020 ;; As USE insns aren't meaningful after reload, this is used instead
12021 ;; to prevent deleting instructions setting registers for PIC code
12022 (define_insn "prologue_use"
12023   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12024   ""
12025   ""
12026   [(set_attr "length" "0")])
12028 ;; Insn emitted into the body of a function to return from a function.
12029 ;; This is only done if the function's epilogue is known to be simple.
12030 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12032 (define_expand "return"
12033   [(simple_return)]
12034   "ix86_can_use_return_insn_p ()"
12036   if (crtl->args.pops_args)
12037     {
12038       rtx popc = GEN_INT (crtl->args.pops_args);
12039       emit_jump_insn (gen_simple_return_pop_internal (popc));
12040       DONE;
12041     }
12044 ;; We need to disable this for TARGET_SEH, as otherwise
12045 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12046 ;; the maximum size of prologue in unwind information.
12048 (define_expand "simple_return"
12049   [(simple_return)]
12050   "!TARGET_SEH"
12052   if (crtl->args.pops_args)
12053     {
12054       rtx popc = GEN_INT (crtl->args.pops_args);
12055       emit_jump_insn (gen_simple_return_pop_internal (popc));
12056       DONE;
12057     }
12060 (define_insn "simple_return_internal"
12061   [(simple_return)]
12062   "reload_completed"
12063   "%!ret"
12064   [(set_attr "length_nobnd" "1")
12065    (set_attr "atom_unit" "jeu")
12066    (set_attr "length_immediate" "0")
12067    (set_attr "modrm" "0")])
12069 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12070 ;; instruction Athlon and K8 have.
12072 (define_insn "simple_return_internal_long"
12073   [(simple_return)
12074    (unspec [(const_int 0)] UNSPEC_REP)]
12075   "reload_completed"
12077   if (ix86_bnd_prefixed_insn_p (insn))
12078     return "%!ret";
12080   return "rep%; ret";
12082   [(set_attr "length" "2")
12083    (set_attr "atom_unit" "jeu")
12084    (set_attr "length_immediate" "0")
12085    (set_attr "prefix_rep" "1")
12086    (set_attr "modrm" "0")])
12088 (define_insn "simple_return_pop_internal"
12089   [(simple_return)
12090    (use (match_operand:SI 0 "const_int_operand"))]
12091   "reload_completed"
12092   "%!ret\t%0"
12093   [(set_attr "length_nobnd" "3")
12094    (set_attr "atom_unit" "jeu")
12095    (set_attr "length_immediate" "2")
12096    (set_attr "modrm" "0")])
12098 (define_insn "simple_return_indirect_internal"
12099   [(simple_return)
12100    (use (match_operand:SI 0 "register_operand" "r"))]
12101   "reload_completed"
12102   "%!jmp\t%A0"
12103   [(set_attr "type" "ibr")
12104    (set_attr "length_immediate" "0")])
12106 (define_insn "nop"
12107   [(const_int 0)]
12108   ""
12109   "nop"
12110   [(set_attr "length" "1")
12111    (set_attr "length_immediate" "0")
12112    (set_attr "modrm" "0")])
12114 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12115 (define_insn "nops"
12116   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12117                     UNSPECV_NOPS)]
12118   "reload_completed"
12120   int num = INTVAL (operands[0]);
12122   gcc_assert (IN_RANGE (num, 1, 8));
12124   while (num--)
12125     fputs ("\tnop\n", asm_out_file);
12127   return "";
12129   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12130    (set_attr "length_immediate" "0")
12131    (set_attr "modrm" "0")])
12133 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12134 ;; branch prediction penalty for the third jump in a 16-byte
12135 ;; block on K8.
12137 (define_insn "pad"
12138   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12139   ""
12141 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12142   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12143 #else
12144   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12145      The align insn is used to avoid 3 jump instructions in the row to improve
12146      branch prediction and the benefits hardly outweigh the cost of extra 8
12147      nops on the average inserted by full alignment pseudo operation.  */
12148 #endif
12149   return "";
12151   [(set_attr "length" "16")])
12153 (define_expand "prologue"
12154   [(const_int 0)]
12155   ""
12156   "ix86_expand_prologue (); DONE;")
12158 (define_insn "set_got"
12159   [(set (match_operand:SI 0 "register_operand" "=r")
12160         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12161    (clobber (reg:CC FLAGS_REG))]
12162   "!TARGET_64BIT"
12163   "* return output_set_got (operands[0], NULL_RTX);"
12164   [(set_attr "type" "multi")
12165    (set_attr "length" "12")])
12167 (define_insn "set_got_labelled"
12168   [(set (match_operand:SI 0 "register_operand" "=r")
12169         (unspec:SI [(label_ref (match_operand 1))]
12170          UNSPEC_SET_GOT))
12171    (clobber (reg:CC FLAGS_REG))]
12172   "!TARGET_64BIT"
12173   "* return output_set_got (operands[0], operands[1]);"
12174   [(set_attr "type" "multi")
12175    (set_attr "length" "12")])
12177 (define_insn "set_got_rex64"
12178   [(set (match_operand:DI 0 "register_operand" "=r")
12179         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12180   "TARGET_64BIT"
12181   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12182   [(set_attr "type" "lea")
12183    (set_attr "length_address" "4")
12184    (set_attr "mode" "DI")])
12186 (define_insn "set_rip_rex64"
12187   [(set (match_operand:DI 0 "register_operand" "=r")
12188         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12189   "TARGET_64BIT"
12190   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12191   [(set_attr "type" "lea")
12192    (set_attr "length_address" "4")
12193    (set_attr "mode" "DI")])
12195 (define_insn "set_got_offset_rex64"
12196   [(set (match_operand:DI 0 "register_operand" "=r")
12197         (unspec:DI
12198           [(label_ref (match_operand 1))]
12199           UNSPEC_SET_GOT_OFFSET))]
12200   "TARGET_LP64"
12201   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12202   [(set_attr "type" "imov")
12203    (set_attr "length_immediate" "0")
12204    (set_attr "length_address" "8")
12205    (set_attr "mode" "DI")])
12207 (define_expand "epilogue"
12208   [(const_int 0)]
12209   ""
12210   "ix86_expand_epilogue (1); DONE;")
12212 (define_expand "sibcall_epilogue"
12213   [(const_int 0)]
12214   ""
12215   "ix86_expand_epilogue (0); DONE;")
12217 (define_expand "eh_return"
12218   [(use (match_operand 0 "register_operand"))]
12219   ""
12221   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12223   /* Tricky bit: we write the address of the handler to which we will
12224      be returning into someone else's stack frame, one word below the
12225      stack address we wish to restore.  */
12226   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12227   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12228   tmp = gen_rtx_MEM (Pmode, tmp);
12229   emit_move_insn (tmp, ra);
12231   emit_jump_insn (gen_eh_return_internal ());
12232   emit_barrier ();
12233   DONE;
12236 (define_insn_and_split "eh_return_internal"
12237   [(eh_return)]
12238   ""
12239   "#"
12240   "epilogue_completed"
12241   [(const_int 0)]
12242   "ix86_expand_epilogue (2); DONE;")
12244 (define_insn "leave"
12245   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12246    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12247    (clobber (mem:BLK (scratch)))]
12248   "!TARGET_64BIT"
12249   "leave"
12250   [(set_attr "type" "leave")])
12252 (define_insn "leave_rex64"
12253   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12254    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12255    (clobber (mem:BLK (scratch)))]
12256   "TARGET_64BIT"
12257   "leave"
12258   [(set_attr "type" "leave")])
12260 ;; Handle -fsplit-stack.
12262 (define_expand "split_stack_prologue"
12263   [(const_int 0)]
12264   ""
12266   ix86_expand_split_stack_prologue ();
12267   DONE;
12270 ;; In order to support the call/return predictor, we use a return
12271 ;; instruction which the middle-end doesn't see.
12272 (define_insn "split_stack_return"
12273   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12274                      UNSPECV_SPLIT_STACK_RETURN)]
12275   ""
12277   if (operands[0] == const0_rtx)
12278     return "ret";
12279   else
12280     return "ret\t%0";
12282   [(set_attr "atom_unit" "jeu")
12283    (set_attr "modrm" "0")
12284    (set (attr "length")
12285         (if_then_else (match_operand:SI 0 "const0_operand")
12286                       (const_int 1)
12287                       (const_int 3)))
12288    (set (attr "length_immediate")
12289         (if_then_else (match_operand:SI 0 "const0_operand")
12290                       (const_int 0)
12291                       (const_int 2)))])
12293 ;; If there are operand 0 bytes available on the stack, jump to
12294 ;; operand 1.
12296 (define_expand "split_stack_space_check"
12297   [(set (pc) (if_then_else
12298               (ltu (minus (reg SP_REG)
12299                           (match_operand 0 "register_operand"))
12300                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12301               (label_ref (match_operand 1))
12302               (pc)))]
12303   ""
12305   rtx reg, size, limit;
12307   reg = gen_reg_rtx (Pmode);
12308   size = force_reg (Pmode, operands[0]);
12309   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12310   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12311                           UNSPEC_STACK_CHECK);
12312   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12313   ix86_expand_branch (GEU, reg, limit, operands[1]);
12315   DONE;
12318 ;; Bit manipulation instructions.
12320 (define_expand "ffs<mode>2"
12321   [(set (match_dup 2) (const_int -1))
12322    (parallel [(set (match_dup 3) (match_dup 4))
12323               (set (match_operand:SWI48 0 "register_operand")
12324                    (ctz:SWI48
12325                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12326    (set (match_dup 0) (if_then_else:SWI48
12327                         (eq (match_dup 3) (const_int 0))
12328                         (match_dup 2)
12329                         (match_dup 0)))
12330    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12331               (clobber (reg:CC FLAGS_REG))])]
12332   ""
12334   machine_mode flags_mode;
12336   if (<MODE>mode == SImode && !TARGET_CMOVE)
12337     {
12338       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12339       DONE;
12340     }
12342   flags_mode
12343     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12345   operands[2] = gen_reg_rtx (<MODE>mode);
12346   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12347   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12350 (define_insn_and_split "ffssi2_no_cmove"
12351   [(set (match_operand:SI 0 "register_operand" "=r")
12352         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12353    (clobber (match_scratch:SI 2 "=&q"))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "!TARGET_CMOVE"
12356   "#"
12357   "&& reload_completed"
12358   [(parallel [(set (match_dup 4) (match_dup 5))
12359               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12360    (set (strict_low_part (match_dup 3))
12361         (eq:QI (match_dup 4) (const_int 0)))
12362    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12363               (clobber (reg:CC FLAGS_REG))])
12364    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12365               (clobber (reg:CC FLAGS_REG))])
12366    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12367               (clobber (reg:CC FLAGS_REG))])]
12369   machine_mode flags_mode
12370     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12372   operands[3] = gen_lowpart (QImode, operands[2]);
12373   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12374   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12376   ix86_expand_clear (operands[2]);
12379 (define_insn "*tzcnt<mode>_1"
12380   [(set (reg:CCC FLAGS_REG)
12381         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12382                      (const_int 0)))
12383    (set (match_operand:SWI48 0 "register_operand" "=r")
12384         (ctz:SWI48 (match_dup 1)))]
12385   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12386   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12387   [(set_attr "type" "alu1")
12388    (set_attr "prefix_0f" "1")
12389    (set_attr "prefix_rep" "1")
12390    (set_attr "btver2_decode" "double")
12391    (set_attr "mode" "<MODE>")])
12393 (define_insn "*bsf<mode>_1"
12394   [(set (reg:CCZ FLAGS_REG)
12395         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12396                      (const_int 0)))
12397    (set (match_operand:SWI48 0 "register_operand" "=r")
12398         (ctz:SWI48 (match_dup 1)))]
12399   ""
12400   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12401   [(set_attr "type" "alu1")
12402    (set_attr "prefix_0f" "1")
12403    (set_attr "btver2_decode" "double")
12404    (set_attr "mode" "<MODE>")])
12406 (define_expand "ctz<mode>2"
12407   [(parallel
12408     [(set (match_operand:SWI248 0 "register_operand")
12409           (ctz:SWI248
12410             (match_operand:SWI248 1 "nonimmediate_operand")))
12411      (clobber (reg:CC FLAGS_REG))])])
12413 ; False dependency happens when destination is only updated by tzcnt,
12414 ; lzcnt or popcnt.  There is no false dependency when destination is
12415 ; also used in source.
12416 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12417   [(set (match_operand:SWI48 0 "register_operand" "=r")
12418         (ctz:SWI48
12419           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "(TARGET_BMI || TARGET_GENERIC)
12422    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12423   "#"
12424   "&& reload_completed"
12425   [(parallel
12426     [(set (match_dup 0)
12427           (ctz:SWI48 (match_dup 1)))
12428      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12429      (clobber (reg:CC FLAGS_REG))])]
12431   if (!reg_mentioned_p (operands[0], operands[1]))
12432     ix86_expand_clear (operands[0]);
12435 (define_insn "*ctz<mode>2_falsedep"
12436   [(set (match_operand:SWI48 0 "register_operand" "=r")
12437         (ctz:SWI48
12438           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12439    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12440            UNSPEC_INSN_FALSE_DEP)
12441    (clobber (reg:CC FLAGS_REG))]
12442   ""
12444   if (TARGET_BMI)
12445     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12446   else if (TARGET_GENERIC)
12447     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12448     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12449   else
12450     gcc_unreachable ();
12452   [(set_attr "type" "alu1")
12453    (set_attr "prefix_0f" "1")
12454    (set_attr "prefix_rep" "1")
12455    (set_attr "mode" "<MODE>")])
12457 (define_insn "*ctz<mode>2"
12458   [(set (match_operand:SWI248 0 "register_operand" "=r")
12459         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   ""
12463   if (TARGET_BMI)
12464     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12465   else if (optimize_function_for_size_p (cfun))
12466     ;
12467   else if (TARGET_GENERIC)
12468     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12469     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12471   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12473   [(set_attr "type" "alu1")
12474    (set_attr "prefix_0f" "1")
12475    (set (attr "prefix_rep")
12476      (if_then_else
12477        (ior (match_test "TARGET_BMI")
12478             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12479                  (match_test "TARGET_GENERIC")))
12480        (const_string "1")
12481        (const_string "0")))
12482    (set_attr "mode" "<MODE>")])
12484 (define_expand "clz<mode>2"
12485   [(parallel
12486      [(set (match_operand:SWI248 0 "register_operand")
12487            (minus:SWI248
12488              (match_dup 2)
12489              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12490       (clobber (reg:CC FLAGS_REG))])
12491    (parallel
12492      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12493       (clobber (reg:CC FLAGS_REG))])]
12494   ""
12496   if (TARGET_LZCNT)
12497     {
12498       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12499       DONE;
12500     }
12501   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12504 (define_expand "clz<mode>2_lzcnt"
12505   [(parallel
12506     [(set (match_operand:SWI248 0 "register_operand")
12507           (clz:SWI248
12508             (match_operand:SWI248 1 "nonimmediate_operand")))
12509      (clobber (reg:CC FLAGS_REG))])]
12510   "TARGET_LZCNT")
12512 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12513   [(set (match_operand:SWI48 0 "register_operand" "=r")
12514         (clz:SWI48
12515           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12516    (clobber (reg:CC FLAGS_REG))]
12517   "TARGET_LZCNT
12518    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12519   "#"
12520   "&& reload_completed"
12521   [(parallel
12522     [(set (match_dup 0)
12523           (clz:SWI48 (match_dup 1)))
12524      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12525      (clobber (reg:CC FLAGS_REG))])]
12527   if (!reg_mentioned_p (operands[0], operands[1]))
12528     ix86_expand_clear (operands[0]);
12531 (define_insn "*clz<mode>2_lzcnt_falsedep"
12532   [(set (match_operand:SWI48 0 "register_operand" "=r")
12533         (clz:SWI48
12534           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12535    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12536            UNSPEC_INSN_FALSE_DEP)
12537    (clobber (reg:CC FLAGS_REG))]
12538   "TARGET_LZCNT"
12539   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12540   [(set_attr "prefix_rep" "1")
12541    (set_attr "type" "bitmanip")
12542    (set_attr "mode" "<MODE>")])
12544 (define_insn "*clz<mode>2_lzcnt"
12545   [(set (match_operand:SWI248 0 "register_operand" "=r")
12546         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12547    (clobber (reg:CC FLAGS_REG))]
12548   "TARGET_LZCNT"
12549   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12550   [(set_attr "prefix_rep" "1")
12551    (set_attr "type" "bitmanip")
12552    (set_attr "mode" "<MODE>")])
12554 ;; BMI instructions.
12555 (define_insn "*bmi_andn_<mode>"
12556   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12557         (and:SWI48
12558           (not:SWI48
12559             (match_operand:SWI48 1 "register_operand" "r,r"))
12560             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12561    (clobber (reg:CC FLAGS_REG))]
12562   "TARGET_BMI"
12563   "andn\t{%2, %1, %0|%0, %1, %2}"
12564   [(set_attr "type" "bitmanip")
12565    (set_attr "btver2_decode" "direct, double")
12566    (set_attr "mode" "<MODE>")])
12568 (define_insn "bmi_bextr_<mode>"
12569   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12570         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12571                        (match_operand:SWI48 2 "register_operand" "r,r")]
12572                        UNSPEC_BEXTR))
12573    (clobber (reg:CC FLAGS_REG))]
12574   "TARGET_BMI"
12575   "bextr\t{%2, %1, %0|%0, %1, %2}"
12576   [(set_attr "type" "bitmanip")
12577    (set_attr "btver2_decode" "direct, double")
12578    (set_attr "mode" "<MODE>")])
12580 (define_insn "*bmi_bextr_<mode>_cczonly"
12581   [(set (reg:CCZ FLAGS_REG)
12582         (compare:CCZ
12583           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12584                          (match_operand:SWI48 2 "register_operand" "r,r")]
12585                         UNSPEC_BEXTR)
12586           (const_int 0)))
12587    (clobber (match_scratch:SWI48 0 "=r,r"))]
12588   "TARGET_BMI"
12589   "bextr\t{%2, %1, %0|%0, %1, %2}"
12590   [(set_attr "type" "bitmanip")
12591    (set_attr "btver2_decode" "direct, double")
12592    (set_attr "mode" "<MODE>")])
12594 (define_insn "*bmi_blsi_<mode>"
12595   [(set (match_operand:SWI48 0 "register_operand" "=r")
12596         (and:SWI48
12597           (neg:SWI48
12598             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12599           (match_dup 1)))
12600    (clobber (reg:CC FLAGS_REG))]
12601   "TARGET_BMI"
12602   "blsi\t{%1, %0|%0, %1}"
12603   [(set_attr "type" "bitmanip")
12604    (set_attr "btver2_decode" "double")
12605    (set_attr "mode" "<MODE>")])
12607 (define_insn "*bmi_blsmsk_<mode>"
12608   [(set (match_operand:SWI48 0 "register_operand" "=r")
12609         (xor:SWI48
12610           (plus:SWI48
12611             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12612             (const_int -1))
12613           (match_dup 1)))
12614    (clobber (reg:CC FLAGS_REG))]
12615   "TARGET_BMI"
12616   "blsmsk\t{%1, %0|%0, %1}"
12617   [(set_attr "type" "bitmanip")
12618    (set_attr "btver2_decode" "double")
12619    (set_attr "mode" "<MODE>")])
12621 (define_insn "*bmi_blsr_<mode>"
12622   [(set (match_operand:SWI48 0 "register_operand" "=r")
12623         (and:SWI48
12624           (plus:SWI48
12625             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12626             (const_int -1))
12627           (match_dup 1)))
12628    (clobber (reg:CC FLAGS_REG))]
12629    "TARGET_BMI"
12630    "blsr\t{%1, %0|%0, %1}"
12631   [(set_attr "type" "bitmanip")
12632    (set_attr "btver2_decode" "double")
12633    (set_attr "mode" "<MODE>")])
12635 ;; BMI2 instructions.
12636 (define_expand "bmi2_bzhi_<mode>3"
12637   [(parallel
12638     [(set (match_operand:SWI48 0 "register_operand")
12639           (zero_extract:SWI48
12640             (match_operand:SWI48 1 "nonimmediate_operand")
12641             (umin:SWI48
12642               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12643                          (const_int 255))
12644               (match_dup 3))
12645             (const_int 0)))
12646      (clobber (reg:CC FLAGS_REG))])]
12647   "TARGET_BMI2"
12648   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12650 (define_insn "*bmi2_bzhi_<mode>3"
12651   [(set (match_operand:SWI48 0 "register_operand" "=r")
12652         (zero_extract:SWI48
12653           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12654           (umin:SWI48
12655             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12656                        (const_int 255))
12657             (match_operand:SWI48 3 "const_int_operand" "n"))
12658           (const_int 0)))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12661   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12662   [(set_attr "type" "bitmanip")
12663    (set_attr "prefix" "vex")
12664    (set_attr "mode" "<MODE>")])
12666 (define_mode_attr k [(SI "k") (DI "q")])
12668 (define_insn "*bmi2_bzhi_<mode>3_1"
12669   [(set (match_operand:SWI48 0 "register_operand" "=r")
12670         (zero_extract:SWI48
12671           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12672           (umin:SWI48
12673             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
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{%<k>2, %1, %0|%0, %1, %<k>2}"
12679   [(set_attr "type" "bitmanip")
12680    (set_attr "prefix" "vex")
12681    (set_attr "mode" "<MODE>")])
12683 (define_insn "*bmi2_bzhi_<mode>3_1_cczonly"
12684   [(set (reg:CCZ FLAGS_REG)
12685         (compare:CCZ
12686           (zero_extract:SWI48
12687             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12688             (umin:SWI48
12689               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12690               (match_operand:SWI48 3 "const_int_operand" "n"))
12691             (const_int 0))
12692         (const_int 0)))
12693    (clobber (match_scratch:SWI48 0 "=r"))]
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_pdep_<mode>3"
12701   [(set (match_operand:SWI48 0 "register_operand" "=r")
12702         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12703                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12704                        UNSPEC_PDEP))]
12705   "TARGET_BMI2"
12706   "pdep\t{%2, %1, %0|%0, %1, %2}"
12707   [(set_attr "type" "bitmanip")
12708    (set_attr "prefix" "vex")
12709    (set_attr "mode" "<MODE>")])
12711 (define_insn "bmi2_pext_<mode>3"
12712   [(set (match_operand:SWI48 0 "register_operand" "=r")
12713         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12714                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12715                        UNSPEC_PEXT))]
12716   "TARGET_BMI2"
12717   "pext\t{%2, %1, %0|%0, %1, %2}"
12718   [(set_attr "type" "bitmanip")
12719    (set_attr "prefix" "vex")
12720    (set_attr "mode" "<MODE>")])
12722 ;; TBM instructions.
12723 (define_insn "tbm_bextri_<mode>"
12724   [(set (match_operand:SWI48 0 "register_operand" "=r")
12725         (zero_extract:SWI48
12726           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12727           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12728           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12729    (clobber (reg:CC FLAGS_REG))]
12730    "TARGET_TBM"
12732   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12733   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12735   [(set_attr "type" "bitmanip")
12736    (set_attr "mode" "<MODE>")])
12738 (define_insn "*tbm_blcfill_<mode>"
12739   [(set (match_operand:SWI48 0 "register_operand" "=r")
12740         (and:SWI48
12741           (plus:SWI48
12742             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12743             (const_int 1))
12744           (match_dup 1)))
12745    (clobber (reg:CC FLAGS_REG))]
12746    "TARGET_TBM"
12747    "blcfill\t{%1, %0|%0, %1}"
12748   [(set_attr "type" "bitmanip")
12749    (set_attr "mode" "<MODE>")])
12751 (define_insn "*tbm_blci_<mode>"
12752   [(set (match_operand:SWI48 0 "register_operand" "=r")
12753         (ior:SWI48
12754           (not:SWI48
12755             (plus:SWI48
12756               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12757               (const_int 1)))
12758           (match_dup 1)))
12759    (clobber (reg:CC FLAGS_REG))]
12760    "TARGET_TBM"
12761    "blci\t{%1, %0|%0, %1}"
12762   [(set_attr "type" "bitmanip")
12763    (set_attr "mode" "<MODE>")])
12765 (define_insn "*tbm_blcic_<mode>"
12766   [(set (match_operand:SWI48 0 "register_operand" "=r")
12767         (and:SWI48
12768           (plus:SWI48
12769             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12770             (const_int 1))
12771           (not:SWI48
12772             (match_dup 1))))
12773    (clobber (reg:CC FLAGS_REG))]
12774    "TARGET_TBM"
12775    "blcic\t{%1, %0|%0, %1}"
12776   [(set_attr "type" "bitmanip")
12777    (set_attr "mode" "<MODE>")])
12779 (define_insn "*tbm_blcmsk_<mode>"
12780   [(set (match_operand:SWI48 0 "register_operand" "=r")
12781         (xor:SWI48
12782           (plus:SWI48
12783             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12784             (const_int 1))
12785           (match_dup 1)))
12786    (clobber (reg:CC FLAGS_REG))]
12787    "TARGET_TBM"
12788    "blcmsk\t{%1, %0|%0, %1}"
12789   [(set_attr "type" "bitmanip")
12790    (set_attr "mode" "<MODE>")])
12792 (define_insn "*tbm_blcs_<mode>"
12793   [(set (match_operand:SWI48 0 "register_operand" "=r")
12794         (ior:SWI48
12795           (plus:SWI48
12796             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12797             (const_int 1))
12798           (match_dup 1)))
12799    (clobber (reg:CC FLAGS_REG))]
12800    "TARGET_TBM"
12801    "blcs\t{%1, %0|%0, %1}"
12802   [(set_attr "type" "bitmanip")
12803    (set_attr "mode" "<MODE>")])
12805 (define_insn "*tbm_blsfill_<mode>"
12806   [(set (match_operand:SWI48 0 "register_operand" "=r")
12807         (ior:SWI48
12808           (plus:SWI48
12809             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12810             (const_int -1))
12811           (match_dup 1)))
12812    (clobber (reg:CC FLAGS_REG))]
12813    "TARGET_TBM"
12814    "blsfill\t{%1, %0|%0, %1}"
12815   [(set_attr "type" "bitmanip")
12816    (set_attr "mode" "<MODE>")])
12818 (define_insn "*tbm_blsic_<mode>"
12819   [(set (match_operand:SWI48 0 "register_operand" "=r")
12820         (ior:SWI48
12821           (plus:SWI48
12822             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12823             (const_int -1))
12824           (not:SWI48
12825             (match_dup 1))))
12826    (clobber (reg:CC FLAGS_REG))]
12827    "TARGET_TBM"
12828    "blsic\t{%1, %0|%0, %1}"
12829   [(set_attr "type" "bitmanip")
12830    (set_attr "mode" "<MODE>")])
12832 (define_insn "*tbm_t1mskc_<mode>"
12833   [(set (match_operand:SWI48 0 "register_operand" "=r")
12834         (ior:SWI48
12835           (plus:SWI48
12836             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12837             (const_int 1))
12838           (not:SWI48
12839             (match_dup 1))))
12840    (clobber (reg:CC FLAGS_REG))]
12841    "TARGET_TBM"
12842    "t1mskc\t{%1, %0|%0, %1}"
12843   [(set_attr "type" "bitmanip")
12844    (set_attr "mode" "<MODE>")])
12846 (define_insn "*tbm_tzmsk_<mode>"
12847   [(set (match_operand:SWI48 0 "register_operand" "=r")
12848         (and:SWI48
12849           (plus:SWI48
12850             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12851             (const_int -1))
12852           (not:SWI48
12853             (match_dup 1))))
12854    (clobber (reg:CC FLAGS_REG))]
12855    "TARGET_TBM"
12856    "tzmsk\t{%1, %0|%0, %1}"
12857   [(set_attr "type" "bitmanip")
12858    (set_attr "mode" "<MODE>")])
12860 (define_insn "bsr_rex64"
12861   [(set (match_operand:DI 0 "register_operand" "=r")
12862         (minus:DI (const_int 63)
12863                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12864    (clobber (reg:CC FLAGS_REG))]
12865   "TARGET_64BIT"
12866   "bsr{q}\t{%1, %0|%0, %1}"
12867   [(set_attr "type" "alu1")
12868    (set_attr "prefix_0f" "1")
12869    (set_attr "mode" "DI")])
12871 (define_insn "bsr"
12872   [(set (match_operand:SI 0 "register_operand" "=r")
12873         (minus:SI (const_int 31)
12874                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12875    (clobber (reg:CC FLAGS_REG))]
12876   ""
12877   "bsr{l}\t{%1, %0|%0, %1}"
12878   [(set_attr "type" "alu1")
12879    (set_attr "prefix_0f" "1")
12880    (set_attr "mode" "SI")])
12882 (define_insn "*bsrhi"
12883   [(set (match_operand:HI 0 "register_operand" "=r")
12884         (minus:HI (const_int 15)
12885                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12886    (clobber (reg:CC FLAGS_REG))]
12887   ""
12888   "bsr{w}\t{%1, %0|%0, %1}"
12889   [(set_attr "type" "alu1")
12890    (set_attr "prefix_0f" "1")
12891    (set_attr "mode" "HI")])
12893 (define_expand "popcount<mode>2"
12894   [(parallel
12895     [(set (match_operand:SWI248 0 "register_operand")
12896           (popcount:SWI248
12897             (match_operand:SWI248 1 "nonimmediate_operand")))
12898      (clobber (reg:CC FLAGS_REG))])]
12899   "TARGET_POPCNT")
12901 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12902   [(set (match_operand:SWI48 0 "register_operand" "=r")
12903         (popcount:SWI48
12904           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12905    (clobber (reg:CC FLAGS_REG))]
12906   "TARGET_POPCNT
12907    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12908   "#"
12909   "&& reload_completed"
12910   [(parallel
12911     [(set (match_dup 0)
12912           (popcount:SWI48 (match_dup 1)))
12913      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12914      (clobber (reg:CC FLAGS_REG))])]
12916   if (!reg_mentioned_p (operands[0], operands[1]))
12917     ix86_expand_clear (operands[0]);
12920 (define_insn "*popcount<mode>2_falsedep"
12921   [(set (match_operand:SWI48 0 "register_operand" "=r")
12922         (popcount:SWI48
12923           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12924    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12925            UNSPEC_INSN_FALSE_DEP)
12926    (clobber (reg:CC FLAGS_REG))]
12927   "TARGET_POPCNT"
12929 #if TARGET_MACHO
12930   return "popcnt\t{%1, %0|%0, %1}";
12931 #else
12932   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12933 #endif
12935   [(set_attr "prefix_rep" "1")
12936    (set_attr "type" "bitmanip")
12937    (set_attr "mode" "<MODE>")])
12939 (define_insn "*popcount<mode>2"
12940   [(set (match_operand:SWI248 0 "register_operand" "=r")
12941         (popcount:SWI248
12942           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
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_expand "bswapdi2"
12957   [(set (match_operand:DI 0 "register_operand")
12958         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12959   "TARGET_64BIT"
12961   if (!TARGET_MOVBE)
12962     operands[1] = force_reg (DImode, operands[1]);
12965 (define_expand "bswapsi2"
12966   [(set (match_operand:SI 0 "register_operand")
12967         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12968   ""
12970   if (TARGET_MOVBE)
12971     ;
12972   else if (TARGET_BSWAP)
12973     operands[1] = force_reg (SImode, operands[1]);
12974   else
12975     {
12976       rtx x = operands[0];
12978       emit_move_insn (x, operands[1]);
12979       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12980       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12981       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12982       DONE;
12983     }
12986 (define_insn "*bswap<mode>2_movbe"
12987   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12988         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12989   "TARGET_MOVBE
12990    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12991   "@
12992     bswap\t%0
12993     movbe\t{%1, %0|%0, %1}
12994     movbe\t{%1, %0|%0, %1}"
12995   [(set_attr "type" "bitmanip,imov,imov")
12996    (set_attr "modrm" "0,1,1")
12997    (set_attr "prefix_0f" "*,1,1")
12998    (set_attr "prefix_extra" "*,1,1")
12999    (set_attr "mode" "<MODE>")])
13001 (define_insn "*bswap<mode>2"
13002   [(set (match_operand:SWI48 0 "register_operand" "=r")
13003         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13004   "TARGET_BSWAP"
13005   "bswap\t%0"
13006   [(set_attr "type" "bitmanip")
13007    (set_attr "modrm" "0")
13008    (set_attr "mode" "<MODE>")])
13010 (define_insn "*bswaphi_lowpart_1"
13011   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13012         (bswap:HI (match_dup 0)))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13015   "@
13016     xchg{b}\t{%h0, %b0|%b0, %h0}
13017     rol{w}\t{$8, %0|%0, 8}"
13018   [(set_attr "length" "2,4")
13019    (set_attr "mode" "QI,HI")])
13021 (define_insn "bswaphi_lowpart"
13022   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13023         (bswap:HI (match_dup 0)))
13024    (clobber (reg:CC FLAGS_REG))]
13025   ""
13026   "rol{w}\t{$8, %0|%0, 8}"
13027   [(set_attr "length" "4")
13028    (set_attr "mode" "HI")])
13030 (define_expand "paritydi2"
13031   [(set (match_operand:DI 0 "register_operand")
13032         (parity:DI (match_operand:DI 1 "register_operand")))]
13033   "! TARGET_POPCNT"
13035   rtx scratch = gen_reg_rtx (QImode);
13036   rtx cond;
13038   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13039                                 NULL_RTX, operands[1]));
13041   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13042                          gen_rtx_REG (CCmode, FLAGS_REG),
13043                          const0_rtx);
13044   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13046   if (TARGET_64BIT)
13047     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13048   else
13049     {
13050       rtx tmp = gen_reg_rtx (SImode);
13052       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13053       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13054     }
13055   DONE;
13058 (define_expand "paritysi2"
13059   [(set (match_operand:SI 0 "register_operand")
13060         (parity:SI (match_operand:SI 1 "register_operand")))]
13061   "! TARGET_POPCNT"
13063   rtx scratch = gen_reg_rtx (QImode);
13064   rtx cond;
13066   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13068   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13069                          gen_rtx_REG (CCmode, FLAGS_REG),
13070                          const0_rtx);
13071   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13073   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13074   DONE;
13077 (define_insn_and_split "paritydi2_cmp"
13078   [(set (reg:CC FLAGS_REG)
13079         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13080                    UNSPEC_PARITY))
13081    (clobber (match_scratch:DI 0 "=r"))
13082    (clobber (match_scratch:SI 1 "=&r"))
13083    (clobber (match_scratch:HI 2 "=Q"))]
13084   "! TARGET_POPCNT"
13085   "#"
13086   "&& reload_completed"
13087   [(parallel
13088      [(set (match_dup 1)
13089            (xor:SI (match_dup 1) (match_dup 4)))
13090       (clobber (reg:CC FLAGS_REG))])
13091    (parallel
13092      [(set (reg:CC FLAGS_REG)
13093            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13094       (clobber (match_dup 1))
13095       (clobber (match_dup 2))])]
13097   operands[4] = gen_lowpart (SImode, operands[3]);
13099   if (TARGET_64BIT)
13100     {
13101       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13102       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13103     }
13104   else
13105     operands[1] = gen_highpart (SImode, operands[3]);
13108 (define_insn_and_split "paritysi2_cmp"
13109   [(set (reg:CC FLAGS_REG)
13110         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13111                    UNSPEC_PARITY))
13112    (clobber (match_scratch:SI 0 "=r"))
13113    (clobber (match_scratch:HI 1 "=&Q"))]
13114   "! TARGET_POPCNT"
13115   "#"
13116   "&& reload_completed"
13117   [(parallel
13118      [(set (match_dup 1)
13119            (xor:HI (match_dup 1) (match_dup 3)))
13120       (clobber (reg:CC FLAGS_REG))])
13121    (parallel
13122      [(set (reg:CC FLAGS_REG)
13123            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13124       (clobber (match_dup 1))])]
13126   operands[3] = gen_lowpart (HImode, operands[2]);
13128   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13129   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13132 (define_insn "*parityhi2_cmp"
13133   [(set (reg:CC FLAGS_REG)
13134         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13135                    UNSPEC_PARITY))
13136    (clobber (match_scratch:HI 0 "=Q"))]
13137   "! TARGET_POPCNT"
13138   "xor{b}\t{%h0, %b0|%b0, %h0}"
13139   [(set_attr "length" "2")
13140    (set_attr "mode" "HI")])
13143 ;; Thread-local storage patterns for ELF.
13145 ;; Note that these code sequences must appear exactly as shown
13146 ;; in order to allow linker relaxation.
13148 (define_insn "*tls_global_dynamic_32_gnu"
13149   [(set (match_operand:SI 0 "register_operand" "=a")
13150         (unspec:SI
13151          [(match_operand:SI 1 "register_operand" "b")
13152           (match_operand 2 "tls_symbolic_operand")
13153           (match_operand 3 "constant_call_address_operand" "Bz")
13154           (reg:SI SP_REG)]
13155          UNSPEC_TLS_GD))
13156    (clobber (match_scratch:SI 4 "=d"))
13157    (clobber (match_scratch:SI 5 "=c"))
13158    (clobber (reg:CC FLAGS_REG))]
13159   "!TARGET_64BIT && TARGET_GNU_TLS"
13161   output_asm_insn
13162     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13163   if (TARGET_SUN_TLS)
13164 #ifdef HAVE_AS_IX86_TLSGDPLT
13165     return "call\t%a2@tlsgdplt";
13166 #else
13167     return "call\t%p3@plt";
13168 #endif
13169   return "call\t%P3";
13171   [(set_attr "type" "multi")
13172    (set_attr "length" "12")])
13174 (define_expand "tls_global_dynamic_32"
13175   [(parallel
13176     [(set (match_operand:SI 0 "register_operand")
13177           (unspec:SI [(match_operand:SI 2 "register_operand")
13178                       (match_operand 1 "tls_symbolic_operand")
13179                       (match_operand 3 "constant_call_address_operand")
13180                       (reg:SI SP_REG)]
13181                      UNSPEC_TLS_GD))
13182      (clobber (match_scratch:SI 4))
13183      (clobber (match_scratch:SI 5))
13184      (clobber (reg:CC FLAGS_REG))])]
13185   ""
13186   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13188 (define_insn "*tls_global_dynamic_64_<mode>"
13189   [(set (match_operand:P 0 "register_operand" "=a")
13190         (call:P
13191          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13192          (match_operand 3)))
13193    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13194              UNSPEC_TLS_GD)]
13195   "TARGET_64BIT"
13197   if (!TARGET_X32)
13198     fputs (ASM_BYTE "0x66\n", asm_out_file);
13199   output_asm_insn
13200     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13201   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13202   fputs ("\trex64\n", asm_out_file);
13203   if (TARGET_SUN_TLS)
13204     return "call\t%p2@plt";
13205   return "call\t%P2";
13207   [(set_attr "type" "multi")
13208    (set (attr "length")
13209         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13211 (define_insn "*tls_global_dynamic_64_largepic"
13212   [(set (match_operand:DI 0 "register_operand" "=a")
13213         (call:DI
13214          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13215                           (match_operand:DI 3 "immediate_operand" "i")))
13216          (match_operand 4)))
13217    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13218              UNSPEC_TLS_GD)]
13219   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13220    && GET_CODE (operands[3]) == CONST
13221    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13222    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13224   output_asm_insn
13225     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13226   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13227   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13228   return "call\t{*%%rax|rax}";
13230   [(set_attr "type" "multi")
13231    (set_attr "length" "22")])
13233 (define_expand "tls_global_dynamic_64_<mode>"
13234   [(parallel
13235     [(set (match_operand:P 0 "register_operand")
13236           (call:P
13237            (mem:QI (match_operand 2))
13238            (const_int 0)))
13239      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13240                UNSPEC_TLS_GD)])]
13241   "TARGET_64BIT"
13242   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13244 (define_insn "*tls_local_dynamic_base_32_gnu"
13245   [(set (match_operand:SI 0 "register_operand" "=a")
13246         (unspec:SI
13247          [(match_operand:SI 1 "register_operand" "b")
13248           (match_operand 2 "constant_call_address_operand" "Bz")
13249           (reg:SI SP_REG)]
13250          UNSPEC_TLS_LD_BASE))
13251    (clobber (match_scratch:SI 3 "=d"))
13252    (clobber (match_scratch:SI 4 "=c"))
13253    (clobber (reg:CC FLAGS_REG))]
13254   "!TARGET_64BIT && TARGET_GNU_TLS"
13256   output_asm_insn
13257     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13258   if (TARGET_SUN_TLS)
13259     {
13260       if (HAVE_AS_IX86_TLSLDMPLT)
13261         return "call\t%&@tlsldmplt";
13262       else
13263         return "call\t%p2@plt";
13264     }
13265   return "call\t%P2";
13267   [(set_attr "type" "multi")
13268    (set_attr "length" "11")])
13270 (define_expand "tls_local_dynamic_base_32"
13271   [(parallel
13272      [(set (match_operand:SI 0 "register_operand")
13273            (unspec:SI
13274             [(match_operand:SI 1 "register_operand")
13275              (match_operand 2 "constant_call_address_operand")
13276              (reg:SI SP_REG)]
13277             UNSPEC_TLS_LD_BASE))
13278       (clobber (match_scratch:SI 3))
13279       (clobber (match_scratch:SI 4))
13280       (clobber (reg:CC FLAGS_REG))])]
13281   ""
13282   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13284 (define_insn "*tls_local_dynamic_base_64_<mode>"
13285   [(set (match_operand:P 0 "register_operand" "=a")
13286         (call:P
13287          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13288          (match_operand 2)))
13289    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13290   "TARGET_64BIT"
13292   output_asm_insn
13293     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13294   if (TARGET_SUN_TLS)
13295     return "call\t%p1@plt";
13296   return "call\t%P1";
13298   [(set_attr "type" "multi")
13299    (set_attr "length" "12")])
13301 (define_insn "*tls_local_dynamic_base_64_largepic"
13302   [(set (match_operand:DI 0 "register_operand" "=a")
13303         (call:DI
13304          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13305                           (match_operand:DI 2 "immediate_operand" "i")))
13306          (match_operand 3)))
13307    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13308   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13309    && GET_CODE (operands[2]) == CONST
13310    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13311    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13313   output_asm_insn
13314     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13315   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13316   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13317   return "call\t{*%%rax|rax}";
13319   [(set_attr "type" "multi")
13320    (set_attr "length" "22")])
13322 (define_expand "tls_local_dynamic_base_64_<mode>"
13323   [(parallel
13324      [(set (match_operand:P 0 "register_operand")
13325            (call:P
13326             (mem:QI (match_operand 1))
13327             (const_int 0)))
13328       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13329   "TARGET_64BIT"
13330   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13332 ;; Local dynamic of a single variable is a lose.  Show combine how
13333 ;; to convert that back to global dynamic.
13335 (define_insn_and_split "*tls_local_dynamic_32_once"
13336   [(set (match_operand:SI 0 "register_operand" "=a")
13337         (plus:SI
13338          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13339                      (match_operand 2 "constant_call_address_operand" "Bz")
13340                      (reg:SI SP_REG)]
13341                     UNSPEC_TLS_LD_BASE)
13342          (const:SI (unspec:SI
13343                     [(match_operand 3 "tls_symbolic_operand")]
13344                     UNSPEC_DTPOFF))))
13345    (clobber (match_scratch:SI 4 "=d"))
13346    (clobber (match_scratch:SI 5 "=c"))
13347    (clobber (reg:CC FLAGS_REG))]
13348   ""
13349   "#"
13350   ""
13351   [(parallel
13352      [(set (match_dup 0)
13353            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13354                        (reg:SI SP_REG)]
13355                       UNSPEC_TLS_GD))
13356       (clobber (match_dup 4))
13357       (clobber (match_dup 5))
13358       (clobber (reg:CC FLAGS_REG))])])
13360 ;; Segment register for the thread base ptr load
13361 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13363 ;; Load and add the thread base pointer from %<tp_seg>:0.
13364 (define_insn "*load_tp_x32"
13365   [(set (match_operand:SI 0 "register_operand" "=r")
13366         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13367   "TARGET_X32"
13368   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13369   [(set_attr "type" "imov")
13370    (set_attr "modrm" "0")
13371    (set_attr "length" "7")
13372    (set_attr "memory" "load")
13373    (set_attr "imm_disp" "false")])
13375 (define_insn "*load_tp_x32_zext"
13376   [(set (match_operand:DI 0 "register_operand" "=r")
13377         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13378   "TARGET_X32"
13379   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13380   [(set_attr "type" "imov")
13381    (set_attr "modrm" "0")
13382    (set_attr "length" "7")
13383    (set_attr "memory" "load")
13384    (set_attr "imm_disp" "false")])
13386 (define_insn "*load_tp_<mode>"
13387   [(set (match_operand:P 0 "register_operand" "=r")
13388         (unspec:P [(const_int 0)] UNSPEC_TP))]
13389   "!TARGET_X32"
13390   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13391   [(set_attr "type" "imov")
13392    (set_attr "modrm" "0")
13393    (set_attr "length" "7")
13394    (set_attr "memory" "load")
13395    (set_attr "imm_disp" "false")])
13397 (define_insn "*add_tp_x32"
13398   [(set (match_operand:SI 0 "register_operand" "=r")
13399         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13400                  (match_operand:SI 1 "register_operand" "0")))
13401    (clobber (reg:CC FLAGS_REG))]
13402   "TARGET_X32"
13403   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13404   [(set_attr "type" "alu")
13405    (set_attr "modrm" "0")
13406    (set_attr "length" "7")
13407    (set_attr "memory" "load")
13408    (set_attr "imm_disp" "false")])
13410 (define_insn "*add_tp_x32_zext"
13411   [(set (match_operand:DI 0 "register_operand" "=r")
13412         (zero_extend:DI
13413           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13414                    (match_operand:SI 1 "register_operand" "0"))))
13415    (clobber (reg:CC FLAGS_REG))]
13416   "TARGET_X32"
13417   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13418   [(set_attr "type" "alu")
13419    (set_attr "modrm" "0")
13420    (set_attr "length" "7")
13421    (set_attr "memory" "load")
13422    (set_attr "imm_disp" "false")])
13424 (define_insn "*add_tp_<mode>"
13425   [(set (match_operand:P 0 "register_operand" "=r")
13426         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13427                 (match_operand:P 1 "register_operand" "0")))
13428    (clobber (reg:CC FLAGS_REG))]
13429   "!TARGET_X32"
13430   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13431   [(set_attr "type" "alu")
13432    (set_attr "modrm" "0")
13433    (set_attr "length" "7")
13434    (set_attr "memory" "load")
13435    (set_attr "imm_disp" "false")])
13437 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13438 ;; %rax as destination of the initial executable code sequence.
13439 (define_insn "tls_initial_exec_64_sun"
13440   [(set (match_operand:DI 0 "register_operand" "=a")
13441         (unspec:DI
13442          [(match_operand 1 "tls_symbolic_operand")]
13443          UNSPEC_TLS_IE_SUN))
13444    (clobber (reg:CC FLAGS_REG))]
13445   "TARGET_64BIT && TARGET_SUN_TLS"
13447   output_asm_insn
13448     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13449   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13451   [(set_attr "type" "multi")])
13453 ;; GNU2 TLS patterns can be split.
13455 (define_expand "tls_dynamic_gnu2_32"
13456   [(set (match_dup 3)
13457         (plus:SI (match_operand:SI 2 "register_operand")
13458                  (const:SI
13459                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13460                              UNSPEC_TLSDESC))))
13461    (parallel
13462     [(set (match_operand:SI 0 "register_operand")
13463           (unspec:SI [(match_dup 1) (match_dup 3)
13464                       (match_dup 2) (reg:SI SP_REG)]
13465                       UNSPEC_TLSDESC))
13466      (clobber (reg:CC FLAGS_REG))])]
13467   "!TARGET_64BIT && TARGET_GNU2_TLS"
13469   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13470   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13473 (define_insn "*tls_dynamic_gnu2_lea_32"
13474   [(set (match_operand:SI 0 "register_operand" "=r")
13475         (plus:SI (match_operand:SI 1 "register_operand" "b")
13476                  (const:SI
13477                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13478                               UNSPEC_TLSDESC))))]
13479   "!TARGET_64BIT && TARGET_GNU2_TLS"
13480   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13481   [(set_attr "type" "lea")
13482    (set_attr "mode" "SI")
13483    (set_attr "length" "6")
13484    (set_attr "length_address" "4")])
13486 (define_insn "*tls_dynamic_gnu2_call_32"
13487   [(set (match_operand:SI 0 "register_operand" "=a")
13488         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13489                     (match_operand:SI 2 "register_operand" "0")
13490                     ;; we have to make sure %ebx still points to the GOT
13491                     (match_operand:SI 3 "register_operand" "b")
13492                     (reg:SI SP_REG)]
13493                    UNSPEC_TLSDESC))
13494    (clobber (reg:CC FLAGS_REG))]
13495   "!TARGET_64BIT && TARGET_GNU2_TLS"
13496   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13497   [(set_attr "type" "call")
13498    (set_attr "length" "2")
13499    (set_attr "length_address" "0")])
13501 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13502   [(set (match_operand:SI 0 "register_operand" "=&a")
13503         (plus:SI
13504          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13505                      (match_operand:SI 4)
13506                      (match_operand:SI 2 "register_operand" "b")
13507                      (reg:SI SP_REG)]
13508                     UNSPEC_TLSDESC)
13509          (const:SI (unspec:SI
13510                     [(match_operand 1 "tls_symbolic_operand")]
13511                     UNSPEC_DTPOFF))))
13512    (clobber (reg:CC FLAGS_REG))]
13513   "!TARGET_64BIT && TARGET_GNU2_TLS"
13514   "#"
13515   ""
13516   [(set (match_dup 0) (match_dup 5))]
13518   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13519   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13522 (define_expand "tls_dynamic_gnu2_64"
13523   [(set (match_dup 2)
13524         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13525                    UNSPEC_TLSDESC))
13526    (parallel
13527     [(set (match_operand:DI 0 "register_operand")
13528           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13529                      UNSPEC_TLSDESC))
13530      (clobber (reg:CC FLAGS_REG))])]
13531   "TARGET_64BIT && TARGET_GNU2_TLS"
13533   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13534   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13537 (define_insn "*tls_dynamic_gnu2_lea_64"
13538   [(set (match_operand:DI 0 "register_operand" "=r")
13539         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13540                    UNSPEC_TLSDESC))]
13541   "TARGET_64BIT && TARGET_GNU2_TLS"
13542   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13543   [(set_attr "type" "lea")
13544    (set_attr "mode" "DI")
13545    (set_attr "length" "7")
13546    (set_attr "length_address" "4")])
13548 (define_insn "*tls_dynamic_gnu2_call_64"
13549   [(set (match_operand:DI 0 "register_operand" "=a")
13550         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13551                     (match_operand:DI 2 "register_operand" "0")
13552                     (reg:DI SP_REG)]
13553                    UNSPEC_TLSDESC))
13554    (clobber (reg:CC FLAGS_REG))]
13555   "TARGET_64BIT && TARGET_GNU2_TLS"
13556   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13557   [(set_attr "type" "call")
13558    (set_attr "length" "2")
13559    (set_attr "length_address" "0")])
13561 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13562   [(set (match_operand:DI 0 "register_operand" "=&a")
13563         (plus:DI
13564          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13565                      (match_operand:DI 3)
13566                      (reg:DI SP_REG)]
13567                     UNSPEC_TLSDESC)
13568          (const:DI (unspec:DI
13569                     [(match_operand 1 "tls_symbolic_operand")]
13570                     UNSPEC_DTPOFF))))
13571    (clobber (reg:CC FLAGS_REG))]
13572   "TARGET_64BIT && TARGET_GNU2_TLS"
13573   "#"
13574   ""
13575   [(set (match_dup 0) (match_dup 4))]
13577   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13578   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13581 ;; These patterns match the binary 387 instructions for addM3, subM3,
13582 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13583 ;; SFmode.  The first is the normal insn, the second the same insn but
13584 ;; with one operand a conversion, and the third the same insn but with
13585 ;; the other operand a conversion.  The conversion may be SFmode or
13586 ;; SImode if the target mode DFmode, but only SImode if the target mode
13587 ;; is SFmode.
13589 ;; Gcc is slightly more smart about handling normal two address instructions
13590 ;; so use special patterns for add and mull.
13592 (define_insn "*fop_<mode>_comm_mixed"
13593   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13594         (match_operator:MODEF 3 "binary_fp_operator"
13595           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13596            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13597   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13598    && COMMUTATIVE_ARITH_P (operands[3])
13599    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13600   "* return output_387_binary_op (insn, operands);"
13601   [(set (attr "type")
13602         (if_then_else (eq_attr "alternative" "1,2")
13603            (if_then_else (match_operand:MODEF 3 "mult_operator")
13604               (const_string "ssemul")
13605               (const_string "sseadd"))
13606            (if_then_else (match_operand:MODEF 3 "mult_operator")
13607               (const_string "fmul")
13608               (const_string "fop"))))
13609    (set_attr "isa" "*,noavx,avx")
13610    (set_attr "prefix" "orig,orig,vex")
13611    (set_attr "mode" "<MODE>")
13612    (set (attr "enabled")
13613      (cond [(eq_attr "alternative" "0")
13614               (symbol_ref "TARGET_MIX_SSE_I387")
13615            ]
13616            (const_string "*")))])
13618 (define_insn "*fop_<mode>_comm_i387"
13619   [(set (match_operand:MODEF 0 "register_operand" "=f")
13620         (match_operator:MODEF 3 "binary_fp_operator"
13621           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13622            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13623   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13624    && COMMUTATIVE_ARITH_P (operands[3])
13625    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13626   "* return output_387_binary_op (insn, operands);"
13627   [(set (attr "type")
13628         (if_then_else (match_operand:MODEF 3 "mult_operator")
13629            (const_string "fmul")
13630            (const_string "fop")))
13631    (set_attr "mode" "<MODE>")])
13633 (define_insn "*rcpsf2_sse"
13634   [(set (match_operand:SF 0 "register_operand" "=x")
13635         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13636                    UNSPEC_RCP))]
13637   "TARGET_SSE_MATH"
13638   "%vrcpss\t{%1, %d0|%d0, %1}"
13639   [(set_attr "type" "sse")
13640    (set_attr "atom_sse_attr" "rcp")
13641    (set_attr "btver2_sse_attr" "rcp")
13642    (set_attr "prefix" "maybe_vex")
13643    (set_attr "mode" "SF")])
13645 (define_insn "*fop_<mode>_1_mixed"
13646   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13647         (match_operator:MODEF 3 "binary_fp_operator"
13648           [(match_operand:MODEF 1
13649              "register_mixssei387nonimm_operand" "0,fm,0,v")
13650            (match_operand:MODEF 2
13651              "nonimmediate_operand"              "fm,0,xm,vm")]))]
13652   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13653    && !COMMUTATIVE_ARITH_P (operands[3])
13654    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13655   "* return output_387_binary_op (insn, operands);"
13656   [(set (attr "type")
13657         (cond [(and (eq_attr "alternative" "2,3")
13658                     (match_operand:MODEF 3 "mult_operator"))
13659                  (const_string "ssemul")
13660                (and (eq_attr "alternative" "2,3")
13661                     (match_operand:MODEF 3 "div_operator"))
13662                  (const_string "ssediv")
13663                (eq_attr "alternative" "2,3")
13664                  (const_string "sseadd")
13665                (match_operand:MODEF 3 "mult_operator")
13666                  (const_string "fmul")
13667                (match_operand:MODEF 3 "div_operator")
13668                  (const_string "fdiv")
13669               ]
13670               (const_string "fop")))
13671    (set_attr "isa" "*,*,noavx,avx")
13672    (set_attr "prefix" "orig,orig,orig,vex")
13673    (set_attr "mode" "<MODE>")
13674    (set (attr "enabled")
13675      (cond [(eq_attr "alternative" "0,1")
13676               (symbol_ref "TARGET_MIX_SSE_I387")
13677            ]
13678            (const_string "*")))])
13680 ;; This pattern is not fully shadowed by the pattern above.
13681 (define_insn "*fop_<mode>_1_i387"
13682   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13683         (match_operator:MODEF 3 "binary_fp_operator"
13684           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13685            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13686   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13687    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13688    && !COMMUTATIVE_ARITH_P (operands[3])
13689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13690   "* return output_387_binary_op (insn, operands);"
13691   [(set (attr "type")
13692         (cond [(match_operand:MODEF 3 "mult_operator")
13693                  (const_string "fmul")
13694                (match_operand:MODEF 3 "div_operator")
13695                  (const_string "fdiv")
13696               ]
13697               (const_string "fop")))
13698    (set_attr "mode" "<MODE>")])
13700 ;; ??? Add SSE splitters for these!
13701 (define_insn "*fop_<MODEF:mode>_2_i387"
13702   [(set (match_operand:MODEF 0 "register_operand" "=f")
13703         (match_operator:MODEF 3 "binary_fp_operator"
13704           [(float:MODEF
13705              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13706            (match_operand:MODEF 2 "register_operand" "0")]))]
13707   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13708    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13709    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13710        || optimize_function_for_size_p (cfun))"
13711   { return output_387_binary_op (insn, operands); }
13712   [(set (attr "type")
13713         (cond [(match_operand:MODEF 3 "mult_operator")
13714                  (const_string "fmul")
13715                (match_operand:MODEF 3 "div_operator")
13716                  (const_string "fdiv")
13717               ]
13718               (const_string "fop")))
13719    (set_attr "fp_int_src" "true")
13720    (set_attr "mode" "<SWI24:MODE>")])
13722 (define_insn "*fop_<MODEF:mode>_3_i387"
13723   [(set (match_operand:MODEF 0 "register_operand" "=f")
13724         (match_operator:MODEF 3 "binary_fp_operator"
13725           [(match_operand:MODEF 1 "register_operand" "0")
13726            (float:MODEF
13727              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13728   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13729    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13730    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13731        || optimize_function_for_size_p (cfun))"
13732   { return output_387_binary_op (insn, operands); }
13733   [(set (attr "type")
13734         (cond [(match_operand:MODEF 3 "mult_operator")
13735                  (const_string "fmul")
13736                (match_operand:MODEF 3 "div_operator")
13737                  (const_string "fdiv")
13738               ]
13739               (const_string "fop")))
13740    (set_attr "fp_int_src" "true")
13741    (set_attr "mode" "<MODE>")])
13743 (define_insn "*fop_df_4_i387"
13744   [(set (match_operand:DF 0 "register_operand" "=f,f")
13745         (match_operator:DF 3 "binary_fp_operator"
13746            [(float_extend:DF
13747              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13748             (match_operand:DF 2 "register_operand" "0,f")]))]
13749   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13750    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13752   "* return output_387_binary_op (insn, operands);"
13753   [(set (attr "type")
13754         (cond [(match_operand:DF 3 "mult_operator")
13755                  (const_string "fmul")
13756                (match_operand:DF 3 "div_operator")
13757                  (const_string "fdiv")
13758               ]
13759               (const_string "fop")))
13760    (set_attr "mode" "SF")])
13762 (define_insn "*fop_df_5_i387"
13763   [(set (match_operand:DF 0 "register_operand" "=f,f")
13764         (match_operator:DF 3 "binary_fp_operator"
13765           [(match_operand:DF 1 "register_operand" "0,f")
13766            (float_extend:DF
13767             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13768   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13769    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13770   "* return output_387_binary_op (insn, operands);"
13771   [(set (attr "type")
13772         (cond [(match_operand:DF 3 "mult_operator")
13773                  (const_string "fmul")
13774                (match_operand:DF 3 "div_operator")
13775                  (const_string "fdiv")
13776               ]
13777               (const_string "fop")))
13778    (set_attr "mode" "SF")])
13780 (define_insn "*fop_df_6_i387"
13781   [(set (match_operand:DF 0 "register_operand" "=f,f")
13782         (match_operator:DF 3 "binary_fp_operator"
13783           [(float_extend:DF
13784             (match_operand:SF 1 "register_operand" "0,f"))
13785            (float_extend:DF
13786             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13787   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13788    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13789   "* return output_387_binary_op (insn, operands);"
13790   [(set (attr "type")
13791         (cond [(match_operand:DF 3 "mult_operator")
13792                  (const_string "fmul")
13793                (match_operand:DF 3 "div_operator")
13794                  (const_string "fdiv")
13795               ]
13796               (const_string "fop")))
13797    (set_attr "mode" "SF")])
13799 (define_insn "*fop_xf_comm_i387"
13800   [(set (match_operand:XF 0 "register_operand" "=f")
13801         (match_operator:XF 3 "binary_fp_operator"
13802                         [(match_operand:XF 1 "register_operand" "%0")
13803                          (match_operand:XF 2 "register_operand" "f")]))]
13804   "TARGET_80387
13805    && COMMUTATIVE_ARITH_P (operands[3])"
13806   "* return output_387_binary_op (insn, operands);"
13807   [(set (attr "type")
13808         (if_then_else (match_operand:XF 3 "mult_operator")
13809            (const_string "fmul")
13810            (const_string "fop")))
13811    (set_attr "mode" "XF")])
13813 (define_insn "*fop_xf_1_i387"
13814   [(set (match_operand:XF 0 "register_operand" "=f,f")
13815         (match_operator:XF 3 "binary_fp_operator"
13816                         [(match_operand:XF 1 "register_operand" "0,f")
13817                          (match_operand:XF 2 "register_operand" "f,0")]))]
13818   "TARGET_80387
13819    && !COMMUTATIVE_ARITH_P (operands[3])"
13820   "* return output_387_binary_op (insn, operands);"
13821   [(set (attr "type")
13822         (cond [(match_operand:XF 3 "mult_operator")
13823                  (const_string "fmul")
13824                (match_operand:XF 3 "div_operator")
13825                  (const_string "fdiv")
13826               ]
13827               (const_string "fop")))
13828    (set_attr "mode" "XF")])
13830 (define_insn "*fop_xf_2_i387"
13831   [(set (match_operand:XF 0 "register_operand" "=f")
13832         (match_operator:XF 3 "binary_fp_operator"
13833           [(float:XF
13834              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13835            (match_operand:XF 2 "register_operand" "0")]))]
13836   "TARGET_80387
13837    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13838   { return output_387_binary_op (insn, operands); }
13839   [(set (attr "type")
13840         (cond [(match_operand:XF 3 "mult_operator")
13841                  (const_string "fmul")
13842                (match_operand:XF 3 "div_operator")
13843                  (const_string "fdiv")
13844               ]
13845               (const_string "fop")))
13846    (set_attr "fp_int_src" "true")
13847    (set_attr "mode" "<MODE>")])
13849 (define_insn "*fop_xf_3_i387"
13850   [(set (match_operand:XF 0 "register_operand" "=f")
13851         (match_operator:XF 3 "binary_fp_operator"
13852           [(match_operand:XF 1 "register_operand" "0")
13853            (float:XF
13854              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13855   "TARGET_80387
13856    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13857   { return output_387_binary_op (insn, operands); }
13858   [(set (attr "type")
13859         (cond [(match_operand:XF 3 "mult_operator")
13860                  (const_string "fmul")
13861                (match_operand:XF 3 "div_operator")
13862                  (const_string "fdiv")
13863               ]
13864               (const_string "fop")))
13865    (set_attr "fp_int_src" "true")
13866    (set_attr "mode" "<MODE>")])
13868 (define_insn "*fop_xf_4_i387"
13869   [(set (match_operand:XF 0 "register_operand" "=f,f")
13870         (match_operator:XF 3 "binary_fp_operator"
13871            [(float_extend:XF
13872               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13873             (match_operand:XF 2 "register_operand" "0,f")]))]
13874   "TARGET_80387"
13875   "* return output_387_binary_op (insn, operands);"
13876   [(set (attr "type")
13877         (cond [(match_operand:XF 3 "mult_operator")
13878                  (const_string "fmul")
13879                (match_operand:XF 3 "div_operator")
13880                  (const_string "fdiv")
13881               ]
13882               (const_string "fop")))
13883    (set_attr "mode" "<MODE>")])
13885 (define_insn "*fop_xf_5_i387"
13886   [(set (match_operand:XF 0 "register_operand" "=f,f")
13887         (match_operator:XF 3 "binary_fp_operator"
13888           [(match_operand:XF 1 "register_operand" "0,f")
13889            (float_extend:XF
13890              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
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_6_i387"
13903   [(set (match_operand:XF 0 "register_operand" "=f,f")
13904         (match_operator:XF 3 "binary_fp_operator"
13905           [(float_extend:XF
13906              (match_operand:MODEF 1 "register_operand" "0,f"))
13907            (float_extend:XF
13908              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13909   "TARGET_80387"
13910   "* return output_387_binary_op (insn, operands);"
13911   [(set (attr "type")
13912         (cond [(match_operand:XF 3 "mult_operator")
13913                  (const_string "fmul")
13914                (match_operand:XF 3 "div_operator")
13915                  (const_string "fdiv")
13916               ]
13917               (const_string "fop")))
13918    (set_attr "mode" "<MODE>")])
13920 ;; FPU special functions.
13922 ;; This pattern implements a no-op XFmode truncation for
13923 ;; all fancy i386 XFmode math functions.
13925 (define_insn "truncxf<mode>2_i387_noop_unspec"
13926   [(set (match_operand:MODEF 0 "register_operand" "=f")
13927         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13928         UNSPEC_TRUNC_NOOP))]
13929   "TARGET_USE_FANCY_MATH_387"
13930   "* return output_387_reg_move (insn, operands);"
13931   [(set_attr "type" "fmov")
13932    (set_attr "mode" "<MODE>")])
13934 (define_insn "sqrtxf2"
13935   [(set (match_operand:XF 0 "register_operand" "=f")
13936         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13937   "TARGET_USE_FANCY_MATH_387"
13938   "fsqrt"
13939   [(set_attr "type" "fpspc")
13940    (set_attr "mode" "XF")
13941    (set_attr "athlon_decode" "direct")
13942    (set_attr "amdfam10_decode" "direct")
13943    (set_attr "bdver1_decode" "direct")])
13945 (define_insn "sqrt_extend<mode>xf2_i387"
13946   [(set (match_operand:XF 0 "register_operand" "=f")
13947         (sqrt:XF
13948           (float_extend:XF
13949             (match_operand:MODEF 1 "register_operand" "0"))))]
13950   "TARGET_USE_FANCY_MATH_387"
13951   "fsqrt"
13952   [(set_attr "type" "fpspc")
13953    (set_attr "mode" "XF")
13954    (set_attr "athlon_decode" "direct")
13955    (set_attr "amdfam10_decode" "direct")
13956    (set_attr "bdver1_decode" "direct")])
13958 (define_insn "*rsqrtsf2_sse"
13959   [(set (match_operand:SF 0 "register_operand" "=x")
13960         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13961                    UNSPEC_RSQRT))]
13962   "TARGET_SSE_MATH"
13963   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13964   [(set_attr "type" "sse")
13965    (set_attr "atom_sse_attr" "rcp")
13966    (set_attr "btver2_sse_attr" "rcp")
13967    (set_attr "prefix" "maybe_vex")
13968    (set_attr "mode" "SF")])
13970 (define_expand "rsqrtsf2"
13971   [(set (match_operand:SF 0 "register_operand")
13972         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13973                    UNSPEC_RSQRT))]
13974   "TARGET_SSE_MATH"
13976   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13977   DONE;
13980 (define_insn "*sqrt<mode>2_sse"
13981   [(set (match_operand:MODEF 0 "register_operand" "=v")
13982         (sqrt:MODEF
13983           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
13984   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13985   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13986   [(set_attr "type" "sse")
13987    (set_attr "atom_sse_attr" "sqrt")
13988    (set_attr "btver2_sse_attr" "sqrt")
13989    (set_attr "prefix" "maybe_vex")
13990    (set_attr "mode" "<MODE>")
13991    (set_attr "athlon_decode" "*")
13992    (set_attr "amdfam10_decode" "*")
13993    (set_attr "bdver1_decode" "*")])
13995 (define_expand "sqrt<mode>2"
13996   [(set (match_operand:MODEF 0 "register_operand")
13997         (sqrt:MODEF
13998           (match_operand:MODEF 1 "nonimmediate_operand")))]
13999   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14000    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14002   if (<MODE>mode == SFmode
14003       && TARGET_SSE_MATH
14004       && TARGET_RECIP_SQRT
14005       && !optimize_function_for_size_p (cfun)
14006       && flag_finite_math_only && !flag_trapping_math
14007       && flag_unsafe_math_optimizations)
14008     {
14009       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14010       DONE;
14011     }
14013   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14014     {
14015       rtx op0 = gen_reg_rtx (XFmode);
14016       rtx op1 = force_reg (<MODE>mode, operands[1]);
14018       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14019       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14020       DONE;
14021    }
14024 (define_insn "fpremxf4_i387"
14025   [(set (match_operand:XF 0 "register_operand" "=f")
14026         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14027                     (match_operand:XF 3 "register_operand" "1")]
14028                    UNSPEC_FPREM_F))
14029    (set (match_operand:XF 1 "register_operand" "=u")
14030         (unspec:XF [(match_dup 2) (match_dup 3)]
14031                    UNSPEC_FPREM_U))
14032    (set (reg:CCFP FPSR_REG)
14033         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14034                      UNSPEC_C2_FLAG))]
14035   "TARGET_USE_FANCY_MATH_387
14036    && flag_finite_math_only"
14037   "fprem"
14038   [(set_attr "type" "fpspc")
14039    (set_attr "mode" "XF")])
14041 (define_expand "fmodxf3"
14042   [(use (match_operand:XF 0 "register_operand"))
14043    (use (match_operand:XF 1 "general_operand"))
14044    (use (match_operand:XF 2 "general_operand"))]
14045   "TARGET_USE_FANCY_MATH_387
14046    && flag_finite_math_only"
14048   rtx_code_label *label = gen_label_rtx ();
14050   rtx op1 = gen_reg_rtx (XFmode);
14051   rtx op2 = gen_reg_rtx (XFmode);
14053   emit_move_insn (op2, operands[2]);
14054   emit_move_insn (op1, operands[1]);
14056   emit_label (label);
14057   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14058   ix86_emit_fp_unordered_jump (label);
14059   LABEL_NUSES (label) = 1;
14061   emit_move_insn (operands[0], op1);
14062   DONE;
14065 (define_expand "fmod<mode>3"
14066   [(use (match_operand:MODEF 0 "register_operand"))
14067    (use (match_operand:MODEF 1 "general_operand"))
14068    (use (match_operand:MODEF 2 "general_operand"))]
14069   "TARGET_USE_FANCY_MATH_387
14070    && flag_finite_math_only"
14072   rtx (*gen_truncxf) (rtx, rtx);
14074   rtx_code_label *label = gen_label_rtx ();
14076   rtx op1 = gen_reg_rtx (XFmode);
14077   rtx op2 = gen_reg_rtx (XFmode);
14079   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14080   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14082   emit_label (label);
14083   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14084   ix86_emit_fp_unordered_jump (label);
14085   LABEL_NUSES (label) = 1;
14087   /* Truncate the result properly for strict SSE math.  */
14088   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14089       && !TARGET_MIX_SSE_I387)
14090     gen_truncxf = gen_truncxf<mode>2;
14091   else
14092     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14094   emit_insn (gen_truncxf (operands[0], op1));
14095   DONE;
14098 (define_insn "fprem1xf4_i387"
14099   [(set (match_operand:XF 0 "register_operand" "=f")
14100         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14101                     (match_operand:XF 3 "register_operand" "1")]
14102                    UNSPEC_FPREM1_F))
14103    (set (match_operand:XF 1 "register_operand" "=u")
14104         (unspec:XF [(match_dup 2) (match_dup 3)]
14105                    UNSPEC_FPREM1_U))
14106    (set (reg:CCFP FPSR_REG)
14107         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14108                      UNSPEC_C2_FLAG))]
14109   "TARGET_USE_FANCY_MATH_387
14110    && flag_finite_math_only"
14111   "fprem1"
14112   [(set_attr "type" "fpspc")
14113    (set_attr "mode" "XF")])
14115 (define_expand "remainderxf3"
14116   [(use (match_operand:XF 0 "register_operand"))
14117    (use (match_operand:XF 1 "general_operand"))
14118    (use (match_operand:XF 2 "general_operand"))]
14119   "TARGET_USE_FANCY_MATH_387
14120    && flag_finite_math_only"
14122   rtx_code_label *label = gen_label_rtx ();
14124   rtx op1 = gen_reg_rtx (XFmode);
14125   rtx op2 = gen_reg_rtx (XFmode);
14127   emit_move_insn (op2, operands[2]);
14128   emit_move_insn (op1, operands[1]);
14130   emit_label (label);
14131   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14132   ix86_emit_fp_unordered_jump (label);
14133   LABEL_NUSES (label) = 1;
14135   emit_move_insn (operands[0], op1);
14136   DONE;
14139 (define_expand "remainder<mode>3"
14140   [(use (match_operand:MODEF 0 "register_operand"))
14141    (use (match_operand:MODEF 1 "general_operand"))
14142    (use (match_operand:MODEF 2 "general_operand"))]
14143   "TARGET_USE_FANCY_MATH_387
14144    && flag_finite_math_only"
14146   rtx (*gen_truncxf) (rtx, rtx);
14148   rtx_code_label *label = gen_label_rtx ();
14150   rtx op1 = gen_reg_rtx (XFmode);
14151   rtx op2 = gen_reg_rtx (XFmode);
14153   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14154   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14156   emit_label (label);
14158   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14159   ix86_emit_fp_unordered_jump (label);
14160   LABEL_NUSES (label) = 1;
14162   /* Truncate the result properly for strict SSE math.  */
14163   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14164       && !TARGET_MIX_SSE_I387)
14165     gen_truncxf = gen_truncxf<mode>2;
14166   else
14167     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14169   emit_insn (gen_truncxf (operands[0], op1));
14170   DONE;
14173 (define_int_iterator SINCOS
14174         [UNSPEC_SIN
14175          UNSPEC_COS])
14177 (define_int_attr sincos
14178         [(UNSPEC_SIN "sin")
14179          (UNSPEC_COS "cos")])
14181 (define_insn "*<sincos>xf2_i387"
14182   [(set (match_operand:XF 0 "register_operand" "=f")
14183         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14184                    SINCOS))]
14185   "TARGET_USE_FANCY_MATH_387
14186    && flag_unsafe_math_optimizations"
14187   "f<sincos>"
14188   [(set_attr "type" "fpspc")
14189    (set_attr "mode" "XF")])
14191 (define_insn "*<sincos>_extend<mode>xf2_i387"
14192   [(set (match_operand:XF 0 "register_operand" "=f")
14193         (unspec:XF [(float_extend:XF
14194                       (match_operand:MODEF 1 "register_operand" "0"))]
14195                    SINCOS))]
14196   "TARGET_USE_FANCY_MATH_387
14197    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14198        || TARGET_MIX_SSE_I387)
14199    && flag_unsafe_math_optimizations"
14200   "f<sincos>"
14201   [(set_attr "type" "fpspc")
14202    (set_attr "mode" "XF")])
14204 ;; When sincos pattern is defined, sin and cos builtin functions will be
14205 ;; expanded to sincos pattern with one of its outputs left unused.
14206 ;; CSE pass will figure out if two sincos patterns can be combined,
14207 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14208 ;; depending on the unused output.
14210 (define_insn "sincosxf3"
14211   [(set (match_operand:XF 0 "register_operand" "=f")
14212         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14213                    UNSPEC_SINCOS_COS))
14214    (set (match_operand:XF 1 "register_operand" "=u")
14215         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14216   "TARGET_USE_FANCY_MATH_387
14217    && flag_unsafe_math_optimizations"
14218   "fsincos"
14219   [(set_attr "type" "fpspc")
14220    (set_attr "mode" "XF")])
14222 (define_split
14223   [(set (match_operand:XF 0 "register_operand")
14224         (unspec:XF [(match_operand:XF 2 "register_operand")]
14225                    UNSPEC_SINCOS_COS))
14226    (set (match_operand:XF 1 "register_operand")
14227         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14228   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14229    && can_create_pseudo_p ()"
14230   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14232 (define_split
14233   [(set (match_operand:XF 0 "register_operand")
14234         (unspec:XF [(match_operand:XF 2 "register_operand")]
14235                    UNSPEC_SINCOS_COS))
14236    (set (match_operand:XF 1 "register_operand")
14237         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14238   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14239    && can_create_pseudo_p ()"
14240   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14242 (define_insn "sincos_extend<mode>xf3_i387"
14243   [(set (match_operand:XF 0 "register_operand" "=f")
14244         (unspec:XF [(float_extend:XF
14245                       (match_operand:MODEF 2 "register_operand" "0"))]
14246                    UNSPEC_SINCOS_COS))
14247    (set (match_operand:XF 1 "register_operand" "=u")
14248         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14249   "TARGET_USE_FANCY_MATH_387
14250    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14251        || TARGET_MIX_SSE_I387)
14252    && flag_unsafe_math_optimizations"
14253   "fsincos"
14254   [(set_attr "type" "fpspc")
14255    (set_attr "mode" "XF")])
14257 (define_split
14258   [(set (match_operand:XF 0 "register_operand")
14259         (unspec:XF [(float_extend:XF
14260                       (match_operand:MODEF 2 "register_operand"))]
14261                    UNSPEC_SINCOS_COS))
14262    (set (match_operand:XF 1 "register_operand")
14263         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14264   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14265    && can_create_pseudo_p ()"
14266   [(set (match_dup 1)
14267         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14269 (define_split
14270   [(set (match_operand:XF 0 "register_operand")
14271         (unspec:XF [(float_extend:XF
14272                       (match_operand:MODEF 2 "register_operand"))]
14273                    UNSPEC_SINCOS_COS))
14274    (set (match_operand:XF 1 "register_operand")
14275         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14276   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14277    && can_create_pseudo_p ()"
14278   [(set (match_dup 0)
14279         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14281 (define_expand "sincos<mode>3"
14282   [(use (match_operand:MODEF 0 "register_operand"))
14283    (use (match_operand:MODEF 1 "register_operand"))
14284    (use (match_operand:MODEF 2 "register_operand"))]
14285   "TARGET_USE_FANCY_MATH_387
14286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14287        || TARGET_MIX_SSE_I387)
14288    && flag_unsafe_math_optimizations"
14290   rtx op0 = gen_reg_rtx (XFmode);
14291   rtx op1 = gen_reg_rtx (XFmode);
14293   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14294   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14295   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14296   DONE;
14299 (define_insn "fptanxf4_i387"
14300   [(set (match_operand:XF 0 "register_operand" "=f")
14301         (match_operand:XF 3 "const_double_operand" "F"))
14302    (set (match_operand:XF 1 "register_operand" "=u")
14303         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14304                    UNSPEC_TAN))]
14305   "TARGET_USE_FANCY_MATH_387
14306    && flag_unsafe_math_optimizations
14307    && standard_80387_constant_p (operands[3]) == 2"
14308   "fptan"
14309   [(set_attr "type" "fpspc")
14310    (set_attr "mode" "XF")])
14312 (define_insn "fptan_extend<mode>xf4_i387"
14313   [(set (match_operand:MODEF 0 "register_operand" "=f")
14314         (match_operand:MODEF 3 "const_double_operand" "F"))
14315    (set (match_operand:XF 1 "register_operand" "=u")
14316         (unspec:XF [(float_extend:XF
14317                       (match_operand:MODEF 2 "register_operand" "0"))]
14318                    UNSPEC_TAN))]
14319   "TARGET_USE_FANCY_MATH_387
14320    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321        || TARGET_MIX_SSE_I387)
14322    && flag_unsafe_math_optimizations
14323    && standard_80387_constant_p (operands[3]) == 2"
14324   "fptan"
14325   [(set_attr "type" "fpspc")
14326    (set_attr "mode" "XF")])
14328 (define_expand "tanxf2"
14329   [(use (match_operand:XF 0 "register_operand"))
14330    (use (match_operand:XF 1 "register_operand"))]
14331   "TARGET_USE_FANCY_MATH_387
14332    && flag_unsafe_math_optimizations"
14334   rtx one = gen_reg_rtx (XFmode);
14335   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14337   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14338   DONE;
14341 (define_expand "tan<mode>2"
14342   [(use (match_operand:MODEF 0 "register_operand"))
14343    (use (match_operand:MODEF 1 "register_operand"))]
14344   "TARGET_USE_FANCY_MATH_387
14345    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14346        || TARGET_MIX_SSE_I387)
14347    && flag_unsafe_math_optimizations"
14349   rtx op0 = gen_reg_rtx (XFmode);
14351   rtx one = gen_reg_rtx (<MODE>mode);
14352   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14354   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14355                                              operands[1], op2));
14356   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14357   DONE;
14360 (define_insn "*fpatanxf3_i387"
14361   [(set (match_operand:XF 0 "register_operand" "=f")
14362         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14363                     (match_operand:XF 2 "register_operand" "u")]
14364                    UNSPEC_FPATAN))
14365    (clobber (match_scratch:XF 3 "=2"))]
14366   "TARGET_USE_FANCY_MATH_387
14367    && flag_unsafe_math_optimizations"
14368   "fpatan"
14369   [(set_attr "type" "fpspc")
14370    (set_attr "mode" "XF")])
14372 (define_insn "fpatan_extend<mode>xf3_i387"
14373   [(set (match_operand:XF 0 "register_operand" "=f")
14374         (unspec:XF [(float_extend:XF
14375                       (match_operand:MODEF 1 "register_operand" "0"))
14376                     (float_extend:XF
14377                       (match_operand:MODEF 2 "register_operand" "u"))]
14378                    UNSPEC_FPATAN))
14379    (clobber (match_scratch:XF 3 "=2"))]
14380   "TARGET_USE_FANCY_MATH_387
14381    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14382        || TARGET_MIX_SSE_I387)
14383    && flag_unsafe_math_optimizations"
14384   "fpatan"
14385   [(set_attr "type" "fpspc")
14386    (set_attr "mode" "XF")])
14388 (define_expand "atan2xf3"
14389   [(parallel [(set (match_operand:XF 0 "register_operand")
14390                    (unspec:XF [(match_operand:XF 2 "register_operand")
14391                                (match_operand:XF 1 "register_operand")]
14392                               UNSPEC_FPATAN))
14393               (clobber (match_scratch:XF 3))])]
14394   "TARGET_USE_FANCY_MATH_387
14395    && flag_unsafe_math_optimizations")
14397 (define_expand "atan2<mode>3"
14398   [(use (match_operand:MODEF 0 "register_operand"))
14399    (use (match_operand:MODEF 1 "register_operand"))
14400    (use (match_operand:MODEF 2 "register_operand"))]
14401   "TARGET_USE_FANCY_MATH_387
14402    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14403        || TARGET_MIX_SSE_I387)
14404    && flag_unsafe_math_optimizations"
14406   rtx op0 = gen_reg_rtx (XFmode);
14408   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14409   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14410   DONE;
14413 (define_expand "atanxf2"
14414   [(parallel [(set (match_operand:XF 0 "register_operand")
14415                    (unspec:XF [(match_dup 2)
14416                                (match_operand:XF 1 "register_operand")]
14417                               UNSPEC_FPATAN))
14418               (clobber (match_scratch:XF 3))])]
14419   "TARGET_USE_FANCY_MATH_387
14420    && flag_unsafe_math_optimizations"
14422   operands[2] = gen_reg_rtx (XFmode);
14423   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14426 (define_expand "atan<mode>2"
14427   [(use (match_operand:MODEF 0 "register_operand"))
14428    (use (match_operand:MODEF 1 "register_operand"))]
14429   "TARGET_USE_FANCY_MATH_387
14430    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14431        || TARGET_MIX_SSE_I387)
14432    && flag_unsafe_math_optimizations"
14434   rtx op0 = gen_reg_rtx (XFmode);
14436   rtx op2 = gen_reg_rtx (<MODE>mode);
14437   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14439   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14440   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14441   DONE;
14444 (define_expand "asinxf2"
14445   [(set (match_dup 2)
14446         (mult:XF (match_operand:XF 1 "register_operand")
14447                  (match_dup 1)))
14448    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14449    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14450    (parallel [(set (match_operand:XF 0 "register_operand")
14451                    (unspec:XF [(match_dup 5) (match_dup 1)]
14452                               UNSPEC_FPATAN))
14453               (clobber (match_scratch:XF 6))])]
14454   "TARGET_USE_FANCY_MATH_387
14455    && flag_unsafe_math_optimizations"
14457   int i;
14459   if (optimize_insn_for_size_p ())
14460     FAIL;
14462   for (i = 2; i < 6; i++)
14463     operands[i] = gen_reg_rtx (XFmode);
14465   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14468 (define_expand "asin<mode>2"
14469   [(use (match_operand:MODEF 0 "register_operand"))
14470    (use (match_operand:MODEF 1 "general_operand"))]
14471  "TARGET_USE_FANCY_MATH_387
14472    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14473        || TARGET_MIX_SSE_I387)
14474    && flag_unsafe_math_optimizations"
14476   rtx op0 = gen_reg_rtx (XFmode);
14477   rtx op1 = gen_reg_rtx (XFmode);
14479   if (optimize_insn_for_size_p ())
14480     FAIL;
14482   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14483   emit_insn (gen_asinxf2 (op0, op1));
14484   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14485   DONE;
14488 (define_expand "acosxf2"
14489   [(set (match_dup 2)
14490         (mult:XF (match_operand:XF 1 "register_operand")
14491                  (match_dup 1)))
14492    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14493    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14494    (parallel [(set (match_operand:XF 0 "register_operand")
14495                    (unspec:XF [(match_dup 1) (match_dup 5)]
14496                               UNSPEC_FPATAN))
14497               (clobber (match_scratch:XF 6))])]
14498   "TARGET_USE_FANCY_MATH_387
14499    && flag_unsafe_math_optimizations"
14501   int i;
14503   if (optimize_insn_for_size_p ())
14504     FAIL;
14506   for (i = 2; i < 6; i++)
14507     operands[i] = gen_reg_rtx (XFmode);
14509   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14512 (define_expand "acos<mode>2"
14513   [(use (match_operand:MODEF 0 "register_operand"))
14514    (use (match_operand:MODEF 1 "general_operand"))]
14515  "TARGET_USE_FANCY_MATH_387
14516    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14517        || TARGET_MIX_SSE_I387)
14518    && flag_unsafe_math_optimizations"
14520   rtx op0 = gen_reg_rtx (XFmode);
14521   rtx op1 = gen_reg_rtx (XFmode);
14523   if (optimize_insn_for_size_p ())
14524     FAIL;
14526   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14527   emit_insn (gen_acosxf2 (op0, op1));
14528   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14529   DONE;
14532 (define_insn "fyl2xxf3_i387"
14533   [(set (match_operand:XF 0 "register_operand" "=f")
14534         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14535                     (match_operand:XF 2 "register_operand" "u")]
14536                    UNSPEC_FYL2X))
14537    (clobber (match_scratch:XF 3 "=2"))]
14538   "TARGET_USE_FANCY_MATH_387
14539    && flag_unsafe_math_optimizations"
14540   "fyl2x"
14541   [(set_attr "type" "fpspc")
14542    (set_attr "mode" "XF")])
14544 (define_insn "fyl2x_extend<mode>xf3_i387"
14545   [(set (match_operand:XF 0 "register_operand" "=f")
14546         (unspec:XF [(float_extend:XF
14547                       (match_operand:MODEF 1 "register_operand" "0"))
14548                     (match_operand:XF 2 "register_operand" "u")]
14549                    UNSPEC_FYL2X))
14550    (clobber (match_scratch:XF 3 "=2"))]
14551   "TARGET_USE_FANCY_MATH_387
14552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553        || TARGET_MIX_SSE_I387)
14554    && flag_unsafe_math_optimizations"
14555   "fyl2x"
14556   [(set_attr "type" "fpspc")
14557    (set_attr "mode" "XF")])
14559 (define_expand "logxf2"
14560   [(parallel [(set (match_operand:XF 0 "register_operand")
14561                    (unspec:XF [(match_operand:XF 1 "register_operand")
14562                                (match_dup 2)] UNSPEC_FYL2X))
14563               (clobber (match_scratch:XF 3))])]
14564   "TARGET_USE_FANCY_MATH_387
14565    && flag_unsafe_math_optimizations"
14567   operands[2] = gen_reg_rtx (XFmode);
14568   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14571 (define_expand "log<mode>2"
14572   [(use (match_operand:MODEF 0 "register_operand"))
14573    (use (match_operand:MODEF 1 "register_operand"))]
14574   "TARGET_USE_FANCY_MATH_387
14575    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576        || TARGET_MIX_SSE_I387)
14577    && flag_unsafe_math_optimizations"
14579   rtx op0 = gen_reg_rtx (XFmode);
14581   rtx op2 = gen_reg_rtx (XFmode);
14582   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14584   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14585   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586   DONE;
14589 (define_expand "log10xf2"
14590   [(parallel [(set (match_operand:XF 0 "register_operand")
14591                    (unspec:XF [(match_operand:XF 1 "register_operand")
14592                                (match_dup 2)] UNSPEC_FYL2X))
14593               (clobber (match_scratch:XF 3))])]
14594   "TARGET_USE_FANCY_MATH_387
14595    && flag_unsafe_math_optimizations"
14597   operands[2] = gen_reg_rtx (XFmode);
14598   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14601 (define_expand "log10<mode>2"
14602   [(use (match_operand:MODEF 0 "register_operand"))
14603    (use (match_operand:MODEF 1 "register_operand"))]
14604   "TARGET_USE_FANCY_MATH_387
14605    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14606        || TARGET_MIX_SSE_I387)
14607    && flag_unsafe_math_optimizations"
14609   rtx op0 = gen_reg_rtx (XFmode);
14611   rtx op2 = gen_reg_rtx (XFmode);
14612   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14614   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14615   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14616   DONE;
14619 (define_expand "log2xf2"
14620   [(parallel [(set (match_operand:XF 0 "register_operand")
14621                    (unspec:XF [(match_operand:XF 1 "register_operand")
14622                                (match_dup 2)] UNSPEC_FYL2X))
14623               (clobber (match_scratch:XF 3))])]
14624   "TARGET_USE_FANCY_MATH_387
14625    && flag_unsafe_math_optimizations"
14627   operands[2] = gen_reg_rtx (XFmode);
14628   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14631 (define_expand "log2<mode>2"
14632   [(use (match_operand:MODEF 0 "register_operand"))
14633    (use (match_operand:MODEF 1 "register_operand"))]
14634   "TARGET_USE_FANCY_MATH_387
14635    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14636        || TARGET_MIX_SSE_I387)
14637    && flag_unsafe_math_optimizations"
14639   rtx op0 = gen_reg_rtx (XFmode);
14641   rtx op2 = gen_reg_rtx (XFmode);
14642   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14644   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14645   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14646   DONE;
14649 (define_insn "fyl2xp1xf3_i387"
14650   [(set (match_operand:XF 0 "register_operand" "=f")
14651         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14652                     (match_operand:XF 2 "register_operand" "u")]
14653                    UNSPEC_FYL2XP1))
14654    (clobber (match_scratch:XF 3 "=2"))]
14655   "TARGET_USE_FANCY_MATH_387
14656    && flag_unsafe_math_optimizations"
14657   "fyl2xp1"
14658   [(set_attr "type" "fpspc")
14659    (set_attr "mode" "XF")])
14661 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14662   [(set (match_operand:XF 0 "register_operand" "=f")
14663         (unspec:XF [(float_extend:XF
14664                       (match_operand:MODEF 1 "register_operand" "0"))
14665                     (match_operand:XF 2 "register_operand" "u")]
14666                    UNSPEC_FYL2XP1))
14667    (clobber (match_scratch:XF 3 "=2"))]
14668   "TARGET_USE_FANCY_MATH_387
14669    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14670        || TARGET_MIX_SSE_I387)
14671    && flag_unsafe_math_optimizations"
14672   "fyl2xp1"
14673   [(set_attr "type" "fpspc")
14674    (set_attr "mode" "XF")])
14676 (define_expand "log1pxf2"
14677   [(use (match_operand:XF 0 "register_operand"))
14678    (use (match_operand:XF 1 "register_operand"))]
14679   "TARGET_USE_FANCY_MATH_387
14680    && flag_unsafe_math_optimizations"
14682   if (optimize_insn_for_size_p ())
14683     FAIL;
14685   ix86_emit_i387_log1p (operands[0], operands[1]);
14686   DONE;
14689 (define_expand "log1p<mode>2"
14690   [(use (match_operand:MODEF 0 "register_operand"))
14691    (use (match_operand:MODEF 1 "register_operand"))]
14692   "TARGET_USE_FANCY_MATH_387
14693    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14694        || TARGET_MIX_SSE_I387)
14695    && flag_unsafe_math_optimizations"
14697   rtx op0;
14699   if (optimize_insn_for_size_p ())
14700     FAIL;
14702   op0 = gen_reg_rtx (XFmode);
14704   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14706   ix86_emit_i387_log1p (op0, operands[1]);
14707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14708   DONE;
14711 (define_insn "fxtractxf3_i387"
14712   [(set (match_operand:XF 0 "register_operand" "=f")
14713         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14714                    UNSPEC_XTRACT_FRACT))
14715    (set (match_operand:XF 1 "register_operand" "=u")
14716         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14717   "TARGET_USE_FANCY_MATH_387
14718    && flag_unsafe_math_optimizations"
14719   "fxtract"
14720   [(set_attr "type" "fpspc")
14721    (set_attr "mode" "XF")])
14723 (define_insn "fxtract_extend<mode>xf3_i387"
14724   [(set (match_operand:XF 0 "register_operand" "=f")
14725         (unspec:XF [(float_extend:XF
14726                       (match_operand:MODEF 2 "register_operand" "0"))]
14727                    UNSPEC_XTRACT_FRACT))
14728    (set (match_operand:XF 1 "register_operand" "=u")
14729         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14732        || TARGET_MIX_SSE_I387)
14733    && flag_unsafe_math_optimizations"
14734   "fxtract"
14735   [(set_attr "type" "fpspc")
14736    (set_attr "mode" "XF")])
14738 (define_expand "logbxf2"
14739   [(parallel [(set (match_dup 2)
14740                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14741                               UNSPEC_XTRACT_FRACT))
14742               (set (match_operand:XF 0 "register_operand")
14743                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14744   "TARGET_USE_FANCY_MATH_387
14745    && flag_unsafe_math_optimizations"
14746   "operands[2] = gen_reg_rtx (XFmode);")
14748 (define_expand "logb<mode>2"
14749   [(use (match_operand:MODEF 0 "register_operand"))
14750    (use (match_operand:MODEF 1 "register_operand"))]
14751   "TARGET_USE_FANCY_MATH_387
14752    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14753        || TARGET_MIX_SSE_I387)
14754    && flag_unsafe_math_optimizations"
14756   rtx op0 = gen_reg_rtx (XFmode);
14757   rtx op1 = gen_reg_rtx (XFmode);
14759   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14760   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14761   DONE;
14764 (define_expand "ilogbxf2"
14765   [(use (match_operand:SI 0 "register_operand"))
14766    (use (match_operand:XF 1 "register_operand"))]
14767   "TARGET_USE_FANCY_MATH_387
14768    && flag_unsafe_math_optimizations"
14770   rtx op0, op1;
14772   if (optimize_insn_for_size_p ())
14773     FAIL;
14775   op0 = gen_reg_rtx (XFmode);
14776   op1 = gen_reg_rtx (XFmode);
14778   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14779   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14780   DONE;
14783 (define_expand "ilogb<mode>2"
14784   [(use (match_operand:SI 0 "register_operand"))
14785    (use (match_operand:MODEF 1 "register_operand"))]
14786   "TARGET_USE_FANCY_MATH_387
14787    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14788        || TARGET_MIX_SSE_I387)
14789    && flag_unsafe_math_optimizations"
14791   rtx op0, op1;
14793   if (optimize_insn_for_size_p ())
14794     FAIL;
14796   op0 = gen_reg_rtx (XFmode);
14797   op1 = gen_reg_rtx (XFmode);
14799   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14800   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14801   DONE;
14804 (define_insn "*f2xm1xf2_i387"
14805   [(set (match_operand:XF 0 "register_operand" "=f")
14806         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14807                    UNSPEC_F2XM1))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && flag_unsafe_math_optimizations"
14810   "f2xm1"
14811   [(set_attr "type" "fpspc")
14812    (set_attr "mode" "XF")])
14814 (define_insn "fscalexf4_i387"
14815   [(set (match_operand:XF 0 "register_operand" "=f")
14816         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14817                     (match_operand:XF 3 "register_operand" "1")]
14818                    UNSPEC_FSCALE_FRACT))
14819    (set (match_operand:XF 1 "register_operand" "=u")
14820         (unspec:XF [(match_dup 2) (match_dup 3)]
14821                    UNSPEC_FSCALE_EXP))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && flag_unsafe_math_optimizations"
14824   "fscale"
14825   [(set_attr "type" "fpspc")
14826    (set_attr "mode" "XF")])
14828 (define_expand "expNcorexf3"
14829   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14830                                (match_operand:XF 2 "register_operand")))
14831    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14832    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14833    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14834    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14835    (parallel [(set (match_operand:XF 0 "register_operand")
14836                    (unspec:XF [(match_dup 8) (match_dup 4)]
14837                               UNSPEC_FSCALE_FRACT))
14838               (set (match_dup 9)
14839                    (unspec:XF [(match_dup 8) (match_dup 4)]
14840                               UNSPEC_FSCALE_EXP))])]
14841   "TARGET_USE_FANCY_MATH_387
14842    && flag_unsafe_math_optimizations"
14844   int i;
14846   if (optimize_insn_for_size_p ())
14847     FAIL;
14849   for (i = 3; i < 10; i++)
14850     operands[i] = gen_reg_rtx (XFmode);
14852   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14855 (define_expand "expxf2"
14856   [(use (match_operand:XF 0 "register_operand"))
14857    (use (match_operand:XF 1 "register_operand"))]
14858   "TARGET_USE_FANCY_MATH_387
14859    && flag_unsafe_math_optimizations"
14861   rtx op2;
14863   if (optimize_insn_for_size_p ())
14864     FAIL;
14866   op2 = gen_reg_rtx (XFmode);
14867   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14869   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14870   DONE;
14873 (define_expand "exp<mode>2"
14874   [(use (match_operand:MODEF 0 "register_operand"))
14875    (use (match_operand:MODEF 1 "general_operand"))]
14876  "TARGET_USE_FANCY_MATH_387
14877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878        || TARGET_MIX_SSE_I387)
14879    && flag_unsafe_math_optimizations"
14881   rtx op0, op1;
14883   if (optimize_insn_for_size_p ())
14884     FAIL;
14886   op0 = gen_reg_rtx (XFmode);
14887   op1 = gen_reg_rtx (XFmode);
14889   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14890   emit_insn (gen_expxf2 (op0, op1));
14891   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14892   DONE;
14895 (define_expand "exp10xf2"
14896   [(use (match_operand:XF 0 "register_operand"))
14897    (use (match_operand:XF 1 "register_operand"))]
14898   "TARGET_USE_FANCY_MATH_387
14899    && flag_unsafe_math_optimizations"
14901   rtx op2;
14903   if (optimize_insn_for_size_p ())
14904     FAIL;
14906   op2 = gen_reg_rtx (XFmode);
14907   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14909   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14910   DONE;
14913 (define_expand "exp10<mode>2"
14914   [(use (match_operand:MODEF 0 "register_operand"))
14915    (use (match_operand:MODEF 1 "general_operand"))]
14916  "TARGET_USE_FANCY_MATH_387
14917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14918        || TARGET_MIX_SSE_I387)
14919    && flag_unsafe_math_optimizations"
14921   rtx op0, op1;
14923   if (optimize_insn_for_size_p ())
14924     FAIL;
14926   op0 = gen_reg_rtx (XFmode);
14927   op1 = gen_reg_rtx (XFmode);
14929   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14930   emit_insn (gen_exp10xf2 (op0, op1));
14931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14932   DONE;
14935 (define_expand "exp2xf2"
14936   [(use (match_operand:XF 0 "register_operand"))
14937    (use (match_operand:XF 1 "register_operand"))]
14938   "TARGET_USE_FANCY_MATH_387
14939    && flag_unsafe_math_optimizations"
14941   rtx op2;
14943   if (optimize_insn_for_size_p ())
14944     FAIL;
14946   op2 = gen_reg_rtx (XFmode);
14947   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14949   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14950   DONE;
14953 (define_expand "exp2<mode>2"
14954   [(use (match_operand:MODEF 0 "register_operand"))
14955    (use (match_operand:MODEF 1 "general_operand"))]
14956  "TARGET_USE_FANCY_MATH_387
14957    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14958        || TARGET_MIX_SSE_I387)
14959    && flag_unsafe_math_optimizations"
14961   rtx op0, op1;
14963   if (optimize_insn_for_size_p ())
14964     FAIL;
14966   op0 = gen_reg_rtx (XFmode);
14967   op1 = gen_reg_rtx (XFmode);
14969   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14970   emit_insn (gen_exp2xf2 (op0, op1));
14971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14972   DONE;
14975 (define_expand "expm1xf2"
14976   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14977                                (match_dup 2)))
14978    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14979    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14980    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14981    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14982    (parallel [(set (match_dup 7)
14983                    (unspec:XF [(match_dup 6) (match_dup 4)]
14984                               UNSPEC_FSCALE_FRACT))
14985               (set (match_dup 8)
14986                    (unspec:XF [(match_dup 6) (match_dup 4)]
14987                               UNSPEC_FSCALE_EXP))])
14988    (parallel [(set (match_dup 10)
14989                    (unspec:XF [(match_dup 9) (match_dup 8)]
14990                               UNSPEC_FSCALE_FRACT))
14991               (set (match_dup 11)
14992                    (unspec:XF [(match_dup 9) (match_dup 8)]
14993                               UNSPEC_FSCALE_EXP))])
14994    (set (match_dup 12) (minus:XF (match_dup 10)
14995                                  (float_extend:XF (match_dup 13))))
14996    (set (match_operand:XF 0 "register_operand")
14997         (plus:XF (match_dup 12) (match_dup 7)))]
14998   "TARGET_USE_FANCY_MATH_387
14999    && flag_unsafe_math_optimizations"
15001   int i;
15003   if (optimize_insn_for_size_p ())
15004     FAIL;
15006   for (i = 2; i < 13; i++)
15007     operands[i] = gen_reg_rtx (XFmode);
15009   operands[13]
15010     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15012   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15015 (define_expand "expm1<mode>2"
15016   [(use (match_operand:MODEF 0 "register_operand"))
15017    (use (match_operand:MODEF 1 "general_operand"))]
15018  "TARGET_USE_FANCY_MATH_387
15019    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15020        || TARGET_MIX_SSE_I387)
15021    && flag_unsafe_math_optimizations"
15023   rtx op0, op1;
15025   if (optimize_insn_for_size_p ())
15026     FAIL;
15028   op0 = gen_reg_rtx (XFmode);
15029   op1 = gen_reg_rtx (XFmode);
15031   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15032   emit_insn (gen_expm1xf2 (op0, op1));
15033   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15034   DONE;
15037 (define_expand "ldexpxf3"
15038   [(match_operand:XF 0 "register_operand")
15039    (match_operand:XF 1 "register_operand")
15040    (match_operand:SI 2 "register_operand")]
15041   "TARGET_USE_FANCY_MATH_387
15042    && flag_unsafe_math_optimizations"
15044   rtx tmp1, tmp2;
15045   if (optimize_insn_for_size_p ())
15046     FAIL;
15048   tmp1 = gen_reg_rtx (XFmode);
15049   tmp2 = gen_reg_rtx (XFmode);
15051   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15052   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15053                                  operands[1], tmp1));
15054   DONE;
15057 (define_expand "ldexp<mode>3"
15058   [(use (match_operand:MODEF 0 "register_operand"))
15059    (use (match_operand:MODEF 1 "general_operand"))
15060    (use (match_operand:SI 2 "register_operand"))]
15061  "TARGET_USE_FANCY_MATH_387
15062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15063        || TARGET_MIX_SSE_I387)
15064    && flag_unsafe_math_optimizations"
15066   rtx op0, op1;
15068   if (optimize_insn_for_size_p ())
15069     FAIL;
15071   op0 = gen_reg_rtx (XFmode);
15072   op1 = gen_reg_rtx (XFmode);
15074   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15075   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15076   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15077   DONE;
15080 (define_expand "scalbxf3"
15081   [(parallel [(set (match_operand:XF 0 " register_operand")
15082                    (unspec:XF [(match_operand:XF 1 "register_operand")
15083                                (match_operand:XF 2 "register_operand")]
15084                               UNSPEC_FSCALE_FRACT))
15085               (set (match_dup 3)
15086                    (unspec:XF [(match_dup 1) (match_dup 2)]
15087                               UNSPEC_FSCALE_EXP))])]
15088   "TARGET_USE_FANCY_MATH_387
15089    && flag_unsafe_math_optimizations"
15091   if (optimize_insn_for_size_p ())
15092     FAIL;
15094   operands[3] = gen_reg_rtx (XFmode);
15097 (define_expand "scalb<mode>3"
15098   [(use (match_operand:MODEF 0 "register_operand"))
15099    (use (match_operand:MODEF 1 "general_operand"))
15100    (use (match_operand:MODEF 2 "general_operand"))]
15101  "TARGET_USE_FANCY_MATH_387
15102    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15103        || TARGET_MIX_SSE_I387)
15104    && flag_unsafe_math_optimizations"
15106   rtx op0, op1, op2;
15108   if (optimize_insn_for_size_p ())
15109     FAIL;
15111   op0 = gen_reg_rtx (XFmode);
15112   op1 = gen_reg_rtx (XFmode);
15113   op2 = gen_reg_rtx (XFmode);
15115   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15116   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15117   emit_insn (gen_scalbxf3 (op0, op1, op2));
15118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15119   DONE;
15122 (define_expand "significandxf2"
15123   [(parallel [(set (match_operand:XF 0 "register_operand")
15124                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15125                               UNSPEC_XTRACT_FRACT))
15126               (set (match_dup 2)
15127                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15128   "TARGET_USE_FANCY_MATH_387
15129    && flag_unsafe_math_optimizations"
15130   "operands[2] = gen_reg_rtx (XFmode);")
15132 (define_expand "significand<mode>2"
15133   [(use (match_operand:MODEF 0 "register_operand"))
15134    (use (match_operand:MODEF 1 "register_operand"))]
15135   "TARGET_USE_FANCY_MATH_387
15136    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15137        || TARGET_MIX_SSE_I387)
15138    && flag_unsafe_math_optimizations"
15140   rtx op0 = gen_reg_rtx (XFmode);
15141   rtx op1 = gen_reg_rtx (XFmode);
15143   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15144   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15145   DONE;
15149 (define_insn "sse4_1_round<mode>2"
15150   [(set (match_operand:MODEF 0 "register_operand" "=x")
15151         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15152                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15153                       UNSPEC_ROUND))]
15154   "TARGET_ROUND"
15155   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15156   [(set_attr "type" "ssecvt")
15157    (set_attr "prefix_extra" "1")
15158    (set_attr "prefix" "maybe_vex")
15159    (set_attr "mode" "<MODE>")])
15161 (define_insn "rintxf2"
15162   [(set (match_operand:XF 0 "register_operand" "=f")
15163         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15164                    UNSPEC_FRNDINT))]
15165   "TARGET_USE_FANCY_MATH_387
15166    && flag_unsafe_math_optimizations"
15167   "frndint"
15168   [(set_attr "type" "fpspc")
15169    (set_attr "mode" "XF")])
15171 (define_expand "rint<mode>2"
15172   [(use (match_operand:MODEF 0 "register_operand"))
15173    (use (match_operand:MODEF 1 "register_operand"))]
15174   "(TARGET_USE_FANCY_MATH_387
15175     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15176         || TARGET_MIX_SSE_I387)
15177     && flag_unsafe_math_optimizations)
15178    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15179        && !flag_trapping_math)"
15181   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15182       && !flag_trapping_math)
15183     {
15184       if (TARGET_ROUND)
15185         emit_insn (gen_sse4_1_round<mode>2
15186                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15187       else if (optimize_insn_for_size_p ())
15188         FAIL;
15189       else
15190         ix86_expand_rint (operands[0], operands[1]);
15191     }
15192   else
15193     {
15194       rtx op0 = gen_reg_rtx (XFmode);
15195       rtx op1 = gen_reg_rtx (XFmode);
15197       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15198       emit_insn (gen_rintxf2 (op0, op1));
15200       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15201     }
15202   DONE;
15205 (define_expand "round<mode>2"
15206   [(match_operand:X87MODEF 0 "register_operand")
15207    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15208   "(TARGET_USE_FANCY_MATH_387
15209     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15210         || TARGET_MIX_SSE_I387)
15211     && flag_unsafe_math_optimizations)
15212    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15213        && !flag_trapping_math && !flag_rounding_math)"
15215   if (optimize_insn_for_size_p ())
15216     FAIL;
15218   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15219       && !flag_trapping_math && !flag_rounding_math)
15220     {
15221       if (TARGET_ROUND)
15222         {
15223           operands[1] = force_reg (<MODE>mode, operands[1]);
15224           ix86_expand_round_sse4 (operands[0], operands[1]);
15225         }
15226       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15227         ix86_expand_round (operands[0], operands[1]);
15228       else
15229         ix86_expand_rounddf_32 (operands[0], operands[1]);
15230     }
15231   else
15232     {
15233       operands[1] = force_reg (<MODE>mode, operands[1]);
15234       ix86_emit_i387_round (operands[0], operands[1]);
15235     }
15236   DONE;
15239 (define_insn_and_split "*fistdi2_1"
15240   [(set (match_operand:DI 0 "nonimmediate_operand")
15241         (unspec:DI [(match_operand:XF 1 "register_operand")]
15242                    UNSPEC_FIST))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && can_create_pseudo_p ()"
15245   "#"
15246   "&& 1"
15247   [(const_int 0)]
15249   if (memory_operand (operands[0], VOIDmode))
15250     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15251   else
15252     {
15253       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15254       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15255                                          operands[2]));
15256     }
15257   DONE;
15259   [(set_attr "type" "fpspc")
15260    (set_attr "mode" "DI")])
15262 (define_insn "fistdi2"
15263   [(set (match_operand:DI 0 "memory_operand" "=m")
15264         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15265                    UNSPEC_FIST))
15266    (clobber (match_scratch:XF 2 "=&1f"))]
15267   "TARGET_USE_FANCY_MATH_387"
15268   "* return output_fix_trunc (insn, operands, false);"
15269   [(set_attr "type" "fpspc")
15270    (set_attr "mode" "DI")])
15272 (define_insn "fistdi2_with_temp"
15273   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15274         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15275                    UNSPEC_FIST))
15276    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15277    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15278   "TARGET_USE_FANCY_MATH_387"
15279   "#"
15280   [(set_attr "type" "fpspc")
15281    (set_attr "mode" "DI")])
15283 (define_split
15284   [(set (match_operand:DI 0 "register_operand")
15285         (unspec:DI [(match_operand:XF 1 "register_operand")]
15286                    UNSPEC_FIST))
15287    (clobber (match_operand:DI 2 "memory_operand"))
15288    (clobber (match_scratch 3))]
15289   "reload_completed"
15290   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15291               (clobber (match_dup 3))])
15292    (set (match_dup 0) (match_dup 2))])
15294 (define_split
15295   [(set (match_operand:DI 0 "memory_operand")
15296         (unspec:DI [(match_operand:XF 1 "register_operand")]
15297                    UNSPEC_FIST))
15298    (clobber (match_operand:DI 2 "memory_operand"))
15299    (clobber (match_scratch 3))]
15300   "reload_completed"
15301   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15302               (clobber (match_dup 3))])])
15304 (define_insn_and_split "*fist<mode>2_1"
15305   [(set (match_operand:SWI24 0 "register_operand")
15306         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15307                       UNSPEC_FIST))]
15308   "TARGET_USE_FANCY_MATH_387
15309    && can_create_pseudo_p ()"
15310   "#"
15311   "&& 1"
15312   [(const_int 0)]
15314   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15315   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15316                                         operands[2]));
15317   DONE;
15319   [(set_attr "type" "fpspc")
15320    (set_attr "mode" "<MODE>")])
15322 (define_insn "fist<mode>2"
15323   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15324         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15325                       UNSPEC_FIST))]
15326   "TARGET_USE_FANCY_MATH_387"
15327   "* return output_fix_trunc (insn, operands, false);"
15328   [(set_attr "type" "fpspc")
15329    (set_attr "mode" "<MODE>")])
15331 (define_insn "fist<mode>2_with_temp"
15332   [(set (match_operand:SWI24 0 "register_operand" "=r")
15333         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15334                       UNSPEC_FIST))
15335    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15336   "TARGET_USE_FANCY_MATH_387"
15337   "#"
15338   [(set_attr "type" "fpspc")
15339    (set_attr "mode" "<MODE>")])
15341 (define_split
15342   [(set (match_operand:SWI24 0 "register_operand")
15343         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15344                       UNSPEC_FIST))
15345    (clobber (match_operand:SWI24 2 "memory_operand"))]
15346   "reload_completed"
15347   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15348    (set (match_dup 0) (match_dup 2))])
15350 (define_split
15351   [(set (match_operand:SWI24 0 "memory_operand")
15352         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15353                       UNSPEC_FIST))
15354    (clobber (match_operand:SWI24 2 "memory_operand"))]
15355   "reload_completed"
15356   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15358 (define_expand "lrintxf<mode>2"
15359   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15360      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15361                      UNSPEC_FIST))]
15362   "TARGET_USE_FANCY_MATH_387")
15364 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15365   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15366      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15367                    UNSPEC_FIX_NOTRUNC))]
15368   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15370 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15371   [(match_operand:SWI248x 0 "nonimmediate_operand")
15372    (match_operand:X87MODEF 1 "register_operand")]
15373   "(TARGET_USE_FANCY_MATH_387
15374     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15375         || TARGET_MIX_SSE_I387)
15376     && flag_unsafe_math_optimizations)
15377    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15378        && <SWI248x:MODE>mode != HImode 
15379        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15380        && !flag_trapping_math && !flag_rounding_math)"
15382   if (optimize_insn_for_size_p ())
15383     FAIL;
15385   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15386       && <SWI248x:MODE>mode != HImode
15387       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15388       && !flag_trapping_math && !flag_rounding_math)
15389     ix86_expand_lround (operands[0], operands[1]);
15390   else
15391     ix86_emit_i387_round (operands[0], operands[1]);
15392   DONE;
15395 (define_int_iterator FRNDINT_ROUNDING
15396         [UNSPEC_FRNDINT_FLOOR
15397          UNSPEC_FRNDINT_CEIL
15398          UNSPEC_FRNDINT_TRUNC])
15400 (define_int_iterator FIST_ROUNDING
15401         [UNSPEC_FIST_FLOOR
15402          UNSPEC_FIST_CEIL])
15404 ;; Base name for define_insn
15405 (define_int_attr rounding_insn
15406         [(UNSPEC_FRNDINT_FLOOR "floor")
15407          (UNSPEC_FRNDINT_CEIL "ceil")
15408          (UNSPEC_FRNDINT_TRUNC "btrunc")
15409          (UNSPEC_FIST_FLOOR "floor")
15410          (UNSPEC_FIST_CEIL "ceil")])
15412 (define_int_attr rounding
15413         [(UNSPEC_FRNDINT_FLOOR "floor")
15414          (UNSPEC_FRNDINT_CEIL "ceil")
15415          (UNSPEC_FRNDINT_TRUNC "trunc")
15416          (UNSPEC_FIST_FLOOR "floor")
15417          (UNSPEC_FIST_CEIL "ceil")])
15419 (define_int_attr ROUNDING
15420         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15421          (UNSPEC_FRNDINT_CEIL "CEIL")
15422          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15423          (UNSPEC_FIST_FLOOR "FLOOR")
15424          (UNSPEC_FIST_CEIL "CEIL")])
15426 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15427 (define_insn_and_split "frndintxf2_<rounding>"
15428   [(set (match_operand:XF 0 "register_operand")
15429         (unspec:XF [(match_operand:XF 1 "register_operand")]
15430                    FRNDINT_ROUNDING))
15431    (clobber (reg:CC FLAGS_REG))]
15432   "TARGET_USE_FANCY_MATH_387
15433    && flag_unsafe_math_optimizations
15434    && can_create_pseudo_p ()"
15435   "#"
15436   "&& 1"
15437   [(const_int 0)]
15439   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15441   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15442   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15444   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15445                                              operands[2], operands[3]));
15446   DONE;
15448   [(set_attr "type" "frndint")
15449    (set_attr "i387_cw" "<rounding>")
15450    (set_attr "mode" "XF")])
15452 (define_insn "frndintxf2_<rounding>_i387"
15453   [(set (match_operand:XF 0 "register_operand" "=f")
15454         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15455                    FRNDINT_ROUNDING))
15456    (use (match_operand:HI 2 "memory_operand" "m"))
15457    (use (match_operand:HI 3 "memory_operand" "m"))]
15458   "TARGET_USE_FANCY_MATH_387
15459    && flag_unsafe_math_optimizations"
15460   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15461   [(set_attr "type" "frndint")
15462    (set_attr "i387_cw" "<rounding>")
15463    (set_attr "mode" "XF")])
15465 (define_expand "<rounding_insn>xf2"
15466   [(parallel [(set (match_operand:XF 0 "register_operand")
15467                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15468                               FRNDINT_ROUNDING))
15469               (clobber (reg:CC FLAGS_REG))])]
15470   "TARGET_USE_FANCY_MATH_387
15471    && flag_unsafe_math_optimizations
15472    && !optimize_insn_for_size_p ()")
15474 (define_expand "<rounding_insn><mode>2"
15475   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15476                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15477                                  FRNDINT_ROUNDING))
15478               (clobber (reg:CC FLAGS_REG))])]
15479   "(TARGET_USE_FANCY_MATH_387
15480     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15481         || TARGET_MIX_SSE_I387)
15482     && flag_unsafe_math_optimizations)
15483    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15484        && !flag_trapping_math)"
15486   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15487       && !flag_trapping_math)
15488     {
15489       if (TARGET_ROUND)
15490         emit_insn (gen_sse4_1_round<mode>2
15491                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15492       else if (optimize_insn_for_size_p ())
15493         FAIL;
15494       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15495         {
15496           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15497             ix86_expand_floorceil (operands[0], operands[1], true);
15498           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15499             ix86_expand_floorceil (operands[0], operands[1], false);
15500           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15501             ix86_expand_trunc (operands[0], operands[1]);
15502           else
15503             gcc_unreachable ();
15504         }
15505       else
15506         {
15507           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15508             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15509           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15510             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15511           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15512             ix86_expand_truncdf_32 (operands[0], operands[1]);
15513           else
15514             gcc_unreachable ();
15515         }
15516     }
15517   else
15518     {
15519       rtx op0, op1;
15521       if (optimize_insn_for_size_p ())
15522         FAIL;
15524       op0 = gen_reg_rtx (XFmode);
15525       op1 = gen_reg_rtx (XFmode);
15526       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15527       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15529       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15530     }
15531   DONE;
15534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15535 (define_insn_and_split "frndintxf2_mask_pm"
15536   [(set (match_operand:XF 0 "register_operand")
15537         (unspec:XF [(match_operand:XF 1 "register_operand")]
15538                    UNSPEC_FRNDINT_MASK_PM))
15539    (clobber (reg:CC FLAGS_REG))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && flag_unsafe_math_optimizations
15542    && can_create_pseudo_p ()"
15543   "#"
15544   "&& 1"
15545   [(const_int 0)]
15547   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15549   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15550   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15552   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15553                                           operands[2], operands[3]));
15554   DONE;
15556   [(set_attr "type" "frndint")
15557    (set_attr "i387_cw" "mask_pm")
15558    (set_attr "mode" "XF")])
15560 (define_insn "frndintxf2_mask_pm_i387"
15561   [(set (match_operand:XF 0 "register_operand" "=f")
15562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15563                    UNSPEC_FRNDINT_MASK_PM))
15564    (use (match_operand:HI 2 "memory_operand" "m"))
15565    (use (match_operand:HI 3 "memory_operand" "m"))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && flag_unsafe_math_optimizations"
15568   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15569   [(set_attr "type" "frndint")
15570    (set_attr "i387_cw" "mask_pm")
15571    (set_attr "mode" "XF")])
15573 (define_expand "nearbyintxf2"
15574   [(parallel [(set (match_operand:XF 0 "register_operand")
15575                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15576                               UNSPEC_FRNDINT_MASK_PM))
15577               (clobber (reg:CC FLAGS_REG))])]
15578   "TARGET_USE_FANCY_MATH_387
15579    && flag_unsafe_math_optimizations")
15581 (define_expand "nearbyint<mode>2"
15582   [(use (match_operand:MODEF 0 "register_operand"))
15583    (use (match_operand:MODEF 1 "register_operand"))]
15584   "TARGET_USE_FANCY_MATH_387
15585    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15586        || TARGET_MIX_SSE_I387)
15587    && flag_unsafe_math_optimizations"
15589   rtx op0 = gen_reg_rtx (XFmode);
15590   rtx op1 = gen_reg_rtx (XFmode);
15592   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15593   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15595   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15596   DONE;
15599 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15600 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15601   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15602         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15603                         FIST_ROUNDING))
15604    (clobber (reg:CC FLAGS_REG))]
15605   "TARGET_USE_FANCY_MATH_387
15606    && flag_unsafe_math_optimizations
15607    && can_create_pseudo_p ()"
15608   "#"
15609   "&& 1"
15610   [(const_int 0)]
15612   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15614   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15615   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15616   if (memory_operand (operands[0], VOIDmode))
15617     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15618                                            operands[2], operands[3]));
15619   else
15620     {
15621       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15622       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15623                   (operands[0], operands[1], operands[2],
15624                    operands[3], operands[4]));
15625     }
15626   DONE;
15628   [(set_attr "type" "fistp")
15629    (set_attr "i387_cw" "<rounding>")
15630    (set_attr "mode" "<MODE>")])
15632 (define_insn "fistdi2_<rounding>"
15633   [(set (match_operand:DI 0 "memory_operand" "=m")
15634         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15635                    FIST_ROUNDING))
15636    (use (match_operand:HI 2 "memory_operand" "m"))
15637    (use (match_operand:HI 3 "memory_operand" "m"))
15638    (clobber (match_scratch:XF 4 "=&1f"))]
15639   "TARGET_USE_FANCY_MATH_387
15640    && flag_unsafe_math_optimizations"
15641   "* return output_fix_trunc (insn, operands, false);"
15642   [(set_attr "type" "fistp")
15643    (set_attr "i387_cw" "<rounding>")
15644    (set_attr "mode" "DI")])
15646 (define_insn "fistdi2_<rounding>_with_temp"
15647   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15648         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15649                    FIST_ROUNDING))
15650    (use (match_operand:HI 2 "memory_operand" "m,m"))
15651    (use (match_operand:HI 3 "memory_operand" "m,m"))
15652    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15653    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15654   "TARGET_USE_FANCY_MATH_387
15655    && flag_unsafe_math_optimizations"
15656   "#"
15657   [(set_attr "type" "fistp")
15658    (set_attr "i387_cw" "<rounding>")
15659    (set_attr "mode" "DI")])
15661 (define_split
15662   [(set (match_operand:DI 0 "register_operand")
15663         (unspec:DI [(match_operand:XF 1 "register_operand")]
15664                    FIST_ROUNDING))
15665    (use (match_operand:HI 2 "memory_operand"))
15666    (use (match_operand:HI 3 "memory_operand"))
15667    (clobber (match_operand:DI 4 "memory_operand"))
15668    (clobber (match_scratch 5))]
15669   "reload_completed"
15670   [(parallel [(set (match_dup 4)
15671                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15672               (use (match_dup 2))
15673               (use (match_dup 3))
15674               (clobber (match_dup 5))])
15675    (set (match_dup 0) (match_dup 4))])
15677 (define_split
15678   [(set (match_operand:DI 0 "memory_operand")
15679         (unspec:DI [(match_operand:XF 1 "register_operand")]
15680                    FIST_ROUNDING))
15681    (use (match_operand:HI 2 "memory_operand"))
15682    (use (match_operand:HI 3 "memory_operand"))
15683    (clobber (match_operand:DI 4 "memory_operand"))
15684    (clobber (match_scratch 5))]
15685   "reload_completed"
15686   [(parallel [(set (match_dup 0)
15687                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15688               (use (match_dup 2))
15689               (use (match_dup 3))
15690               (clobber (match_dup 5))])])
15692 (define_insn "fist<mode>2_<rounding>"
15693   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15694         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15695                       FIST_ROUNDING))
15696    (use (match_operand:HI 2 "memory_operand" "m"))
15697    (use (match_operand:HI 3 "memory_operand" "m"))]
15698   "TARGET_USE_FANCY_MATH_387
15699    && flag_unsafe_math_optimizations"
15700   "* return output_fix_trunc (insn, operands, false);"
15701   [(set_attr "type" "fistp")
15702    (set_attr "i387_cw" "<rounding>")
15703    (set_attr "mode" "<MODE>")])
15705 (define_insn "fist<mode>2_<rounding>_with_temp"
15706   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15707         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15708                       FIST_ROUNDING))
15709    (use (match_operand:HI 2 "memory_operand" "m,m"))
15710    (use (match_operand:HI 3 "memory_operand" "m,m"))
15711    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && flag_unsafe_math_optimizations"
15714   "#"
15715   [(set_attr "type" "fistp")
15716    (set_attr "i387_cw" "<rounding>")
15717    (set_attr "mode" "<MODE>")])
15719 (define_split
15720   [(set (match_operand:SWI24 0 "register_operand")
15721         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15722                       FIST_ROUNDING))
15723    (use (match_operand:HI 2 "memory_operand"))
15724    (use (match_operand:HI 3 "memory_operand"))
15725    (clobber (match_operand:SWI24 4 "memory_operand"))]
15726   "reload_completed"
15727   [(parallel [(set (match_dup 4)
15728                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15729               (use (match_dup 2))
15730               (use (match_dup 3))])
15731    (set (match_dup 0) (match_dup 4))])
15733 (define_split
15734   [(set (match_operand:SWI24 0 "memory_operand")
15735         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15736                       FIST_ROUNDING))
15737    (use (match_operand:HI 2 "memory_operand"))
15738    (use (match_operand:HI 3 "memory_operand"))
15739    (clobber (match_operand:SWI24 4 "memory_operand"))]
15740   "reload_completed"
15741   [(parallel [(set (match_dup 0)
15742                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15743               (use (match_dup 2))
15744               (use (match_dup 3))])])
15746 (define_expand "l<rounding_insn>xf<mode>2"
15747   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15748                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15749                                    FIST_ROUNDING))
15750               (clobber (reg:CC FLAGS_REG))])]
15751   "TARGET_USE_FANCY_MATH_387
15752    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations")
15755 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15756   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15757                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15758                                  FIST_ROUNDING))
15759               (clobber (reg:CC FLAGS_REG))])]
15760   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15761    && !flag_trapping_math"
15763   if (TARGET_64BIT && optimize_insn_for_size_p ())
15764     FAIL;
15766   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15767     ix86_expand_lfloorceil (operands[0], operands[1], true);
15768   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15769     ix86_expand_lfloorceil (operands[0], operands[1], false);
15770   else
15771     gcc_unreachable ();
15773   DONE;
15776 (define_insn "fxam<mode>2_i387"
15777   [(set (match_operand:HI 0 "register_operand" "=a")
15778         (unspec:HI
15779           [(match_operand:X87MODEF 1 "register_operand" "f")]
15780           UNSPEC_FXAM))]
15781   "TARGET_USE_FANCY_MATH_387"
15782   "fxam\n\tfnstsw\t%0"
15783   [(set_attr "type" "multi")
15784    (set_attr "length" "4")
15785    (set_attr "unit" "i387")
15786    (set_attr "mode" "<MODE>")])
15788 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15789   [(set (match_operand:HI 0 "register_operand")
15790         (unspec:HI
15791           [(match_operand:MODEF 1 "memory_operand")]
15792           UNSPEC_FXAM_MEM))]
15793   "TARGET_USE_FANCY_MATH_387
15794    && can_create_pseudo_p ()"
15795   "#"
15796   "&& 1"
15797   [(set (match_dup 2)(match_dup 1))
15798    (set (match_dup 0)
15799         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15801   operands[2] = gen_reg_rtx (<MODE>mode);
15803   MEM_VOLATILE_P (operands[1]) = 1;
15805   [(set_attr "type" "multi")
15806    (set_attr "unit" "i387")
15807    (set_attr "mode" "<MODE>")])
15809 (define_expand "isinfxf2"
15810   [(use (match_operand:SI 0 "register_operand"))
15811    (use (match_operand:XF 1 "register_operand"))]
15812   "TARGET_USE_FANCY_MATH_387
15813    && ix86_libc_has_function (function_c99_misc)"
15815   rtx mask = GEN_INT (0x45);
15816   rtx val = GEN_INT (0x05);
15818   rtx cond;
15820   rtx scratch = gen_reg_rtx (HImode);
15821   rtx res = gen_reg_rtx (QImode);
15823   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15825   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15826   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15827   cond = gen_rtx_fmt_ee (EQ, QImode,
15828                          gen_rtx_REG (CCmode, FLAGS_REG),
15829                          const0_rtx);
15830   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15831   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15832   DONE;
15835 (define_expand "isinf<mode>2"
15836   [(use (match_operand:SI 0 "register_operand"))
15837    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15838   "TARGET_USE_FANCY_MATH_387
15839    && ix86_libc_has_function (function_c99_misc)
15840    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15842   rtx mask = GEN_INT (0x45);
15843   rtx val = GEN_INT (0x05);
15845   rtx cond;
15847   rtx scratch = gen_reg_rtx (HImode);
15848   rtx res = gen_reg_rtx (QImode);
15850   /* Remove excess precision by forcing value through memory. */
15851   if (memory_operand (operands[1], VOIDmode))
15852     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15853   else
15854     {
15855       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15857       emit_move_insn (temp, operands[1]);
15858       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15859     }
15861   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15862   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15863   cond = gen_rtx_fmt_ee (EQ, QImode,
15864                          gen_rtx_REG (CCmode, FLAGS_REG),
15865                          const0_rtx);
15866   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15867   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15868   DONE;
15871 (define_expand "signbitxf2"
15872   [(use (match_operand:SI 0 "register_operand"))
15873    (use (match_operand:XF 1 "register_operand"))]
15874   "TARGET_USE_FANCY_MATH_387"
15876   rtx scratch = gen_reg_rtx (HImode);
15878   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15879   emit_insn (gen_andsi3 (operands[0],
15880              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15881   DONE;
15884 (define_insn "movmsk_df"
15885   [(set (match_operand:SI 0 "register_operand" "=r")
15886         (unspec:SI
15887           [(match_operand:DF 1 "register_operand" "x")]
15888           UNSPEC_MOVMSK))]
15889   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15890   "%vmovmskpd\t{%1, %0|%0, %1}"
15891   [(set_attr "type" "ssemov")
15892    (set_attr "prefix" "maybe_vex")
15893    (set_attr "mode" "DF")])
15895 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15896 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15897 (define_expand "signbitdf2"
15898   [(use (match_operand:SI 0 "register_operand"))
15899    (use (match_operand:DF 1 "register_operand"))]
15900   "TARGET_USE_FANCY_MATH_387
15901    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15903   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15904     {
15905       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15906       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15907     }
15908   else
15909     {
15910       rtx scratch = gen_reg_rtx (HImode);
15912       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15913       emit_insn (gen_andsi3 (operands[0],
15914                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15915     }
15916   DONE;
15919 (define_expand "signbitsf2"
15920   [(use (match_operand:SI 0 "register_operand"))
15921    (use (match_operand:SF 1 "register_operand"))]
15922   "TARGET_USE_FANCY_MATH_387
15923    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15925   rtx scratch = gen_reg_rtx (HImode);
15927   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15928   emit_insn (gen_andsi3 (operands[0],
15929              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15930   DONE;
15933 ;; Block operation instructions
15935 (define_insn "cld"
15936   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15937   ""
15938   "cld"
15939   [(set_attr "length" "1")
15940    (set_attr "length_immediate" "0")
15941    (set_attr "modrm" "0")])
15943 (define_expand "movmem<mode>"
15944   [(use (match_operand:BLK 0 "memory_operand"))
15945    (use (match_operand:BLK 1 "memory_operand"))
15946    (use (match_operand:SWI48 2 "nonmemory_operand"))
15947    (use (match_operand:SWI48 3 "const_int_operand"))
15948    (use (match_operand:SI 4 "const_int_operand"))
15949    (use (match_operand:SI 5 "const_int_operand"))
15950    (use (match_operand:SI 6 ""))
15951    (use (match_operand:SI 7 ""))
15952    (use (match_operand:SI 8 ""))]
15953   ""
15955  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15956                                 operands[2], NULL, operands[3],
15957                                 operands[4], operands[5],
15958                                 operands[6], operands[7],
15959                                 operands[8], false))
15960    DONE;
15961  else
15962    FAIL;
15965 ;; Most CPUs don't like single string operations
15966 ;; Handle this case here to simplify previous expander.
15968 (define_expand "strmov"
15969   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15970    (set (match_operand 1 "memory_operand") (match_dup 4))
15971    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15972               (clobber (reg:CC FLAGS_REG))])
15973    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15974               (clobber (reg:CC FLAGS_REG))])]
15975   ""
15977   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15979   /* If .md ever supports :P for Pmode, these can be directly
15980      in the pattern above.  */
15981   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15982   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15984   /* Can't use this if the user has appropriated esi or edi.  */
15985   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15986       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15987     {
15988       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15989                                       operands[2], operands[3],
15990                                       operands[5], operands[6]));
15991       DONE;
15992     }
15994   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15997 (define_expand "strmov_singleop"
15998   [(parallel [(set (match_operand 1 "memory_operand")
15999                    (match_operand 3 "memory_operand"))
16000               (set (match_operand 0 "register_operand")
16001                    (match_operand 4))
16002               (set (match_operand 2 "register_operand")
16003                    (match_operand 5))])]
16004   ""
16005   "ix86_current_function_needs_cld = 1;")
16007 (define_insn "*strmovdi_rex_1"
16008   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16009         (mem:DI (match_operand:P 3 "register_operand" "1")))
16010    (set (match_operand:P 0 "register_operand" "=D")
16011         (plus:P (match_dup 2)
16012                 (const_int 8)))
16013    (set (match_operand:P 1 "register_operand" "=S")
16014         (plus:P (match_dup 3)
16015                 (const_int 8)))]
16016   "TARGET_64BIT
16017    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16018   "%^movsq"
16019   [(set_attr "type" "str")
16020    (set_attr "memory" "both")
16021    (set_attr "mode" "DI")])
16023 (define_insn "*strmovsi_1"
16024   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16025         (mem:SI (match_operand:P 3 "register_operand" "1")))
16026    (set (match_operand:P 0 "register_operand" "=D")
16027         (plus:P (match_dup 2)
16028                 (const_int 4)))
16029    (set (match_operand:P 1 "register_operand" "=S")
16030         (plus:P (match_dup 3)
16031                 (const_int 4)))]
16032   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16033   "%^movs{l|d}"
16034   [(set_attr "type" "str")
16035    (set_attr "memory" "both")
16036    (set_attr "mode" "SI")])
16038 (define_insn "*strmovhi_1"
16039   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16040         (mem:HI (match_operand:P 3 "register_operand" "1")))
16041    (set (match_operand:P 0 "register_operand" "=D")
16042         (plus:P (match_dup 2)
16043                 (const_int 2)))
16044    (set (match_operand:P 1 "register_operand" "=S")
16045         (plus:P (match_dup 3)
16046                 (const_int 2)))]
16047   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16048   "%^movsw"
16049   [(set_attr "type" "str")
16050    (set_attr "memory" "both")
16051    (set_attr "mode" "HI")])
16053 (define_insn "*strmovqi_1"
16054   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16055         (mem:QI (match_operand:P 3 "register_operand" "1")))
16056    (set (match_operand:P 0 "register_operand" "=D")
16057         (plus:P (match_dup 2)
16058                 (const_int 1)))
16059    (set (match_operand:P 1 "register_operand" "=S")
16060         (plus:P (match_dup 3)
16061                 (const_int 1)))]
16062   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16063   "%^movsb"
16064   [(set_attr "type" "str")
16065    (set_attr "memory" "both")
16066    (set (attr "prefix_rex")
16067         (if_then_else
16068           (match_test "<P:MODE>mode == DImode")
16069           (const_string "0")
16070           (const_string "*")))
16071    (set_attr "mode" "QI")])
16073 (define_expand "rep_mov"
16074   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16075               (set (match_operand 0 "register_operand")
16076                    (match_operand 5))
16077               (set (match_operand 2 "register_operand")
16078                    (match_operand 6))
16079               (set (match_operand 1 "memory_operand")
16080                    (match_operand 3 "memory_operand"))
16081               (use (match_dup 4))])]
16082   ""
16083   "ix86_current_function_needs_cld = 1;")
16085 (define_insn "*rep_movdi_rex64"
16086   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16087    (set (match_operand:P 0 "register_operand" "=D")
16088         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16089                           (const_int 3))
16090                 (match_operand:P 3 "register_operand" "0")))
16091    (set (match_operand:P 1 "register_operand" "=S")
16092         (plus:P (ashift:P (match_dup 5) (const_int 3))
16093                 (match_operand:P 4 "register_operand" "1")))
16094    (set (mem:BLK (match_dup 3))
16095         (mem:BLK (match_dup 4)))
16096    (use (match_dup 5))]
16097   "TARGET_64BIT
16098    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16099   "%^rep{%;} movsq"
16100   [(set_attr "type" "str")
16101    (set_attr "prefix_rep" "1")
16102    (set_attr "memory" "both")
16103    (set_attr "mode" "DI")])
16105 (define_insn "*rep_movsi"
16106   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16107    (set (match_operand:P 0 "register_operand" "=D")
16108         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16109                           (const_int 2))
16110                  (match_operand:P 3 "register_operand" "0")))
16111    (set (match_operand:P 1 "register_operand" "=S")
16112         (plus:P (ashift:P (match_dup 5) (const_int 2))
16113                 (match_operand:P 4 "register_operand" "1")))
16114    (set (mem:BLK (match_dup 3))
16115         (mem:BLK (match_dup 4)))
16116    (use (match_dup 5))]
16117   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16118   "%^rep{%;} movs{l|d}"
16119   [(set_attr "type" "str")
16120    (set_attr "prefix_rep" "1")
16121    (set_attr "memory" "both")
16122    (set_attr "mode" "SI")])
16124 (define_insn "*rep_movqi"
16125   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16126    (set (match_operand:P 0 "register_operand" "=D")
16127         (plus:P (match_operand:P 3 "register_operand" "0")
16128                 (match_operand:P 5 "register_operand" "2")))
16129    (set (match_operand:P 1 "register_operand" "=S")
16130         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
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{%;} movsb"
16136   [(set_attr "type" "str")
16137    (set_attr "prefix_rep" "1")
16138    (set_attr "memory" "both")
16139    (set_attr "mode" "QI")])
16141 (define_expand "setmem<mode>"
16142    [(use (match_operand:BLK 0 "memory_operand"))
16143     (use (match_operand:SWI48 1 "nonmemory_operand"))
16144     (use (match_operand:QI 2 "nonmemory_operand"))
16145     (use (match_operand 3 "const_int_operand"))
16146     (use (match_operand:SI 4 "const_int_operand"))
16147     (use (match_operand:SI 5 "const_int_operand"))
16148     (use (match_operand:SI 6 ""))
16149     (use (match_operand:SI 7 ""))
16150     (use (match_operand:SI 8 ""))]
16151   ""
16153  if (ix86_expand_set_or_movmem (operands[0], NULL,
16154                                 operands[1], operands[2],
16155                                 operands[3], operands[4],
16156                                 operands[5], operands[6],
16157                                 operands[7], operands[8], true))
16158    DONE;
16159  else
16160    FAIL;
16163 ;; Most CPUs don't like single string operations
16164 ;; Handle this case here to simplify previous expander.
16166 (define_expand "strset"
16167   [(set (match_operand 1 "memory_operand")
16168         (match_operand 2 "register_operand"))
16169    (parallel [(set (match_operand 0 "register_operand")
16170                    (match_dup 3))
16171               (clobber (reg:CC FLAGS_REG))])]
16172   ""
16174   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16175     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16177   /* If .md ever supports :P for Pmode, this can be directly
16178      in the pattern above.  */
16179   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16180                               GEN_INT (GET_MODE_SIZE (GET_MODE
16181                                                       (operands[2]))));
16182   /* Can't use this if the user has appropriated eax or edi.  */
16183   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16184       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16185     {
16186       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16187                                       operands[3]));
16188       DONE;
16189     }
16192 (define_expand "strset_singleop"
16193   [(parallel [(set (match_operand 1 "memory_operand")
16194                    (match_operand 2 "register_operand"))
16195               (set (match_operand 0 "register_operand")
16196                    (match_operand 3))
16197               (unspec [(const_int 0)] UNSPEC_STOS)])]
16198   ""
16199   "ix86_current_function_needs_cld = 1;")
16201 (define_insn "*strsetdi_rex_1"
16202   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16203         (match_operand:DI 2 "register_operand" "a"))
16204    (set (match_operand:P 0 "register_operand" "=D")
16205         (plus:P (match_dup 1)
16206                 (const_int 8)))
16207    (unspec [(const_int 0)] UNSPEC_STOS)]
16208   "TARGET_64BIT
16209    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16210   "%^stosq"
16211   [(set_attr "type" "str")
16212    (set_attr "memory" "store")
16213    (set_attr "mode" "DI")])
16215 (define_insn "*strsetsi_1"
16216   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16217         (match_operand:SI 2 "register_operand" "a"))
16218    (set (match_operand:P 0 "register_operand" "=D")
16219         (plus:P (match_dup 1)
16220                 (const_int 4)))
16221    (unspec [(const_int 0)] UNSPEC_STOS)]
16222   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16223   "%^stos{l|d}"
16224   [(set_attr "type" "str")
16225    (set_attr "memory" "store")
16226    (set_attr "mode" "SI")])
16228 (define_insn "*strsethi_1"
16229   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16230         (match_operand:HI 2 "register_operand" "a"))
16231    (set (match_operand:P 0 "register_operand" "=D")
16232         (plus:P (match_dup 1)
16233                 (const_int 2)))
16234    (unspec [(const_int 0)] UNSPEC_STOS)]
16235   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16236   "%^stosw"
16237   [(set_attr "type" "str")
16238    (set_attr "memory" "store")
16239    (set_attr "mode" "HI")])
16241 (define_insn "*strsetqi_1"
16242   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16243         (match_operand:QI 2 "register_operand" "a"))
16244    (set (match_operand:P 0 "register_operand" "=D")
16245         (plus:P (match_dup 1)
16246                 (const_int 1)))
16247    (unspec [(const_int 0)] UNSPEC_STOS)]
16248   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16249   "%^stosb"
16250   [(set_attr "type" "str")
16251    (set_attr "memory" "store")
16252    (set (attr "prefix_rex")
16253         (if_then_else
16254           (match_test "<P:MODE>mode == DImode")
16255           (const_string "0")
16256           (const_string "*")))
16257    (set_attr "mode" "QI")])
16259 (define_expand "rep_stos"
16260   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16261               (set (match_operand 0 "register_operand")
16262                    (match_operand 4))
16263               (set (match_operand 2 "memory_operand") (const_int 0))
16264               (use (match_operand 3 "register_operand"))
16265               (use (match_dup 1))])]
16266   ""
16267   "ix86_current_function_needs_cld = 1;")
16269 (define_insn "*rep_stosdi_rex64"
16270   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16271    (set (match_operand:P 0 "register_operand" "=D")
16272         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16273                           (const_int 3))
16274                  (match_operand:P 3 "register_operand" "0")))
16275    (set (mem:BLK (match_dup 3))
16276         (const_int 0))
16277    (use (match_operand:DI 2 "register_operand" "a"))
16278    (use (match_dup 4))]
16279   "TARGET_64BIT
16280    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16281   "%^rep{%;} stosq"
16282   [(set_attr "type" "str")
16283    (set_attr "prefix_rep" "1")
16284    (set_attr "memory" "store")
16285    (set_attr "mode" "DI")])
16287 (define_insn "*rep_stossi"
16288   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16289    (set (match_operand:P 0 "register_operand" "=D")
16290         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16291                           (const_int 2))
16292                  (match_operand:P 3 "register_operand" "0")))
16293    (set (mem:BLK (match_dup 3))
16294         (const_int 0))
16295    (use (match_operand:SI 2 "register_operand" "a"))
16296    (use (match_dup 4))]
16297   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16298   "%^rep{%;} stos{l|d}"
16299   [(set_attr "type" "str")
16300    (set_attr "prefix_rep" "1")
16301    (set_attr "memory" "store")
16302    (set_attr "mode" "SI")])
16304 (define_insn "*rep_stosqi"
16305   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16306    (set (match_operand:P 0 "register_operand" "=D")
16307         (plus:P (match_operand:P 3 "register_operand" "0")
16308                 (match_operand:P 4 "register_operand" "1")))
16309    (set (mem:BLK (match_dup 3))
16310         (const_int 0))
16311    (use (match_operand:QI 2 "register_operand" "a"))
16312    (use (match_dup 4))]
16313   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16314   "%^rep{%;} stosb"
16315   [(set_attr "type" "str")
16316    (set_attr "prefix_rep" "1")
16317    (set_attr "memory" "store")
16318    (set (attr "prefix_rex")
16319         (if_then_else
16320           (match_test "<P:MODE>mode == DImode")
16321           (const_string "0")
16322           (const_string "*")))
16323    (set_attr "mode" "QI")])
16325 (define_expand "cmpstrnsi"
16326   [(set (match_operand:SI 0 "register_operand")
16327         (compare:SI (match_operand:BLK 1 "general_operand")
16328                     (match_operand:BLK 2 "general_operand")))
16329    (use (match_operand 3 "general_operand"))
16330    (use (match_operand 4 "immediate_operand"))]
16331   ""
16333   rtx addr1, addr2, out, outlow, count, countreg, align;
16335   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16336     FAIL;
16338   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16339   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16340     FAIL;
16342   out = operands[0];
16343   if (!REG_P (out))
16344     out = gen_reg_rtx (SImode);
16346   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16347   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16348   if (addr1 != XEXP (operands[1], 0))
16349     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16350   if (addr2 != XEXP (operands[2], 0))
16351     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16353   count = operands[3];
16354   countreg = ix86_zero_extend_to_Pmode (count);
16356   /* %%% Iff we are testing strict equality, we can use known alignment
16357      to good advantage.  This may be possible with combine, particularly
16358      once cc0 is dead.  */
16359   align = operands[4];
16361   if (CONST_INT_P (count))
16362     {
16363       if (INTVAL (count) == 0)
16364         {
16365           emit_move_insn (operands[0], const0_rtx);
16366           DONE;
16367         }
16368       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16369                                      operands[1], operands[2]));
16370     }
16371   else
16372     {
16373       rtx (*gen_cmp) (rtx, rtx);
16375       gen_cmp = (TARGET_64BIT
16376                  ? gen_cmpdi_1 : gen_cmpsi_1);
16378       emit_insn (gen_cmp (countreg, countreg));
16379       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16380                                   operands[1], operands[2]));
16381     }
16383   outlow = gen_lowpart (QImode, out);
16384   emit_insn (gen_cmpintqi (outlow));
16385   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16387   if (operands[0] != out)
16388     emit_move_insn (operands[0], out);
16390   DONE;
16393 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16395 (define_expand "cmpintqi"
16396   [(set (match_dup 1)
16397         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16398    (set (match_dup 2)
16399         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16400    (parallel [(set (match_operand:QI 0 "register_operand")
16401                    (minus:QI (match_dup 1)
16402                              (match_dup 2)))
16403               (clobber (reg:CC FLAGS_REG))])]
16404   ""
16406   operands[1] = gen_reg_rtx (QImode);
16407   operands[2] = gen_reg_rtx (QImode);
16410 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16411 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16413 (define_expand "cmpstrnqi_nz_1"
16414   [(parallel [(set (reg:CC FLAGS_REG)
16415                    (compare:CC (match_operand 4 "memory_operand")
16416                                (match_operand 5 "memory_operand")))
16417               (use (match_operand 2 "register_operand"))
16418               (use (match_operand:SI 3 "immediate_operand"))
16419               (clobber (match_operand 0 "register_operand"))
16420               (clobber (match_operand 1 "register_operand"))
16421               (clobber (match_dup 2))])]
16422   ""
16423   "ix86_current_function_needs_cld = 1;")
16425 (define_insn "*cmpstrnqi_nz_1"
16426   [(set (reg:CC FLAGS_REG)
16427         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16428                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16429    (use (match_operand:P 6 "register_operand" "2"))
16430    (use (match_operand:SI 3 "immediate_operand" "i"))
16431    (clobber (match_operand:P 0 "register_operand" "=S"))
16432    (clobber (match_operand:P 1 "register_operand" "=D"))
16433    (clobber (match_operand:P 2 "register_operand" "=c"))]
16434   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16435   "%^repz{%;} cmpsb"
16436   [(set_attr "type" "str")
16437    (set_attr "mode" "QI")
16438    (set (attr "prefix_rex")
16439         (if_then_else
16440           (match_test "<P:MODE>mode == DImode")
16441           (const_string "0")
16442           (const_string "*")))
16443    (set_attr "prefix_rep" "1")])
16445 ;; The same, but the count is not known to not be zero.
16447 (define_expand "cmpstrnqi_1"
16448   [(parallel [(set (reg:CC FLAGS_REG)
16449                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16450                                      (const_int 0))
16451                   (compare:CC (match_operand 4 "memory_operand")
16452                               (match_operand 5 "memory_operand"))
16453                   (const_int 0)))
16454               (use (match_operand:SI 3 "immediate_operand"))
16455               (use (reg:CC FLAGS_REG))
16456               (clobber (match_operand 0 "register_operand"))
16457               (clobber (match_operand 1 "register_operand"))
16458               (clobber (match_dup 2))])]
16459   ""
16460   "ix86_current_function_needs_cld = 1;")
16462 (define_insn "*cmpstrnqi_1"
16463   [(set (reg:CC FLAGS_REG)
16464         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16465                              (const_int 0))
16466           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16467                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16468           (const_int 0)))
16469    (use (match_operand:SI 3 "immediate_operand" "i"))
16470    (use (reg:CC FLAGS_REG))
16471    (clobber (match_operand:P 0 "register_operand" "=S"))
16472    (clobber (match_operand:P 1 "register_operand" "=D"))
16473    (clobber (match_operand:P 2 "register_operand" "=c"))]
16474   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16475   "%^repz{%;} cmpsb"
16476   [(set_attr "type" "str")
16477    (set_attr "mode" "QI")
16478    (set (attr "prefix_rex")
16479         (if_then_else
16480           (match_test "<P:MODE>mode == DImode")
16481           (const_string "0")
16482           (const_string "*")))
16483    (set_attr "prefix_rep" "1")])
16485 (define_expand "strlen<mode>"
16486   [(set (match_operand:P 0 "register_operand")
16487         (unspec:P [(match_operand:BLK 1 "general_operand")
16488                    (match_operand:QI 2 "immediate_operand")
16489                    (match_operand 3 "immediate_operand")]
16490                   UNSPEC_SCAS))]
16491   ""
16493  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16494    DONE;
16495  else
16496    FAIL;
16499 (define_expand "strlenqi_1"
16500   [(parallel [(set (match_operand 0 "register_operand")
16501                    (match_operand 2))
16502               (clobber (match_operand 1 "register_operand"))
16503               (clobber (reg:CC FLAGS_REG))])]
16504   ""
16505   "ix86_current_function_needs_cld = 1;")
16507 (define_insn "*strlenqi_1"
16508   [(set (match_operand:P 0 "register_operand" "=&c")
16509         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16510                    (match_operand:QI 2 "register_operand" "a")
16511                    (match_operand:P 3 "immediate_operand" "i")
16512                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16513    (clobber (match_operand:P 1 "register_operand" "=D"))
16514    (clobber (reg:CC FLAGS_REG))]
16515   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16516   "%^repnz{%;} scasb"
16517   [(set_attr "type" "str")
16518    (set_attr "mode" "QI")
16519    (set (attr "prefix_rex")
16520         (if_then_else
16521           (match_test "<P:MODE>mode == DImode")
16522           (const_string "0")
16523           (const_string "*")))
16524    (set_attr "prefix_rep" "1")])
16526 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16527 ;; handled in combine, but it is not currently up to the task.
16528 ;; When used for their truth value, the cmpstrn* expanders generate
16529 ;; code like this:
16531 ;;   repz cmpsb
16532 ;;   seta       %al
16533 ;;   setb       %dl
16534 ;;   cmpb       %al, %dl
16535 ;;   jcc        label
16537 ;; The intermediate three instructions are unnecessary.
16539 ;; This one handles cmpstrn*_nz_1...
16540 (define_peephole2
16541   [(parallel[
16542      (set (reg:CC FLAGS_REG)
16543           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16544                       (mem:BLK (match_operand 5 "register_operand"))))
16545      (use (match_operand 6 "register_operand"))
16546      (use (match_operand:SI 3 "immediate_operand"))
16547      (clobber (match_operand 0 "register_operand"))
16548      (clobber (match_operand 1 "register_operand"))
16549      (clobber (match_operand 2 "register_operand"))])
16550    (set (match_operand:QI 7 "register_operand")
16551         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16552    (set (match_operand:QI 8 "register_operand")
16553         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16554    (set (reg FLAGS_REG)
16555         (compare (match_dup 7) (match_dup 8)))
16556   ]
16557   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16558   [(parallel[
16559      (set (reg:CC FLAGS_REG)
16560           (compare:CC (mem:BLK (match_dup 4))
16561                       (mem:BLK (match_dup 5))))
16562      (use (match_dup 6))
16563      (use (match_dup 3))
16564      (clobber (match_dup 0))
16565      (clobber (match_dup 1))
16566      (clobber (match_dup 2))])])
16568 ;; ...and this one handles cmpstrn*_1.
16569 (define_peephole2
16570   [(parallel[
16571      (set (reg:CC FLAGS_REG)
16572           (if_then_else:CC (ne (match_operand 6 "register_operand")
16573                                (const_int 0))
16574             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16575                         (mem:BLK (match_operand 5 "register_operand")))
16576             (const_int 0)))
16577      (use (match_operand:SI 3 "immediate_operand"))
16578      (use (reg:CC FLAGS_REG))
16579      (clobber (match_operand 0 "register_operand"))
16580      (clobber (match_operand 1 "register_operand"))
16581      (clobber (match_operand 2 "register_operand"))])
16582    (set (match_operand:QI 7 "register_operand")
16583         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16584    (set (match_operand:QI 8 "register_operand")
16585         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16586    (set (reg FLAGS_REG)
16587         (compare (match_dup 7) (match_dup 8)))
16588   ]
16589   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16590   [(parallel[
16591      (set (reg:CC FLAGS_REG)
16592           (if_then_else:CC (ne (match_dup 6)
16593                                (const_int 0))
16594             (compare:CC (mem:BLK (match_dup 4))
16595                         (mem:BLK (match_dup 5)))
16596             (const_int 0)))
16597      (use (match_dup 3))
16598      (use (reg:CC FLAGS_REG))
16599      (clobber (match_dup 0))
16600      (clobber (match_dup 1))
16601      (clobber (match_dup 2))])])
16603 ;; Conditional move instructions.
16605 (define_expand "mov<mode>cc"
16606   [(set (match_operand:SWIM 0 "register_operand")
16607         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16608                            (match_operand:SWIM 2 "<general_operand>")
16609                            (match_operand:SWIM 3 "<general_operand>")))]
16610   ""
16611   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16613 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16614 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16615 ;; So just document what we're doing explicitly.
16617 (define_expand "x86_mov<mode>cc_0_m1"
16618   [(parallel
16619     [(set (match_operand:SWI48 0 "register_operand")
16620           (if_then_else:SWI48
16621             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16622              [(match_operand 1 "flags_reg_operand")
16623               (const_int 0)])
16624             (const_int -1)
16625             (const_int 0)))
16626      (clobber (reg:CC FLAGS_REG))])])
16628 (define_insn "*x86_mov<mode>cc_0_m1"
16629   [(set (match_operand:SWI48 0 "register_operand" "=r")
16630         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16631                              [(reg FLAGS_REG) (const_int 0)])
16632           (const_int -1)
16633           (const_int 0)))
16634    (clobber (reg:CC FLAGS_REG))]
16635   ""
16636   "sbb{<imodesuffix>}\t%0, %0"
16637   ; Since we don't have the proper number of operands for an alu insn,
16638   ; fill in all the blanks.
16639   [(set_attr "type" "alu")
16640    (set_attr "use_carry" "1")
16641    (set_attr "pent_pair" "pu")
16642    (set_attr "memory" "none")
16643    (set_attr "imm_disp" "false")
16644    (set_attr "mode" "<MODE>")
16645    (set_attr "length_immediate" "0")])
16647 (define_insn "*x86_mov<mode>cc_0_m1_se"
16648   [(set (match_operand:SWI48 0 "register_operand" "=r")
16649         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16650                              [(reg FLAGS_REG) (const_int 0)])
16651                             (const_int 1)
16652                             (const_int 0)))
16653    (clobber (reg:CC FLAGS_REG))]
16654   ""
16655   "sbb{<imodesuffix>}\t%0, %0"
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_neg"
16665   [(set (match_operand:SWI48 0 "register_operand" "=r")
16666         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16667                     [(reg FLAGS_REG) (const_int 0)])))
16668    (clobber (reg:CC FLAGS_REG))]
16669   ""
16670   "sbb{<imodesuffix>}\t%0, %0"
16671   [(set_attr "type" "alu")
16672    (set_attr "use_carry" "1")
16673    (set_attr "pent_pair" "pu")
16674    (set_attr "memory" "none")
16675    (set_attr "imm_disp" "false")
16676    (set_attr "mode" "<MODE>")
16677    (set_attr "length_immediate" "0")])
16679 (define_insn "*mov<mode>cc_noc"
16680   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16681         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16682                                [(reg FLAGS_REG) (const_int 0)])
16683           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16684           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16685   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16686   "@
16687    cmov%O2%C1\t{%2, %0|%0, %2}
16688    cmov%O2%c1\t{%3, %0|%0, %3}"
16689   [(set_attr "type" "icmov")
16690    (set_attr "mode" "<MODE>")])
16692 ;; Don't do conditional moves with memory inputs.  This splitter helps
16693 ;; register starved x86_32 by forcing inputs into registers before reload.
16694 (define_split
16695   [(set (match_operand:SWI248 0 "register_operand")
16696         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16697                                [(reg FLAGS_REG) (const_int 0)])
16698           (match_operand:SWI248 2 "nonimmediate_operand")
16699           (match_operand:SWI248 3 "nonimmediate_operand")))]
16700   "!TARGET_64BIT && TARGET_CMOVE
16701    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16702    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16703    && can_create_pseudo_p ()
16704    && optimize_insn_for_speed_p ()"
16705   [(set (match_dup 0)
16706         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16708   if (MEM_P (operands[2]))
16709     operands[2] = force_reg (<MODE>mode, operands[2]);
16710   if (MEM_P (operands[3]))
16711     operands[3] = force_reg (<MODE>mode, operands[3]);
16714 (define_insn "*movqicc_noc"
16715   [(set (match_operand:QI 0 "register_operand" "=r,r")
16716         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16717                            [(reg FLAGS_REG) (const_int 0)])
16718                       (match_operand:QI 2 "register_operand" "r,0")
16719                       (match_operand:QI 3 "register_operand" "0,r")))]
16720   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16721   "#"
16722   [(set_attr "type" "icmov")
16723    (set_attr "mode" "QI")])
16725 (define_split
16726   [(set (match_operand:SWI12 0 "register_operand")
16727         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16728                               [(reg FLAGS_REG) (const_int 0)])
16729                       (match_operand:SWI12 2 "register_operand")
16730                       (match_operand:SWI12 3 "register_operand")))]
16731   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16732    && reload_completed"
16733   [(set (match_dup 0)
16734         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16736   operands[0] = gen_lowpart (SImode, operands[0]);
16737   operands[2] = gen_lowpart (SImode, operands[2]);
16738   operands[3] = gen_lowpart (SImode, operands[3]);
16741 ;; Don't do conditional moves with memory inputs
16742 (define_peephole2
16743   [(match_scratch:SWI248 2 "r")
16744    (set (match_operand:SWI248 0 "register_operand")
16745         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16746                                [(reg FLAGS_REG) (const_int 0)])
16747           (match_dup 0)
16748           (match_operand:SWI248 3 "memory_operand")))]
16749   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16750    && optimize_insn_for_speed_p ()"
16751   [(set (match_dup 2) (match_dup 3))
16752    (set (match_dup 0)
16753         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16755 (define_peephole2
16756   [(match_scratch:SWI248 2 "r")
16757    (set (match_operand:SWI248 0 "register_operand")
16758         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16759                                [(reg FLAGS_REG) (const_int 0)])
16760           (match_operand:SWI248 3 "memory_operand")
16761           (match_dup 0)))]
16762   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16763    && optimize_insn_for_speed_p ()"
16764   [(set (match_dup 2) (match_dup 3))
16765    (set (match_dup 0)
16766         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16768 (define_expand "mov<mode>cc"
16769   [(set (match_operand:X87MODEF 0 "register_operand")
16770         (if_then_else:X87MODEF
16771           (match_operand 1 "comparison_operator")
16772           (match_operand:X87MODEF 2 "register_operand")
16773           (match_operand:X87MODEF 3 "register_operand")))]
16774   "(TARGET_80387 && TARGET_CMOVE)
16775    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16776   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16778 (define_insn "*movxfcc_1"
16779   [(set (match_operand:XF 0 "register_operand" "=f,f")
16780         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16781                                 [(reg FLAGS_REG) (const_int 0)])
16782                       (match_operand:XF 2 "register_operand" "f,0")
16783                       (match_operand:XF 3 "register_operand" "0,f")))]
16784   "TARGET_80387 && TARGET_CMOVE"
16785   "@
16786    fcmov%F1\t{%2, %0|%0, %2}
16787    fcmov%f1\t{%3, %0|%0, %3}"
16788   [(set_attr "type" "fcmov")
16789    (set_attr "mode" "XF")])
16791 (define_insn "*movdfcc_1"
16792   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16793         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16794                                 [(reg FLAGS_REG) (const_int 0)])
16795                       (match_operand:DF 2 "nonimmediate_operand"
16796                                                "f ,0,rm,0 ,rm,0")
16797                       (match_operand:DF 3 "nonimmediate_operand"
16798                                                "0 ,f,0 ,rm,0, rm")))]
16799   "TARGET_80387 && TARGET_CMOVE
16800    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16801   "@
16802    fcmov%F1\t{%2, %0|%0, %2}
16803    fcmov%f1\t{%3, %0|%0, %3}
16804    #
16805    #
16806    cmov%O2%C1\t{%2, %0|%0, %2}
16807    cmov%O2%c1\t{%3, %0|%0, %3}"
16808   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16809    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16810    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16812 (define_split
16813   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16814         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16815                                 [(reg FLAGS_REG) (const_int 0)])
16816                       (match_operand:DF 2 "nonimmediate_operand")
16817                       (match_operand:DF 3 "nonimmediate_operand")))]
16818   "!TARGET_64BIT && reload_completed"
16819   [(set (match_dup 2)
16820         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16821    (set (match_dup 3)
16822         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16824   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16825   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16828 (define_insn "*movsfcc_1_387"
16829   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16830         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16831                                 [(reg FLAGS_REG) (const_int 0)])
16832                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16833                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16834   "TARGET_80387 && TARGET_CMOVE
16835    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16836   "@
16837    fcmov%F1\t{%2, %0|%0, %2}
16838    fcmov%f1\t{%3, %0|%0, %3}
16839    cmov%O2%C1\t{%2, %0|%0, %2}
16840    cmov%O2%c1\t{%3, %0|%0, %3}"
16841   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16842    (set_attr "mode" "SF,SF,SI,SI")])
16844 ;; Don't do conditional moves with memory inputs.  This splitter helps
16845 ;; register starved x86_32 by forcing inputs into registers before reload.
16846 (define_split
16847   [(set (match_operand:MODEF 0 "register_operand")
16848         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16849                               [(reg FLAGS_REG) (const_int 0)])
16850           (match_operand:MODEF 2 "nonimmediate_operand")
16851           (match_operand:MODEF 3 "nonimmediate_operand")))]
16852   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16853    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16854    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16855    && can_create_pseudo_p ()
16856    && optimize_insn_for_speed_p ()"
16857   [(set (match_dup 0)
16858         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16860   if (MEM_P (operands[2]))
16861     operands[2] = force_reg (<MODE>mode, operands[2]);
16862   if (MEM_P (operands[3]))
16863     operands[3] = force_reg (<MODE>mode, operands[3]);
16866 ;; Don't do conditional moves with memory inputs
16867 (define_peephole2
16868   [(match_scratch:MODEF 2 "r")
16869    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16870         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16871                               [(reg FLAGS_REG) (const_int 0)])
16872           (match_dup 0)
16873           (match_operand:MODEF 3 "memory_operand")))]
16874   "(<MODE>mode != DFmode || TARGET_64BIT)
16875    && TARGET_80387 && TARGET_CMOVE
16876    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16877    && optimize_insn_for_speed_p ()"
16878   [(set (match_dup 2) (match_dup 3))
16879    (set (match_dup 0)
16880         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16882 (define_peephole2
16883   [(match_scratch:MODEF 2 "r")
16884    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16885         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16886                               [(reg FLAGS_REG) (const_int 0)])
16887           (match_operand:MODEF 3 "memory_operand")
16888           (match_dup 0)))]
16889   "(<MODE>mode != DFmode || TARGET_64BIT)
16890    && TARGET_80387 && TARGET_CMOVE
16891    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16892    && optimize_insn_for_speed_p ()"
16893   [(set (match_dup 2) (match_dup 3))
16894    (set (match_dup 0)
16895         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16897 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16898 ;; the scalar versions to have only XMM registers as operands.
16900 ;; XOP conditional move
16901 (define_insn "*xop_pcmov_<mode>"
16902   [(set (match_operand:MODEF 0 "register_operand" "=x")
16903         (if_then_else:MODEF
16904           (match_operand:MODEF 1 "register_operand" "x")
16905           (match_operand:MODEF 2 "register_operand" "x")
16906           (match_operand:MODEF 3 "register_operand" "x")))]
16907   "TARGET_XOP"
16908   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16909   [(set_attr "type" "sse4arg")])
16911 ;; These versions of the min/max patterns are intentionally ignorant of
16912 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16913 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16914 ;; are undefined in this condition, we're certain this is correct.
16916 (define_insn "<code><mode>3"
16917   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16918         (smaxmin:MODEF
16919           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16920           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16921   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16922   "@
16923    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16924    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16925   [(set_attr "isa" "noavx,avx")
16926    (set_attr "prefix" "orig,vex")
16927    (set_attr "type" "sseadd")
16928    (set_attr "mode" "<MODE>")])
16930 ;; These versions of the min/max patterns implement exactly the operations
16931 ;;   min = (op1 < op2 ? op1 : op2)
16932 ;;   max = (!(op1 < op2) ? op1 : op2)
16933 ;; Their operands are not commutative, and thus they may be used in the
16934 ;; presence of -0.0 and NaN.
16936 (define_int_iterator IEEE_MAXMIN
16937         [UNSPEC_IEEE_MAX
16938          UNSPEC_IEEE_MIN])
16940 (define_int_attr ieee_maxmin
16941         [(UNSPEC_IEEE_MAX "max")
16942          (UNSPEC_IEEE_MIN "min")])
16944 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16945   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16946         (unspec:MODEF
16947           [(match_operand:MODEF 1 "register_operand" "0,v")
16948            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16949           IEEE_MAXMIN))]
16950   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16951   "@
16952    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16953    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16954   [(set_attr "isa" "noavx,avx")
16955    (set_attr "prefix" "orig,maybe_evex")
16956    (set_attr "type" "sseadd")
16957    (set_attr "mode" "<MODE>")])
16959 ;; Make two stack loads independent:
16960 ;;   fld aa              fld aa
16961 ;;   fld %st(0)     ->   fld bb
16962 ;;   fmul bb             fmul %st(1), %st
16964 ;; Actually we only match the last two instructions for simplicity.
16965 (define_peephole2
16966   [(set (match_operand 0 "fp_register_operand")
16967         (match_operand 1 "fp_register_operand"))
16968    (set (match_dup 0)
16969         (match_operator 2 "binary_fp_operator"
16970            [(match_dup 0)
16971             (match_operand 3 "memory_operand")]))]
16972   "REGNO (operands[0]) != REGNO (operands[1])"
16973   [(set (match_dup 0) (match_dup 3))
16974    (set (match_dup 0) (match_dup 4))]
16976   ;; The % modifier is not operational anymore in peephole2's, so we have to
16977   ;; swap the operands manually in the case of addition and multiplication.
16979   rtx op0, op1;
16981   if (COMMUTATIVE_ARITH_P (operands[2]))
16982     op0 = operands[0], op1 = operands[1];
16983   else
16984     op0 = operands[1], op1 = operands[0];
16986   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16987                                 GET_MODE (operands[2]),
16988                                 op0, op1);
16991 ;; Conditional addition patterns
16992 (define_expand "add<mode>cc"
16993   [(match_operand:SWI 0 "register_operand")
16994    (match_operand 1 "ordered_comparison_operator")
16995    (match_operand:SWI 2 "register_operand")
16996    (match_operand:SWI 3 "const_int_operand")]
16997   ""
16998   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17000 ;; Misc patterns (?)
17002 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17003 ;; Otherwise there will be nothing to keep
17005 ;; [(set (reg ebp) (reg esp))]
17006 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17007 ;;  (clobber (eflags)]
17008 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17010 ;; in proper program order.
17012 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17013   [(set (match_operand:P 0 "register_operand" "=r,r")
17014         (plus:P (match_operand:P 1 "register_operand" "0,r")
17015                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17016    (clobber (reg:CC FLAGS_REG))
17017    (clobber (mem:BLK (scratch)))]
17018   ""
17020   switch (get_attr_type (insn))
17021     {
17022     case TYPE_IMOV:
17023       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17025     case TYPE_ALU:
17026       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17027       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17028         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17030       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17032     default:
17033       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17034       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17035     }
17037   [(set (attr "type")
17038         (cond [(and (eq_attr "alternative" "0")
17039                     (not (match_test "TARGET_OPT_AGU")))
17040                  (const_string "alu")
17041                (match_operand:<MODE> 2 "const0_operand")
17042                  (const_string "imov")
17043               ]
17044               (const_string "lea")))
17045    (set (attr "length_immediate")
17046         (cond [(eq_attr "type" "imov")
17047                  (const_string "0")
17048                (and (eq_attr "type" "alu")
17049                     (match_operand 2 "const128_operand"))
17050                  (const_string "1")
17051               ]
17052               (const_string "*")))
17053    (set_attr "mode" "<MODE>")])
17055 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17056   [(set (match_operand:P 0 "register_operand" "=r")
17057         (minus:P (match_operand:P 1 "register_operand" "0")
17058                  (match_operand:P 2 "register_operand" "r")))
17059    (clobber (reg:CC FLAGS_REG))
17060    (clobber (mem:BLK (scratch)))]
17061   ""
17062   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17063   [(set_attr "type" "alu")
17064    (set_attr "mode" "<MODE>")])
17066 (define_insn "allocate_stack_worker_probe_<mode>"
17067   [(set (match_operand:P 0 "register_operand" "=a")
17068         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17069                             UNSPECV_STACK_PROBE))
17070    (clobber (reg:CC FLAGS_REG))]
17071   "ix86_target_stack_probe ()"
17072   "call\t___chkstk_ms"
17073   [(set_attr "type" "multi")
17074    (set_attr "length" "5")])
17076 (define_expand "allocate_stack"
17077   [(match_operand 0 "register_operand")
17078    (match_operand 1 "general_operand")]
17079   "ix86_target_stack_probe ()"
17081   rtx x;
17083 #ifndef CHECK_STACK_LIMIT
17084 #define CHECK_STACK_LIMIT 0
17085 #endif
17087   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17088       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17089     x = operands[1];
17090   else
17091     {
17092       rtx (*insn) (rtx, rtx);
17094       x = copy_to_mode_reg (Pmode, operands[1]);
17096       insn = (TARGET_64BIT
17097               ? gen_allocate_stack_worker_probe_di
17098               : gen_allocate_stack_worker_probe_si);
17100       emit_insn (insn (x, x));
17101     }
17103   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17104                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17106   if (x != stack_pointer_rtx)
17107     emit_move_insn (stack_pointer_rtx, x);
17109   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17110   DONE;
17113 ;; Use IOR for stack probes, this is shorter.
17114 (define_expand "probe_stack"
17115   [(match_operand 0 "memory_operand")]
17116   ""
17118   rtx (*gen_ior3) (rtx, rtx, rtx);
17120   gen_ior3 = (GET_MODE (operands[0]) == DImode
17121               ? gen_iordi3 : gen_iorsi3);
17123   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17124   DONE;
17127 (define_insn "adjust_stack_and_probe<mode>"
17128   [(set (match_operand:P 0 "register_operand" "=r")
17129         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17130                             UNSPECV_PROBE_STACK_RANGE))
17131    (set (reg:P SP_REG)
17132         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17133    (clobber (reg:CC FLAGS_REG))
17134    (clobber (mem:BLK (scratch)))]
17135   ""
17136   "* return output_adjust_stack_and_probe (operands[0]);"
17137   [(set_attr "type" "multi")])
17139 (define_insn "probe_stack_range<mode>"
17140   [(set (match_operand:P 0 "register_operand" "=r")
17141         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17142                             (match_operand:P 2 "const_int_operand" "n")]
17143                             UNSPECV_PROBE_STACK_RANGE))
17144    (clobber (reg:CC FLAGS_REG))]
17145   ""
17146   "* return output_probe_stack_range (operands[0], operands[2]);"
17147   [(set_attr "type" "multi")])
17149 (define_expand "builtin_setjmp_receiver"
17150   [(label_ref (match_operand 0))]
17151   "!TARGET_64BIT && flag_pic"
17153 #if TARGET_MACHO
17154   if (TARGET_MACHO)
17155     {
17156       rtx xops[3];
17157       rtx_code_label *label_rtx = gen_label_rtx ();
17158       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17159       xops[0] = xops[1] = pic_offset_table_rtx;
17160       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17161       ix86_expand_binary_operator (MINUS, SImode, xops);
17162     }
17163   else
17164 #endif
17165     emit_insn (gen_set_got (pic_offset_table_rtx));
17166   DONE;
17169 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17170 ;; Do not split instructions with mask registers.
17171 (define_split
17172   [(set (match_operand 0 "general_reg_operand")
17173         (match_operator 3 "promotable_binary_operator"
17174            [(match_operand 1 "general_reg_operand")
17175             (match_operand 2 "aligned_operand")]))
17176    (clobber (reg:CC FLAGS_REG))]
17177   "! TARGET_PARTIAL_REG_STALL && reload_completed
17178    && ((GET_MODE (operands[0]) == HImode
17179         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17180             /* ??? next two lines just !satisfies_constraint_K (...) */
17181             || !CONST_INT_P (operands[2])
17182             || satisfies_constraint_K (operands[2])))
17183        || (GET_MODE (operands[0]) == QImode
17184            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17185   [(parallel [(set (match_dup 0)
17186                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17187               (clobber (reg:CC FLAGS_REG))])]
17189   operands[0] = gen_lowpart (SImode, operands[0]);
17190   operands[1] = gen_lowpart (SImode, operands[1]);
17191   if (GET_CODE (operands[3]) != ASHIFT)
17192     operands[2] = gen_lowpart (SImode, operands[2]);
17193   PUT_MODE (operands[3], SImode);
17196 ; Promote the QImode tests, as i386 has encoding of the AND
17197 ; instruction with 32-bit sign-extended immediate and thus the
17198 ; instruction size is unchanged, except in the %eax case for
17199 ; which it is increased by one byte, hence the ! optimize_size.
17200 (define_split
17201   [(set (match_operand 0 "flags_reg_operand")
17202         (match_operator 2 "compare_operator"
17203           [(and (match_operand 3 "aligned_operand")
17204                 (match_operand 4 "const_int_operand"))
17205            (const_int 0)]))
17206    (set (match_operand 1 "register_operand")
17207         (and (match_dup 3) (match_dup 4)))]
17208   "! TARGET_PARTIAL_REG_STALL && reload_completed
17209    && optimize_insn_for_speed_p ()
17210    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17211        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17212    /* Ensure that the operand will remain sign-extended immediate.  */
17213    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17214   [(parallel [(set (match_dup 0)
17215                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17216                                     (const_int 0)]))
17217               (set (match_dup 1)
17218                    (and:SI (match_dup 3) (match_dup 4)))])]
17220   operands[4]
17221     = gen_int_mode (INTVAL (operands[4])
17222                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17223   operands[1] = gen_lowpart (SImode, operands[1]);
17224   operands[3] = gen_lowpart (SImode, operands[3]);
17227 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17228 ; the TEST instruction with 32-bit sign-extended immediate and thus
17229 ; the instruction size would at least double, which is not what we
17230 ; want even with ! optimize_size.
17231 (define_split
17232   [(set (match_operand 0 "flags_reg_operand")
17233         (match_operator 1 "compare_operator"
17234           [(and (match_operand:HI 2 "aligned_operand")
17235                 (match_operand:HI 3 "const_int_operand"))
17236            (const_int 0)]))]
17237   "! TARGET_PARTIAL_REG_STALL && reload_completed
17238    && ! TARGET_FAST_PREFIX
17239    && optimize_insn_for_speed_p ()
17240    /* Ensure that the operand will remain sign-extended immediate.  */
17241    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17242   [(set (match_dup 0)
17243         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17244                          (const_int 0)]))]
17246   operands[3]
17247     = gen_int_mode (INTVAL (operands[3])
17248                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17249   operands[2] = gen_lowpart (SImode, operands[2]);
17252 (define_split
17253   [(set (match_operand 0 "register_operand")
17254         (neg (match_operand 1 "register_operand")))
17255    (clobber (reg:CC FLAGS_REG))]
17256   "! TARGET_PARTIAL_REG_STALL && reload_completed
17257    && (GET_MODE (operands[0]) == HImode
17258        || (GET_MODE (operands[0]) == QImode
17259            && (TARGET_PROMOTE_QImode
17260                || optimize_insn_for_size_p ())))"
17261   [(parallel [(set (match_dup 0)
17262                    (neg:SI (match_dup 1)))
17263               (clobber (reg:CC FLAGS_REG))])]
17265   operands[0] = gen_lowpart (SImode, operands[0]);
17266   operands[1] = gen_lowpart (SImode, operands[1]);
17269 ;; Do not split instructions with mask regs.
17270 (define_split
17271   [(set (match_operand 0 "general_reg_operand")
17272         (not (match_operand 1 "general_reg_operand")))]
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   [(set (match_dup 0)
17279         (not:SI (match_dup 1)))]
17281   operands[0] = gen_lowpart (SImode, operands[0]);
17282   operands[1] = gen_lowpart (SImode, operands[1]);
17285 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17286 ;; transform a complex memory operation into two memory to register operations.
17288 ;; Don't push memory operands
17289 (define_peephole2
17290   [(set (match_operand:SWI 0 "push_operand")
17291         (match_operand:SWI 1 "memory_operand"))
17292    (match_scratch:SWI 2 "<r>")]
17293   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17294    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17295   [(set (match_dup 2) (match_dup 1))
17296    (set (match_dup 0) (match_dup 2))])
17298 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17299 ;; SImode pushes.
17300 (define_peephole2
17301   [(set (match_operand:SF 0 "push_operand")
17302         (match_operand:SF 1 "memory_operand"))
17303    (match_scratch:SF 2 "r")]
17304   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17305    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17306   [(set (match_dup 2) (match_dup 1))
17307    (set (match_dup 0) (match_dup 2))])
17309 ;; Don't move an immediate directly to memory when the instruction
17310 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17311 (define_peephole2
17312   [(match_scratch:SWI124 1 "<r>")
17313    (set (match_operand:SWI124 0 "memory_operand")
17314         (const_int 0))]
17315   "optimize_insn_for_speed_p ()
17316    && ((<MODE>mode == HImode
17317        && TARGET_LCP_STALL)
17318        || (!TARGET_USE_MOV0
17319           && TARGET_SPLIT_LONG_MOVES
17320           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17321    && peep2_regno_dead_p (0, FLAGS_REG)"
17322   [(parallel [(set (match_dup 2) (const_int 0))
17323               (clobber (reg:CC FLAGS_REG))])
17324    (set (match_dup 0) (match_dup 1))]
17325   "operands[2] = gen_lowpart (SImode, operands[1]);")
17327 (define_peephole2
17328   [(match_scratch:SWI124 2 "<r>")
17329    (set (match_operand:SWI124 0 "memory_operand")
17330         (match_operand:SWI124 1 "immediate_operand"))]
17331   "optimize_insn_for_speed_p ()
17332    && ((<MODE>mode == HImode
17333        && TARGET_LCP_STALL)
17334        || (TARGET_SPLIT_LONG_MOVES
17335           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17336   [(set (match_dup 2) (match_dup 1))
17337    (set (match_dup 0) (match_dup 2))])
17339 ;; Don't compare memory with zero, load and use a test instead.
17340 (define_peephole2
17341   [(set (match_operand 0 "flags_reg_operand")
17342         (match_operator 1 "compare_operator"
17343           [(match_operand:SI 2 "memory_operand")
17344            (const_int 0)]))
17345    (match_scratch:SI 3 "r")]
17346   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17347   [(set (match_dup 3) (match_dup 2))
17348    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17350 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17351 ;; Don't split NOTs with a displacement operand, because resulting XOR
17352 ;; will not be pairable anyway.
17354 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17355 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17356 ;; so this split helps here as well.
17358 ;; Note: Can't do this as a regular split because we can't get proper
17359 ;; lifetime information then.
17361 (define_peephole2
17362   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17363         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17364   "optimize_insn_for_speed_p ()
17365    && ((TARGET_NOT_UNPAIRABLE
17366         && (!MEM_P (operands[0])
17367             || !memory_displacement_operand (operands[0], <MODE>mode)))
17368        || (TARGET_NOT_VECTORMODE
17369            && long_memory_operand (operands[0], <MODE>mode)))
17370    && peep2_regno_dead_p (0, FLAGS_REG)"
17371   [(parallel [(set (match_dup 0)
17372                    (xor:SWI124 (match_dup 1) (const_int -1)))
17373               (clobber (reg:CC FLAGS_REG))])])
17375 ;; Non pairable "test imm, reg" instructions can be translated to
17376 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17377 ;; byte opcode instead of two, have a short form for byte operands),
17378 ;; so do it for other CPUs as well.  Given that the value was dead,
17379 ;; this should not create any new dependencies.  Pass on the sub-word
17380 ;; versions if we're concerned about partial register stalls.
17382 (define_peephole2
17383   [(set (match_operand 0 "flags_reg_operand")
17384         (match_operator 1 "compare_operator"
17385           [(and:SI (match_operand:SI 2 "register_operand")
17386                    (match_operand:SI 3 "immediate_operand"))
17387            (const_int 0)]))]
17388   "ix86_match_ccmode (insn, CCNOmode)
17389    && (true_regnum (operands[2]) != AX_REG
17390        || satisfies_constraint_K (operands[3]))
17391    && peep2_reg_dead_p (1, operands[2])"
17392   [(parallel
17393      [(set (match_dup 0)
17394            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17395                             (const_int 0)]))
17396       (set (match_dup 2)
17397            (and:SI (match_dup 2) (match_dup 3)))])])
17399 ;; We don't need to handle HImode case, because it will be promoted to SImode
17400 ;; on ! TARGET_PARTIAL_REG_STALL
17402 (define_peephole2
17403   [(set (match_operand 0 "flags_reg_operand")
17404         (match_operator 1 "compare_operator"
17405           [(and:QI (match_operand:QI 2 "register_operand")
17406                    (match_operand:QI 3 "immediate_operand"))
17407            (const_int 0)]))]
17408   "! TARGET_PARTIAL_REG_STALL
17409    && ix86_match_ccmode (insn, CCNOmode)
17410    && true_regnum (operands[2]) != AX_REG
17411    && peep2_reg_dead_p (1, operands[2])"
17412   [(parallel
17413      [(set (match_dup 0)
17414            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17415                             (const_int 0)]))
17416       (set (match_dup 2)
17417            (and:QI (match_dup 2) (match_dup 3)))])])
17419 (define_peephole2
17420   [(set (match_operand 0 "flags_reg_operand")
17421         (match_operator 1 "compare_operator"
17422           [(and:SI
17423              (zero_extract:SI
17424                (match_operand 2 "QIreg_operand")
17425                (const_int 8)
17426                (const_int 8))
17427              (match_operand 3 "const_int_operand"))
17428            (const_int 0)]))]
17429   "! TARGET_PARTIAL_REG_STALL
17430    && ix86_match_ccmode (insn, CCNOmode)
17431    && true_regnum (operands[2]) != AX_REG
17432    && peep2_reg_dead_p (1, operands[2])"
17433   [(parallel [(set (match_dup 0)
17434                    (match_op_dup 1
17435                      [(and:SI
17436                         (zero_extract:SI
17437                           (match_dup 2)
17438                           (const_int 8)
17439                           (const_int 8))
17440                         (match_dup 3))
17441                       (const_int 0)]))
17442               (set (zero_extract:SI (match_dup 2)
17443                                     (const_int 8)
17444                                     (const_int 8))
17445                    (and:SI
17446                      (zero_extract:SI
17447                        (match_dup 2)
17448                        (const_int 8)
17449                        (const_int 8))
17450                      (match_dup 3)))])])
17452 ;; Don't do logical operations with memory inputs.
17453 (define_peephole2
17454   [(match_scratch:SI 2 "r")
17455    (parallel [(set (match_operand:SI 0 "register_operand")
17456                    (match_operator:SI 3 "arith_or_logical_operator"
17457                      [(match_dup 0)
17458                       (match_operand:SI 1 "memory_operand")]))
17459               (clobber (reg:CC FLAGS_REG))])]
17460   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17461   [(set (match_dup 2) (match_dup 1))
17462    (parallel [(set (match_dup 0)
17463                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17464               (clobber (reg:CC FLAGS_REG))])])
17466 (define_peephole2
17467   [(match_scratch:SI 2 "r")
17468    (parallel [(set (match_operand:SI 0 "register_operand")
17469                    (match_operator:SI 3 "arith_or_logical_operator"
17470                      [(match_operand:SI 1 "memory_operand")
17471                       (match_dup 0)]))
17472               (clobber (reg:CC FLAGS_REG))])]
17473   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17474   [(set (match_dup 2) (match_dup 1))
17475    (parallel [(set (match_dup 0)
17476                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17477               (clobber (reg:CC FLAGS_REG))])])
17479 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17480 ;; refers to the destination of the load!
17482 (define_peephole2
17483   [(set (match_operand:SI 0 "register_operand")
17484         (match_operand:SI 1 "register_operand"))
17485    (parallel [(set (match_dup 0)
17486                    (match_operator:SI 3 "commutative_operator"
17487                      [(match_dup 0)
17488                       (match_operand:SI 2 "memory_operand")]))
17489               (clobber (reg:CC FLAGS_REG))])]
17490   "REGNO (operands[0]) != REGNO (operands[1])
17491    && GENERAL_REGNO_P (REGNO (operands[0]))
17492    && GENERAL_REGNO_P (REGNO (operands[1]))"
17493   [(set (match_dup 0) (match_dup 4))
17494    (parallel [(set (match_dup 0)
17495                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17496               (clobber (reg:CC FLAGS_REG))])]
17497   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17499 (define_peephole2
17500   [(set (match_operand 0 "register_operand")
17501         (match_operand 1 "register_operand"))
17502    (set (match_dup 0)
17503                    (match_operator 3 "commutative_operator"
17504                      [(match_dup 0)
17505                       (match_operand 2 "memory_operand")]))]
17506   "REGNO (operands[0]) != REGNO (operands[1])
17507    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17508        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17509   [(set (match_dup 0) (match_dup 2))
17510    (set (match_dup 0)
17511         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17513 ; Don't do logical operations with memory outputs
17515 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17516 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17517 ; the same decoder scheduling characteristics as the original.
17519 (define_peephole2
17520   [(match_scratch:SI 2 "r")
17521    (parallel [(set (match_operand:SI 0 "memory_operand")
17522                    (match_operator:SI 3 "arith_or_logical_operator"
17523                      [(match_dup 0)
17524                       (match_operand:SI 1 "nonmemory_operand")]))
17525               (clobber (reg:CC FLAGS_REG))])]
17526   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17527    /* Do not split stack checking probes.  */
17528    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17529   [(set (match_dup 2) (match_dup 0))
17530    (parallel [(set (match_dup 2)
17531                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17532               (clobber (reg:CC FLAGS_REG))])
17533    (set (match_dup 0) (match_dup 2))])
17535 (define_peephole2
17536   [(match_scratch:SI 2 "r")
17537    (parallel [(set (match_operand:SI 0 "memory_operand")
17538                    (match_operator:SI 3 "arith_or_logical_operator"
17539                      [(match_operand:SI 1 "nonmemory_operand")
17540                       (match_dup 0)]))
17541               (clobber (reg:CC FLAGS_REG))])]
17542   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17543    /* Do not split stack checking probes.  */
17544    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17545   [(set (match_dup 2) (match_dup 0))
17546    (parallel [(set (match_dup 2)
17547                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17548               (clobber (reg:CC FLAGS_REG))])
17549    (set (match_dup 0) (match_dup 2))])
17551 ;; Attempt to use arith or logical operations with memory outputs with
17552 ;; setting of flags.
17553 (define_peephole2
17554   [(set (match_operand:SWI 0 "register_operand")
17555         (match_operand:SWI 1 "memory_operand"))
17556    (parallel [(set (match_dup 0)
17557                    (match_operator:SWI 3 "plusminuslogic_operator"
17558                      [(match_dup 0)
17559                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17560               (clobber (reg:CC FLAGS_REG))])
17561    (set (match_dup 1) (match_dup 0))
17562    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17563   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17564    && peep2_reg_dead_p (4, operands[0])
17565    && !reg_overlap_mentioned_p (operands[0], operands[1])
17566    && !reg_overlap_mentioned_p (operands[0], operands[2])
17567    && (<MODE>mode != QImode
17568        || immediate_operand (operands[2], QImode)
17569        || any_QIreg_operand (operands[2], QImode))
17570    && ix86_match_ccmode (peep2_next_insn (3),
17571                          (GET_CODE (operands[3]) == PLUS
17572                           || GET_CODE (operands[3]) == MINUS)
17573                          ? CCGOCmode : CCNOmode)"
17574   [(parallel [(set (match_dup 4) (match_dup 5))
17575               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17576                                                   (match_dup 2)]))])]
17578   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17579   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17580                                 copy_rtx (operands[1]),
17581                                 copy_rtx (operands[2]));
17582   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17583                                  operands[5], const0_rtx);
17586 (define_peephole2
17587   [(parallel [(set (match_operand:SWI 0 "register_operand")
17588                    (match_operator:SWI 2 "plusminuslogic_operator"
17589                      [(match_dup 0)
17590                       (match_operand:SWI 1 "memory_operand")]))
17591               (clobber (reg:CC FLAGS_REG))])
17592    (set (match_dup 1) (match_dup 0))
17593    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17594   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17595    && GET_CODE (operands[2]) != MINUS
17596    && peep2_reg_dead_p (3, operands[0])
17597    && !reg_overlap_mentioned_p (operands[0], operands[1])
17598    && ix86_match_ccmode (peep2_next_insn (2),
17599                          GET_CODE (operands[2]) == PLUS
17600                          ? CCGOCmode : CCNOmode)"
17601   [(parallel [(set (match_dup 3) (match_dup 4))
17602               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17603                                                   (match_dup 0)]))])]
17605   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17606   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17607                                 copy_rtx (operands[1]),
17608                                 copy_rtx (operands[0]));
17609   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17610                                  operands[4], const0_rtx);
17613 (define_peephole2
17614   [(set (match_operand:SWI12 0 "register_operand")
17615         (match_operand:SWI12 1 "memory_operand"))
17616    (parallel [(set (match_operand:SI 4 "register_operand")
17617                    (match_operator:SI 3 "plusminuslogic_operator"
17618                      [(match_dup 4)
17619                       (match_operand:SI 2 "nonmemory_operand")]))
17620               (clobber (reg:CC FLAGS_REG))])
17621    (set (match_dup 1) (match_dup 0))
17622    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17623   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17624    && REG_P (operands[0]) && REG_P (operands[4])
17625    && REGNO (operands[0]) == REGNO (operands[4])
17626    && peep2_reg_dead_p (4, operands[0])
17627    && (<MODE>mode != QImode
17628        || immediate_operand (operands[2], SImode)
17629        || any_QIreg_operand (operands[2], SImode))
17630    && !reg_overlap_mentioned_p (operands[0], operands[1])
17631    && !reg_overlap_mentioned_p (operands[0], operands[2])
17632    && ix86_match_ccmode (peep2_next_insn (3),
17633                          (GET_CODE (operands[3]) == PLUS
17634                           || GET_CODE (operands[3]) == MINUS)
17635                          ? CCGOCmode : CCNOmode)"
17636   [(parallel [(set (match_dup 4) (match_dup 5))
17637               (set (match_dup 1) (match_dup 6))])]
17639   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17640   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17641   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17642                                 copy_rtx (operands[1]), operands[2]);
17643   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17644                                  operands[5], const0_rtx);
17645   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17646                                 copy_rtx (operands[1]),
17647                                 copy_rtx (operands[2]));
17650 ;; Attempt to always use XOR for zeroing registers.
17651 (define_peephole2
17652   [(set (match_operand 0 "register_operand")
17653         (match_operand 1 "const0_operand"))]
17654   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17655    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17656    && GENERAL_REG_P (operands[0])
17657    && peep2_regno_dead_p (0, FLAGS_REG)"
17658   [(parallel [(set (match_dup 0) (const_int 0))
17659               (clobber (reg:CC FLAGS_REG))])]
17660   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17662 (define_peephole2
17663   [(set (strict_low_part (match_operand 0 "register_operand"))
17664         (const_int 0))]
17665   "(GET_MODE (operands[0]) == QImode
17666     || GET_MODE (operands[0]) == HImode)
17667    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17668    && peep2_regno_dead_p (0, FLAGS_REG)"
17669   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17670               (clobber (reg:CC FLAGS_REG))])])
17672 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17673 (define_peephole2
17674   [(set (match_operand:SWI248 0 "register_operand")
17675         (const_int -1))]
17676   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17677    && peep2_regno_dead_p (0, FLAGS_REG)"
17678   [(parallel [(set (match_dup 0) (const_int -1))
17679               (clobber (reg:CC FLAGS_REG))])]
17681   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17682     operands[0] = gen_lowpart (SImode, operands[0]);
17685 ;; Attempt to convert simple lea to add/shift.
17686 ;; These can be created by move expanders.
17687 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17688 ;; relevant lea instructions were already split.
17690 (define_peephole2
17691   [(set (match_operand:SWI48 0 "register_operand")
17692         (plus:SWI48 (match_dup 0)
17693                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17694   "!TARGET_OPT_AGU
17695    && peep2_regno_dead_p (0, FLAGS_REG)"
17696   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17697               (clobber (reg:CC FLAGS_REG))])])
17699 (define_peephole2
17700   [(set (match_operand:SWI48 0 "register_operand")
17701         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17702                     (match_dup 0)))]
17703   "!TARGET_OPT_AGU
17704    && peep2_regno_dead_p (0, FLAGS_REG)"
17705   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17706               (clobber (reg:CC FLAGS_REG))])])
17708 (define_peephole2
17709   [(set (match_operand:DI 0 "register_operand")
17710         (zero_extend:DI
17711           (plus:SI (match_operand:SI 1 "register_operand")
17712                    (match_operand:SI 2 "nonmemory_operand"))))]
17713   "TARGET_64BIT && !TARGET_OPT_AGU
17714    && REGNO (operands[0]) == REGNO (operands[1])
17715    && peep2_regno_dead_p (0, FLAGS_REG)"
17716   [(parallel [(set (match_dup 0)
17717                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17718               (clobber (reg:CC FLAGS_REG))])])
17720 (define_peephole2
17721   [(set (match_operand:DI 0 "register_operand")
17722         (zero_extend:DI
17723           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17724                    (match_operand:SI 2 "register_operand"))))]
17725   "TARGET_64BIT && !TARGET_OPT_AGU
17726    && REGNO (operands[0]) == REGNO (operands[2])
17727    && peep2_regno_dead_p (0, FLAGS_REG)"
17728   [(parallel [(set (match_dup 0)
17729                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17730               (clobber (reg:CC FLAGS_REG))])])
17732 (define_peephole2
17733   [(set (match_operand:SWI48 0 "register_operand")
17734         (mult:SWI48 (match_dup 0)
17735                     (match_operand:SWI48 1 "const_int_operand")))]
17736   "exact_log2 (INTVAL (operands[1])) >= 0
17737    && peep2_regno_dead_p (0, FLAGS_REG)"
17738   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17739               (clobber (reg:CC FLAGS_REG))])]
17740   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17742 (define_peephole2
17743   [(set (match_operand:DI 0 "register_operand")
17744         (zero_extend:DI
17745           (mult:SI (match_operand:SI 1 "register_operand")
17746                    (match_operand:SI 2 "const_int_operand"))))]
17747   "TARGET_64BIT
17748    && exact_log2 (INTVAL (operands[2])) >= 0
17749    && REGNO (operands[0]) == REGNO (operands[1])
17750    && peep2_regno_dead_p (0, FLAGS_REG)"
17751   [(parallel [(set (match_dup 0)
17752                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17753               (clobber (reg:CC FLAGS_REG))])]
17754   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17756 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17757 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17758 ;; On many CPUs it is also faster, since special hardware to avoid esp
17759 ;; dependencies is present.
17761 ;; While some of these conversions may be done using splitters, we use
17762 ;; peepholes in order to allow combine_stack_adjustments pass to see
17763 ;; nonobfuscated RTL.
17765 ;; Convert prologue esp subtractions to push.
17766 ;; We need register to push.  In order to keep verify_flow_info happy we have
17767 ;; two choices
17768 ;; - use scratch and clobber it in order to avoid dependencies
17769 ;; - use already live register
17770 ;; We can't use the second way right now, since there is no reliable way how to
17771 ;; verify that given register is live.  First choice will also most likely in
17772 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17773 ;; call clobbered registers are dead.  We may want to use base pointer as an
17774 ;; alternative when no register is available later.
17776 (define_peephole2
17777   [(match_scratch:W 1 "r")
17778    (parallel [(set (reg:P SP_REG)
17779                    (plus:P (reg:P SP_REG)
17780                            (match_operand:P 0 "const_int_operand")))
17781               (clobber (reg:CC FLAGS_REG))
17782               (clobber (mem:BLK (scratch)))])]
17783   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17784    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17785   [(clobber (match_dup 1))
17786    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17787               (clobber (mem:BLK (scratch)))])])
17789 (define_peephole2
17790   [(match_scratch:W 1 "r")
17791    (parallel [(set (reg:P SP_REG)
17792                    (plus:P (reg:P SP_REG)
17793                            (match_operand:P 0 "const_int_operand")))
17794               (clobber (reg:CC FLAGS_REG))
17795               (clobber (mem:BLK (scratch)))])]
17796   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17797    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17798   [(clobber (match_dup 1))
17799    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17800    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17801               (clobber (mem:BLK (scratch)))])])
17803 ;; Convert esp subtractions to push.
17804 (define_peephole2
17805   [(match_scratch:W 1 "r")
17806    (parallel [(set (reg:P SP_REG)
17807                    (plus:P (reg:P SP_REG)
17808                            (match_operand:P 0 "const_int_operand")))
17809               (clobber (reg:CC FLAGS_REG))])]
17810   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17811    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17812   [(clobber (match_dup 1))
17813    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17815 (define_peephole2
17816   [(match_scratch:W 1 "r")
17817    (parallel [(set (reg:P SP_REG)
17818                    (plus:P (reg:P SP_REG)
17819                            (match_operand:P 0 "const_int_operand")))
17820               (clobber (reg:CC FLAGS_REG))])]
17821   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17822    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17823   [(clobber (match_dup 1))
17824    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17825    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17827 ;; Convert epilogue deallocator to pop.
17828 (define_peephole2
17829   [(match_scratch:W 1 "r")
17830    (parallel [(set (reg:P SP_REG)
17831                    (plus:P (reg:P SP_REG)
17832                            (match_operand:P 0 "const_int_operand")))
17833               (clobber (reg:CC FLAGS_REG))
17834               (clobber (mem:BLK (scratch)))])]
17835   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17836    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17837   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17838               (clobber (mem:BLK (scratch)))])])
17840 ;; Two pops case is tricky, since pop causes dependency
17841 ;; on destination register.  We use two registers if available.
17842 (define_peephole2
17843   [(match_scratch:W 1 "r")
17844    (match_scratch:W 2 "r")
17845    (parallel [(set (reg:P SP_REG)
17846                    (plus:P (reg:P SP_REG)
17847                            (match_operand:P 0 "const_int_operand")))
17848               (clobber (reg:CC FLAGS_REG))
17849               (clobber (mem:BLK (scratch)))])]
17850   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17851    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17852   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17853               (clobber (mem:BLK (scratch)))])
17854    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17856 (define_peephole2
17857   [(match_scratch:W 1 "r")
17858    (parallel [(set (reg:P SP_REG)
17859                    (plus:P (reg:P SP_REG)
17860                            (match_operand:P 0 "const_int_operand")))
17861               (clobber (reg:CC FLAGS_REG))
17862               (clobber (mem:BLK (scratch)))])]
17863   "optimize_insn_for_size_p ()
17864    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17865   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17866               (clobber (mem:BLK (scratch)))])
17867    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17869 ;; Convert esp additions to pop.
17870 (define_peephole2
17871   [(match_scratch:W 1 "r")
17872    (parallel [(set (reg:P SP_REG)
17873                    (plus:P (reg:P SP_REG)
17874                            (match_operand:P 0 "const_int_operand")))
17875               (clobber (reg:CC FLAGS_REG))])]
17876   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17877   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17879 ;; Two pops case is tricky, since pop causes dependency
17880 ;; on destination register.  We use two registers if available.
17881 (define_peephole2
17882   [(match_scratch:W 1 "r")
17883    (match_scratch:W 2 "r")
17884    (parallel [(set (reg:P SP_REG)
17885                    (plus:P (reg:P SP_REG)
17886                            (match_operand:P 0 "const_int_operand")))
17887               (clobber (reg:CC FLAGS_REG))])]
17888   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17889   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17890    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17892 (define_peephole2
17893   [(match_scratch:W 1 "r")
17894    (parallel [(set (reg:P SP_REG)
17895                    (plus:P (reg:P SP_REG)
17896                            (match_operand:P 0 "const_int_operand")))
17897               (clobber (reg:CC FLAGS_REG))])]
17898   "optimize_insn_for_size_p ()
17899    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17900   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17901    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17903 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17904 ;; required and register dies.  Similarly for 128 to -128.
17905 (define_peephole2
17906   [(set (match_operand 0 "flags_reg_operand")
17907         (match_operator 1 "compare_operator"
17908           [(match_operand 2 "register_operand")
17909            (match_operand 3 "const_int_operand")]))]
17910   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17911      && incdec_operand (operands[3], GET_MODE (operands[3])))
17912     || (!TARGET_FUSE_CMP_AND_BRANCH
17913         && INTVAL (operands[3]) == 128))
17914    && ix86_match_ccmode (insn, CCGCmode)
17915    && peep2_reg_dead_p (1, operands[2])"
17916   [(parallel [(set (match_dup 0)
17917                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17918               (clobber (match_dup 2))])])
17920 ;; Convert imul by three, five and nine into lea
17921 (define_peephole2
17922   [(parallel
17923     [(set (match_operand:SWI48 0 "register_operand")
17924           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17925                       (match_operand:SWI48 2 "const359_operand")))
17926      (clobber (reg:CC FLAGS_REG))])]
17927   "!TARGET_PARTIAL_REG_STALL
17928    || <MODE>mode == SImode
17929    || optimize_function_for_size_p (cfun)"
17930   [(set (match_dup 0)
17931         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17932                     (match_dup 1)))]
17933   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17935 (define_peephole2
17936   [(parallel
17937     [(set (match_operand:SWI48 0 "register_operand")
17938           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17939                       (match_operand:SWI48 2 "const359_operand")))
17940      (clobber (reg:CC FLAGS_REG))])]
17941   "optimize_insn_for_speed_p ()
17942    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17943   [(set (match_dup 0) (match_dup 1))
17944    (set (match_dup 0)
17945         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17946                     (match_dup 0)))]
17947   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17949 ;; imul $32bit_imm, mem, reg is vector decoded, while
17950 ;; imul $32bit_imm, reg, reg is direct decoded.
17951 (define_peephole2
17952   [(match_scratch:SWI48 3 "r")
17953    (parallel [(set (match_operand:SWI48 0 "register_operand")
17954                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17955                                (match_operand:SWI48 2 "immediate_operand")))
17956               (clobber (reg:CC FLAGS_REG))])]
17957   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17958    && !satisfies_constraint_K (operands[2])"
17959   [(set (match_dup 3) (match_dup 1))
17960    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17961               (clobber (reg:CC FLAGS_REG))])])
17963 (define_peephole2
17964   [(match_scratch:SI 3 "r")
17965    (parallel [(set (match_operand:DI 0 "register_operand")
17966                    (zero_extend:DI
17967                      (mult:SI (match_operand:SI 1 "memory_operand")
17968                               (match_operand:SI 2 "immediate_operand"))))
17969               (clobber (reg:CC FLAGS_REG))])]
17970   "TARGET_64BIT
17971    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17972    && !satisfies_constraint_K (operands[2])"
17973   [(set (match_dup 3) (match_dup 1))
17974    (parallel [(set (match_dup 0)
17975                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17976               (clobber (reg:CC FLAGS_REG))])])
17978 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17979 ;; Convert it into imul reg, reg
17980 ;; It would be better to force assembler to encode instruction using long
17981 ;; immediate, but there is apparently no way to do so.
17982 (define_peephole2
17983   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17984                    (mult:SWI248
17985                     (match_operand:SWI248 1 "nonimmediate_operand")
17986                     (match_operand:SWI248 2 "const_int_operand")))
17987               (clobber (reg:CC FLAGS_REG))])
17988    (match_scratch:SWI248 3 "r")]
17989   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17990    && satisfies_constraint_K (operands[2])"
17991   [(set (match_dup 3) (match_dup 2))
17992    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17993               (clobber (reg:CC FLAGS_REG))])]
17995   if (!rtx_equal_p (operands[0], operands[1]))
17996     emit_move_insn (operands[0], operands[1]);
17999 ;; After splitting up read-modify operations, array accesses with memory
18000 ;; operands might end up in form:
18001 ;;  sall    $2, %eax
18002 ;;  movl    4(%esp), %edx
18003 ;;  addl    %edx, %eax
18004 ;; instead of pre-splitting:
18005 ;;  sall    $2, %eax
18006 ;;  addl    4(%esp), %eax
18007 ;; Turn it into:
18008 ;;  movl    4(%esp), %edx
18009 ;;  leal    (%edx,%eax,4), %eax
18011 (define_peephole2
18012   [(match_scratch:W 5 "r")
18013    (parallel [(set (match_operand 0 "register_operand")
18014                    (ashift (match_operand 1 "register_operand")
18015                            (match_operand 2 "const_int_operand")))
18016                (clobber (reg:CC FLAGS_REG))])
18017    (parallel [(set (match_operand 3 "register_operand")
18018                    (plus (match_dup 0)
18019                          (match_operand 4 "x86_64_general_operand")))
18020                    (clobber (reg:CC FLAGS_REG))])]
18021   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18022    /* Validate MODE for lea.  */
18023    && ((!TARGET_PARTIAL_REG_STALL
18024         && (GET_MODE (operands[0]) == QImode
18025             || GET_MODE (operands[0]) == HImode))
18026        || GET_MODE (operands[0]) == SImode
18027        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18028    && (rtx_equal_p (operands[0], operands[3])
18029        || peep2_reg_dead_p (2, operands[0]))
18030    /* We reorder load and the shift.  */
18031    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18032   [(set (match_dup 5) (match_dup 4))
18033    (set (match_dup 0) (match_dup 1))]
18035   machine_mode op1mode = GET_MODE (operands[1]);
18036   machine_mode mode = op1mode == DImode ? DImode : SImode;
18037   int scale = 1 << INTVAL (operands[2]);
18038   rtx index = gen_lowpart (word_mode, operands[1]);
18039   rtx base = gen_lowpart (word_mode, operands[5]);
18040   rtx dest = gen_lowpart (mode, operands[3]);
18042   operands[1] = gen_rtx_PLUS (word_mode, base,
18043                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18044   operands[5] = base;
18045   if (mode != word_mode)
18046     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18047   if (op1mode != word_mode)
18048     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18049   operands[0] = dest;
18052 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18053 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18054 ;; caught for use by garbage collectors and the like.  Using an insn that
18055 ;; maps to SIGILL makes it more likely the program will rightfully die.
18056 ;; Keeping with tradition, "6" is in honor of #UD.
18057 (define_insn "trap"
18058   [(trap_if (const_int 1) (const_int 6))]
18059   ""
18061 #ifdef HAVE_AS_IX86_UD2
18062   return "ud2";
18063 #else
18064   return ASM_SHORT "0x0b0f";
18065 #endif
18067   [(set_attr "length" "2")])
18069 (define_expand "prefetch"
18070   [(prefetch (match_operand 0 "address_operand")
18071              (match_operand:SI 1 "const_int_operand")
18072              (match_operand:SI 2 "const_int_operand"))]
18073   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18075   bool write = INTVAL (operands[1]) != 0;
18076   int locality = INTVAL (operands[2]);
18078   gcc_assert (IN_RANGE (locality, 0, 3));
18080   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18081      supported by SSE counterpart or the SSE prefetch is not available
18082      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18083      of locality.  */
18084   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18085     operands[2] = const2_rtx;
18086   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18087     operands[2] = GEN_INT (3);
18088   else
18089     operands[1] = const0_rtx;
18092 (define_insn "*prefetch_sse"
18093   [(prefetch (match_operand 0 "address_operand" "p")
18094              (const_int 0)
18095              (match_operand:SI 1 "const_int_operand"))]
18096   "TARGET_PREFETCH_SSE"
18098   static const char * const patterns[4] = {
18099    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18100   };
18102   int locality = INTVAL (operands[1]);
18103   gcc_assert (IN_RANGE (locality, 0, 3));
18105   return patterns[locality];
18107   [(set_attr "type" "sse")
18108    (set_attr "atom_sse_attr" "prefetch")
18109    (set (attr "length_address")
18110         (symbol_ref "memory_address_length (operands[0], false)"))
18111    (set_attr "memory" "none")])
18113 (define_insn "*prefetch_3dnow"
18114   [(prefetch (match_operand 0 "address_operand" "p")
18115              (match_operand:SI 1 "const_int_operand" "n")
18116              (const_int 3))]
18117   "TARGET_PRFCHW"
18119   if (INTVAL (operands[1]) == 0)
18120     return "prefetch\t%a0";
18121   else
18122     return "prefetchw\t%a0";
18124   [(set_attr "type" "mmx")
18125    (set (attr "length_address")
18126         (symbol_ref "memory_address_length (operands[0], false)"))
18127    (set_attr "memory" "none")])
18129 (define_insn "*prefetch_prefetchwt1"
18130   [(prefetch (match_operand 0 "address_operand" "p")
18131              (const_int 1)
18132              (const_int 2))]
18133   "TARGET_PREFETCHWT1"
18134   "prefetchwt1\t%a0";
18135   [(set_attr "type" "sse")
18136    (set (attr "length_address")
18137         (symbol_ref "memory_address_length (operands[0], false)"))
18138    (set_attr "memory" "none")])
18140 (define_expand "stack_protect_set"
18141   [(match_operand 0 "memory_operand")
18142    (match_operand 1 "memory_operand")]
18143   "TARGET_SSP_TLS_GUARD"
18145   rtx (*insn)(rtx, rtx);
18147 #ifdef TARGET_THREAD_SSP_OFFSET
18148   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18149   insn = (TARGET_LP64
18150           ? gen_stack_tls_protect_set_di
18151           : gen_stack_tls_protect_set_si);
18152 #else
18153   insn = (TARGET_LP64
18154           ? gen_stack_protect_set_di
18155           : gen_stack_protect_set_si);
18156 #endif
18158   emit_insn (insn (operands[0], operands[1]));
18159   DONE;
18162 (define_insn "stack_protect_set_<mode>"
18163   [(set (match_operand:PTR 0 "memory_operand" "=m")
18164         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18165                     UNSPEC_SP_SET))
18166    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18167    (clobber (reg:CC FLAGS_REG))]
18168   "TARGET_SSP_TLS_GUARD"
18169   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18170   [(set_attr "type" "multi")])
18172 (define_insn "stack_tls_protect_set_<mode>"
18173   [(set (match_operand:PTR 0 "memory_operand" "=m")
18174         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18175                     UNSPEC_SP_TLS_SET))
18176    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18177    (clobber (reg:CC FLAGS_REG))]
18178   ""
18179   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18180   [(set_attr "type" "multi")])
18182 (define_expand "stack_protect_test"
18183   [(match_operand 0 "memory_operand")
18184    (match_operand 1 "memory_operand")
18185    (match_operand 2)]
18186   "TARGET_SSP_TLS_GUARD"
18188   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18190   rtx (*insn)(rtx, rtx, rtx);
18192 #ifdef TARGET_THREAD_SSP_OFFSET
18193   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18194   insn = (TARGET_LP64
18195           ? gen_stack_tls_protect_test_di
18196           : gen_stack_tls_protect_test_si);
18197 #else
18198   insn = (TARGET_LP64
18199           ? gen_stack_protect_test_di
18200           : gen_stack_protect_test_si);
18201 #endif
18203   emit_insn (insn (flags, operands[0], operands[1]));
18205   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18206                                   flags, const0_rtx, operands[2]));
18207   DONE;
18210 (define_insn "stack_protect_test_<mode>"
18211   [(set (match_operand:CCZ 0 "flags_reg_operand")
18212         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18213                      (match_operand:PTR 2 "memory_operand" "m")]
18214                     UNSPEC_SP_TEST))
18215    (clobber (match_scratch:PTR 3 "=&r"))]
18216   "TARGET_SSP_TLS_GUARD"
18217   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18218   [(set_attr "type" "multi")])
18220 (define_insn "stack_tls_protect_test_<mode>"
18221   [(set (match_operand:CCZ 0 "flags_reg_operand")
18222         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18223                      (match_operand:PTR 2 "const_int_operand" "i")]
18224                     UNSPEC_SP_TLS_TEST))
18225    (clobber (match_scratch:PTR 3 "=r"))]
18226   ""
18227   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18228   [(set_attr "type" "multi")])
18230 (define_insn "sse4_2_crc32<mode>"
18231   [(set (match_operand:SI 0 "register_operand" "=r")
18232         (unspec:SI
18233           [(match_operand:SI 1 "register_operand" "0")
18234            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18235           UNSPEC_CRC32))]
18236   "TARGET_SSE4_2 || TARGET_CRC32"
18237   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18238   [(set_attr "type" "sselog1")
18239    (set_attr "prefix_rep" "1")
18240    (set_attr "prefix_extra" "1")
18241    (set (attr "prefix_data16")
18242      (if_then_else (match_operand:HI 2)
18243        (const_string "1")
18244        (const_string "*")))
18245    (set (attr "prefix_rex")
18246      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18247        (const_string "1")
18248        (const_string "*")))
18249    (set_attr "mode" "SI")])
18251 (define_insn "sse4_2_crc32di"
18252   [(set (match_operand:DI 0 "register_operand" "=r")
18253         (unspec:DI
18254           [(match_operand:DI 1 "register_operand" "0")
18255            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18256           UNSPEC_CRC32))]
18257   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18258   "crc32{q}\t{%2, %0|%0, %2}"
18259   [(set_attr "type" "sselog1")
18260    (set_attr "prefix_rep" "1")
18261    (set_attr "prefix_extra" "1")
18262    (set_attr "mode" "DI")])
18264 (define_insn "rdpmc"
18265   [(set (match_operand:DI 0 "register_operand" "=A")
18266         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18267                             UNSPECV_RDPMC))]
18268   "!TARGET_64BIT"
18269   "rdpmc"
18270   [(set_attr "type" "other")
18271    (set_attr "length" "2")])
18273 (define_insn "rdpmc_rex64"
18274   [(set (match_operand:DI 0 "register_operand" "=a")
18275         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18276                             UNSPECV_RDPMC))
18277    (set (match_operand:DI 1 "register_operand" "=d")
18278         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18279   "TARGET_64BIT"
18280   "rdpmc"
18281   [(set_attr "type" "other")
18282    (set_attr "length" "2")])
18284 (define_insn "rdtsc"
18285   [(set (match_operand:DI 0 "register_operand" "=A")
18286         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18287   "!TARGET_64BIT"
18288   "rdtsc"
18289   [(set_attr "type" "other")
18290    (set_attr "length" "2")])
18292 (define_insn "rdtsc_rex64"
18293   [(set (match_operand:DI 0 "register_operand" "=a")
18294         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18295    (set (match_operand:DI 1 "register_operand" "=d")
18296         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18297   "TARGET_64BIT"
18298   "rdtsc"
18299   [(set_attr "type" "other")
18300    (set_attr "length" "2")])
18302 (define_insn "rdtscp"
18303   [(set (match_operand:DI 0 "register_operand" "=A")
18304         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18305    (set (match_operand:SI 1 "register_operand" "=c")
18306         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18307   "!TARGET_64BIT"
18308   "rdtscp"
18309   [(set_attr "type" "other")
18310    (set_attr "length" "3")])
18312 (define_insn "rdtscp_rex64"
18313   [(set (match_operand:DI 0 "register_operand" "=a")
18314         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18315    (set (match_operand:DI 1 "register_operand" "=d")
18316         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18317    (set (match_operand:SI 2 "register_operand" "=c")
18318         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18319   "TARGET_64BIT"
18320   "rdtscp"
18321   [(set_attr "type" "other")
18322    (set_attr "length" "3")])
18324 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18326 ;; FXSR, XSAVE and XSAVEOPT instructions
18328 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18330 (define_insn "fxsave"
18331   [(set (match_operand:BLK 0 "memory_operand" "=m")
18332         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18333   "TARGET_FXSR"
18334   "fxsave\t%0"
18335   [(set_attr "type" "other")
18336    (set_attr "memory" "store")
18337    (set (attr "length")
18338         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18340 (define_insn "fxsave64"
18341   [(set (match_operand:BLK 0 "memory_operand" "=m")
18342         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18343   "TARGET_64BIT && TARGET_FXSR"
18344   "fxsave64\t%0"
18345   [(set_attr "type" "other")
18346    (set_attr "memory" "store")
18347    (set (attr "length")
18348         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18350 (define_insn "fxrstor"
18351   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18352                     UNSPECV_FXRSTOR)]
18353   "TARGET_FXSR"
18354   "fxrstor\t%0"
18355   [(set_attr "type" "other")
18356    (set_attr "memory" "load")
18357    (set (attr "length")
18358         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18360 (define_insn "fxrstor64"
18361   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18362                     UNSPECV_FXRSTOR64)]
18363   "TARGET_64BIT && TARGET_FXSR"
18364   "fxrstor64\t%0"
18365   [(set_attr "type" "other")
18366    (set_attr "memory" "load")
18367    (set (attr "length")
18368         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18370 (define_int_iterator ANY_XSAVE
18371         [UNSPECV_XSAVE
18372          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18373          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18374          (UNSPECV_XSAVES "TARGET_XSAVES")])
18376 (define_int_iterator ANY_XSAVE64
18377         [UNSPECV_XSAVE64
18378          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18379          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18380          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18382 (define_int_attr xsave
18383         [(UNSPECV_XSAVE "xsave")
18384          (UNSPECV_XSAVE64 "xsave64")
18385          (UNSPECV_XSAVEOPT "xsaveopt")
18386          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18387          (UNSPECV_XSAVEC "xsavec")
18388          (UNSPECV_XSAVEC64 "xsavec64")
18389          (UNSPECV_XSAVES "xsaves")
18390          (UNSPECV_XSAVES64 "xsaves64")])
18392 (define_int_iterator ANY_XRSTOR
18393         [UNSPECV_XRSTOR
18394          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18396 (define_int_iterator ANY_XRSTOR64
18397         [UNSPECV_XRSTOR64
18398          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18400 (define_int_attr xrstor
18401         [(UNSPECV_XRSTOR "xrstor")
18402          (UNSPECV_XRSTOR64 "xrstor")
18403          (UNSPECV_XRSTORS "xrstors")
18404          (UNSPECV_XRSTORS64 "xrstors")])
18406 (define_insn "<xsave>"
18407   [(set (match_operand:BLK 0 "memory_operand" "=m")
18408         (unspec_volatile:BLK
18409          [(match_operand:DI 1 "register_operand" "A")]
18410          ANY_XSAVE))]
18411   "!TARGET_64BIT && TARGET_XSAVE"
18412   "<xsave>\t%0"
18413   [(set_attr "type" "other")
18414    (set_attr "memory" "store")
18415    (set (attr "length")
18416         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18418 (define_insn "<xsave>_rex64"
18419   [(set (match_operand:BLK 0 "memory_operand" "=m")
18420         (unspec_volatile:BLK
18421          [(match_operand:SI 1 "register_operand" "a")
18422           (match_operand:SI 2 "register_operand" "d")]
18423          ANY_XSAVE))]
18424   "TARGET_64BIT && TARGET_XSAVE"
18425   "<xsave>\t%0"
18426   [(set_attr "type" "other")
18427    (set_attr "memory" "store")
18428    (set (attr "length")
18429         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18431 (define_insn "<xsave>"
18432   [(set (match_operand:BLK 0 "memory_operand" "=m")
18433         (unspec_volatile:BLK
18434          [(match_operand:SI 1 "register_operand" "a")
18435           (match_operand:SI 2 "register_operand" "d")]
18436          ANY_XSAVE64))]
18437   "TARGET_64BIT && TARGET_XSAVE"
18438   "<xsave>\t%0"
18439   [(set_attr "type" "other")
18440    (set_attr "memory" "store")
18441    (set (attr "length")
18442         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18444 (define_insn "<xrstor>"
18445    [(unspec_volatile:BLK
18446      [(match_operand:BLK 0 "memory_operand" "m")
18447       (match_operand:DI 1 "register_operand" "A")]
18448      ANY_XRSTOR)]
18449   "!TARGET_64BIT && TARGET_XSAVE"
18450   "<xrstor>\t%0"
18451   [(set_attr "type" "other")
18452    (set_attr "memory" "load")
18453    (set (attr "length")
18454         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18456 (define_insn "<xrstor>_rex64"
18457    [(unspec_volatile:BLK
18458      [(match_operand:BLK 0 "memory_operand" "m")
18459       (match_operand:SI 1 "register_operand" "a")
18460       (match_operand:SI 2 "register_operand" "d")]
18461      ANY_XRSTOR)]
18462   "TARGET_64BIT && TARGET_XSAVE"
18463   "<xrstor>\t%0"
18464   [(set_attr "type" "other")
18465    (set_attr "memory" "load")
18466    (set (attr "length")
18467         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18469 (define_insn "<xrstor>64"
18470    [(unspec_volatile:BLK
18471      [(match_operand:BLK 0 "memory_operand" "m")
18472       (match_operand:SI 1 "register_operand" "a")
18473       (match_operand:SI 2 "register_operand" "d")]
18474      ANY_XRSTOR64)]
18475   "TARGET_64BIT && TARGET_XSAVE"
18476   "<xrstor>64\t%0"
18477   [(set_attr "type" "other")
18478    (set_attr "memory" "load")
18479    (set (attr "length")
18480         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18482 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18484 ;; Floating-point instructions for atomic compound assignments
18486 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18488 ; Clobber all floating-point registers on environment save and restore
18489 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18490 (define_insn "fnstenv"
18491   [(set (match_operand:BLK 0 "memory_operand" "=m")
18492         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18493    (clobber (reg:HI FPCR_REG))
18494    (clobber (reg:XF ST0_REG))
18495    (clobber (reg:XF ST1_REG))
18496    (clobber (reg:XF ST2_REG))
18497    (clobber (reg:XF ST3_REG))
18498    (clobber (reg:XF ST4_REG))
18499    (clobber (reg:XF ST5_REG))
18500    (clobber (reg:XF ST6_REG))
18501    (clobber (reg:XF ST7_REG))]
18502   "TARGET_80387"
18503   "fnstenv\t%0"
18504   [(set_attr "type" "other")
18505    (set_attr "memory" "store")
18506    (set (attr "length")
18507         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18509 (define_insn "fldenv"
18510   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18511                     UNSPECV_FLDENV)
18512    (clobber (reg:CCFP FPSR_REG))
18513    (clobber (reg:HI FPCR_REG))
18514    (clobber (reg:XF ST0_REG))
18515    (clobber (reg:XF ST1_REG))
18516    (clobber (reg:XF ST2_REG))
18517    (clobber (reg:XF ST3_REG))
18518    (clobber (reg:XF ST4_REG))
18519    (clobber (reg:XF ST5_REG))
18520    (clobber (reg:XF ST6_REG))
18521    (clobber (reg:XF ST7_REG))]
18522   "TARGET_80387"
18523   "fldenv\t%0"
18524   [(set_attr "type" "other")
18525    (set_attr "memory" "load")
18526    (set (attr "length")
18527         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18529 (define_insn "fnstsw"
18530   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18531         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18532   "TARGET_80387"
18533   "fnstsw\t%0"
18534   [(set_attr "type" "other,other")
18535    (set_attr "memory" "none,store")
18536    (set (attr "length")
18537         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18539 (define_insn "fnclex"
18540   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18541   "TARGET_80387"
18542   "fnclex"
18543   [(set_attr "type" "other")
18544    (set_attr "memory" "none")
18545    (set_attr "length" "2")])
18547 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18549 ;; LWP instructions
18551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18553 (define_expand "lwp_llwpcb"
18554   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18555                     UNSPECV_LLWP_INTRINSIC)]
18556   "TARGET_LWP")
18558 (define_insn "*lwp_llwpcb<mode>1"
18559   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18560                     UNSPECV_LLWP_INTRINSIC)]
18561   "TARGET_LWP"
18562   "llwpcb\t%0"
18563   [(set_attr "type" "lwp")
18564    (set_attr "mode" "<MODE>")
18565    (set_attr "length" "5")])
18567 (define_expand "lwp_slwpcb"
18568   [(set (match_operand 0 "register_operand" "=r")
18569         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18570   "TARGET_LWP"
18572   rtx (*insn)(rtx);
18574   insn = (Pmode == DImode
18575           ? gen_lwp_slwpcbdi
18576           : gen_lwp_slwpcbsi);
18578   emit_insn (insn (operands[0]));
18579   DONE;
18582 (define_insn "lwp_slwpcb<mode>"
18583   [(set (match_operand:P 0 "register_operand" "=r")
18584         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18585   "TARGET_LWP"
18586   "slwpcb\t%0"
18587   [(set_attr "type" "lwp")
18588    (set_attr "mode" "<MODE>")
18589    (set_attr "length" "5")])
18591 (define_expand "lwp_lwpval<mode>3"
18592   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18593                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18594                      (match_operand:SI 3 "const_int_operand" "i")]
18595                     UNSPECV_LWPVAL_INTRINSIC)]
18596   "TARGET_LWP"
18597   ;; Avoid unused variable warning.
18598   "(void) operands[0];")
18600 (define_insn "*lwp_lwpval<mode>3_1"
18601   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18602                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18603                      (match_operand:SI 2 "const_int_operand" "i")]
18604                     UNSPECV_LWPVAL_INTRINSIC)]
18605   "TARGET_LWP"
18606   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18607   [(set_attr "type" "lwp")
18608    (set_attr "mode" "<MODE>")
18609    (set (attr "length")
18610         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18612 (define_expand "lwp_lwpins<mode>3"
18613   [(set (reg:CCC FLAGS_REG)
18614         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18615                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18616                               (match_operand:SI 3 "const_int_operand" "i")]
18617                              UNSPECV_LWPINS_INTRINSIC))
18618    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18619         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18620   "TARGET_LWP")
18622 (define_insn "*lwp_lwpins<mode>3_1"
18623   [(set (reg:CCC FLAGS_REG)
18624         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18625                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18626                               (match_operand:SI 2 "const_int_operand" "i")]
18627                              UNSPECV_LWPINS_INTRINSIC))]
18628   "TARGET_LWP"
18629   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18630   [(set_attr "type" "lwp")
18631    (set_attr "mode" "<MODE>")
18632    (set (attr "length")
18633         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18635 (define_int_iterator RDFSGSBASE
18636         [UNSPECV_RDFSBASE
18637          UNSPECV_RDGSBASE])
18639 (define_int_iterator WRFSGSBASE
18640         [UNSPECV_WRFSBASE
18641          UNSPECV_WRGSBASE])
18643 (define_int_attr fsgs
18644         [(UNSPECV_RDFSBASE "fs")
18645          (UNSPECV_RDGSBASE "gs")
18646          (UNSPECV_WRFSBASE "fs")
18647          (UNSPECV_WRGSBASE "gs")])
18649 (define_insn "rd<fsgs>base<mode>"
18650   [(set (match_operand:SWI48 0 "register_operand" "=r")
18651         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18652   "TARGET_64BIT && TARGET_FSGSBASE"
18653   "rd<fsgs>base\t%0"
18654   [(set_attr "type" "other")
18655    (set_attr "prefix_extra" "2")])
18657 (define_insn "wr<fsgs>base<mode>"
18658   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18659                     WRFSGSBASE)]
18660   "TARGET_64BIT && TARGET_FSGSBASE"
18661   "wr<fsgs>base\t%0"
18662   [(set_attr "type" "other")
18663    (set_attr "prefix_extra" "2")])
18665 (define_insn "rdrand<mode>_1"
18666   [(set (match_operand:SWI248 0 "register_operand" "=r")
18667         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18668    (set (reg:CCC FLAGS_REG)
18669         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18670   "TARGET_RDRND"
18671   "rdrand\t%0"
18672   [(set_attr "type" "other")
18673    (set_attr "prefix_extra" "1")])
18675 (define_insn "rdseed<mode>_1"
18676   [(set (match_operand:SWI248 0 "register_operand" "=r")
18677         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18678    (set (reg:CCC FLAGS_REG)
18679         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18680   "TARGET_RDSEED"
18681   "rdseed\t%0"
18682   [(set_attr "type" "other")
18683    (set_attr "prefix_extra" "1")])
18685 (define_expand "pause"
18686   [(set (match_dup 0)
18687         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18688   ""
18690   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18691   MEM_VOLATILE_P (operands[0]) = 1;
18694 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18695 ;; They have the same encoding.
18696 (define_insn "*pause"
18697   [(set (match_operand:BLK 0)
18698         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18699   ""
18700   "rep%; nop"
18701   [(set_attr "length" "2")
18702    (set_attr "memory" "unknown")])
18704 (define_expand "xbegin"
18705   [(set (match_operand:SI 0 "register_operand")
18706         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18707   "TARGET_RTM"
18709   rtx_code_label *label = gen_label_rtx ();
18711   /* xbegin is emitted as jump_insn, so reload won't be able
18712      to reload its operand.  Force the value into AX hard register.  */
18713   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18714   emit_move_insn (ax_reg, constm1_rtx);
18716   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18718   emit_label (label);
18719   LABEL_NUSES (label) = 1;
18721   emit_move_insn (operands[0], ax_reg);
18723   DONE;
18726 (define_insn "xbegin_1"
18727   [(set (pc)
18728         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18729                           (const_int 0))
18730                       (label_ref (match_operand 1))
18731                       (pc)))
18732    (set (match_operand:SI 0 "register_operand" "+a")
18733         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18734   "TARGET_RTM"
18735   "xbegin\t%l1"
18736   [(set_attr "type" "other")
18737    (set_attr "length" "6")])
18739 (define_insn "xend"
18740   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18741   "TARGET_RTM"
18742   "xend"
18743   [(set_attr "type" "other")
18744    (set_attr "length" "3")])
18746 (define_insn "xabort"
18747   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18748                     UNSPECV_XABORT)]
18749   "TARGET_RTM"
18750   "xabort\t%0"
18751   [(set_attr "type" "other")
18752    (set_attr "length" "3")])
18754 (define_expand "xtest"
18755   [(set (match_operand:QI 0 "register_operand")
18756         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18757   "TARGET_RTM"
18759   emit_insn (gen_xtest_1 ());
18761   ix86_expand_setcc (operands[0], NE,
18762                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18763   DONE;
18766 (define_insn "xtest_1"
18767   [(set (reg:CCZ FLAGS_REG)
18768         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18769   "TARGET_RTM"
18770   "xtest"
18771   [(set_attr "type" "other")
18772    (set_attr "length" "3")])
18774 (define_insn "pcommit"
18775   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18776   "TARGET_PCOMMIT"
18777   "pcommit"
18778   [(set_attr "type" "other")
18779    (set_attr "length" "4")])
18781 (define_insn "clwb"
18782   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18783                    UNSPECV_CLWB)]
18784   "TARGET_CLWB"
18785   "clwb\t%a0"
18786   [(set_attr "type" "sse")
18787    (set_attr "atom_sse_attr" "fence")
18788    (set_attr "memory" "unknown")])
18790 (define_insn "clflushopt"
18791   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18792                    UNSPECV_CLFLUSHOPT)]
18793   "TARGET_CLFLUSHOPT"
18794   "clflushopt\t%a0"
18795   [(set_attr "type" "sse")
18796    (set_attr "atom_sse_attr" "fence")
18797    (set_attr "memory" "unknown")])
18799 ;; MPX instructions
18801 (define_expand "<mode>_mk"
18802   [(set (match_operand:BND 0 "register_operand")
18803     (unspec:BND
18804       [(mem:<bnd_ptr>
18805        (match_par_dup 3
18806         [(match_operand:<bnd_ptr> 1 "register_operand")
18807          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18808       UNSPEC_BNDMK))]
18809   "TARGET_MPX"
18811   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18812                                                   operands[2]),
18813                                 UNSPEC_BNDMK_ADDR);
18816 (define_insn "*<mode>_mk"
18817   [(set (match_operand:BND 0 "register_operand" "=w")
18818     (unspec:BND
18819       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18820         [(unspec:<bnd_ptr>
18821            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18822             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18823            UNSPEC_BNDMK_ADDR)])]
18824       UNSPEC_BNDMK))]
18825   "TARGET_MPX"
18826   "bndmk\t{%3, %0|%0, %3}"
18827   [(set_attr "type" "mpxmk")])
18829 (define_expand "mov<mode>"
18830   [(set (match_operand:BND 0 "general_operand")
18831         (match_operand:BND 1 "general_operand"))]
18832   "TARGET_MPX"
18834   ix86_expand_move (<MODE>mode, operands);DONE;
18837 (define_insn "*mov<mode>_internal_mpx"
18838   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18839         (match_operand:BND 1 "general_operand" "wm,w"))]
18840   "TARGET_MPX"
18841   "bndmov\t{%1, %0|%0, %1}"
18842   [(set_attr "type" "mpxmov")])
18844 (define_expand "<mode>_<bndcheck>"
18845   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18846                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18847               (set (match_dup 2)
18848                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18849   "TARGET_MPX"
18851   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18852   MEM_VOLATILE_P (operands[2]) = 1;
18855 (define_insn "*<mode>_<bndcheck>"
18856   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18857                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18858               (set (match_operand:BLK 2 "bnd_mem_operator")
18859                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18860   "TARGET_MPX"
18861   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18862   [(set_attr "type" "mpxchk")])
18864 (define_expand "<mode>_ldx"
18865   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18866                        (unspec:BND
18867                          [(mem:<bnd_ptr>
18868                            (match_par_dup 3
18869                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18870                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18871                          UNSPEC_BNDLDX))
18872               (use (mem:BLK (match_dup 1)))])]
18873   "TARGET_MPX"
18875   /* Avoid registers which connot be used as index.  */
18876   if (!index_register_operand (operands[2], Pmode))
18877     {
18878       rtx temp = gen_reg_rtx (Pmode);
18879       emit_move_insn (temp, operands[2]);
18880       operands[2] = temp;
18881     }
18883   /* If it was a register originally then it may have
18884      mode other than Pmode.  We need to extend in such
18885      case because bndldx may work only with Pmode regs.  */
18886   if (GET_MODE (operands[2]) != Pmode)
18887     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18889   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18890                                                   operands[2]),
18891                                 UNSPEC_BNDLDX_ADDR);
18894 (define_insn "*<mode>_ldx"
18895   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18896                        (unspec:BND
18897                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18898                            [(unspec:<bnd_ptr>
18899                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18900                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18901                             UNSPEC_BNDLDX_ADDR)])]
18902                          UNSPEC_BNDLDX))
18903               (use (mem:BLK (match_dup 1)))])]
18904   "TARGET_MPX"
18905   "bndldx\t{%3, %0|%0, %3}"
18906   [(set_attr "type" "mpxld")])
18908 (define_expand "<mode>_stx"
18909   [(parallel [(unspec [(mem:<bnd_ptr>
18910                          (match_par_dup 3
18911                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18912                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18913                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18914               (set (match_dup 4)
18915                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18916   "TARGET_MPX"
18918   /* Avoid registers which connot be used as index.  */
18919   if (!index_register_operand (operands[1], Pmode))
18920     {
18921       rtx temp = gen_reg_rtx (Pmode);
18922       emit_move_insn (temp, operands[1]);
18923       operands[1] = temp;
18924     }
18926   /* If it was a register originally then it may have
18927      mode other than Pmode.  We need to extend in such
18928      case because bndstx may work only with Pmode regs.  */
18929   if (GET_MODE (operands[1]) != Pmode)
18930     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18932   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18933                                                   operands[1]),
18934                                 UNSPEC_BNDLDX_ADDR);
18935   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18936   MEM_VOLATILE_P (operands[4]) = 1;
18939 (define_insn "*<mode>_stx"
18940   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18941                          [(unspec:<bnd_ptr>
18942                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18943                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18944                          UNSPEC_BNDLDX_ADDR)])
18945                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18946               (set (match_operand:BLK 4 "bnd_mem_operator")
18947                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18948   "TARGET_MPX"
18949   "bndstx\t{%2, %3|%3, %2}"
18950   [(set_attr "type" "mpxst")])
18952 (define_insn "move_size_reloc_<mode>"
18953   [(set (match_operand:SWI48 0 "register_operand" "=r")
18954        (unspec:SWI48
18955         [(match_operand:SWI48 1 "symbol_operand")]
18956         UNSPEC_SIZEOF))]
18957   "TARGET_MPX"
18959   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18960     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18961   else
18962     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18964   [(set_attr "type" "imov")
18965    (set_attr "mode" "<MODE>")])
18967 (include "mmx.md")
18968 (include "sse.md")
18969 (include "sync.md")