* config/i386/i386.c: Use HOST_WIDE_INT_1 instead of (HOST_WIDE_INT) 1
[official-gcc.git] / gcc / config / i386 / i386.md
blob0e941b6be6683a290db7296e3281291c8434e637
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        < (HOST_WIDE_INT_1U << 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 (match_operand:SWI48 1 "register_operand" "r,r"))
12559           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12560    (clobber (reg:CC FLAGS_REG))]
12561   "TARGET_BMI"
12562   "andn\t{%2, %1, %0|%0, %1, %2}"
12563   [(set_attr "type" "bitmanip")
12564    (set_attr "btver2_decode" "direct, double")
12565    (set_attr "mode" "<MODE>")])
12567 (define_insn "*bmi_andn_<mode>_ccno"
12568   [(set (reg FLAGS_REG)
12569         (compare
12570           (and:SWI48
12571             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12572             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12573           (const_int 0)))
12574    (clobber (match_scratch:SWI48 0 "=r,r"))]
12575   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12576   "andn\t{%2, %1, %0|%0, %1, %2}"
12577   [(set_attr "type" "bitmanip")
12578    (set_attr "btver2_decode" "direct, double")
12579    (set_attr "mode" "<MODE>")])
12581 (define_insn "bmi_bextr_<mode>"
12582   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12583         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12584                        (match_operand:SWI48 2 "register_operand" "r,r")]
12585                       UNSPEC_BEXTR))
12586    (clobber (reg:CC FLAGS_REG))]
12587   "TARGET_BMI"
12588   "bextr\t{%2, %1, %0|%0, %1, %2}"
12589   [(set_attr "type" "bitmanip")
12590    (set_attr "btver2_decode" "direct, double")
12591    (set_attr "mode" "<MODE>")])
12593 (define_insn "*bmi_bextr_<mode>_ccz"
12594   [(set (reg:CCZ FLAGS_REG)
12595         (compare:CCZ
12596           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12597                          (match_operand:SWI48 2 "register_operand" "r,r")]
12598                         UNSPEC_BEXTR)
12599           (const_int 0)))
12600    (clobber (match_scratch:SWI48 0 "=r,r"))]
12601   "TARGET_BMI"
12602   "bextr\t{%2, %1, %0|%0, %1, %2}"
12603   [(set_attr "type" "bitmanip")
12604    (set_attr "btver2_decode" "direct, double")
12605    (set_attr "mode" "<MODE>")])
12607 (define_insn "*bmi_blsi_<mode>"
12608   [(set (match_operand:SWI48 0 "register_operand" "=r")
12609         (and:SWI48
12610           (neg:SWI48
12611             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12612           (match_dup 1)))
12613    (clobber (reg:CC FLAGS_REG))]
12614   "TARGET_BMI"
12615   "blsi\t{%1, %0|%0, %1}"
12616   [(set_attr "type" "bitmanip")
12617    (set_attr "btver2_decode" "double")
12618    (set_attr "mode" "<MODE>")])
12620 (define_insn "*bmi_blsmsk_<mode>"
12621   [(set (match_operand:SWI48 0 "register_operand" "=r")
12622         (xor:SWI48
12623           (plus:SWI48
12624             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12625             (const_int -1))
12626           (match_dup 1)))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "TARGET_BMI"
12629   "blsmsk\t{%1, %0|%0, %1}"
12630   [(set_attr "type" "bitmanip")
12631    (set_attr "btver2_decode" "double")
12632    (set_attr "mode" "<MODE>")])
12634 (define_insn "*bmi_blsr_<mode>"
12635   [(set (match_operand:SWI48 0 "register_operand" "=r")
12636         (and:SWI48
12637           (plus:SWI48
12638             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12639             (const_int -1))
12640           (match_dup 1)))
12641    (clobber (reg:CC FLAGS_REG))]
12642    "TARGET_BMI"
12643    "blsr\t{%1, %0|%0, %1}"
12644   [(set_attr "type" "bitmanip")
12645    (set_attr "btver2_decode" "double")
12646    (set_attr "mode" "<MODE>")])
12648 ;; BMI2 instructions.
12649 (define_expand "bmi2_bzhi_<mode>3"
12650   [(parallel
12651     [(set (match_operand:SWI48 0 "register_operand")
12652           (zero_extract:SWI48
12653             (match_operand:SWI48 1 "nonimmediate_operand")
12654             (umin:SWI48
12655               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12656                          (const_int 255))
12657               (match_dup 3))
12658             (const_int 0)))
12659      (clobber (reg:CC FLAGS_REG))])]
12660   "TARGET_BMI2"
12661   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12663 (define_insn "*bmi2_bzhi_<mode>3"
12664   [(set (match_operand:SWI48 0 "register_operand" "=r")
12665         (zero_extract:SWI48
12666           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12667           (umin:SWI48
12668             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12669                        (const_int 255))
12670             (match_operand:SWI48 3 "const_int_operand" "n"))
12671           (const_int 0)))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12674   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12675   [(set_attr "type" "bitmanip")
12676    (set_attr "prefix" "vex")
12677    (set_attr "mode" "<MODE>")])
12679 (define_mode_attr k [(SI "k") (DI "q")])
12681 (define_insn "*bmi2_bzhi_<mode>3_1"
12682   [(set (match_operand:SWI48 0 "register_operand" "=r")
12683         (zero_extract:SWI48
12684           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12685           (umin:SWI48
12686             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12687             (match_operand:SWI48 3 "const_int_operand" "n"))
12688           (const_int 0)))
12689    (clobber (reg:CC FLAGS_REG))]
12690   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12691   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12692   [(set_attr "type" "bitmanip")
12693    (set_attr "prefix" "vex")
12694    (set_attr "mode" "<MODE>")])
12696 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12697   [(set (reg:CCZ FLAGS_REG)
12698         (compare:CCZ
12699           (zero_extract:SWI48
12700             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12701             (umin:SWI48
12702               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12703               (match_operand:SWI48 3 "const_int_operand" "n"))
12704             (const_int 0))
12705         (const_int 0)))
12706    (clobber (match_scratch:SWI48 0 "=r"))]
12707   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12708   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12709   [(set_attr "type" "bitmanip")
12710    (set_attr "prefix" "vex")
12711    (set_attr "mode" "<MODE>")])
12713 (define_insn "bmi2_pdep_<mode>3"
12714   [(set (match_operand:SWI48 0 "register_operand" "=r")
12715         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12716                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12717                        UNSPEC_PDEP))]
12718   "TARGET_BMI2"
12719   "pdep\t{%2, %1, %0|%0, %1, %2}"
12720   [(set_attr "type" "bitmanip")
12721    (set_attr "prefix" "vex")
12722    (set_attr "mode" "<MODE>")])
12724 (define_insn "bmi2_pext_<mode>3"
12725   [(set (match_operand:SWI48 0 "register_operand" "=r")
12726         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12727                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12728                        UNSPEC_PEXT))]
12729   "TARGET_BMI2"
12730   "pext\t{%2, %1, %0|%0, %1, %2}"
12731   [(set_attr "type" "bitmanip")
12732    (set_attr "prefix" "vex")
12733    (set_attr "mode" "<MODE>")])
12735 ;; TBM instructions.
12736 (define_insn "tbm_bextri_<mode>"
12737   [(set (match_operand:SWI48 0 "register_operand" "=r")
12738         (zero_extract:SWI48
12739           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12740           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12741           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12742    (clobber (reg:CC FLAGS_REG))]
12743    "TARGET_TBM"
12745   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12746   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12748   [(set_attr "type" "bitmanip")
12749    (set_attr "mode" "<MODE>")])
12751 (define_insn "*tbm_blcfill_<mode>"
12752   [(set (match_operand:SWI48 0 "register_operand" "=r")
12753         (and:SWI48
12754           (plus:SWI48
12755             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12756             (const_int 1))
12757           (match_dup 1)))
12758    (clobber (reg:CC FLAGS_REG))]
12759    "TARGET_TBM"
12760    "blcfill\t{%1, %0|%0, %1}"
12761   [(set_attr "type" "bitmanip")
12762    (set_attr "mode" "<MODE>")])
12764 (define_insn "*tbm_blci_<mode>"
12765   [(set (match_operand:SWI48 0 "register_operand" "=r")
12766         (ior:SWI48
12767           (not:SWI48
12768             (plus:SWI48
12769               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12770               (const_int 1)))
12771           (match_dup 1)))
12772    (clobber (reg:CC FLAGS_REG))]
12773    "TARGET_TBM"
12774    "blci\t{%1, %0|%0, %1}"
12775   [(set_attr "type" "bitmanip")
12776    (set_attr "mode" "<MODE>")])
12778 (define_insn "*tbm_blcic_<mode>"
12779   [(set (match_operand:SWI48 0 "register_operand" "=r")
12780         (and:SWI48
12781           (plus:SWI48
12782             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12783             (const_int 1))
12784           (not:SWI48
12785             (match_dup 1))))
12786    (clobber (reg:CC FLAGS_REG))]
12787    "TARGET_TBM"
12788    "blcic\t{%1, %0|%0, %1}"
12789   [(set_attr "type" "bitmanip")
12790    (set_attr "mode" "<MODE>")])
12792 (define_insn "*tbm_blcmsk_<mode>"
12793   [(set (match_operand:SWI48 0 "register_operand" "=r")
12794         (xor: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    "blcmsk\t{%1, %0|%0, %1}"
12802   [(set_attr "type" "bitmanip")
12803    (set_attr "mode" "<MODE>")])
12805 (define_insn "*tbm_blcs_<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    "blcs\t{%1, %0|%0, %1}"
12815   [(set_attr "type" "bitmanip")
12816    (set_attr "mode" "<MODE>")])
12818 (define_insn "*tbm_blsfill_<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           (match_dup 1)))
12825    (clobber (reg:CC FLAGS_REG))]
12826    "TARGET_TBM"
12827    "blsfill\t{%1, %0|%0, %1}"
12828   [(set_attr "type" "bitmanip")
12829    (set_attr "mode" "<MODE>")])
12831 (define_insn "*tbm_blsic_<mode>"
12832   [(set (match_operand:SWI48 0 "register_operand" "=r")
12833         (ior:SWI48
12834           (plus:SWI48
12835             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12836             (const_int -1))
12837           (not:SWI48
12838             (match_dup 1))))
12839    (clobber (reg:CC FLAGS_REG))]
12840    "TARGET_TBM"
12841    "blsic\t{%1, %0|%0, %1}"
12842   [(set_attr "type" "bitmanip")
12843    (set_attr "mode" "<MODE>")])
12845 (define_insn "*tbm_t1mskc_<mode>"
12846   [(set (match_operand:SWI48 0 "register_operand" "=r")
12847         (ior:SWI48
12848           (plus:SWI48
12849             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12850             (const_int 1))
12851           (not:SWI48
12852             (match_dup 1))))
12853    (clobber (reg:CC FLAGS_REG))]
12854    "TARGET_TBM"
12855    "t1mskc\t{%1, %0|%0, %1}"
12856   [(set_attr "type" "bitmanip")
12857    (set_attr "mode" "<MODE>")])
12859 (define_insn "*tbm_tzmsk_<mode>"
12860   [(set (match_operand:SWI48 0 "register_operand" "=r")
12861         (and:SWI48
12862           (plus:SWI48
12863             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12864             (const_int -1))
12865           (not:SWI48
12866             (match_dup 1))))
12867    (clobber (reg:CC FLAGS_REG))]
12868    "TARGET_TBM"
12869    "tzmsk\t{%1, %0|%0, %1}"
12870   [(set_attr "type" "bitmanip")
12871    (set_attr "mode" "<MODE>")])
12873 (define_insn "bsr_rex64"
12874   [(set (match_operand:DI 0 "register_operand" "=r")
12875         (minus:DI (const_int 63)
12876                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12877    (clobber (reg:CC FLAGS_REG))]
12878   "TARGET_64BIT"
12879   "bsr{q}\t{%1, %0|%0, %1}"
12880   [(set_attr "type" "alu1")
12881    (set_attr "prefix_0f" "1")
12882    (set_attr "mode" "DI")])
12884 (define_insn "bsr"
12885   [(set (match_operand:SI 0 "register_operand" "=r")
12886         (minus:SI (const_int 31)
12887                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12888    (clobber (reg:CC FLAGS_REG))]
12889   ""
12890   "bsr{l}\t{%1, %0|%0, %1}"
12891   [(set_attr "type" "alu1")
12892    (set_attr "prefix_0f" "1")
12893    (set_attr "mode" "SI")])
12895 (define_insn "*bsrhi"
12896   [(set (match_operand:HI 0 "register_operand" "=r")
12897         (minus:HI (const_int 15)
12898                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12899    (clobber (reg:CC FLAGS_REG))]
12900   ""
12901   "bsr{w}\t{%1, %0|%0, %1}"
12902   [(set_attr "type" "alu1")
12903    (set_attr "prefix_0f" "1")
12904    (set_attr "mode" "HI")])
12906 (define_expand "popcount<mode>2"
12907   [(parallel
12908     [(set (match_operand:SWI248 0 "register_operand")
12909           (popcount:SWI248
12910             (match_operand:SWI248 1 "nonimmediate_operand")))
12911      (clobber (reg:CC FLAGS_REG))])]
12912   "TARGET_POPCNT")
12914 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12915   [(set (match_operand:SWI48 0 "register_operand" "=r")
12916         (popcount:SWI48
12917           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12918    (clobber (reg:CC FLAGS_REG))]
12919   "TARGET_POPCNT
12920    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12921   "#"
12922   "&& reload_completed"
12923   [(parallel
12924     [(set (match_dup 0)
12925           (popcount:SWI48 (match_dup 1)))
12926      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12927      (clobber (reg:CC FLAGS_REG))])]
12929   if (!reg_mentioned_p (operands[0], operands[1]))
12930     ix86_expand_clear (operands[0]);
12933 (define_insn "*popcount<mode>2_falsedep"
12934   [(set (match_operand:SWI48 0 "register_operand" "=r")
12935         (popcount:SWI48
12936           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12937    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12938            UNSPEC_INSN_FALSE_DEP)
12939    (clobber (reg:CC FLAGS_REG))]
12940   "TARGET_POPCNT"
12942 #if TARGET_MACHO
12943   return "popcnt\t{%1, %0|%0, %1}";
12944 #else
12945   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12946 #endif
12948   [(set_attr "prefix_rep" "1")
12949    (set_attr "type" "bitmanip")
12950    (set_attr "mode" "<MODE>")])
12952 (define_insn "*popcount<mode>2"
12953   [(set (match_operand:SWI248 0 "register_operand" "=r")
12954         (popcount:SWI248
12955           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "TARGET_POPCNT"
12959 #if TARGET_MACHO
12960   return "popcnt\t{%1, %0|%0, %1}";
12961 #else
12962   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12963 #endif
12965   [(set_attr "prefix_rep" "1")
12966    (set_attr "type" "bitmanip")
12967    (set_attr "mode" "<MODE>")])
12969 (define_expand "bswapdi2"
12970   [(set (match_operand:DI 0 "register_operand")
12971         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12972   "TARGET_64BIT"
12974   if (!TARGET_MOVBE)
12975     operands[1] = force_reg (DImode, operands[1]);
12978 (define_expand "bswapsi2"
12979   [(set (match_operand:SI 0 "register_operand")
12980         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12981   ""
12983   if (TARGET_MOVBE)
12984     ;
12985   else if (TARGET_BSWAP)
12986     operands[1] = force_reg (SImode, operands[1]);
12987   else
12988     {
12989       rtx x = operands[0];
12991       emit_move_insn (x, operands[1]);
12992       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12993       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12994       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12995       DONE;
12996     }
12999 (define_insn "*bswap<mode>2_movbe"
13000   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13001         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13002   "TARGET_MOVBE
13003    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13004   "@
13005     bswap\t%0
13006     movbe\t{%1, %0|%0, %1}
13007     movbe\t{%1, %0|%0, %1}"
13008   [(set_attr "type" "bitmanip,imov,imov")
13009    (set_attr "modrm" "0,1,1")
13010    (set_attr "prefix_0f" "*,1,1")
13011    (set_attr "prefix_extra" "*,1,1")
13012    (set_attr "mode" "<MODE>")])
13014 (define_insn "*bswap<mode>2"
13015   [(set (match_operand:SWI48 0 "register_operand" "=r")
13016         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13017   "TARGET_BSWAP"
13018   "bswap\t%0"
13019   [(set_attr "type" "bitmanip")
13020    (set_attr "modrm" "0")
13021    (set_attr "mode" "<MODE>")])
13023 (define_insn "*bswaphi_lowpart_1"
13024   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13025         (bswap:HI (match_dup 0)))
13026    (clobber (reg:CC FLAGS_REG))]
13027   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13028   "@
13029     xchg{b}\t{%h0, %b0|%b0, %h0}
13030     rol{w}\t{$8, %0|%0, 8}"
13031   [(set_attr "length" "2,4")
13032    (set_attr "mode" "QI,HI")])
13034 (define_insn "bswaphi_lowpart"
13035   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13036         (bswap:HI (match_dup 0)))
13037    (clobber (reg:CC FLAGS_REG))]
13038   ""
13039   "rol{w}\t{$8, %0|%0, 8}"
13040   [(set_attr "length" "4")
13041    (set_attr "mode" "HI")])
13043 (define_expand "paritydi2"
13044   [(set (match_operand:DI 0 "register_operand")
13045         (parity:DI (match_operand:DI 1 "register_operand")))]
13046   "! TARGET_POPCNT"
13048   rtx scratch = gen_reg_rtx (QImode);
13049   rtx cond;
13051   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13052                                 NULL_RTX, operands[1]));
13054   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13055                          gen_rtx_REG (CCmode, FLAGS_REG),
13056                          const0_rtx);
13057   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13059   if (TARGET_64BIT)
13060     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13061   else
13062     {
13063       rtx tmp = gen_reg_rtx (SImode);
13065       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13066       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13067     }
13068   DONE;
13071 (define_expand "paritysi2"
13072   [(set (match_operand:SI 0 "register_operand")
13073         (parity:SI (match_operand:SI 1 "register_operand")))]
13074   "! TARGET_POPCNT"
13076   rtx scratch = gen_reg_rtx (QImode);
13077   rtx cond;
13079   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13081   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13082                          gen_rtx_REG (CCmode, FLAGS_REG),
13083                          const0_rtx);
13084   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13086   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13087   DONE;
13090 (define_insn_and_split "paritydi2_cmp"
13091   [(set (reg:CC FLAGS_REG)
13092         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13093                    UNSPEC_PARITY))
13094    (clobber (match_scratch:DI 0 "=r"))
13095    (clobber (match_scratch:SI 1 "=&r"))
13096    (clobber (match_scratch:HI 2 "=Q"))]
13097   "! TARGET_POPCNT"
13098   "#"
13099   "&& reload_completed"
13100   [(parallel
13101      [(set (match_dup 1)
13102            (xor:SI (match_dup 1) (match_dup 4)))
13103       (clobber (reg:CC FLAGS_REG))])
13104    (parallel
13105      [(set (reg:CC FLAGS_REG)
13106            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13107       (clobber (match_dup 1))
13108       (clobber (match_dup 2))])]
13110   operands[4] = gen_lowpart (SImode, operands[3]);
13112   if (TARGET_64BIT)
13113     {
13114       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13115       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13116     }
13117   else
13118     operands[1] = gen_highpart (SImode, operands[3]);
13121 (define_insn_and_split "paritysi2_cmp"
13122   [(set (reg:CC FLAGS_REG)
13123         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13124                    UNSPEC_PARITY))
13125    (clobber (match_scratch:SI 0 "=r"))
13126    (clobber (match_scratch:HI 1 "=&Q"))]
13127   "! TARGET_POPCNT"
13128   "#"
13129   "&& reload_completed"
13130   [(parallel
13131      [(set (match_dup 1)
13132            (xor:HI (match_dup 1) (match_dup 3)))
13133       (clobber (reg:CC FLAGS_REG))])
13134    (parallel
13135      [(set (reg:CC FLAGS_REG)
13136            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13137       (clobber (match_dup 1))])]
13139   operands[3] = gen_lowpart (HImode, operands[2]);
13141   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13142   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13145 (define_insn "*parityhi2_cmp"
13146   [(set (reg:CC FLAGS_REG)
13147         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13148                    UNSPEC_PARITY))
13149    (clobber (match_scratch:HI 0 "=Q"))]
13150   "! TARGET_POPCNT"
13151   "xor{b}\t{%h0, %b0|%b0, %h0}"
13152   [(set_attr "length" "2")
13153    (set_attr "mode" "HI")])
13156 ;; Thread-local storage patterns for ELF.
13158 ;; Note that these code sequences must appear exactly as shown
13159 ;; in order to allow linker relaxation.
13161 (define_insn "*tls_global_dynamic_32_gnu"
13162   [(set (match_operand:SI 0 "register_operand" "=a")
13163         (unspec:SI
13164          [(match_operand:SI 1 "register_operand" "b")
13165           (match_operand 2 "tls_symbolic_operand")
13166           (match_operand 3 "constant_call_address_operand" "Bz")
13167           (reg:SI SP_REG)]
13168          UNSPEC_TLS_GD))
13169    (clobber (match_scratch:SI 4 "=d"))
13170    (clobber (match_scratch:SI 5 "=c"))
13171    (clobber (reg:CC FLAGS_REG))]
13172   "!TARGET_64BIT && TARGET_GNU_TLS"
13174   output_asm_insn
13175     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13176   if (TARGET_SUN_TLS)
13177 #ifdef HAVE_AS_IX86_TLSGDPLT
13178     return "call\t%a2@tlsgdplt";
13179 #else
13180     return "call\t%p3@plt";
13181 #endif
13182   return "call\t%P3";
13184   [(set_attr "type" "multi")
13185    (set_attr "length" "12")])
13187 (define_expand "tls_global_dynamic_32"
13188   [(parallel
13189     [(set (match_operand:SI 0 "register_operand")
13190           (unspec:SI [(match_operand:SI 2 "register_operand")
13191                       (match_operand 1 "tls_symbolic_operand")
13192                       (match_operand 3 "constant_call_address_operand")
13193                       (reg:SI SP_REG)]
13194                      UNSPEC_TLS_GD))
13195      (clobber (match_scratch:SI 4))
13196      (clobber (match_scratch:SI 5))
13197      (clobber (reg:CC FLAGS_REG))])]
13198   ""
13199   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13201 (define_insn "*tls_global_dynamic_64_<mode>"
13202   [(set (match_operand:P 0 "register_operand" "=a")
13203         (call:P
13204          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13205          (match_operand 3)))
13206    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13207              UNSPEC_TLS_GD)]
13208   "TARGET_64BIT"
13210   if (!TARGET_X32)
13211     fputs (ASM_BYTE "0x66\n", asm_out_file);
13212   output_asm_insn
13213     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13214   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13215   fputs ("\trex64\n", asm_out_file);
13216   if (TARGET_SUN_TLS)
13217     return "call\t%p2@plt";
13218   return "call\t%P2";
13220   [(set_attr "type" "multi")
13221    (set (attr "length")
13222         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13224 (define_insn "*tls_global_dynamic_64_largepic"
13225   [(set (match_operand:DI 0 "register_operand" "=a")
13226         (call:DI
13227          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13228                           (match_operand:DI 3 "immediate_operand" "i")))
13229          (match_operand 4)))
13230    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13231              UNSPEC_TLS_GD)]
13232   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13233    && GET_CODE (operands[3]) == CONST
13234    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13235    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13237   output_asm_insn
13238     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13239   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13240   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13241   return "call\t{*%%rax|rax}";
13243   [(set_attr "type" "multi")
13244    (set_attr "length" "22")])
13246 (define_expand "tls_global_dynamic_64_<mode>"
13247   [(parallel
13248     [(set (match_operand:P 0 "register_operand")
13249           (call:P
13250            (mem:QI (match_operand 2))
13251            (const_int 0)))
13252      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13253                UNSPEC_TLS_GD)])]
13254   "TARGET_64BIT"
13255   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13257 (define_insn "*tls_local_dynamic_base_32_gnu"
13258   [(set (match_operand:SI 0 "register_operand" "=a")
13259         (unspec:SI
13260          [(match_operand:SI 1 "register_operand" "b")
13261           (match_operand 2 "constant_call_address_operand" "Bz")
13262           (reg:SI SP_REG)]
13263          UNSPEC_TLS_LD_BASE))
13264    (clobber (match_scratch:SI 3 "=d"))
13265    (clobber (match_scratch:SI 4 "=c"))
13266    (clobber (reg:CC FLAGS_REG))]
13267   "!TARGET_64BIT && TARGET_GNU_TLS"
13269   output_asm_insn
13270     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13271   if (TARGET_SUN_TLS)
13272     {
13273       if (HAVE_AS_IX86_TLSLDMPLT)
13274         return "call\t%&@tlsldmplt";
13275       else
13276         return "call\t%p2@plt";
13277     }
13278   return "call\t%P2";
13280   [(set_attr "type" "multi")
13281    (set_attr "length" "11")])
13283 (define_expand "tls_local_dynamic_base_32"
13284   [(parallel
13285      [(set (match_operand:SI 0 "register_operand")
13286            (unspec:SI
13287             [(match_operand:SI 1 "register_operand")
13288              (match_operand 2 "constant_call_address_operand")
13289              (reg:SI SP_REG)]
13290             UNSPEC_TLS_LD_BASE))
13291       (clobber (match_scratch:SI 3))
13292       (clobber (match_scratch:SI 4))
13293       (clobber (reg:CC FLAGS_REG))])]
13294   ""
13295   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13297 (define_insn "*tls_local_dynamic_base_64_<mode>"
13298   [(set (match_operand:P 0 "register_operand" "=a")
13299         (call:P
13300          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13301          (match_operand 2)))
13302    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13303   "TARGET_64BIT"
13305   output_asm_insn
13306     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13307   if (TARGET_SUN_TLS)
13308     return "call\t%p1@plt";
13309   return "call\t%P1";
13311   [(set_attr "type" "multi")
13312    (set_attr "length" "12")])
13314 (define_insn "*tls_local_dynamic_base_64_largepic"
13315   [(set (match_operand:DI 0 "register_operand" "=a")
13316         (call:DI
13317          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13318                           (match_operand:DI 2 "immediate_operand" "i")))
13319          (match_operand 3)))
13320    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13321   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13322    && GET_CODE (operands[2]) == CONST
13323    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13324    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13326   output_asm_insn
13327     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13328   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13329   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13330   return "call\t{*%%rax|rax}";
13332   [(set_attr "type" "multi")
13333    (set_attr "length" "22")])
13335 (define_expand "tls_local_dynamic_base_64_<mode>"
13336   [(parallel
13337      [(set (match_operand:P 0 "register_operand")
13338            (call:P
13339             (mem:QI (match_operand 1))
13340             (const_int 0)))
13341       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13342   "TARGET_64BIT"
13343   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13345 ;; Local dynamic of a single variable is a lose.  Show combine how
13346 ;; to convert that back to global dynamic.
13348 (define_insn_and_split "*tls_local_dynamic_32_once"
13349   [(set (match_operand:SI 0 "register_operand" "=a")
13350         (plus:SI
13351          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13352                      (match_operand 2 "constant_call_address_operand" "Bz")
13353                      (reg:SI SP_REG)]
13354                     UNSPEC_TLS_LD_BASE)
13355          (const:SI (unspec:SI
13356                     [(match_operand 3 "tls_symbolic_operand")]
13357                     UNSPEC_DTPOFF))))
13358    (clobber (match_scratch:SI 4 "=d"))
13359    (clobber (match_scratch:SI 5 "=c"))
13360    (clobber (reg:CC FLAGS_REG))]
13361   ""
13362   "#"
13363   ""
13364   [(parallel
13365      [(set (match_dup 0)
13366            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13367                        (reg:SI SP_REG)]
13368                       UNSPEC_TLS_GD))
13369       (clobber (match_dup 4))
13370       (clobber (match_dup 5))
13371       (clobber (reg:CC FLAGS_REG))])])
13373 ;; Segment register for the thread base ptr load
13374 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13376 ;; Load and add the thread base pointer from %<tp_seg>:0.
13377 (define_insn "*load_tp_x32"
13378   [(set (match_operand:SI 0 "register_operand" "=r")
13379         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13380   "TARGET_X32"
13381   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13382   [(set_attr "type" "imov")
13383    (set_attr "modrm" "0")
13384    (set_attr "length" "7")
13385    (set_attr "memory" "load")
13386    (set_attr "imm_disp" "false")])
13388 (define_insn "*load_tp_x32_zext"
13389   [(set (match_operand:DI 0 "register_operand" "=r")
13390         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13391   "TARGET_X32"
13392   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13393   [(set_attr "type" "imov")
13394    (set_attr "modrm" "0")
13395    (set_attr "length" "7")
13396    (set_attr "memory" "load")
13397    (set_attr "imm_disp" "false")])
13399 (define_insn "*load_tp_<mode>"
13400   [(set (match_operand:P 0 "register_operand" "=r")
13401         (unspec:P [(const_int 0)] UNSPEC_TP))]
13402   "!TARGET_X32"
13403   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13404   [(set_attr "type" "imov")
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"
13411   [(set (match_operand:SI 0 "register_operand" "=r")
13412         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13413                  (match_operand:SI 1 "register_operand" "0")))
13414    (clobber (reg:CC FLAGS_REG))]
13415   "TARGET_X32"
13416   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13417   [(set_attr "type" "alu")
13418    (set_attr "modrm" "0")
13419    (set_attr "length" "7")
13420    (set_attr "memory" "load")
13421    (set_attr "imm_disp" "false")])
13423 (define_insn "*add_tp_x32_zext"
13424   [(set (match_operand:DI 0 "register_operand" "=r")
13425         (zero_extend:DI
13426           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13427                    (match_operand:SI 1 "register_operand" "0"))))
13428    (clobber (reg:CC FLAGS_REG))]
13429   "TARGET_X32"
13430   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs: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 (define_insn "*add_tp_<mode>"
13438   [(set (match_operand:P 0 "register_operand" "=r")
13439         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13440                 (match_operand:P 1 "register_operand" "0")))
13441    (clobber (reg:CC FLAGS_REG))]
13442   "!TARGET_X32"
13443   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13444   [(set_attr "type" "alu")
13445    (set_attr "modrm" "0")
13446    (set_attr "length" "7")
13447    (set_attr "memory" "load")
13448    (set_attr "imm_disp" "false")])
13450 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13451 ;; %rax as destination of the initial executable code sequence.
13452 (define_insn "tls_initial_exec_64_sun"
13453   [(set (match_operand:DI 0 "register_operand" "=a")
13454         (unspec:DI
13455          [(match_operand 1 "tls_symbolic_operand")]
13456          UNSPEC_TLS_IE_SUN))
13457    (clobber (reg:CC FLAGS_REG))]
13458   "TARGET_64BIT && TARGET_SUN_TLS"
13460   output_asm_insn
13461     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13462   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13464   [(set_attr "type" "multi")])
13466 ;; GNU2 TLS patterns can be split.
13468 (define_expand "tls_dynamic_gnu2_32"
13469   [(set (match_dup 3)
13470         (plus:SI (match_operand:SI 2 "register_operand")
13471                  (const:SI
13472                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13473                              UNSPEC_TLSDESC))))
13474    (parallel
13475     [(set (match_operand:SI 0 "register_operand")
13476           (unspec:SI [(match_dup 1) (match_dup 3)
13477                       (match_dup 2) (reg:SI SP_REG)]
13478                       UNSPEC_TLSDESC))
13479      (clobber (reg:CC FLAGS_REG))])]
13480   "!TARGET_64BIT && TARGET_GNU2_TLS"
13482   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13483   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13486 (define_insn "*tls_dynamic_gnu2_lea_32"
13487   [(set (match_operand:SI 0 "register_operand" "=r")
13488         (plus:SI (match_operand:SI 1 "register_operand" "b")
13489                  (const:SI
13490                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13491                               UNSPEC_TLSDESC))))]
13492   "!TARGET_64BIT && TARGET_GNU2_TLS"
13493   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13494   [(set_attr "type" "lea")
13495    (set_attr "mode" "SI")
13496    (set_attr "length" "6")
13497    (set_attr "length_address" "4")])
13499 (define_insn "*tls_dynamic_gnu2_call_32"
13500   [(set (match_operand:SI 0 "register_operand" "=a")
13501         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13502                     (match_operand:SI 2 "register_operand" "0")
13503                     ;; we have to make sure %ebx still points to the GOT
13504                     (match_operand:SI 3 "register_operand" "b")
13505                     (reg:SI SP_REG)]
13506                    UNSPEC_TLSDESC))
13507    (clobber (reg:CC FLAGS_REG))]
13508   "!TARGET_64BIT && TARGET_GNU2_TLS"
13509   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13510   [(set_attr "type" "call")
13511    (set_attr "length" "2")
13512    (set_attr "length_address" "0")])
13514 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13515   [(set (match_operand:SI 0 "register_operand" "=&a")
13516         (plus:SI
13517          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13518                      (match_operand:SI 4)
13519                      (match_operand:SI 2 "register_operand" "b")
13520                      (reg:SI SP_REG)]
13521                     UNSPEC_TLSDESC)
13522          (const:SI (unspec:SI
13523                     [(match_operand 1 "tls_symbolic_operand")]
13524                     UNSPEC_DTPOFF))))
13525    (clobber (reg:CC FLAGS_REG))]
13526   "!TARGET_64BIT && TARGET_GNU2_TLS"
13527   "#"
13528   ""
13529   [(set (match_dup 0) (match_dup 5))]
13531   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13532   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13535 (define_expand "tls_dynamic_gnu2_64"
13536   [(set (match_dup 2)
13537         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13538                    UNSPEC_TLSDESC))
13539    (parallel
13540     [(set (match_operand:DI 0 "register_operand")
13541           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13542                      UNSPEC_TLSDESC))
13543      (clobber (reg:CC FLAGS_REG))])]
13544   "TARGET_64BIT && TARGET_GNU2_TLS"
13546   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13547   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13550 (define_insn "*tls_dynamic_gnu2_lea_64"
13551   [(set (match_operand:DI 0 "register_operand" "=r")
13552         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13553                    UNSPEC_TLSDESC))]
13554   "TARGET_64BIT && TARGET_GNU2_TLS"
13555   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13556   [(set_attr "type" "lea")
13557    (set_attr "mode" "DI")
13558    (set_attr "length" "7")
13559    (set_attr "length_address" "4")])
13561 (define_insn "*tls_dynamic_gnu2_call_64"
13562   [(set (match_operand:DI 0 "register_operand" "=a")
13563         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13564                     (match_operand:DI 2 "register_operand" "0")
13565                     (reg:DI SP_REG)]
13566                    UNSPEC_TLSDESC))
13567    (clobber (reg:CC FLAGS_REG))]
13568   "TARGET_64BIT && TARGET_GNU2_TLS"
13569   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13570   [(set_attr "type" "call")
13571    (set_attr "length" "2")
13572    (set_attr "length_address" "0")])
13574 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13575   [(set (match_operand:DI 0 "register_operand" "=&a")
13576         (plus:DI
13577          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13578                      (match_operand:DI 3)
13579                      (reg:DI SP_REG)]
13580                     UNSPEC_TLSDESC)
13581          (const:DI (unspec:DI
13582                     [(match_operand 1 "tls_symbolic_operand")]
13583                     UNSPEC_DTPOFF))))
13584    (clobber (reg:CC FLAGS_REG))]
13585   "TARGET_64BIT && TARGET_GNU2_TLS"
13586   "#"
13587   ""
13588   [(set (match_dup 0) (match_dup 4))]
13590   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13591   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13594 ;; These patterns match the binary 387 instructions for addM3, subM3,
13595 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13596 ;; SFmode.  The first is the normal insn, the second the same insn but
13597 ;; with one operand a conversion, and the third the same insn but with
13598 ;; the other operand a conversion.  The conversion may be SFmode or
13599 ;; SImode if the target mode DFmode, but only SImode if the target mode
13600 ;; is SFmode.
13602 ;; Gcc is slightly more smart about handling normal two address instructions
13603 ;; so use special patterns for add and mull.
13605 (define_insn "*fop_<mode>_comm_mixed"
13606   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13607         (match_operator:MODEF 3 "binary_fp_operator"
13608           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13609            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13610   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13611    && COMMUTATIVE_ARITH_P (operands[3])
13612    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13613   "* return output_387_binary_op (insn, operands);"
13614   [(set (attr "type")
13615         (if_then_else (eq_attr "alternative" "1,2")
13616            (if_then_else (match_operand:MODEF 3 "mult_operator")
13617               (const_string "ssemul")
13618               (const_string "sseadd"))
13619            (if_then_else (match_operand:MODEF 3 "mult_operator")
13620               (const_string "fmul")
13621               (const_string "fop"))))
13622    (set_attr "isa" "*,noavx,avx")
13623    (set_attr "prefix" "orig,orig,vex")
13624    (set_attr "mode" "<MODE>")
13625    (set (attr "enabled")
13626      (cond [(eq_attr "alternative" "0")
13627               (symbol_ref "TARGET_MIX_SSE_I387")
13628            ]
13629            (const_string "*")))])
13631 (define_insn "*fop_<mode>_comm_i387"
13632   [(set (match_operand:MODEF 0 "register_operand" "=f")
13633         (match_operator:MODEF 3 "binary_fp_operator"
13634           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13635            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13636   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13637    && COMMUTATIVE_ARITH_P (operands[3])
13638    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13639   "* return output_387_binary_op (insn, operands);"
13640   [(set (attr "type")
13641         (if_then_else (match_operand:MODEF 3 "mult_operator")
13642            (const_string "fmul")
13643            (const_string "fop")))
13644    (set_attr "mode" "<MODE>")])
13646 (define_insn "*rcpsf2_sse"
13647   [(set (match_operand:SF 0 "register_operand" "=x")
13648         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13649                    UNSPEC_RCP))]
13650   "TARGET_SSE_MATH"
13651   "%vrcpss\t{%1, %d0|%d0, %1}"
13652   [(set_attr "type" "sse")
13653    (set_attr "atom_sse_attr" "rcp")
13654    (set_attr "btver2_sse_attr" "rcp")
13655    (set_attr "prefix" "maybe_vex")
13656    (set_attr "mode" "SF")])
13658 (define_insn "*fop_<mode>_1_mixed"
13659   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13660         (match_operator:MODEF 3 "binary_fp_operator"
13661           [(match_operand:MODEF 1
13662              "register_mixssei387nonimm_operand" "0,fm,0,v")
13663            (match_operand:MODEF 2
13664              "nonimmediate_operand"              "fm,0,xm,vm")]))]
13665   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13666    && !COMMUTATIVE_ARITH_P (operands[3])
13667    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13668   "* return output_387_binary_op (insn, operands);"
13669   [(set (attr "type")
13670         (cond [(and (eq_attr "alternative" "2,3")
13671                     (match_operand:MODEF 3 "mult_operator"))
13672                  (const_string "ssemul")
13673                (and (eq_attr "alternative" "2,3")
13674                     (match_operand:MODEF 3 "div_operator"))
13675                  (const_string "ssediv")
13676                (eq_attr "alternative" "2,3")
13677                  (const_string "sseadd")
13678                (match_operand:MODEF 3 "mult_operator")
13679                  (const_string "fmul")
13680                (match_operand:MODEF 3 "div_operator")
13681                  (const_string "fdiv")
13682               ]
13683               (const_string "fop")))
13684    (set_attr "isa" "*,*,noavx,avx")
13685    (set_attr "prefix" "orig,orig,orig,vex")
13686    (set_attr "mode" "<MODE>")
13687    (set (attr "enabled")
13688      (cond [(eq_attr "alternative" "0,1")
13689               (symbol_ref "TARGET_MIX_SSE_I387")
13690            ]
13691            (const_string "*")))])
13693 ;; This pattern is not fully shadowed by the pattern above.
13694 (define_insn "*fop_<mode>_1_i387"
13695   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13696         (match_operator:MODEF 3 "binary_fp_operator"
13697           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13698            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13699   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13700    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13701    && !COMMUTATIVE_ARITH_P (operands[3])
13702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13703   "* return output_387_binary_op (insn, operands);"
13704   [(set (attr "type")
13705         (cond [(match_operand:MODEF 3 "mult_operator")
13706                  (const_string "fmul")
13707                (match_operand:MODEF 3 "div_operator")
13708                  (const_string "fdiv")
13709               ]
13710               (const_string "fop")))
13711    (set_attr "mode" "<MODE>")])
13713 ;; ??? Add SSE splitters for these!
13714 (define_insn "*fop_<MODEF:mode>_2_i387"
13715   [(set (match_operand:MODEF 0 "register_operand" "=f")
13716         (match_operator:MODEF 3 "binary_fp_operator"
13717           [(float:MODEF
13718              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13719            (match_operand:MODEF 2 "register_operand" "0")]))]
13720   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13721    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13722    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13723        || optimize_function_for_size_p (cfun))"
13724   { return output_387_binary_op (insn, operands); }
13725   [(set (attr "type")
13726         (cond [(match_operand:MODEF 3 "mult_operator")
13727                  (const_string "fmul")
13728                (match_operand:MODEF 3 "div_operator")
13729                  (const_string "fdiv")
13730               ]
13731               (const_string "fop")))
13732    (set_attr "fp_int_src" "true")
13733    (set_attr "mode" "<SWI24:MODE>")])
13735 (define_insn "*fop_<MODEF:mode>_3_i387"
13736   [(set (match_operand:MODEF 0 "register_operand" "=f")
13737         (match_operator:MODEF 3 "binary_fp_operator"
13738           [(match_operand:MODEF 1 "register_operand" "0")
13739            (float:MODEF
13740              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13741   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13742    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13743    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13744        || optimize_function_for_size_p (cfun))"
13745   { return output_387_binary_op (insn, operands); }
13746   [(set (attr "type")
13747         (cond [(match_operand:MODEF 3 "mult_operator")
13748                  (const_string "fmul")
13749                (match_operand:MODEF 3 "div_operator")
13750                  (const_string "fdiv")
13751               ]
13752               (const_string "fop")))
13753    (set_attr "fp_int_src" "true")
13754    (set_attr "mode" "<MODE>")])
13756 (define_insn "*fop_df_4_i387"
13757   [(set (match_operand:DF 0 "register_operand" "=f,f")
13758         (match_operator:DF 3 "binary_fp_operator"
13759            [(float_extend:DF
13760              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13761             (match_operand:DF 2 "register_operand" "0,f")]))]
13762   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13763    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13765   "* return output_387_binary_op (insn, operands);"
13766   [(set (attr "type")
13767         (cond [(match_operand:DF 3 "mult_operator")
13768                  (const_string "fmul")
13769                (match_operand:DF 3 "div_operator")
13770                  (const_string "fdiv")
13771               ]
13772               (const_string "fop")))
13773    (set_attr "mode" "SF")])
13775 (define_insn "*fop_df_5_i387"
13776   [(set (match_operand:DF 0 "register_operand" "=f,f")
13777         (match_operator:DF 3 "binary_fp_operator"
13778           [(match_operand:DF 1 "register_operand" "0,f")
13779            (float_extend:DF
13780             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13781   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13782    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13783   "* return output_387_binary_op (insn, operands);"
13784   [(set (attr "type")
13785         (cond [(match_operand:DF 3 "mult_operator")
13786                  (const_string "fmul")
13787                (match_operand:DF 3 "div_operator")
13788                  (const_string "fdiv")
13789               ]
13790               (const_string "fop")))
13791    (set_attr "mode" "SF")])
13793 (define_insn "*fop_df_6_i387"
13794   [(set (match_operand:DF 0 "register_operand" "=f,f")
13795         (match_operator:DF 3 "binary_fp_operator"
13796           [(float_extend:DF
13797             (match_operand:SF 1 "register_operand" "0,f"))
13798            (float_extend:DF
13799             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13800   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13801    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13802   "* return output_387_binary_op (insn, operands);"
13803   [(set (attr "type")
13804         (cond [(match_operand:DF 3 "mult_operator")
13805                  (const_string "fmul")
13806                (match_operand:DF 3 "div_operator")
13807                  (const_string "fdiv")
13808               ]
13809               (const_string "fop")))
13810    (set_attr "mode" "SF")])
13812 (define_insn "*fop_xf_comm_i387"
13813   [(set (match_operand:XF 0 "register_operand" "=f")
13814         (match_operator:XF 3 "binary_fp_operator"
13815                         [(match_operand:XF 1 "register_operand" "%0")
13816                          (match_operand:XF 2 "register_operand" "f")]))]
13817   "TARGET_80387
13818    && COMMUTATIVE_ARITH_P (operands[3])"
13819   "* return output_387_binary_op (insn, operands);"
13820   [(set (attr "type")
13821         (if_then_else (match_operand:XF 3 "mult_operator")
13822            (const_string "fmul")
13823            (const_string "fop")))
13824    (set_attr "mode" "XF")])
13826 (define_insn "*fop_xf_1_i387"
13827   [(set (match_operand:XF 0 "register_operand" "=f,f")
13828         (match_operator:XF 3 "binary_fp_operator"
13829                         [(match_operand:XF 1 "register_operand" "0,f")
13830                          (match_operand:XF 2 "register_operand" "f,0")]))]
13831   "TARGET_80387
13832    && !COMMUTATIVE_ARITH_P (operands[3])"
13833   "* return output_387_binary_op (insn, operands);"
13834   [(set (attr "type")
13835         (cond [(match_operand:XF 3 "mult_operator")
13836                  (const_string "fmul")
13837                (match_operand:XF 3 "div_operator")
13838                  (const_string "fdiv")
13839               ]
13840               (const_string "fop")))
13841    (set_attr "mode" "XF")])
13843 (define_insn "*fop_xf_2_i387"
13844   [(set (match_operand:XF 0 "register_operand" "=f")
13845         (match_operator:XF 3 "binary_fp_operator"
13846           [(float:XF
13847              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13848            (match_operand:XF 2 "register_operand" "0")]))]
13849   "TARGET_80387
13850    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13851   { return output_387_binary_op (insn, operands); }
13852   [(set (attr "type")
13853         (cond [(match_operand:XF 3 "mult_operator")
13854                  (const_string "fmul")
13855                (match_operand:XF 3 "div_operator")
13856                  (const_string "fdiv")
13857               ]
13858               (const_string "fop")))
13859    (set_attr "fp_int_src" "true")
13860    (set_attr "mode" "<MODE>")])
13862 (define_insn "*fop_xf_3_i387"
13863   [(set (match_operand:XF 0 "register_operand" "=f")
13864         (match_operator:XF 3 "binary_fp_operator"
13865           [(match_operand:XF 1 "register_operand" "0")
13866            (float:XF
13867              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13868   "TARGET_80387
13869    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13870   { return output_387_binary_op (insn, operands); }
13871   [(set (attr "type")
13872         (cond [(match_operand:XF 3 "mult_operator")
13873                  (const_string "fmul")
13874                (match_operand:XF 3 "div_operator")
13875                  (const_string "fdiv")
13876               ]
13877               (const_string "fop")))
13878    (set_attr "fp_int_src" "true")
13879    (set_attr "mode" "<MODE>")])
13881 (define_insn "*fop_xf_4_i387"
13882   [(set (match_operand:XF 0 "register_operand" "=f,f")
13883         (match_operator:XF 3 "binary_fp_operator"
13884            [(float_extend:XF
13885               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13886             (match_operand:XF 2 "register_operand" "0,f")]))]
13887   "TARGET_80387"
13888   "* return output_387_binary_op (insn, operands);"
13889   [(set (attr "type")
13890         (cond [(match_operand:XF 3 "mult_operator")
13891                  (const_string "fmul")
13892                (match_operand:XF 3 "div_operator")
13893                  (const_string "fdiv")
13894               ]
13895               (const_string "fop")))
13896    (set_attr "mode" "<MODE>")])
13898 (define_insn "*fop_xf_5_i387"
13899   [(set (match_operand:XF 0 "register_operand" "=f,f")
13900         (match_operator:XF 3 "binary_fp_operator"
13901           [(match_operand:XF 1 "register_operand" "0,f")
13902            (float_extend:XF
13903              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13904   "TARGET_80387"
13905   "* return output_387_binary_op (insn, operands);"
13906   [(set (attr "type")
13907         (cond [(match_operand:XF 3 "mult_operator")
13908                  (const_string "fmul")
13909                (match_operand:XF 3 "div_operator")
13910                  (const_string "fdiv")
13911               ]
13912               (const_string "fop")))
13913    (set_attr "mode" "<MODE>")])
13915 (define_insn "*fop_xf_6_i387"
13916   [(set (match_operand:XF 0 "register_operand" "=f,f")
13917         (match_operator:XF 3 "binary_fp_operator"
13918           [(float_extend:XF
13919              (match_operand:MODEF 1 "register_operand" "0,f"))
13920            (float_extend:XF
13921              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13922   "TARGET_80387"
13923   "* return output_387_binary_op (insn, operands);"
13924   [(set (attr "type")
13925         (cond [(match_operand:XF 3 "mult_operator")
13926                  (const_string "fmul")
13927                (match_operand:XF 3 "div_operator")
13928                  (const_string "fdiv")
13929               ]
13930               (const_string "fop")))
13931    (set_attr "mode" "<MODE>")])
13933 ;; FPU special functions.
13935 ;; This pattern implements a no-op XFmode truncation for
13936 ;; all fancy i386 XFmode math functions.
13938 (define_insn "truncxf<mode>2_i387_noop_unspec"
13939   [(set (match_operand:MODEF 0 "register_operand" "=f")
13940         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13941         UNSPEC_TRUNC_NOOP))]
13942   "TARGET_USE_FANCY_MATH_387"
13943   "* return output_387_reg_move (insn, operands);"
13944   [(set_attr "type" "fmov")
13945    (set_attr "mode" "<MODE>")])
13947 (define_insn "sqrtxf2"
13948   [(set (match_operand:XF 0 "register_operand" "=f")
13949         (sqrt:XF (match_operand:XF 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 "sqrt_extend<mode>xf2_i387"
13959   [(set (match_operand:XF 0 "register_operand" "=f")
13960         (sqrt:XF
13961           (float_extend:XF
13962             (match_operand:MODEF 1 "register_operand" "0"))))]
13963   "TARGET_USE_FANCY_MATH_387"
13964   "fsqrt"
13965   [(set_attr "type" "fpspc")
13966    (set_attr "mode" "XF")
13967    (set_attr "athlon_decode" "direct")
13968    (set_attr "amdfam10_decode" "direct")
13969    (set_attr "bdver1_decode" "direct")])
13971 (define_insn "*rsqrtsf2_sse"
13972   [(set (match_operand:SF 0 "register_operand" "=x")
13973         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13974                    UNSPEC_RSQRT))]
13975   "TARGET_SSE_MATH"
13976   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13977   [(set_attr "type" "sse")
13978    (set_attr "atom_sse_attr" "rcp")
13979    (set_attr "btver2_sse_attr" "rcp")
13980    (set_attr "prefix" "maybe_vex")
13981    (set_attr "mode" "SF")])
13983 (define_expand "rsqrtsf2"
13984   [(set (match_operand:SF 0 "register_operand")
13985         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13986                    UNSPEC_RSQRT))]
13987   "TARGET_SSE_MATH"
13989   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13990   DONE;
13993 (define_insn "*sqrt<mode>2_sse"
13994   [(set (match_operand:MODEF 0 "register_operand" "=v")
13995         (sqrt:MODEF
13996           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
13997   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13998   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13999   [(set_attr "type" "sse")
14000    (set_attr "atom_sse_attr" "sqrt")
14001    (set_attr "btver2_sse_attr" "sqrt")
14002    (set_attr "prefix" "maybe_vex")
14003    (set_attr "mode" "<MODE>")
14004    (set_attr "athlon_decode" "*")
14005    (set_attr "amdfam10_decode" "*")
14006    (set_attr "bdver1_decode" "*")])
14008 (define_expand "sqrt<mode>2"
14009   [(set (match_operand:MODEF 0 "register_operand")
14010         (sqrt:MODEF
14011           (match_operand:MODEF 1 "nonimmediate_operand")))]
14012   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14013    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14015   if (<MODE>mode == SFmode
14016       && TARGET_SSE_MATH
14017       && TARGET_RECIP_SQRT
14018       && !optimize_function_for_size_p (cfun)
14019       && flag_finite_math_only && !flag_trapping_math
14020       && flag_unsafe_math_optimizations)
14021     {
14022       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14023       DONE;
14024     }
14026   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14027     {
14028       rtx op0 = gen_reg_rtx (XFmode);
14029       rtx op1 = force_reg (<MODE>mode, operands[1]);
14031       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14032       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14033       DONE;
14034    }
14037 (define_insn "fpremxf4_i387"
14038   [(set (match_operand:XF 0 "register_operand" "=f")
14039         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14040                     (match_operand:XF 3 "register_operand" "1")]
14041                    UNSPEC_FPREM_F))
14042    (set (match_operand:XF 1 "register_operand" "=u")
14043         (unspec:XF [(match_dup 2) (match_dup 3)]
14044                    UNSPEC_FPREM_U))
14045    (set (reg:CCFP FPSR_REG)
14046         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14047                      UNSPEC_C2_FLAG))]
14048   "TARGET_USE_FANCY_MATH_387
14049    && flag_finite_math_only"
14050   "fprem"
14051   [(set_attr "type" "fpspc")
14052    (set_attr "mode" "XF")])
14054 (define_expand "fmodxf3"
14055   [(use (match_operand:XF 0 "register_operand"))
14056    (use (match_operand:XF 1 "general_operand"))
14057    (use (match_operand:XF 2 "general_operand"))]
14058   "TARGET_USE_FANCY_MATH_387
14059    && flag_finite_math_only"
14061   rtx_code_label *label = gen_label_rtx ();
14063   rtx op1 = gen_reg_rtx (XFmode);
14064   rtx op2 = gen_reg_rtx (XFmode);
14066   emit_move_insn (op2, operands[2]);
14067   emit_move_insn (op1, operands[1]);
14069   emit_label (label);
14070   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14071   ix86_emit_fp_unordered_jump (label);
14072   LABEL_NUSES (label) = 1;
14074   emit_move_insn (operands[0], op1);
14075   DONE;
14078 (define_expand "fmod<mode>3"
14079   [(use (match_operand:MODEF 0 "register_operand"))
14080    (use (match_operand:MODEF 1 "general_operand"))
14081    (use (match_operand:MODEF 2 "general_operand"))]
14082   "TARGET_USE_FANCY_MATH_387
14083    && flag_finite_math_only"
14085   rtx (*gen_truncxf) (rtx, rtx);
14087   rtx_code_label *label = gen_label_rtx ();
14089   rtx op1 = gen_reg_rtx (XFmode);
14090   rtx op2 = gen_reg_rtx (XFmode);
14092   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14093   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14095   emit_label (label);
14096   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14097   ix86_emit_fp_unordered_jump (label);
14098   LABEL_NUSES (label) = 1;
14100   /* Truncate the result properly for strict SSE math.  */
14101   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14102       && !TARGET_MIX_SSE_I387)
14103     gen_truncxf = gen_truncxf<mode>2;
14104   else
14105     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14107   emit_insn (gen_truncxf (operands[0], op1));
14108   DONE;
14111 (define_insn "fprem1xf4_i387"
14112   [(set (match_operand:XF 0 "register_operand" "=f")
14113         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14114                     (match_operand:XF 3 "register_operand" "1")]
14115                    UNSPEC_FPREM1_F))
14116    (set (match_operand:XF 1 "register_operand" "=u")
14117         (unspec:XF [(match_dup 2) (match_dup 3)]
14118                    UNSPEC_FPREM1_U))
14119    (set (reg:CCFP FPSR_REG)
14120         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14121                      UNSPEC_C2_FLAG))]
14122   "TARGET_USE_FANCY_MATH_387
14123    && flag_finite_math_only"
14124   "fprem1"
14125   [(set_attr "type" "fpspc")
14126    (set_attr "mode" "XF")])
14128 (define_expand "remainderxf3"
14129   [(use (match_operand:XF 0 "register_operand"))
14130    (use (match_operand:XF 1 "general_operand"))
14131    (use (match_operand:XF 2 "general_operand"))]
14132   "TARGET_USE_FANCY_MATH_387
14133    && flag_finite_math_only"
14135   rtx_code_label *label = gen_label_rtx ();
14137   rtx op1 = gen_reg_rtx (XFmode);
14138   rtx op2 = gen_reg_rtx (XFmode);
14140   emit_move_insn (op2, operands[2]);
14141   emit_move_insn (op1, operands[1]);
14143   emit_label (label);
14144   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14145   ix86_emit_fp_unordered_jump (label);
14146   LABEL_NUSES (label) = 1;
14148   emit_move_insn (operands[0], op1);
14149   DONE;
14152 (define_expand "remainder<mode>3"
14153   [(use (match_operand:MODEF 0 "register_operand"))
14154    (use (match_operand:MODEF 1 "general_operand"))
14155    (use (match_operand:MODEF 2 "general_operand"))]
14156   "TARGET_USE_FANCY_MATH_387
14157    && flag_finite_math_only"
14159   rtx (*gen_truncxf) (rtx, rtx);
14161   rtx_code_label *label = gen_label_rtx ();
14163   rtx op1 = gen_reg_rtx (XFmode);
14164   rtx op2 = gen_reg_rtx (XFmode);
14166   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14167   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14169   emit_label (label);
14171   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14172   ix86_emit_fp_unordered_jump (label);
14173   LABEL_NUSES (label) = 1;
14175   /* Truncate the result properly for strict SSE math.  */
14176   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14177       && !TARGET_MIX_SSE_I387)
14178     gen_truncxf = gen_truncxf<mode>2;
14179   else
14180     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14182   emit_insn (gen_truncxf (operands[0], op1));
14183   DONE;
14186 (define_int_iterator SINCOS
14187         [UNSPEC_SIN
14188          UNSPEC_COS])
14190 (define_int_attr sincos
14191         [(UNSPEC_SIN "sin")
14192          (UNSPEC_COS "cos")])
14194 (define_insn "*<sincos>xf2_i387"
14195   [(set (match_operand:XF 0 "register_operand" "=f")
14196         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14197                    SINCOS))]
14198   "TARGET_USE_FANCY_MATH_387
14199    && flag_unsafe_math_optimizations"
14200   "f<sincos>"
14201   [(set_attr "type" "fpspc")
14202    (set_attr "mode" "XF")])
14204 (define_insn "*<sincos>_extend<mode>xf2_i387"
14205   [(set (match_operand:XF 0 "register_operand" "=f")
14206         (unspec:XF [(float_extend:XF
14207                       (match_operand:MODEF 1 "register_operand" "0"))]
14208                    SINCOS))]
14209   "TARGET_USE_FANCY_MATH_387
14210    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14211        || TARGET_MIX_SSE_I387)
14212    && flag_unsafe_math_optimizations"
14213   "f<sincos>"
14214   [(set_attr "type" "fpspc")
14215    (set_attr "mode" "XF")])
14217 ;; When sincos pattern is defined, sin and cos builtin functions will be
14218 ;; expanded to sincos pattern with one of its outputs left unused.
14219 ;; CSE pass will figure out if two sincos patterns can be combined,
14220 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14221 ;; depending on the unused output.
14223 (define_insn "sincosxf3"
14224   [(set (match_operand:XF 0 "register_operand" "=f")
14225         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14226                    UNSPEC_SINCOS_COS))
14227    (set (match_operand:XF 1 "register_operand" "=u")
14228         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14229   "TARGET_USE_FANCY_MATH_387
14230    && flag_unsafe_math_optimizations"
14231   "fsincos"
14232   [(set_attr "type" "fpspc")
14233    (set_attr "mode" "XF")])
14235 (define_split
14236   [(set (match_operand:XF 0 "register_operand")
14237         (unspec:XF [(match_operand:XF 2 "register_operand")]
14238                    UNSPEC_SINCOS_COS))
14239    (set (match_operand:XF 1 "register_operand")
14240         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14241   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14242    && can_create_pseudo_p ()"
14243   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14245 (define_split
14246   [(set (match_operand:XF 0 "register_operand")
14247         (unspec:XF [(match_operand:XF 2 "register_operand")]
14248                    UNSPEC_SINCOS_COS))
14249    (set (match_operand:XF 1 "register_operand")
14250         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14251   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14252    && can_create_pseudo_p ()"
14253   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14255 (define_insn "sincos_extend<mode>xf3_i387"
14256   [(set (match_operand:XF 0 "register_operand" "=f")
14257         (unspec:XF [(float_extend:XF
14258                       (match_operand:MODEF 2 "register_operand" "0"))]
14259                    UNSPEC_SINCOS_COS))
14260    (set (match_operand:XF 1 "register_operand" "=u")
14261         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14262   "TARGET_USE_FANCY_MATH_387
14263    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264        || TARGET_MIX_SSE_I387)
14265    && flag_unsafe_math_optimizations"
14266   "fsincos"
14267   [(set_attr "type" "fpspc")
14268    (set_attr "mode" "XF")])
14270 (define_split
14271   [(set (match_operand:XF 0 "register_operand")
14272         (unspec:XF [(float_extend:XF
14273                       (match_operand:MODEF 2 "register_operand"))]
14274                    UNSPEC_SINCOS_COS))
14275    (set (match_operand:XF 1 "register_operand")
14276         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14277   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14278    && can_create_pseudo_p ()"
14279   [(set (match_dup 1)
14280         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14282 (define_split
14283   [(set (match_operand:XF 0 "register_operand")
14284         (unspec:XF [(float_extend:XF
14285                       (match_operand:MODEF 2 "register_operand"))]
14286                    UNSPEC_SINCOS_COS))
14287    (set (match_operand:XF 1 "register_operand")
14288         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14289   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14290    && can_create_pseudo_p ()"
14291   [(set (match_dup 0)
14292         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14294 (define_expand "sincos<mode>3"
14295   [(use (match_operand:MODEF 0 "register_operand"))
14296    (use (match_operand:MODEF 1 "register_operand"))
14297    (use (match_operand:MODEF 2 "register_operand"))]
14298   "TARGET_USE_FANCY_MATH_387
14299    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300        || TARGET_MIX_SSE_I387)
14301    && flag_unsafe_math_optimizations"
14303   rtx op0 = gen_reg_rtx (XFmode);
14304   rtx op1 = gen_reg_rtx (XFmode);
14306   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14307   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14308   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14309   DONE;
14312 (define_insn "fptanxf4_i387"
14313   [(set (match_operand:XF 0 "register_operand" "=f")
14314         (match_operand:XF 3 "const_double_operand" "F"))
14315    (set (match_operand:XF 1 "register_operand" "=u")
14316         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14317                    UNSPEC_TAN))]
14318   "TARGET_USE_FANCY_MATH_387
14319    && flag_unsafe_math_optimizations
14320    && standard_80387_constant_p (operands[3]) == 2"
14321   "fptan"
14322   [(set_attr "type" "fpspc")
14323    (set_attr "mode" "XF")])
14325 (define_insn "fptan_extend<mode>xf4_i387"
14326   [(set (match_operand:MODEF 0 "register_operand" "=f")
14327         (match_operand:MODEF 3 "const_double_operand" "F"))
14328    (set (match_operand:XF 1 "register_operand" "=u")
14329         (unspec:XF [(float_extend:XF
14330                       (match_operand:MODEF 2 "register_operand" "0"))]
14331                    UNSPEC_TAN))]
14332   "TARGET_USE_FANCY_MATH_387
14333    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334        || TARGET_MIX_SSE_I387)
14335    && flag_unsafe_math_optimizations
14336    && standard_80387_constant_p (operands[3]) == 2"
14337   "fptan"
14338   [(set_attr "type" "fpspc")
14339    (set_attr "mode" "XF")])
14341 (define_expand "tanxf2"
14342   [(use (match_operand:XF 0 "register_operand"))
14343    (use (match_operand:XF 1 "register_operand"))]
14344   "TARGET_USE_FANCY_MATH_387
14345    && flag_unsafe_math_optimizations"
14347   rtx one = gen_reg_rtx (XFmode);
14348   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14350   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14351   DONE;
14354 (define_expand "tan<mode>2"
14355   [(use (match_operand:MODEF 0 "register_operand"))
14356    (use (match_operand:MODEF 1 "register_operand"))]
14357   "TARGET_USE_FANCY_MATH_387
14358    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14359        || TARGET_MIX_SSE_I387)
14360    && flag_unsafe_math_optimizations"
14362   rtx op0 = gen_reg_rtx (XFmode);
14364   rtx one = gen_reg_rtx (<MODE>mode);
14365   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14367   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14368                                              operands[1], op2));
14369   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370   DONE;
14373 (define_insn "*fpatanxf3_i387"
14374   [(set (match_operand:XF 0 "register_operand" "=f")
14375         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14376                     (match_operand:XF 2 "register_operand" "u")]
14377                    UNSPEC_FPATAN))
14378    (clobber (match_scratch:XF 3 "=2"))]
14379   "TARGET_USE_FANCY_MATH_387
14380    && flag_unsafe_math_optimizations"
14381   "fpatan"
14382   [(set_attr "type" "fpspc")
14383    (set_attr "mode" "XF")])
14385 (define_insn "fpatan_extend<mode>xf3_i387"
14386   [(set (match_operand:XF 0 "register_operand" "=f")
14387         (unspec:XF [(float_extend:XF
14388                       (match_operand:MODEF 1 "register_operand" "0"))
14389                     (float_extend:XF
14390                       (match_operand:MODEF 2 "register_operand" "u"))]
14391                    UNSPEC_FPATAN))
14392    (clobber (match_scratch:XF 3 "=2"))]
14393   "TARGET_USE_FANCY_MATH_387
14394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395        || TARGET_MIX_SSE_I387)
14396    && flag_unsafe_math_optimizations"
14397   "fpatan"
14398   [(set_attr "type" "fpspc")
14399    (set_attr "mode" "XF")])
14401 (define_expand "atan2xf3"
14402   [(parallel [(set (match_operand:XF 0 "register_operand")
14403                    (unspec:XF [(match_operand:XF 2 "register_operand")
14404                                (match_operand:XF 1 "register_operand")]
14405                               UNSPEC_FPATAN))
14406               (clobber (match_scratch:XF 3))])]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations")
14410 (define_expand "atan2<mode>3"
14411   [(use (match_operand:MODEF 0 "register_operand"))
14412    (use (match_operand:MODEF 1 "register_operand"))
14413    (use (match_operand:MODEF 2 "register_operand"))]
14414   "TARGET_USE_FANCY_MATH_387
14415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14416        || TARGET_MIX_SSE_I387)
14417    && flag_unsafe_math_optimizations"
14419   rtx op0 = gen_reg_rtx (XFmode);
14421   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14422   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423   DONE;
14426 (define_expand "atanxf2"
14427   [(parallel [(set (match_operand:XF 0 "register_operand")
14428                    (unspec:XF [(match_dup 2)
14429                                (match_operand:XF 1 "register_operand")]
14430                               UNSPEC_FPATAN))
14431               (clobber (match_scratch:XF 3))])]
14432   "TARGET_USE_FANCY_MATH_387
14433    && flag_unsafe_math_optimizations"
14435   operands[2] = gen_reg_rtx (XFmode);
14436   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14439 (define_expand "atan<mode>2"
14440   [(use (match_operand:MODEF 0 "register_operand"))
14441    (use (match_operand:MODEF 1 "register_operand"))]
14442   "TARGET_USE_FANCY_MATH_387
14443    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14444        || TARGET_MIX_SSE_I387)
14445    && flag_unsafe_math_optimizations"
14447   rtx op0 = gen_reg_rtx (XFmode);
14449   rtx op2 = gen_reg_rtx (<MODE>mode);
14450   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14452   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14453   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14454   DONE;
14457 (define_expand "asinxf2"
14458   [(set (match_dup 2)
14459         (mult:XF (match_operand:XF 1 "register_operand")
14460                  (match_dup 1)))
14461    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14462    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14463    (parallel [(set (match_operand:XF 0 "register_operand")
14464                    (unspec:XF [(match_dup 5) (match_dup 1)]
14465                               UNSPEC_FPATAN))
14466               (clobber (match_scratch:XF 6))])]
14467   "TARGET_USE_FANCY_MATH_387
14468    && flag_unsafe_math_optimizations"
14470   int i;
14472   if (optimize_insn_for_size_p ())
14473     FAIL;
14475   for (i = 2; i < 6; i++)
14476     operands[i] = gen_reg_rtx (XFmode);
14478   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14481 (define_expand "asin<mode>2"
14482   [(use (match_operand:MODEF 0 "register_operand"))
14483    (use (match_operand:MODEF 1 "general_operand"))]
14484  "TARGET_USE_FANCY_MATH_387
14485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14486        || TARGET_MIX_SSE_I387)
14487    && flag_unsafe_math_optimizations"
14489   rtx op0 = gen_reg_rtx (XFmode);
14490   rtx op1 = gen_reg_rtx (XFmode);
14492   if (optimize_insn_for_size_p ())
14493     FAIL;
14495   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14496   emit_insn (gen_asinxf2 (op0, op1));
14497   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14498   DONE;
14501 (define_expand "acosxf2"
14502   [(set (match_dup 2)
14503         (mult:XF (match_operand:XF 1 "register_operand")
14504                  (match_dup 1)))
14505    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14506    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14507    (parallel [(set (match_operand:XF 0 "register_operand")
14508                    (unspec:XF [(match_dup 1) (match_dup 5)]
14509                               UNSPEC_FPATAN))
14510               (clobber (match_scratch:XF 6))])]
14511   "TARGET_USE_FANCY_MATH_387
14512    && flag_unsafe_math_optimizations"
14514   int i;
14516   if (optimize_insn_for_size_p ())
14517     FAIL;
14519   for (i = 2; i < 6; i++)
14520     operands[i] = gen_reg_rtx (XFmode);
14522   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14525 (define_expand "acos<mode>2"
14526   [(use (match_operand:MODEF 0 "register_operand"))
14527    (use (match_operand:MODEF 1 "general_operand"))]
14528  "TARGET_USE_FANCY_MATH_387
14529    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14530        || TARGET_MIX_SSE_I387)
14531    && flag_unsafe_math_optimizations"
14533   rtx op0 = gen_reg_rtx (XFmode);
14534   rtx op1 = gen_reg_rtx (XFmode);
14536   if (optimize_insn_for_size_p ())
14537     FAIL;
14539   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14540   emit_insn (gen_acosxf2 (op0, op1));
14541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14542   DONE;
14545 (define_insn "fyl2xxf3_i387"
14546   [(set (match_operand:XF 0 "register_operand" "=f")
14547         (unspec:XF [(match_operand:XF 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    && flag_unsafe_math_optimizations"
14553   "fyl2x"
14554   [(set_attr "type" "fpspc")
14555    (set_attr "mode" "XF")])
14557 (define_insn "fyl2x_extend<mode>xf3_i387"
14558   [(set (match_operand:XF 0 "register_operand" "=f")
14559         (unspec:XF [(float_extend:XF
14560                       (match_operand:MODEF 1 "register_operand" "0"))
14561                     (match_operand:XF 2 "register_operand" "u")]
14562                    UNSPEC_FYL2X))
14563    (clobber (match_scratch:XF 3 "=2"))]
14564   "TARGET_USE_FANCY_MATH_387
14565    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14566        || TARGET_MIX_SSE_I387)
14567    && flag_unsafe_math_optimizations"
14568   "fyl2x"
14569   [(set_attr "type" "fpspc")
14570    (set_attr "mode" "XF")])
14572 (define_expand "logxf2"
14573   [(parallel [(set (match_operand:XF 0 "register_operand")
14574                    (unspec:XF [(match_operand:XF 1 "register_operand")
14575                                (match_dup 2)] UNSPEC_FYL2X))
14576               (clobber (match_scratch:XF 3))])]
14577   "TARGET_USE_FANCY_MATH_387
14578    && flag_unsafe_math_optimizations"
14580   operands[2] = gen_reg_rtx (XFmode);
14581   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14584 (define_expand "log<mode>2"
14585   [(use (match_operand:MODEF 0 "register_operand"))
14586    (use (match_operand:MODEF 1 "register_operand"))]
14587   "TARGET_USE_FANCY_MATH_387
14588    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14589        || TARGET_MIX_SSE_I387)
14590    && flag_unsafe_math_optimizations"
14592   rtx op0 = gen_reg_rtx (XFmode);
14594   rtx op2 = gen_reg_rtx (XFmode);
14595   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14597   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14598   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14599   DONE;
14602 (define_expand "log10xf2"
14603   [(parallel [(set (match_operand:XF 0 "register_operand")
14604                    (unspec:XF [(match_operand:XF 1 "register_operand")
14605                                (match_dup 2)] UNSPEC_FYL2X))
14606               (clobber (match_scratch:XF 3))])]
14607   "TARGET_USE_FANCY_MATH_387
14608    && flag_unsafe_math_optimizations"
14610   operands[2] = gen_reg_rtx (XFmode);
14611   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14614 (define_expand "log10<mode>2"
14615   [(use (match_operand:MODEF 0 "register_operand"))
14616    (use (match_operand:MODEF 1 "register_operand"))]
14617   "TARGET_USE_FANCY_MATH_387
14618    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14619        || TARGET_MIX_SSE_I387)
14620    && flag_unsafe_math_optimizations"
14622   rtx op0 = gen_reg_rtx (XFmode);
14624   rtx op2 = gen_reg_rtx (XFmode);
14625   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14627   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14628   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14629   DONE;
14632 (define_expand "log2xf2"
14633   [(parallel [(set (match_operand:XF 0 "register_operand")
14634                    (unspec:XF [(match_operand:XF 1 "register_operand")
14635                                (match_dup 2)] UNSPEC_FYL2X))
14636               (clobber (match_scratch:XF 3))])]
14637   "TARGET_USE_FANCY_MATH_387
14638    && flag_unsafe_math_optimizations"
14640   operands[2] = gen_reg_rtx (XFmode);
14641   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14644 (define_expand "log2<mode>2"
14645   [(use (match_operand:MODEF 0 "register_operand"))
14646    (use (match_operand:MODEF 1 "register_operand"))]
14647   "TARGET_USE_FANCY_MATH_387
14648    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649        || TARGET_MIX_SSE_I387)
14650    && flag_unsafe_math_optimizations"
14652   rtx op0 = gen_reg_rtx (XFmode);
14654   rtx op2 = gen_reg_rtx (XFmode);
14655   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14657   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14658   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14659   DONE;
14662 (define_insn "fyl2xp1xf3_i387"
14663   [(set (match_operand:XF 0 "register_operand" "=f")
14664         (unspec:XF [(match_operand:XF 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    && flag_unsafe_math_optimizations"
14670   "fyl2xp1"
14671   [(set_attr "type" "fpspc")
14672    (set_attr "mode" "XF")])
14674 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14675   [(set (match_operand:XF 0 "register_operand" "=f")
14676         (unspec:XF [(float_extend:XF
14677                       (match_operand:MODEF 1 "register_operand" "0"))
14678                     (match_operand:XF 2 "register_operand" "u")]
14679                    UNSPEC_FYL2XP1))
14680    (clobber (match_scratch:XF 3 "=2"))]
14681   "TARGET_USE_FANCY_MATH_387
14682    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14683        || TARGET_MIX_SSE_I387)
14684    && flag_unsafe_math_optimizations"
14685   "fyl2xp1"
14686   [(set_attr "type" "fpspc")
14687    (set_attr "mode" "XF")])
14689 (define_expand "log1pxf2"
14690   [(use (match_operand:XF 0 "register_operand"))
14691    (use (match_operand:XF 1 "register_operand"))]
14692   "TARGET_USE_FANCY_MATH_387
14693    && flag_unsafe_math_optimizations"
14695   if (optimize_insn_for_size_p ())
14696     FAIL;
14698   ix86_emit_i387_log1p (operands[0], operands[1]);
14699   DONE;
14702 (define_expand "log1p<mode>2"
14703   [(use (match_operand:MODEF 0 "register_operand"))
14704    (use (match_operand:MODEF 1 "register_operand"))]
14705   "TARGET_USE_FANCY_MATH_387
14706    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14707        || TARGET_MIX_SSE_I387)
14708    && flag_unsafe_math_optimizations"
14710   rtx op0;
14712   if (optimize_insn_for_size_p ())
14713     FAIL;
14715   op0 = gen_reg_rtx (XFmode);
14717   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14719   ix86_emit_i387_log1p (op0, operands[1]);
14720   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14721   DONE;
14724 (define_insn "fxtractxf3_i387"
14725   [(set (match_operand:XF 0 "register_operand" "=f")
14726         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14727                    UNSPEC_XTRACT_FRACT))
14728    (set (match_operand:XF 1 "register_operand" "=u")
14729         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14730   "TARGET_USE_FANCY_MATH_387
14731    && flag_unsafe_math_optimizations"
14732   "fxtract"
14733   [(set_attr "type" "fpspc")
14734    (set_attr "mode" "XF")])
14736 (define_insn "fxtract_extend<mode>xf3_i387"
14737   [(set (match_operand:XF 0 "register_operand" "=f")
14738         (unspec:XF [(float_extend:XF
14739                       (match_operand:MODEF 2 "register_operand" "0"))]
14740                    UNSPEC_XTRACT_FRACT))
14741    (set (match_operand:XF 1 "register_operand" "=u")
14742         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14745        || TARGET_MIX_SSE_I387)
14746    && flag_unsafe_math_optimizations"
14747   "fxtract"
14748   [(set_attr "type" "fpspc")
14749    (set_attr "mode" "XF")])
14751 (define_expand "logbxf2"
14752   [(parallel [(set (match_dup 2)
14753                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14754                               UNSPEC_XTRACT_FRACT))
14755               (set (match_operand:XF 0 "register_operand")
14756                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14757   "TARGET_USE_FANCY_MATH_387
14758    && flag_unsafe_math_optimizations"
14759   "operands[2] = gen_reg_rtx (XFmode);")
14761 (define_expand "logb<mode>2"
14762   [(use (match_operand:MODEF 0 "register_operand"))
14763    (use (match_operand:MODEF 1 "register_operand"))]
14764   "TARGET_USE_FANCY_MATH_387
14765    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14766        || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14769   rtx op0 = gen_reg_rtx (XFmode);
14770   rtx op1 = gen_reg_rtx (XFmode);
14772   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14773   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14774   DONE;
14777 (define_expand "ilogbxf2"
14778   [(use (match_operand:SI 0 "register_operand"))
14779    (use (match_operand:XF 1 "register_operand"))]
14780   "TARGET_USE_FANCY_MATH_387
14781    && flag_unsafe_math_optimizations"
14783   rtx op0, op1;
14785   if (optimize_insn_for_size_p ())
14786     FAIL;
14788   op0 = gen_reg_rtx (XFmode);
14789   op1 = gen_reg_rtx (XFmode);
14791   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14792   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14793   DONE;
14796 (define_expand "ilogb<mode>2"
14797   [(use (match_operand:SI 0 "register_operand"))
14798    (use (match_operand:MODEF 1 "register_operand"))]
14799   "TARGET_USE_FANCY_MATH_387
14800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14801        || TARGET_MIX_SSE_I387)
14802    && flag_unsafe_math_optimizations"
14804   rtx op0, op1;
14806   if (optimize_insn_for_size_p ())
14807     FAIL;
14809   op0 = gen_reg_rtx (XFmode);
14810   op1 = gen_reg_rtx (XFmode);
14812   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14813   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14814   DONE;
14817 (define_insn "*f2xm1xf2_i387"
14818   [(set (match_operand:XF 0 "register_operand" "=f")
14819         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14820                    UNSPEC_F2XM1))]
14821   "TARGET_USE_FANCY_MATH_387
14822    && flag_unsafe_math_optimizations"
14823   "f2xm1"
14824   [(set_attr "type" "fpspc")
14825    (set_attr "mode" "XF")])
14827 (define_insn "fscalexf4_i387"
14828   [(set (match_operand:XF 0 "register_operand" "=f")
14829         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14830                     (match_operand:XF 3 "register_operand" "1")]
14831                    UNSPEC_FSCALE_FRACT))
14832    (set (match_operand:XF 1 "register_operand" "=u")
14833         (unspec:XF [(match_dup 2) (match_dup 3)]
14834                    UNSPEC_FSCALE_EXP))]
14835   "TARGET_USE_FANCY_MATH_387
14836    && flag_unsafe_math_optimizations"
14837   "fscale"
14838   [(set_attr "type" "fpspc")
14839    (set_attr "mode" "XF")])
14841 (define_expand "expNcorexf3"
14842   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14843                                (match_operand:XF 2 "register_operand")))
14844    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14845    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14846    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14847    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14848    (parallel [(set (match_operand:XF 0 "register_operand")
14849                    (unspec:XF [(match_dup 8) (match_dup 4)]
14850                               UNSPEC_FSCALE_FRACT))
14851               (set (match_dup 9)
14852                    (unspec:XF [(match_dup 8) (match_dup 4)]
14853                               UNSPEC_FSCALE_EXP))])]
14854   "TARGET_USE_FANCY_MATH_387
14855    && flag_unsafe_math_optimizations"
14857   int i;
14859   if (optimize_insn_for_size_p ())
14860     FAIL;
14862   for (i = 3; i < 10; i++)
14863     operands[i] = gen_reg_rtx (XFmode);
14865   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14868 (define_expand "expxf2"
14869   [(use (match_operand:XF 0 "register_operand"))
14870    (use (match_operand:XF 1 "register_operand"))]
14871   "TARGET_USE_FANCY_MATH_387
14872    && flag_unsafe_math_optimizations"
14874   rtx op2;
14876   if (optimize_insn_for_size_p ())
14877     FAIL;
14879   op2 = gen_reg_rtx (XFmode);
14880   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14882   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14883   DONE;
14886 (define_expand "exp<mode>2"
14887   [(use (match_operand:MODEF 0 "register_operand"))
14888    (use (match_operand:MODEF 1 "general_operand"))]
14889  "TARGET_USE_FANCY_MATH_387
14890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891        || TARGET_MIX_SSE_I387)
14892    && flag_unsafe_math_optimizations"
14894   rtx op0, op1;
14896   if (optimize_insn_for_size_p ())
14897     FAIL;
14899   op0 = gen_reg_rtx (XFmode);
14900   op1 = gen_reg_rtx (XFmode);
14902   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14903   emit_insn (gen_expxf2 (op0, op1));
14904   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14905   DONE;
14908 (define_expand "exp10xf2"
14909   [(use (match_operand:XF 0 "register_operand"))
14910    (use (match_operand:XF 1 "register_operand"))]
14911   "TARGET_USE_FANCY_MATH_387
14912    && flag_unsafe_math_optimizations"
14914   rtx op2;
14916   if (optimize_insn_for_size_p ())
14917     FAIL;
14919   op2 = gen_reg_rtx (XFmode);
14920   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14922   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14923   DONE;
14926 (define_expand "exp10<mode>2"
14927   [(use (match_operand:MODEF 0 "register_operand"))
14928    (use (match_operand:MODEF 1 "general_operand"))]
14929  "TARGET_USE_FANCY_MATH_387
14930    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14931        || TARGET_MIX_SSE_I387)
14932    && flag_unsafe_math_optimizations"
14934   rtx op0, op1;
14936   if (optimize_insn_for_size_p ())
14937     FAIL;
14939   op0 = gen_reg_rtx (XFmode);
14940   op1 = gen_reg_rtx (XFmode);
14942   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14943   emit_insn (gen_exp10xf2 (op0, op1));
14944   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14945   DONE;
14948 (define_expand "exp2xf2"
14949   [(use (match_operand:XF 0 "register_operand"))
14950    (use (match_operand:XF 1 "register_operand"))]
14951   "TARGET_USE_FANCY_MATH_387
14952    && flag_unsafe_math_optimizations"
14954   rtx op2;
14956   if (optimize_insn_for_size_p ())
14957     FAIL;
14959   op2 = gen_reg_rtx (XFmode);
14960   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14962   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14963   DONE;
14966 (define_expand "exp2<mode>2"
14967   [(use (match_operand:MODEF 0 "register_operand"))
14968    (use (match_operand:MODEF 1 "general_operand"))]
14969  "TARGET_USE_FANCY_MATH_387
14970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971        || TARGET_MIX_SSE_I387)
14972    && flag_unsafe_math_optimizations"
14974   rtx op0, op1;
14976   if (optimize_insn_for_size_p ())
14977     FAIL;
14979   op0 = gen_reg_rtx (XFmode);
14980   op1 = gen_reg_rtx (XFmode);
14982   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14983   emit_insn (gen_exp2xf2 (op0, op1));
14984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14985   DONE;
14988 (define_expand "expm1xf2"
14989   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14990                                (match_dup 2)))
14991    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14992    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14993    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14994    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14995    (parallel [(set (match_dup 7)
14996                    (unspec:XF [(match_dup 6) (match_dup 4)]
14997                               UNSPEC_FSCALE_FRACT))
14998               (set (match_dup 8)
14999                    (unspec:XF [(match_dup 6) (match_dup 4)]
15000                               UNSPEC_FSCALE_EXP))])
15001    (parallel [(set (match_dup 10)
15002                    (unspec:XF [(match_dup 9) (match_dup 8)]
15003                               UNSPEC_FSCALE_FRACT))
15004               (set (match_dup 11)
15005                    (unspec:XF [(match_dup 9) (match_dup 8)]
15006                               UNSPEC_FSCALE_EXP))])
15007    (set (match_dup 12) (minus:XF (match_dup 10)
15008                                  (float_extend:XF (match_dup 13))))
15009    (set (match_operand:XF 0 "register_operand")
15010         (plus:XF (match_dup 12) (match_dup 7)))]
15011   "TARGET_USE_FANCY_MATH_387
15012    && flag_unsafe_math_optimizations"
15014   int i;
15016   if (optimize_insn_for_size_p ())
15017     FAIL;
15019   for (i = 2; i < 13; i++)
15020     operands[i] = gen_reg_rtx (XFmode);
15022   operands[13]
15023     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15025   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15028 (define_expand "expm1<mode>2"
15029   [(use (match_operand:MODEF 0 "register_operand"))
15030    (use (match_operand:MODEF 1 "general_operand"))]
15031  "TARGET_USE_FANCY_MATH_387
15032    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15033        || TARGET_MIX_SSE_I387)
15034    && flag_unsafe_math_optimizations"
15036   rtx op0, op1;
15038   if (optimize_insn_for_size_p ())
15039     FAIL;
15041   op0 = gen_reg_rtx (XFmode);
15042   op1 = gen_reg_rtx (XFmode);
15044   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15045   emit_insn (gen_expm1xf2 (op0, op1));
15046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15047   DONE;
15050 (define_expand "ldexpxf3"
15051   [(match_operand:XF 0 "register_operand")
15052    (match_operand:XF 1 "register_operand")
15053    (match_operand:SI 2 "register_operand")]
15054   "TARGET_USE_FANCY_MATH_387
15055    && flag_unsafe_math_optimizations"
15057   rtx tmp1, tmp2;
15058   if (optimize_insn_for_size_p ())
15059     FAIL;
15061   tmp1 = gen_reg_rtx (XFmode);
15062   tmp2 = gen_reg_rtx (XFmode);
15064   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15065   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15066                                  operands[1], tmp1));
15067   DONE;
15070 (define_expand "ldexp<mode>3"
15071   [(use (match_operand:MODEF 0 "register_operand"))
15072    (use (match_operand:MODEF 1 "general_operand"))
15073    (use (match_operand:SI 2 "register_operand"))]
15074  "TARGET_USE_FANCY_MATH_387
15075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15076        || TARGET_MIX_SSE_I387)
15077    && flag_unsafe_math_optimizations"
15079   rtx op0, op1;
15081   if (optimize_insn_for_size_p ())
15082     FAIL;
15084   op0 = gen_reg_rtx (XFmode);
15085   op1 = gen_reg_rtx (XFmode);
15087   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15088   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15090   DONE;
15093 (define_expand "scalbxf3"
15094   [(parallel [(set (match_operand:XF 0 " register_operand")
15095                    (unspec:XF [(match_operand:XF 1 "register_operand")
15096                                (match_operand:XF 2 "register_operand")]
15097                               UNSPEC_FSCALE_FRACT))
15098               (set (match_dup 3)
15099                    (unspec:XF [(match_dup 1) (match_dup 2)]
15100                               UNSPEC_FSCALE_EXP))])]
15101   "TARGET_USE_FANCY_MATH_387
15102    && flag_unsafe_math_optimizations"
15104   if (optimize_insn_for_size_p ())
15105     FAIL;
15107   operands[3] = gen_reg_rtx (XFmode);
15110 (define_expand "scalb<mode>3"
15111   [(use (match_operand:MODEF 0 "register_operand"))
15112    (use (match_operand:MODEF 1 "general_operand"))
15113    (use (match_operand:MODEF 2 "general_operand"))]
15114  "TARGET_USE_FANCY_MATH_387
15115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15116        || TARGET_MIX_SSE_I387)
15117    && flag_unsafe_math_optimizations"
15119   rtx op0, op1, op2;
15121   if (optimize_insn_for_size_p ())
15122     FAIL;
15124   op0 = gen_reg_rtx (XFmode);
15125   op1 = gen_reg_rtx (XFmode);
15126   op2 = gen_reg_rtx (XFmode);
15128   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15129   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15130   emit_insn (gen_scalbxf3 (op0, op1, op2));
15131   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15132   DONE;
15135 (define_expand "significandxf2"
15136   [(parallel [(set (match_operand:XF 0 "register_operand")
15137                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15138                               UNSPEC_XTRACT_FRACT))
15139               (set (match_dup 2)
15140                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15141   "TARGET_USE_FANCY_MATH_387
15142    && flag_unsafe_math_optimizations"
15143   "operands[2] = gen_reg_rtx (XFmode);")
15145 (define_expand "significand<mode>2"
15146   [(use (match_operand:MODEF 0 "register_operand"))
15147    (use (match_operand:MODEF 1 "register_operand"))]
15148   "TARGET_USE_FANCY_MATH_387
15149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15150        || TARGET_MIX_SSE_I387)
15151    && flag_unsafe_math_optimizations"
15153   rtx op0 = gen_reg_rtx (XFmode);
15154   rtx op1 = gen_reg_rtx (XFmode);
15156   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15157   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15158   DONE;
15162 (define_insn "sse4_1_round<mode>2"
15163   [(set (match_operand:MODEF 0 "register_operand" "=x")
15164         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15165                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15166                       UNSPEC_ROUND))]
15167   "TARGET_ROUND"
15168   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15169   [(set_attr "type" "ssecvt")
15170    (set_attr "prefix_extra" "1")
15171    (set_attr "prefix" "maybe_vex")
15172    (set_attr "mode" "<MODE>")])
15174 (define_insn "rintxf2"
15175   [(set (match_operand:XF 0 "register_operand" "=f")
15176         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15177                    UNSPEC_FRNDINT))]
15178   "TARGET_USE_FANCY_MATH_387
15179    && flag_unsafe_math_optimizations"
15180   "frndint"
15181   [(set_attr "type" "fpspc")
15182    (set_attr "mode" "XF")])
15184 (define_expand "rint<mode>2"
15185   [(use (match_operand:MODEF 0 "register_operand"))
15186    (use (match_operand:MODEF 1 "register_operand"))]
15187   "(TARGET_USE_FANCY_MATH_387
15188     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15189         || TARGET_MIX_SSE_I387)
15190     && flag_unsafe_math_optimizations)
15191    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15192        && !flag_trapping_math)"
15194   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15195       && !flag_trapping_math)
15196     {
15197       if (TARGET_ROUND)
15198         emit_insn (gen_sse4_1_round<mode>2
15199                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15200       else if (optimize_insn_for_size_p ())
15201         FAIL;
15202       else
15203         ix86_expand_rint (operands[0], operands[1]);
15204     }
15205   else
15206     {
15207       rtx op0 = gen_reg_rtx (XFmode);
15208       rtx op1 = gen_reg_rtx (XFmode);
15210       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15211       emit_insn (gen_rintxf2 (op0, op1));
15213       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15214     }
15215   DONE;
15218 (define_expand "round<mode>2"
15219   [(match_operand:X87MODEF 0 "register_operand")
15220    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15221   "(TARGET_USE_FANCY_MATH_387
15222     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15223         || TARGET_MIX_SSE_I387)
15224     && flag_unsafe_math_optimizations)
15225    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15226        && !flag_trapping_math && !flag_rounding_math)"
15228   if (optimize_insn_for_size_p ())
15229     FAIL;
15231   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15232       && !flag_trapping_math && !flag_rounding_math)
15233     {
15234       if (TARGET_ROUND)
15235         {
15236           operands[1] = force_reg (<MODE>mode, operands[1]);
15237           ix86_expand_round_sse4 (operands[0], operands[1]);
15238         }
15239       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15240         ix86_expand_round (operands[0], operands[1]);
15241       else
15242         ix86_expand_rounddf_32 (operands[0], operands[1]);
15243     }
15244   else
15245     {
15246       operands[1] = force_reg (<MODE>mode, operands[1]);
15247       ix86_emit_i387_round (operands[0], operands[1]);
15248     }
15249   DONE;
15252 (define_insn_and_split "*fistdi2_1"
15253   [(set (match_operand:DI 0 "nonimmediate_operand")
15254         (unspec:DI [(match_operand:XF 1 "register_operand")]
15255                    UNSPEC_FIST))]
15256   "TARGET_USE_FANCY_MATH_387
15257    && can_create_pseudo_p ()"
15258   "#"
15259   "&& 1"
15260   [(const_int 0)]
15262   if (memory_operand (operands[0], VOIDmode))
15263     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15264   else
15265     {
15266       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15267       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15268                                          operands[2]));
15269     }
15270   DONE;
15272   [(set_attr "type" "fpspc")
15273    (set_attr "mode" "DI")])
15275 (define_insn "fistdi2"
15276   [(set (match_operand:DI 0 "memory_operand" "=m")
15277         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15278                    UNSPEC_FIST))
15279    (clobber (match_scratch:XF 2 "=&1f"))]
15280   "TARGET_USE_FANCY_MATH_387"
15281   "* return output_fix_trunc (insn, operands, false);"
15282   [(set_attr "type" "fpspc")
15283    (set_attr "mode" "DI")])
15285 (define_insn "fistdi2_with_temp"
15286   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15287         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15288                    UNSPEC_FIST))
15289    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15290    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15291   "TARGET_USE_FANCY_MATH_387"
15292   "#"
15293   [(set_attr "type" "fpspc")
15294    (set_attr "mode" "DI")])
15296 (define_split
15297   [(set (match_operand:DI 0 "register_operand")
15298         (unspec:DI [(match_operand:XF 1 "register_operand")]
15299                    UNSPEC_FIST))
15300    (clobber (match_operand:DI 2 "memory_operand"))
15301    (clobber (match_scratch 3))]
15302   "reload_completed"
15303   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15304               (clobber (match_dup 3))])
15305    (set (match_dup 0) (match_dup 2))])
15307 (define_split
15308   [(set (match_operand:DI 0 "memory_operand")
15309         (unspec:DI [(match_operand:XF 1 "register_operand")]
15310                    UNSPEC_FIST))
15311    (clobber (match_operand:DI 2 "memory_operand"))
15312    (clobber (match_scratch 3))]
15313   "reload_completed"
15314   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15315               (clobber (match_dup 3))])])
15317 (define_insn_and_split "*fist<mode>2_1"
15318   [(set (match_operand:SWI24 0 "register_operand")
15319         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15320                       UNSPEC_FIST))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && can_create_pseudo_p ()"
15323   "#"
15324   "&& 1"
15325   [(const_int 0)]
15327   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15328   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15329                                         operands[2]));
15330   DONE;
15332   [(set_attr "type" "fpspc")
15333    (set_attr "mode" "<MODE>")])
15335 (define_insn "fist<mode>2"
15336   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15337         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15338                       UNSPEC_FIST))]
15339   "TARGET_USE_FANCY_MATH_387"
15340   "* return output_fix_trunc (insn, operands, false);"
15341   [(set_attr "type" "fpspc")
15342    (set_attr "mode" "<MODE>")])
15344 (define_insn "fist<mode>2_with_temp"
15345   [(set (match_operand:SWI24 0 "register_operand" "=r")
15346         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15347                       UNSPEC_FIST))
15348    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15349   "TARGET_USE_FANCY_MATH_387"
15350   "#"
15351   [(set_attr "type" "fpspc")
15352    (set_attr "mode" "<MODE>")])
15354 (define_split
15355   [(set (match_operand:SWI24 0 "register_operand")
15356         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15357                       UNSPEC_FIST))
15358    (clobber (match_operand:SWI24 2 "memory_operand"))]
15359   "reload_completed"
15360   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15361    (set (match_dup 0) (match_dup 2))])
15363 (define_split
15364   [(set (match_operand:SWI24 0 "memory_operand")
15365         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15366                       UNSPEC_FIST))
15367    (clobber (match_operand:SWI24 2 "memory_operand"))]
15368   "reload_completed"
15369   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15371 (define_expand "lrintxf<mode>2"
15372   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15373      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15374                      UNSPEC_FIST))]
15375   "TARGET_USE_FANCY_MATH_387")
15377 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15378   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15379      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15380                    UNSPEC_FIX_NOTRUNC))]
15381   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15383 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15384   [(match_operand:SWI248x 0 "nonimmediate_operand")
15385    (match_operand:X87MODEF 1 "register_operand")]
15386   "(TARGET_USE_FANCY_MATH_387
15387     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15388         || TARGET_MIX_SSE_I387)
15389     && flag_unsafe_math_optimizations)
15390    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15391        && <SWI248x:MODE>mode != HImode 
15392        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15393        && !flag_trapping_math && !flag_rounding_math)"
15395   if (optimize_insn_for_size_p ())
15396     FAIL;
15398   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15399       && <SWI248x:MODE>mode != HImode
15400       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15401       && !flag_trapping_math && !flag_rounding_math)
15402     ix86_expand_lround (operands[0], operands[1]);
15403   else
15404     ix86_emit_i387_round (operands[0], operands[1]);
15405   DONE;
15408 (define_int_iterator FRNDINT_ROUNDING
15409         [UNSPEC_FRNDINT_FLOOR
15410          UNSPEC_FRNDINT_CEIL
15411          UNSPEC_FRNDINT_TRUNC])
15413 (define_int_iterator FIST_ROUNDING
15414         [UNSPEC_FIST_FLOOR
15415          UNSPEC_FIST_CEIL])
15417 ;; Base name for define_insn
15418 (define_int_attr rounding_insn
15419         [(UNSPEC_FRNDINT_FLOOR "floor")
15420          (UNSPEC_FRNDINT_CEIL "ceil")
15421          (UNSPEC_FRNDINT_TRUNC "btrunc")
15422          (UNSPEC_FIST_FLOOR "floor")
15423          (UNSPEC_FIST_CEIL "ceil")])
15425 (define_int_attr rounding
15426         [(UNSPEC_FRNDINT_FLOOR "floor")
15427          (UNSPEC_FRNDINT_CEIL "ceil")
15428          (UNSPEC_FRNDINT_TRUNC "trunc")
15429          (UNSPEC_FIST_FLOOR "floor")
15430          (UNSPEC_FIST_CEIL "ceil")])
15432 (define_int_attr ROUNDING
15433         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15434          (UNSPEC_FRNDINT_CEIL "CEIL")
15435          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15436          (UNSPEC_FIST_FLOOR "FLOOR")
15437          (UNSPEC_FIST_CEIL "CEIL")])
15439 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15440 (define_insn_and_split "frndintxf2_<rounding>"
15441   [(set (match_operand:XF 0 "register_operand")
15442         (unspec:XF [(match_operand:XF 1 "register_operand")]
15443                    FRNDINT_ROUNDING))
15444    (clobber (reg:CC FLAGS_REG))]
15445   "TARGET_USE_FANCY_MATH_387
15446    && flag_unsafe_math_optimizations
15447    && can_create_pseudo_p ()"
15448   "#"
15449   "&& 1"
15450   [(const_int 0)]
15452   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15454   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15455   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15457   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15458                                              operands[2], operands[3]));
15459   DONE;
15461   [(set_attr "type" "frndint")
15462    (set_attr "i387_cw" "<rounding>")
15463    (set_attr "mode" "XF")])
15465 (define_insn "frndintxf2_<rounding>_i387"
15466   [(set (match_operand:XF 0 "register_operand" "=f")
15467         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15468                    FRNDINT_ROUNDING))
15469    (use (match_operand:HI 2 "memory_operand" "m"))
15470    (use (match_operand:HI 3 "memory_operand" "m"))]
15471   "TARGET_USE_FANCY_MATH_387
15472    && flag_unsafe_math_optimizations"
15473   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15474   [(set_attr "type" "frndint")
15475    (set_attr "i387_cw" "<rounding>")
15476    (set_attr "mode" "XF")])
15478 (define_expand "<rounding_insn>xf2"
15479   [(parallel [(set (match_operand:XF 0 "register_operand")
15480                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15481                               FRNDINT_ROUNDING))
15482               (clobber (reg:CC FLAGS_REG))])]
15483   "TARGET_USE_FANCY_MATH_387
15484    && flag_unsafe_math_optimizations
15485    && !optimize_insn_for_size_p ()")
15487 (define_expand "<rounding_insn><mode>2"
15488   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15489                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15490                                  FRNDINT_ROUNDING))
15491               (clobber (reg:CC FLAGS_REG))])]
15492   "(TARGET_USE_FANCY_MATH_387
15493     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494         || TARGET_MIX_SSE_I387)
15495     && flag_unsafe_math_optimizations)
15496    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15497        && !flag_trapping_math)"
15499   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15500       && !flag_trapping_math)
15501     {
15502       if (TARGET_ROUND)
15503         emit_insn (gen_sse4_1_round<mode>2
15504                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15505       else if (optimize_insn_for_size_p ())
15506         FAIL;
15507       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15508         {
15509           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15510             ix86_expand_floorceil (operands[0], operands[1], true);
15511           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15512             ix86_expand_floorceil (operands[0], operands[1], false);
15513           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15514             ix86_expand_trunc (operands[0], operands[1]);
15515           else
15516             gcc_unreachable ();
15517         }
15518       else
15519         {
15520           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15521             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15522           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15523             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15524           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15525             ix86_expand_truncdf_32 (operands[0], operands[1]);
15526           else
15527             gcc_unreachable ();
15528         }
15529     }
15530   else
15531     {
15532       rtx op0, op1;
15534       if (optimize_insn_for_size_p ())
15535         FAIL;
15537       op0 = gen_reg_rtx (XFmode);
15538       op1 = gen_reg_rtx (XFmode);
15539       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15540       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15542       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15543     }
15544   DONE;
15547 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15548 (define_insn_and_split "frndintxf2_mask_pm"
15549   [(set (match_operand:XF 0 "register_operand")
15550         (unspec:XF [(match_operand:XF 1 "register_operand")]
15551                    UNSPEC_FRNDINT_MASK_PM))
15552    (clobber (reg:CC FLAGS_REG))]
15553   "TARGET_USE_FANCY_MATH_387
15554    && flag_unsafe_math_optimizations
15555    && can_create_pseudo_p ()"
15556   "#"
15557   "&& 1"
15558   [(const_int 0)]
15560   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15562   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15563   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15565   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15566                                           operands[2], operands[3]));
15567   DONE;
15569   [(set_attr "type" "frndint")
15570    (set_attr "i387_cw" "mask_pm")
15571    (set_attr "mode" "XF")])
15573 (define_insn "frndintxf2_mask_pm_i387"
15574   [(set (match_operand:XF 0 "register_operand" "=f")
15575         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15576                    UNSPEC_FRNDINT_MASK_PM))
15577    (use (match_operand:HI 2 "memory_operand" "m"))
15578    (use (match_operand:HI 3 "memory_operand" "m"))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && flag_unsafe_math_optimizations"
15581   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15582   [(set_attr "type" "frndint")
15583    (set_attr "i387_cw" "mask_pm")
15584    (set_attr "mode" "XF")])
15586 (define_expand "nearbyintxf2"
15587   [(parallel [(set (match_operand:XF 0 "register_operand")
15588                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15589                               UNSPEC_FRNDINT_MASK_PM))
15590               (clobber (reg:CC FLAGS_REG))])]
15591   "TARGET_USE_FANCY_MATH_387
15592    && flag_unsafe_math_optimizations")
15594 (define_expand "nearbyint<mode>2"
15595   [(use (match_operand:MODEF 0 "register_operand"))
15596    (use (match_operand:MODEF 1 "register_operand"))]
15597   "TARGET_USE_FANCY_MATH_387
15598    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15599        || TARGET_MIX_SSE_I387)
15600    && flag_unsafe_math_optimizations"
15602   rtx op0 = gen_reg_rtx (XFmode);
15603   rtx op1 = gen_reg_rtx (XFmode);
15605   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15606   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15608   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15609   DONE;
15612 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15613 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15614   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15615         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15616                         FIST_ROUNDING))
15617    (clobber (reg:CC FLAGS_REG))]
15618   "TARGET_USE_FANCY_MATH_387
15619    && flag_unsafe_math_optimizations
15620    && can_create_pseudo_p ()"
15621   "#"
15622   "&& 1"
15623   [(const_int 0)]
15625   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15627   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15628   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15629   if (memory_operand (operands[0], VOIDmode))
15630     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15631                                            operands[2], operands[3]));
15632   else
15633     {
15634       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15635       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15636                   (operands[0], operands[1], operands[2],
15637                    operands[3], operands[4]));
15638     }
15639   DONE;
15641   [(set_attr "type" "fistp")
15642    (set_attr "i387_cw" "<rounding>")
15643    (set_attr "mode" "<MODE>")])
15645 (define_insn "fistdi2_<rounding>"
15646   [(set (match_operand:DI 0 "memory_operand" "=m")
15647         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15648                    FIST_ROUNDING))
15649    (use (match_operand:HI 2 "memory_operand" "m"))
15650    (use (match_operand:HI 3 "memory_operand" "m"))
15651    (clobber (match_scratch:XF 4 "=&1f"))]
15652   "TARGET_USE_FANCY_MATH_387
15653    && flag_unsafe_math_optimizations"
15654   "* return output_fix_trunc (insn, operands, false);"
15655   [(set_attr "type" "fistp")
15656    (set_attr "i387_cw" "<rounding>")
15657    (set_attr "mode" "DI")])
15659 (define_insn "fistdi2_<rounding>_with_temp"
15660   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15661         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15662                    FIST_ROUNDING))
15663    (use (match_operand:HI 2 "memory_operand" "m,m"))
15664    (use (match_operand:HI 3 "memory_operand" "m,m"))
15665    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15666    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15667   "TARGET_USE_FANCY_MATH_387
15668    && flag_unsafe_math_optimizations"
15669   "#"
15670   [(set_attr "type" "fistp")
15671    (set_attr "i387_cw" "<rounding>")
15672    (set_attr "mode" "DI")])
15674 (define_split
15675   [(set (match_operand:DI 0 "register_operand")
15676         (unspec:DI [(match_operand:XF 1 "register_operand")]
15677                    FIST_ROUNDING))
15678    (use (match_operand:HI 2 "memory_operand"))
15679    (use (match_operand:HI 3 "memory_operand"))
15680    (clobber (match_operand:DI 4 "memory_operand"))
15681    (clobber (match_scratch 5))]
15682   "reload_completed"
15683   [(parallel [(set (match_dup 4)
15684                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15685               (use (match_dup 2))
15686               (use (match_dup 3))
15687               (clobber (match_dup 5))])
15688    (set (match_dup 0) (match_dup 4))])
15690 (define_split
15691   [(set (match_operand:DI 0 "memory_operand")
15692         (unspec:DI [(match_operand:XF 1 "register_operand")]
15693                    FIST_ROUNDING))
15694    (use (match_operand:HI 2 "memory_operand"))
15695    (use (match_operand:HI 3 "memory_operand"))
15696    (clobber (match_operand:DI 4 "memory_operand"))
15697    (clobber (match_scratch 5))]
15698   "reload_completed"
15699   [(parallel [(set (match_dup 0)
15700                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15701               (use (match_dup 2))
15702               (use (match_dup 3))
15703               (clobber (match_dup 5))])])
15705 (define_insn "fist<mode>2_<rounding>"
15706   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15707         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15708                       FIST_ROUNDING))
15709    (use (match_operand:HI 2 "memory_operand" "m"))
15710    (use (match_operand:HI 3 "memory_operand" "m"))]
15711   "TARGET_USE_FANCY_MATH_387
15712    && flag_unsafe_math_optimizations"
15713   "* return output_fix_trunc (insn, operands, false);"
15714   [(set_attr "type" "fistp")
15715    (set_attr "i387_cw" "<rounding>")
15716    (set_attr "mode" "<MODE>")])
15718 (define_insn "fist<mode>2_<rounding>_with_temp"
15719   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15720         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15721                       FIST_ROUNDING))
15722    (use (match_operand:HI 2 "memory_operand" "m,m"))
15723    (use (match_operand:HI 3 "memory_operand" "m,m"))
15724    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15725   "TARGET_USE_FANCY_MATH_387
15726    && flag_unsafe_math_optimizations"
15727   "#"
15728   [(set_attr "type" "fistp")
15729    (set_attr "i387_cw" "<rounding>")
15730    (set_attr "mode" "<MODE>")])
15732 (define_split
15733   [(set (match_operand:SWI24 0 "register_operand")
15734         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15735                       FIST_ROUNDING))
15736    (use (match_operand:HI 2 "memory_operand"))
15737    (use (match_operand:HI 3 "memory_operand"))
15738    (clobber (match_operand:SWI24 4 "memory_operand"))]
15739   "reload_completed"
15740   [(parallel [(set (match_dup 4)
15741                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15742               (use (match_dup 2))
15743               (use (match_dup 3))])
15744    (set (match_dup 0) (match_dup 4))])
15746 (define_split
15747   [(set (match_operand:SWI24 0 "memory_operand")
15748         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15749                       FIST_ROUNDING))
15750    (use (match_operand:HI 2 "memory_operand"))
15751    (use (match_operand:HI 3 "memory_operand"))
15752    (clobber (match_operand:SWI24 4 "memory_operand"))]
15753   "reload_completed"
15754   [(parallel [(set (match_dup 0)
15755                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15756               (use (match_dup 2))
15757               (use (match_dup 3))])])
15759 (define_expand "l<rounding_insn>xf<mode>2"
15760   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15761                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15762                                    FIST_ROUNDING))
15763               (clobber (reg:CC FLAGS_REG))])]
15764   "TARGET_USE_FANCY_MATH_387
15765    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15766    && flag_unsafe_math_optimizations")
15768 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15769   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15770                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15771                                  FIST_ROUNDING))
15772               (clobber (reg:CC FLAGS_REG))])]
15773   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15774    && !flag_trapping_math"
15776   if (TARGET_64BIT && optimize_insn_for_size_p ())
15777     FAIL;
15779   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15780     ix86_expand_lfloorceil (operands[0], operands[1], true);
15781   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15782     ix86_expand_lfloorceil (operands[0], operands[1], false);
15783   else
15784     gcc_unreachable ();
15786   DONE;
15789 (define_insn "fxam<mode>2_i387"
15790   [(set (match_operand:HI 0 "register_operand" "=a")
15791         (unspec:HI
15792           [(match_operand:X87MODEF 1 "register_operand" "f")]
15793           UNSPEC_FXAM))]
15794   "TARGET_USE_FANCY_MATH_387"
15795   "fxam\n\tfnstsw\t%0"
15796   [(set_attr "type" "multi")
15797    (set_attr "length" "4")
15798    (set_attr "unit" "i387")
15799    (set_attr "mode" "<MODE>")])
15801 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15802   [(set (match_operand:HI 0 "register_operand")
15803         (unspec:HI
15804           [(match_operand:MODEF 1 "memory_operand")]
15805           UNSPEC_FXAM_MEM))]
15806   "TARGET_USE_FANCY_MATH_387
15807    && can_create_pseudo_p ()"
15808   "#"
15809   "&& 1"
15810   [(set (match_dup 2)(match_dup 1))
15811    (set (match_dup 0)
15812         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15814   operands[2] = gen_reg_rtx (<MODE>mode);
15816   MEM_VOLATILE_P (operands[1]) = 1;
15818   [(set_attr "type" "multi")
15819    (set_attr "unit" "i387")
15820    (set_attr "mode" "<MODE>")])
15822 (define_expand "isinfxf2"
15823   [(use (match_operand:SI 0 "register_operand"))
15824    (use (match_operand:XF 1 "register_operand"))]
15825   "TARGET_USE_FANCY_MATH_387
15826    && ix86_libc_has_function (function_c99_misc)"
15828   rtx mask = GEN_INT (0x45);
15829   rtx val = GEN_INT (0x05);
15831   rtx cond;
15833   rtx scratch = gen_reg_rtx (HImode);
15834   rtx res = gen_reg_rtx (QImode);
15836   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15838   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15839   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15840   cond = gen_rtx_fmt_ee (EQ, QImode,
15841                          gen_rtx_REG (CCmode, FLAGS_REG),
15842                          const0_rtx);
15843   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15844   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15845   DONE;
15848 (define_expand "isinf<mode>2"
15849   [(use (match_operand:SI 0 "register_operand"))
15850    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15851   "TARGET_USE_FANCY_MATH_387
15852    && ix86_libc_has_function (function_c99_misc)
15853    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15855   rtx mask = GEN_INT (0x45);
15856   rtx val = GEN_INT (0x05);
15858   rtx cond;
15860   rtx scratch = gen_reg_rtx (HImode);
15861   rtx res = gen_reg_rtx (QImode);
15863   /* Remove excess precision by forcing value through memory. */
15864   if (memory_operand (operands[1], VOIDmode))
15865     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15866   else
15867     {
15868       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15870       emit_move_insn (temp, operands[1]);
15871       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15872     }
15874   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15875   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15876   cond = gen_rtx_fmt_ee (EQ, QImode,
15877                          gen_rtx_REG (CCmode, FLAGS_REG),
15878                          const0_rtx);
15879   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15880   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15881   DONE;
15884 (define_expand "signbitxf2"
15885   [(use (match_operand:SI 0 "register_operand"))
15886    (use (match_operand:XF 1 "register_operand"))]
15887   "TARGET_USE_FANCY_MATH_387"
15889   rtx scratch = gen_reg_rtx (HImode);
15891   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15892   emit_insn (gen_andsi3 (operands[0],
15893              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15894   DONE;
15897 (define_insn "movmsk_df"
15898   [(set (match_operand:SI 0 "register_operand" "=r")
15899         (unspec:SI
15900           [(match_operand:DF 1 "register_operand" "x")]
15901           UNSPEC_MOVMSK))]
15902   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15903   "%vmovmskpd\t{%1, %0|%0, %1}"
15904   [(set_attr "type" "ssemov")
15905    (set_attr "prefix" "maybe_vex")
15906    (set_attr "mode" "DF")])
15908 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15909 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15910 (define_expand "signbitdf2"
15911   [(use (match_operand:SI 0 "register_operand"))
15912    (use (match_operand:DF 1 "register_operand"))]
15913   "TARGET_USE_FANCY_MATH_387
15914    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15916   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15917     {
15918       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15919       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15920     }
15921   else
15922     {
15923       rtx scratch = gen_reg_rtx (HImode);
15925       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15926       emit_insn (gen_andsi3 (operands[0],
15927                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15928     }
15929   DONE;
15932 (define_expand "signbitsf2"
15933   [(use (match_operand:SI 0 "register_operand"))
15934    (use (match_operand:SF 1 "register_operand"))]
15935   "TARGET_USE_FANCY_MATH_387
15936    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15938   rtx scratch = gen_reg_rtx (HImode);
15940   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15941   emit_insn (gen_andsi3 (operands[0],
15942              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15943   DONE;
15946 ;; Block operation instructions
15948 (define_insn "cld"
15949   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15950   ""
15951   "cld"
15952   [(set_attr "length" "1")
15953    (set_attr "length_immediate" "0")
15954    (set_attr "modrm" "0")])
15956 (define_expand "movmem<mode>"
15957   [(use (match_operand:BLK 0 "memory_operand"))
15958    (use (match_operand:BLK 1 "memory_operand"))
15959    (use (match_operand:SWI48 2 "nonmemory_operand"))
15960    (use (match_operand:SWI48 3 "const_int_operand"))
15961    (use (match_operand:SI 4 "const_int_operand"))
15962    (use (match_operand:SI 5 "const_int_operand"))
15963    (use (match_operand:SI 6 ""))
15964    (use (match_operand:SI 7 ""))
15965    (use (match_operand:SI 8 ""))]
15966   ""
15968  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15969                                 operands[2], NULL, operands[3],
15970                                 operands[4], operands[5],
15971                                 operands[6], operands[7],
15972                                 operands[8], false))
15973    DONE;
15974  else
15975    FAIL;
15978 ;; Most CPUs don't like single string operations
15979 ;; Handle this case here to simplify previous expander.
15981 (define_expand "strmov"
15982   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15983    (set (match_operand 1 "memory_operand") (match_dup 4))
15984    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15985               (clobber (reg:CC FLAGS_REG))])
15986    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15987               (clobber (reg:CC FLAGS_REG))])]
15988   ""
15990   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15992   /* If .md ever supports :P for Pmode, these can be directly
15993      in the pattern above.  */
15994   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15995   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15997   /* Can't use this if the user has appropriated esi or edi.  */
15998   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15999       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16000     {
16001       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16002                                       operands[2], operands[3],
16003                                       operands[5], operands[6]));
16004       DONE;
16005     }
16007   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16010 (define_expand "strmov_singleop"
16011   [(parallel [(set (match_operand 1 "memory_operand")
16012                    (match_operand 3 "memory_operand"))
16013               (set (match_operand 0 "register_operand")
16014                    (match_operand 4))
16015               (set (match_operand 2 "register_operand")
16016                    (match_operand 5))])]
16017   ""
16018   "ix86_current_function_needs_cld = 1;")
16020 (define_insn "*strmovdi_rex_1"
16021   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16022         (mem:DI (match_operand:P 3 "register_operand" "1")))
16023    (set (match_operand:P 0 "register_operand" "=D")
16024         (plus:P (match_dup 2)
16025                 (const_int 8)))
16026    (set (match_operand:P 1 "register_operand" "=S")
16027         (plus:P (match_dup 3)
16028                 (const_int 8)))]
16029   "TARGET_64BIT
16030    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16031   "%^movsq"
16032   [(set_attr "type" "str")
16033    (set_attr "memory" "both")
16034    (set_attr "mode" "DI")])
16036 (define_insn "*strmovsi_1"
16037   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16038         (mem:SI (match_operand:P 3 "register_operand" "1")))
16039    (set (match_operand:P 0 "register_operand" "=D")
16040         (plus:P (match_dup 2)
16041                 (const_int 4)))
16042    (set (match_operand:P 1 "register_operand" "=S")
16043         (plus:P (match_dup 3)
16044                 (const_int 4)))]
16045   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16046   "%^movs{l|d}"
16047   [(set_attr "type" "str")
16048    (set_attr "memory" "both")
16049    (set_attr "mode" "SI")])
16051 (define_insn "*strmovhi_1"
16052   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16053         (mem:HI (match_operand:P 3 "register_operand" "1")))
16054    (set (match_operand:P 0 "register_operand" "=D")
16055         (plus:P (match_dup 2)
16056                 (const_int 2)))
16057    (set (match_operand:P 1 "register_operand" "=S")
16058         (plus:P (match_dup 3)
16059                 (const_int 2)))]
16060   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16061   "%^movsw"
16062   [(set_attr "type" "str")
16063    (set_attr "memory" "both")
16064    (set_attr "mode" "HI")])
16066 (define_insn "*strmovqi_1"
16067   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16068         (mem:QI (match_operand:P 3 "register_operand" "1")))
16069    (set (match_operand:P 0 "register_operand" "=D")
16070         (plus:P (match_dup 2)
16071                 (const_int 1)))
16072    (set (match_operand:P 1 "register_operand" "=S")
16073         (plus:P (match_dup 3)
16074                 (const_int 1)))]
16075   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16076   "%^movsb"
16077   [(set_attr "type" "str")
16078    (set_attr "memory" "both")
16079    (set (attr "prefix_rex")
16080         (if_then_else
16081           (match_test "<P:MODE>mode == DImode")
16082           (const_string "0")
16083           (const_string "*")))
16084    (set_attr "mode" "QI")])
16086 (define_expand "rep_mov"
16087   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16088               (set (match_operand 0 "register_operand")
16089                    (match_operand 5))
16090               (set (match_operand 2 "register_operand")
16091                    (match_operand 6))
16092               (set (match_operand 1 "memory_operand")
16093                    (match_operand 3 "memory_operand"))
16094               (use (match_dup 4))])]
16095   ""
16096   "ix86_current_function_needs_cld = 1;")
16098 (define_insn "*rep_movdi_rex64"
16099   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16100    (set (match_operand:P 0 "register_operand" "=D")
16101         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16102                           (const_int 3))
16103                 (match_operand:P 3 "register_operand" "0")))
16104    (set (match_operand:P 1 "register_operand" "=S")
16105         (plus:P (ashift:P (match_dup 5) (const_int 3))
16106                 (match_operand:P 4 "register_operand" "1")))
16107    (set (mem:BLK (match_dup 3))
16108         (mem:BLK (match_dup 4)))
16109    (use (match_dup 5))]
16110   "TARGET_64BIT
16111    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16112   "%^rep{%;} movsq"
16113   [(set_attr "type" "str")
16114    (set_attr "prefix_rep" "1")
16115    (set_attr "memory" "both")
16116    (set_attr "mode" "DI")])
16118 (define_insn "*rep_movsi"
16119   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16120    (set (match_operand:P 0 "register_operand" "=D")
16121         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16122                           (const_int 2))
16123                  (match_operand:P 3 "register_operand" "0")))
16124    (set (match_operand:P 1 "register_operand" "=S")
16125         (plus:P (ashift:P (match_dup 5) (const_int 2))
16126                 (match_operand:P 4 "register_operand" "1")))
16127    (set (mem:BLK (match_dup 3))
16128         (mem:BLK (match_dup 4)))
16129    (use (match_dup 5))]
16130   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16131   "%^rep{%;} movs{l|d}"
16132   [(set_attr "type" "str")
16133    (set_attr "prefix_rep" "1")
16134    (set_attr "memory" "both")
16135    (set_attr "mode" "SI")])
16137 (define_insn "*rep_movqi"
16138   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16139    (set (match_operand:P 0 "register_operand" "=D")
16140         (plus:P (match_operand:P 3 "register_operand" "0")
16141                 (match_operand:P 5 "register_operand" "2")))
16142    (set (match_operand:P 1 "register_operand" "=S")
16143         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16144    (set (mem:BLK (match_dup 3))
16145         (mem:BLK (match_dup 4)))
16146    (use (match_dup 5))]
16147   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16148   "%^rep{%;} movsb"
16149   [(set_attr "type" "str")
16150    (set_attr "prefix_rep" "1")
16151    (set_attr "memory" "both")
16152    (set_attr "mode" "QI")])
16154 (define_expand "setmem<mode>"
16155    [(use (match_operand:BLK 0 "memory_operand"))
16156     (use (match_operand:SWI48 1 "nonmemory_operand"))
16157     (use (match_operand:QI 2 "nonmemory_operand"))
16158     (use (match_operand 3 "const_int_operand"))
16159     (use (match_operand:SI 4 "const_int_operand"))
16160     (use (match_operand:SI 5 "const_int_operand"))
16161     (use (match_operand:SI 6 ""))
16162     (use (match_operand:SI 7 ""))
16163     (use (match_operand:SI 8 ""))]
16164   ""
16166  if (ix86_expand_set_or_movmem (operands[0], NULL,
16167                                 operands[1], operands[2],
16168                                 operands[3], operands[4],
16169                                 operands[5], operands[6],
16170                                 operands[7], operands[8], true))
16171    DONE;
16172  else
16173    FAIL;
16176 ;; Most CPUs don't like single string operations
16177 ;; Handle this case here to simplify previous expander.
16179 (define_expand "strset"
16180   [(set (match_operand 1 "memory_operand")
16181         (match_operand 2 "register_operand"))
16182    (parallel [(set (match_operand 0 "register_operand")
16183                    (match_dup 3))
16184               (clobber (reg:CC FLAGS_REG))])]
16185   ""
16187   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16188     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16190   /* If .md ever supports :P for Pmode, this can be directly
16191      in the pattern above.  */
16192   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16193                               GEN_INT (GET_MODE_SIZE (GET_MODE
16194                                                       (operands[2]))));
16195   /* Can't use this if the user has appropriated eax or edi.  */
16196   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16197       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16198     {
16199       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16200                                       operands[3]));
16201       DONE;
16202     }
16205 (define_expand "strset_singleop"
16206   [(parallel [(set (match_operand 1 "memory_operand")
16207                    (match_operand 2 "register_operand"))
16208               (set (match_operand 0 "register_operand")
16209                    (match_operand 3))
16210               (unspec [(const_int 0)] UNSPEC_STOS)])]
16211   ""
16212   "ix86_current_function_needs_cld = 1;")
16214 (define_insn "*strsetdi_rex_1"
16215   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16216         (match_operand:DI 2 "register_operand" "a"))
16217    (set (match_operand:P 0 "register_operand" "=D")
16218         (plus:P (match_dup 1)
16219                 (const_int 8)))
16220    (unspec [(const_int 0)] UNSPEC_STOS)]
16221   "TARGET_64BIT
16222    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16223   "%^stosq"
16224   [(set_attr "type" "str")
16225    (set_attr "memory" "store")
16226    (set_attr "mode" "DI")])
16228 (define_insn "*strsetsi_1"
16229   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16230         (match_operand:SI 2 "register_operand" "a"))
16231    (set (match_operand:P 0 "register_operand" "=D")
16232         (plus:P (match_dup 1)
16233                 (const_int 4)))
16234    (unspec [(const_int 0)] UNSPEC_STOS)]
16235   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16236   "%^stos{l|d}"
16237   [(set_attr "type" "str")
16238    (set_attr "memory" "store")
16239    (set_attr "mode" "SI")])
16241 (define_insn "*strsethi_1"
16242   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16243         (match_operand:HI 2 "register_operand" "a"))
16244    (set (match_operand:P 0 "register_operand" "=D")
16245         (plus:P (match_dup 1)
16246                 (const_int 2)))
16247    (unspec [(const_int 0)] UNSPEC_STOS)]
16248   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16249   "%^stosw"
16250   [(set_attr "type" "str")
16251    (set_attr "memory" "store")
16252    (set_attr "mode" "HI")])
16254 (define_insn "*strsetqi_1"
16255   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16256         (match_operand:QI 2 "register_operand" "a"))
16257    (set (match_operand:P 0 "register_operand" "=D")
16258         (plus:P (match_dup 1)
16259                 (const_int 1)))
16260    (unspec [(const_int 0)] UNSPEC_STOS)]
16261   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16262   "%^stosb"
16263   [(set_attr "type" "str")
16264    (set_attr "memory" "store")
16265    (set (attr "prefix_rex")
16266         (if_then_else
16267           (match_test "<P:MODE>mode == DImode")
16268           (const_string "0")
16269           (const_string "*")))
16270    (set_attr "mode" "QI")])
16272 (define_expand "rep_stos"
16273   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16274               (set (match_operand 0 "register_operand")
16275                    (match_operand 4))
16276               (set (match_operand 2 "memory_operand") (const_int 0))
16277               (use (match_operand 3 "register_operand"))
16278               (use (match_dup 1))])]
16279   ""
16280   "ix86_current_function_needs_cld = 1;")
16282 (define_insn "*rep_stosdi_rex64"
16283   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16284    (set (match_operand:P 0 "register_operand" "=D")
16285         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16286                           (const_int 3))
16287                  (match_operand:P 3 "register_operand" "0")))
16288    (set (mem:BLK (match_dup 3))
16289         (const_int 0))
16290    (use (match_operand:DI 2 "register_operand" "a"))
16291    (use (match_dup 4))]
16292   "TARGET_64BIT
16293    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16294   "%^rep{%;} stosq"
16295   [(set_attr "type" "str")
16296    (set_attr "prefix_rep" "1")
16297    (set_attr "memory" "store")
16298    (set_attr "mode" "DI")])
16300 (define_insn "*rep_stossi"
16301   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16302    (set (match_operand:P 0 "register_operand" "=D")
16303         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16304                           (const_int 2))
16305                  (match_operand:P 3 "register_operand" "0")))
16306    (set (mem:BLK (match_dup 3))
16307         (const_int 0))
16308    (use (match_operand:SI 2 "register_operand" "a"))
16309    (use (match_dup 4))]
16310   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16311   "%^rep{%;} stos{l|d}"
16312   [(set_attr "type" "str")
16313    (set_attr "prefix_rep" "1")
16314    (set_attr "memory" "store")
16315    (set_attr "mode" "SI")])
16317 (define_insn "*rep_stosqi"
16318   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16319    (set (match_operand:P 0 "register_operand" "=D")
16320         (plus:P (match_operand:P 3 "register_operand" "0")
16321                 (match_operand:P 4 "register_operand" "1")))
16322    (set (mem:BLK (match_dup 3))
16323         (const_int 0))
16324    (use (match_operand:QI 2 "register_operand" "a"))
16325    (use (match_dup 4))]
16326   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16327   "%^rep{%;} stosb"
16328   [(set_attr "type" "str")
16329    (set_attr "prefix_rep" "1")
16330    (set_attr "memory" "store")
16331    (set (attr "prefix_rex")
16332         (if_then_else
16333           (match_test "<P:MODE>mode == DImode")
16334           (const_string "0")
16335           (const_string "*")))
16336    (set_attr "mode" "QI")])
16338 (define_expand "cmpstrnsi"
16339   [(set (match_operand:SI 0 "register_operand")
16340         (compare:SI (match_operand:BLK 1 "general_operand")
16341                     (match_operand:BLK 2 "general_operand")))
16342    (use (match_operand 3 "general_operand"))
16343    (use (match_operand 4 "immediate_operand"))]
16344   ""
16346   rtx addr1, addr2, out, outlow, count, countreg, align;
16348   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16349     FAIL;
16351   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16352   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16353     FAIL;
16355   out = operands[0];
16356   if (!REG_P (out))
16357     out = gen_reg_rtx (SImode);
16359   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16360   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16361   if (addr1 != XEXP (operands[1], 0))
16362     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16363   if (addr2 != XEXP (operands[2], 0))
16364     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16366   count = operands[3];
16367   countreg = ix86_zero_extend_to_Pmode (count);
16369   /* %%% Iff we are testing strict equality, we can use known alignment
16370      to good advantage.  This may be possible with combine, particularly
16371      once cc0 is dead.  */
16372   align = operands[4];
16374   if (CONST_INT_P (count))
16375     {
16376       if (INTVAL (count) == 0)
16377         {
16378           emit_move_insn (operands[0], const0_rtx);
16379           DONE;
16380         }
16381       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16382                                      operands[1], operands[2]));
16383     }
16384   else
16385     {
16386       rtx (*gen_cmp) (rtx, rtx);
16388       gen_cmp = (TARGET_64BIT
16389                  ? gen_cmpdi_1 : gen_cmpsi_1);
16391       emit_insn (gen_cmp (countreg, countreg));
16392       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16393                                   operands[1], operands[2]));
16394     }
16396   outlow = gen_lowpart (QImode, out);
16397   emit_insn (gen_cmpintqi (outlow));
16398   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16400   if (operands[0] != out)
16401     emit_move_insn (operands[0], out);
16403   DONE;
16406 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16408 (define_expand "cmpintqi"
16409   [(set (match_dup 1)
16410         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16411    (set (match_dup 2)
16412         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16413    (parallel [(set (match_operand:QI 0 "register_operand")
16414                    (minus:QI (match_dup 1)
16415                              (match_dup 2)))
16416               (clobber (reg:CC FLAGS_REG))])]
16417   ""
16419   operands[1] = gen_reg_rtx (QImode);
16420   operands[2] = gen_reg_rtx (QImode);
16423 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16424 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16426 (define_expand "cmpstrnqi_nz_1"
16427   [(parallel [(set (reg:CC FLAGS_REG)
16428                    (compare:CC (match_operand 4 "memory_operand")
16429                                (match_operand 5 "memory_operand")))
16430               (use (match_operand 2 "register_operand"))
16431               (use (match_operand:SI 3 "immediate_operand"))
16432               (clobber (match_operand 0 "register_operand"))
16433               (clobber (match_operand 1 "register_operand"))
16434               (clobber (match_dup 2))])]
16435   ""
16436   "ix86_current_function_needs_cld = 1;")
16438 (define_insn "*cmpstrnqi_nz_1"
16439   [(set (reg:CC FLAGS_REG)
16440         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16441                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16442    (use (match_operand:P 6 "register_operand" "2"))
16443    (use (match_operand:SI 3 "immediate_operand" "i"))
16444    (clobber (match_operand:P 0 "register_operand" "=S"))
16445    (clobber (match_operand:P 1 "register_operand" "=D"))
16446    (clobber (match_operand:P 2 "register_operand" "=c"))]
16447   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16448   "%^repz{%;} cmpsb"
16449   [(set_attr "type" "str")
16450    (set_attr "mode" "QI")
16451    (set (attr "prefix_rex")
16452         (if_then_else
16453           (match_test "<P:MODE>mode == DImode")
16454           (const_string "0")
16455           (const_string "*")))
16456    (set_attr "prefix_rep" "1")])
16458 ;; The same, but the count is not known to not be zero.
16460 (define_expand "cmpstrnqi_1"
16461   [(parallel [(set (reg:CC FLAGS_REG)
16462                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16463                                      (const_int 0))
16464                   (compare:CC (match_operand 4 "memory_operand")
16465                               (match_operand 5 "memory_operand"))
16466                   (const_int 0)))
16467               (use (match_operand:SI 3 "immediate_operand"))
16468               (use (reg:CC FLAGS_REG))
16469               (clobber (match_operand 0 "register_operand"))
16470               (clobber (match_operand 1 "register_operand"))
16471               (clobber (match_dup 2))])]
16472   ""
16473   "ix86_current_function_needs_cld = 1;")
16475 (define_insn "*cmpstrnqi_1"
16476   [(set (reg:CC FLAGS_REG)
16477         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16478                              (const_int 0))
16479           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16480                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16481           (const_int 0)))
16482    (use (match_operand:SI 3 "immediate_operand" "i"))
16483    (use (reg:CC FLAGS_REG))
16484    (clobber (match_operand:P 0 "register_operand" "=S"))
16485    (clobber (match_operand:P 1 "register_operand" "=D"))
16486    (clobber (match_operand:P 2 "register_operand" "=c"))]
16487   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16488   "%^repz{%;} cmpsb"
16489   [(set_attr "type" "str")
16490    (set_attr "mode" "QI")
16491    (set (attr "prefix_rex")
16492         (if_then_else
16493           (match_test "<P:MODE>mode == DImode")
16494           (const_string "0")
16495           (const_string "*")))
16496    (set_attr "prefix_rep" "1")])
16498 (define_expand "strlen<mode>"
16499   [(set (match_operand:P 0 "register_operand")
16500         (unspec:P [(match_operand:BLK 1 "general_operand")
16501                    (match_operand:QI 2 "immediate_operand")
16502                    (match_operand 3 "immediate_operand")]
16503                   UNSPEC_SCAS))]
16504   ""
16506  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16507    DONE;
16508  else
16509    FAIL;
16512 (define_expand "strlenqi_1"
16513   [(parallel [(set (match_operand 0 "register_operand")
16514                    (match_operand 2))
16515               (clobber (match_operand 1 "register_operand"))
16516               (clobber (reg:CC FLAGS_REG))])]
16517   ""
16518   "ix86_current_function_needs_cld = 1;")
16520 (define_insn "*strlenqi_1"
16521   [(set (match_operand:P 0 "register_operand" "=&c")
16522         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16523                    (match_operand:QI 2 "register_operand" "a")
16524                    (match_operand:P 3 "immediate_operand" "i")
16525                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16526    (clobber (match_operand:P 1 "register_operand" "=D"))
16527    (clobber (reg:CC FLAGS_REG))]
16528   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16529   "%^repnz{%;} scasb"
16530   [(set_attr "type" "str")
16531    (set_attr "mode" "QI")
16532    (set (attr "prefix_rex")
16533         (if_then_else
16534           (match_test "<P:MODE>mode == DImode")
16535           (const_string "0")
16536           (const_string "*")))
16537    (set_attr "prefix_rep" "1")])
16539 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16540 ;; handled in combine, but it is not currently up to the task.
16541 ;; When used for their truth value, the cmpstrn* expanders generate
16542 ;; code like this:
16544 ;;   repz cmpsb
16545 ;;   seta       %al
16546 ;;   setb       %dl
16547 ;;   cmpb       %al, %dl
16548 ;;   jcc        label
16550 ;; The intermediate three instructions are unnecessary.
16552 ;; This one handles cmpstrn*_nz_1...
16553 (define_peephole2
16554   [(parallel[
16555      (set (reg:CC FLAGS_REG)
16556           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16557                       (mem:BLK (match_operand 5 "register_operand"))))
16558      (use (match_operand 6 "register_operand"))
16559      (use (match_operand:SI 3 "immediate_operand"))
16560      (clobber (match_operand 0 "register_operand"))
16561      (clobber (match_operand 1 "register_operand"))
16562      (clobber (match_operand 2 "register_operand"))])
16563    (set (match_operand:QI 7 "register_operand")
16564         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16565    (set (match_operand:QI 8 "register_operand")
16566         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16567    (set (reg FLAGS_REG)
16568         (compare (match_dup 7) (match_dup 8)))
16569   ]
16570   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16571   [(parallel[
16572      (set (reg:CC FLAGS_REG)
16573           (compare:CC (mem:BLK (match_dup 4))
16574                       (mem:BLK (match_dup 5))))
16575      (use (match_dup 6))
16576      (use (match_dup 3))
16577      (clobber (match_dup 0))
16578      (clobber (match_dup 1))
16579      (clobber (match_dup 2))])])
16581 ;; ...and this one handles cmpstrn*_1.
16582 (define_peephole2
16583   [(parallel[
16584      (set (reg:CC FLAGS_REG)
16585           (if_then_else:CC (ne (match_operand 6 "register_operand")
16586                                (const_int 0))
16587             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16588                         (mem:BLK (match_operand 5 "register_operand")))
16589             (const_int 0)))
16590      (use (match_operand:SI 3 "immediate_operand"))
16591      (use (reg:CC FLAGS_REG))
16592      (clobber (match_operand 0 "register_operand"))
16593      (clobber (match_operand 1 "register_operand"))
16594      (clobber (match_operand 2 "register_operand"))])
16595    (set (match_operand:QI 7 "register_operand")
16596         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16597    (set (match_operand:QI 8 "register_operand")
16598         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16599    (set (reg FLAGS_REG)
16600         (compare (match_dup 7) (match_dup 8)))
16601   ]
16602   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16603   [(parallel[
16604      (set (reg:CC FLAGS_REG)
16605           (if_then_else:CC (ne (match_dup 6)
16606                                (const_int 0))
16607             (compare:CC (mem:BLK (match_dup 4))
16608                         (mem:BLK (match_dup 5)))
16609             (const_int 0)))
16610      (use (match_dup 3))
16611      (use (reg:CC FLAGS_REG))
16612      (clobber (match_dup 0))
16613      (clobber (match_dup 1))
16614      (clobber (match_dup 2))])])
16616 ;; Conditional move instructions.
16618 (define_expand "mov<mode>cc"
16619   [(set (match_operand:SWIM 0 "register_operand")
16620         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16621                            (match_operand:SWIM 2 "<general_operand>")
16622                            (match_operand:SWIM 3 "<general_operand>")))]
16623   ""
16624   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16626 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16627 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16628 ;; So just document what we're doing explicitly.
16630 (define_expand "x86_mov<mode>cc_0_m1"
16631   [(parallel
16632     [(set (match_operand:SWI48 0 "register_operand")
16633           (if_then_else:SWI48
16634             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16635              [(match_operand 1 "flags_reg_operand")
16636               (const_int 0)])
16637             (const_int -1)
16638             (const_int 0)))
16639      (clobber (reg:CC FLAGS_REG))])])
16641 (define_insn "*x86_mov<mode>cc_0_m1"
16642   [(set (match_operand:SWI48 0 "register_operand" "=r")
16643         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16644                              [(reg FLAGS_REG) (const_int 0)])
16645           (const_int -1)
16646           (const_int 0)))
16647    (clobber (reg:CC FLAGS_REG))]
16648   ""
16649   "sbb{<imodesuffix>}\t%0, %0"
16650   ; Since we don't have the proper number of operands for an alu insn,
16651   ; fill in all the blanks.
16652   [(set_attr "type" "alu")
16653    (set_attr "use_carry" "1")
16654    (set_attr "pent_pair" "pu")
16655    (set_attr "memory" "none")
16656    (set_attr "imm_disp" "false")
16657    (set_attr "mode" "<MODE>")
16658    (set_attr "length_immediate" "0")])
16660 (define_insn "*x86_mov<mode>cc_0_m1_se"
16661   [(set (match_operand:SWI48 0 "register_operand" "=r")
16662         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16663                              [(reg FLAGS_REG) (const_int 0)])
16664                             (const_int 1)
16665                             (const_int 0)))
16666    (clobber (reg:CC FLAGS_REG))]
16667   ""
16668   "sbb{<imodesuffix>}\t%0, %0"
16669   [(set_attr "type" "alu")
16670    (set_attr "use_carry" "1")
16671    (set_attr "pent_pair" "pu")
16672    (set_attr "memory" "none")
16673    (set_attr "imm_disp" "false")
16674    (set_attr "mode" "<MODE>")
16675    (set_attr "length_immediate" "0")])
16677 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16678   [(set (match_operand:SWI48 0 "register_operand" "=r")
16679         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16680                     [(reg FLAGS_REG) (const_int 0)])))
16681    (clobber (reg:CC FLAGS_REG))]
16682   ""
16683   "sbb{<imodesuffix>}\t%0, %0"
16684   [(set_attr "type" "alu")
16685    (set_attr "use_carry" "1")
16686    (set_attr "pent_pair" "pu")
16687    (set_attr "memory" "none")
16688    (set_attr "imm_disp" "false")
16689    (set_attr "mode" "<MODE>")
16690    (set_attr "length_immediate" "0")])
16692 (define_insn "*mov<mode>cc_noc"
16693   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16694         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16695                                [(reg FLAGS_REG) (const_int 0)])
16696           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16697           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16698   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16699   "@
16700    cmov%O2%C1\t{%2, %0|%0, %2}
16701    cmov%O2%c1\t{%3, %0|%0, %3}"
16702   [(set_attr "type" "icmov")
16703    (set_attr "mode" "<MODE>")])
16705 ;; Don't do conditional moves with memory inputs.  This splitter helps
16706 ;; register starved x86_32 by forcing inputs into registers before reload.
16707 (define_split
16708   [(set (match_operand:SWI248 0 "register_operand")
16709         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16710                                [(reg FLAGS_REG) (const_int 0)])
16711           (match_operand:SWI248 2 "nonimmediate_operand")
16712           (match_operand:SWI248 3 "nonimmediate_operand")))]
16713   "!TARGET_64BIT && TARGET_CMOVE
16714    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16715    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16716    && can_create_pseudo_p ()
16717    && optimize_insn_for_speed_p ()"
16718   [(set (match_dup 0)
16719         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16721   if (MEM_P (operands[2]))
16722     operands[2] = force_reg (<MODE>mode, operands[2]);
16723   if (MEM_P (operands[3]))
16724     operands[3] = force_reg (<MODE>mode, operands[3]);
16727 (define_insn "*movqicc_noc"
16728   [(set (match_operand:QI 0 "register_operand" "=r,r")
16729         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16730                            [(reg FLAGS_REG) (const_int 0)])
16731                       (match_operand:QI 2 "register_operand" "r,0")
16732                       (match_operand:QI 3 "register_operand" "0,r")))]
16733   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16734   "#"
16735   [(set_attr "type" "icmov")
16736    (set_attr "mode" "QI")])
16738 (define_split
16739   [(set (match_operand:SWI12 0 "register_operand")
16740         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16741                               [(reg FLAGS_REG) (const_int 0)])
16742                       (match_operand:SWI12 2 "register_operand")
16743                       (match_operand:SWI12 3 "register_operand")))]
16744   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16745    && reload_completed"
16746   [(set (match_dup 0)
16747         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16749   operands[0] = gen_lowpart (SImode, operands[0]);
16750   operands[2] = gen_lowpart (SImode, operands[2]);
16751   operands[3] = gen_lowpart (SImode, operands[3]);
16754 ;; Don't do conditional moves with memory inputs
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_dup 0)
16761           (match_operand:SWI248 3 "memory_operand")))]
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 0) (match_dup 2)))])
16768 (define_peephole2
16769   [(match_scratch:SWI248 2 "r")
16770    (set (match_operand:SWI248 0 "register_operand")
16771         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16772                                [(reg FLAGS_REG) (const_int 0)])
16773           (match_operand:SWI248 3 "memory_operand")
16774           (match_dup 0)))]
16775   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16776    && optimize_insn_for_speed_p ()"
16777   [(set (match_dup 2) (match_dup 3))
16778    (set (match_dup 0)
16779         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16781 (define_expand "mov<mode>cc"
16782   [(set (match_operand:X87MODEF 0 "register_operand")
16783         (if_then_else:X87MODEF
16784           (match_operand 1 "comparison_operator")
16785           (match_operand:X87MODEF 2 "register_operand")
16786           (match_operand:X87MODEF 3 "register_operand")))]
16787   "(TARGET_80387 && TARGET_CMOVE)
16788    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16789   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16791 (define_insn "*movxfcc_1"
16792   [(set (match_operand:XF 0 "register_operand" "=f,f")
16793         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16794                                 [(reg FLAGS_REG) (const_int 0)])
16795                       (match_operand:XF 2 "register_operand" "f,0")
16796                       (match_operand:XF 3 "register_operand" "0,f")))]
16797   "TARGET_80387 && TARGET_CMOVE"
16798   "@
16799    fcmov%F1\t{%2, %0|%0, %2}
16800    fcmov%f1\t{%3, %0|%0, %3}"
16801   [(set_attr "type" "fcmov")
16802    (set_attr "mode" "XF")])
16804 (define_insn "*movdfcc_1"
16805   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16806         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16807                                 [(reg FLAGS_REG) (const_int 0)])
16808                       (match_operand:DF 2 "nonimmediate_operand"
16809                                                "f ,0,rm,0 ,rm,0")
16810                       (match_operand:DF 3 "nonimmediate_operand"
16811                                                "0 ,f,0 ,rm,0, rm")))]
16812   "TARGET_80387 && TARGET_CMOVE
16813    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16814   "@
16815    fcmov%F1\t{%2, %0|%0, %2}
16816    fcmov%f1\t{%3, %0|%0, %3}
16817    #
16818    #
16819    cmov%O2%C1\t{%2, %0|%0, %2}
16820    cmov%O2%c1\t{%3, %0|%0, %3}"
16821   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16822    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16823    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16825 (define_split
16826   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16827         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16828                                 [(reg FLAGS_REG) (const_int 0)])
16829                       (match_operand:DF 2 "nonimmediate_operand")
16830                       (match_operand:DF 3 "nonimmediate_operand")))]
16831   "!TARGET_64BIT && reload_completed"
16832   [(set (match_dup 2)
16833         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16834    (set (match_dup 3)
16835         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16837   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16838   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16841 (define_insn "*movsfcc_1_387"
16842   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16843         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16844                                 [(reg FLAGS_REG) (const_int 0)])
16845                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16846                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16847   "TARGET_80387 && TARGET_CMOVE
16848    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16849   "@
16850    fcmov%F1\t{%2, %0|%0, %2}
16851    fcmov%f1\t{%3, %0|%0, %3}
16852    cmov%O2%C1\t{%2, %0|%0, %2}
16853    cmov%O2%c1\t{%3, %0|%0, %3}"
16854   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16855    (set_attr "mode" "SF,SF,SI,SI")])
16857 ;; Don't do conditional moves with memory inputs.  This splitter helps
16858 ;; register starved x86_32 by forcing inputs into registers before reload.
16859 (define_split
16860   [(set (match_operand:MODEF 0 "register_operand")
16861         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16862                               [(reg FLAGS_REG) (const_int 0)])
16863           (match_operand:MODEF 2 "nonimmediate_operand")
16864           (match_operand:MODEF 3 "nonimmediate_operand")))]
16865   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16866    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16867    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16868    && can_create_pseudo_p ()
16869    && optimize_insn_for_speed_p ()"
16870   [(set (match_dup 0)
16871         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16873   if (MEM_P (operands[2]))
16874     operands[2] = force_reg (<MODE>mode, operands[2]);
16875   if (MEM_P (operands[3]))
16876     operands[3] = force_reg (<MODE>mode, operands[3]);
16879 ;; Don't do conditional moves with memory inputs
16880 (define_peephole2
16881   [(match_scratch:MODEF 2 "r")
16882    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16883         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16884                               [(reg FLAGS_REG) (const_int 0)])
16885           (match_dup 0)
16886           (match_operand:MODEF 3 "memory_operand")))]
16887   "(<MODE>mode != DFmode || TARGET_64BIT)
16888    && TARGET_80387 && TARGET_CMOVE
16889    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16890    && optimize_insn_for_speed_p ()"
16891   [(set (match_dup 2) (match_dup 3))
16892    (set (match_dup 0)
16893         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16895 (define_peephole2
16896   [(match_scratch:MODEF 2 "r")
16897    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16898         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16899                               [(reg FLAGS_REG) (const_int 0)])
16900           (match_operand:MODEF 3 "memory_operand")
16901           (match_dup 0)))]
16902   "(<MODE>mode != DFmode || TARGET_64BIT)
16903    && TARGET_80387 && TARGET_CMOVE
16904    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16905    && optimize_insn_for_speed_p ()"
16906   [(set (match_dup 2) (match_dup 3))
16907    (set (match_dup 0)
16908         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16910 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16911 ;; the scalar versions to have only XMM registers as operands.
16913 ;; XOP conditional move
16914 (define_insn "*xop_pcmov_<mode>"
16915   [(set (match_operand:MODEF 0 "register_operand" "=x")
16916         (if_then_else:MODEF
16917           (match_operand:MODEF 1 "register_operand" "x")
16918           (match_operand:MODEF 2 "register_operand" "x")
16919           (match_operand:MODEF 3 "register_operand" "x")))]
16920   "TARGET_XOP"
16921   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16922   [(set_attr "type" "sse4arg")])
16924 ;; These versions of the min/max patterns are intentionally ignorant of
16925 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16926 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16927 ;; are undefined in this condition, we're certain this is correct.
16929 (define_insn "<code><mode>3"
16930   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16931         (smaxmin:MODEF
16932           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16933           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16934   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16935   "@
16936    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16937    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16938   [(set_attr "isa" "noavx,avx")
16939    (set_attr "prefix" "orig,vex")
16940    (set_attr "type" "sseadd")
16941    (set_attr "mode" "<MODE>")])
16943 ;; These versions of the min/max patterns implement exactly the operations
16944 ;;   min = (op1 < op2 ? op1 : op2)
16945 ;;   max = (!(op1 < op2) ? op1 : op2)
16946 ;; Their operands are not commutative, and thus they may be used in the
16947 ;; presence of -0.0 and NaN.
16949 (define_int_iterator IEEE_MAXMIN
16950         [UNSPEC_IEEE_MAX
16951          UNSPEC_IEEE_MIN])
16953 (define_int_attr ieee_maxmin
16954         [(UNSPEC_IEEE_MAX "max")
16955          (UNSPEC_IEEE_MIN "min")])
16957 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16958   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16959         (unspec:MODEF
16960           [(match_operand:MODEF 1 "register_operand" "0,v")
16961            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16962           IEEE_MAXMIN))]
16963   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16964   "@
16965    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16966    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16967   [(set_attr "isa" "noavx,avx")
16968    (set_attr "prefix" "orig,maybe_evex")
16969    (set_attr "type" "sseadd")
16970    (set_attr "mode" "<MODE>")])
16972 ;; Make two stack loads independent:
16973 ;;   fld aa              fld aa
16974 ;;   fld %st(0)     ->   fld bb
16975 ;;   fmul bb             fmul %st(1), %st
16977 ;; Actually we only match the last two instructions for simplicity.
16978 (define_peephole2
16979   [(set (match_operand 0 "fp_register_operand")
16980         (match_operand 1 "fp_register_operand"))
16981    (set (match_dup 0)
16982         (match_operator 2 "binary_fp_operator"
16983            [(match_dup 0)
16984             (match_operand 3 "memory_operand")]))]
16985   "REGNO (operands[0]) != REGNO (operands[1])"
16986   [(set (match_dup 0) (match_dup 3))
16987    (set (match_dup 0) (match_dup 4))]
16989   ;; The % modifier is not operational anymore in peephole2's, so we have to
16990   ;; swap the operands manually in the case of addition and multiplication.
16992   rtx op0, op1;
16994   if (COMMUTATIVE_ARITH_P (operands[2]))
16995     op0 = operands[0], op1 = operands[1];
16996   else
16997     op0 = operands[1], op1 = operands[0];
16999   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17000                                 GET_MODE (operands[2]),
17001                                 op0, op1);
17004 ;; Conditional addition patterns
17005 (define_expand "add<mode>cc"
17006   [(match_operand:SWI 0 "register_operand")
17007    (match_operand 1 "ordered_comparison_operator")
17008    (match_operand:SWI 2 "register_operand")
17009    (match_operand:SWI 3 "const_int_operand")]
17010   ""
17011   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17013 ;; Misc patterns (?)
17015 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17016 ;; Otherwise there will be nothing to keep
17018 ;; [(set (reg ebp) (reg esp))]
17019 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17020 ;;  (clobber (eflags)]
17021 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17023 ;; in proper program order.
17025 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17026   [(set (match_operand:P 0 "register_operand" "=r,r")
17027         (plus:P (match_operand:P 1 "register_operand" "0,r")
17028                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17029    (clobber (reg:CC FLAGS_REG))
17030    (clobber (mem:BLK (scratch)))]
17031   ""
17033   switch (get_attr_type (insn))
17034     {
17035     case TYPE_IMOV:
17036       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17038     case TYPE_ALU:
17039       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17040       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17041         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17043       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17045     default:
17046       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17047       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17048     }
17050   [(set (attr "type")
17051         (cond [(and (eq_attr "alternative" "0")
17052                     (not (match_test "TARGET_OPT_AGU")))
17053                  (const_string "alu")
17054                (match_operand:<MODE> 2 "const0_operand")
17055                  (const_string "imov")
17056               ]
17057               (const_string "lea")))
17058    (set (attr "length_immediate")
17059         (cond [(eq_attr "type" "imov")
17060                  (const_string "0")
17061                (and (eq_attr "type" "alu")
17062                     (match_operand 2 "const128_operand"))
17063                  (const_string "1")
17064               ]
17065               (const_string "*")))
17066    (set_attr "mode" "<MODE>")])
17068 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17069   [(set (match_operand:P 0 "register_operand" "=r")
17070         (minus:P (match_operand:P 1 "register_operand" "0")
17071                  (match_operand:P 2 "register_operand" "r")))
17072    (clobber (reg:CC FLAGS_REG))
17073    (clobber (mem:BLK (scratch)))]
17074   ""
17075   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17076   [(set_attr "type" "alu")
17077    (set_attr "mode" "<MODE>")])
17079 (define_insn "allocate_stack_worker_probe_<mode>"
17080   [(set (match_operand:P 0 "register_operand" "=a")
17081         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17082                             UNSPECV_STACK_PROBE))
17083    (clobber (reg:CC FLAGS_REG))]
17084   "ix86_target_stack_probe ()"
17085   "call\t___chkstk_ms"
17086   [(set_attr "type" "multi")
17087    (set_attr "length" "5")])
17089 (define_expand "allocate_stack"
17090   [(match_operand 0 "register_operand")
17091    (match_operand 1 "general_operand")]
17092   "ix86_target_stack_probe ()"
17094   rtx x;
17096 #ifndef CHECK_STACK_LIMIT
17097 #define CHECK_STACK_LIMIT 0
17098 #endif
17100   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17101       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17102     x = operands[1];
17103   else
17104     {
17105       rtx (*insn) (rtx, rtx);
17107       x = copy_to_mode_reg (Pmode, operands[1]);
17109       insn = (TARGET_64BIT
17110               ? gen_allocate_stack_worker_probe_di
17111               : gen_allocate_stack_worker_probe_si);
17113       emit_insn (insn (x, x));
17114     }
17116   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17117                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17119   if (x != stack_pointer_rtx)
17120     emit_move_insn (stack_pointer_rtx, x);
17122   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17123   DONE;
17126 ;; Use IOR for stack probes, this is shorter.
17127 (define_expand "probe_stack"
17128   [(match_operand 0 "memory_operand")]
17129   ""
17131   rtx (*gen_ior3) (rtx, rtx, rtx);
17133   gen_ior3 = (GET_MODE (operands[0]) == DImode
17134               ? gen_iordi3 : gen_iorsi3);
17136   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17137   DONE;
17140 (define_insn "adjust_stack_and_probe<mode>"
17141   [(set (match_operand:P 0 "register_operand" "=r")
17142         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17143                             UNSPECV_PROBE_STACK_RANGE))
17144    (set (reg:P SP_REG)
17145         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17146    (clobber (reg:CC FLAGS_REG))
17147    (clobber (mem:BLK (scratch)))]
17148   ""
17149   "* return output_adjust_stack_and_probe (operands[0]);"
17150   [(set_attr "type" "multi")])
17152 (define_insn "probe_stack_range<mode>"
17153   [(set (match_operand:P 0 "register_operand" "=r")
17154         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17155                             (match_operand:P 2 "const_int_operand" "n")]
17156                             UNSPECV_PROBE_STACK_RANGE))
17157    (clobber (reg:CC FLAGS_REG))]
17158   ""
17159   "* return output_probe_stack_range (operands[0], operands[2]);"
17160   [(set_attr "type" "multi")])
17162 (define_expand "builtin_setjmp_receiver"
17163   [(label_ref (match_operand 0))]
17164   "!TARGET_64BIT && flag_pic"
17166 #if TARGET_MACHO
17167   if (TARGET_MACHO)
17168     {
17169       rtx xops[3];
17170       rtx_code_label *label_rtx = gen_label_rtx ();
17171       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17172       xops[0] = xops[1] = pic_offset_table_rtx;
17173       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17174       ix86_expand_binary_operator (MINUS, SImode, xops);
17175     }
17176   else
17177 #endif
17178     emit_insn (gen_set_got (pic_offset_table_rtx));
17179   DONE;
17182 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17183 ;; Do not split instructions with mask registers.
17184 (define_split
17185   [(set (match_operand 0 "general_reg_operand")
17186         (match_operator 3 "promotable_binary_operator"
17187            [(match_operand 1 "general_reg_operand")
17188             (match_operand 2 "aligned_operand")]))
17189    (clobber (reg:CC FLAGS_REG))]
17190   "! TARGET_PARTIAL_REG_STALL && reload_completed
17191    && ((GET_MODE (operands[0]) == HImode
17192         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17193             /* ??? next two lines just !satisfies_constraint_K (...) */
17194             || !CONST_INT_P (operands[2])
17195             || satisfies_constraint_K (operands[2])))
17196        || (GET_MODE (operands[0]) == QImode
17197            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17198   [(parallel [(set (match_dup 0)
17199                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17200               (clobber (reg:CC FLAGS_REG))])]
17202   operands[0] = gen_lowpart (SImode, operands[0]);
17203   operands[1] = gen_lowpart (SImode, operands[1]);
17204   if (GET_CODE (operands[3]) != ASHIFT)
17205     operands[2] = gen_lowpart (SImode, operands[2]);
17206   PUT_MODE (operands[3], SImode);
17209 ; Promote the QImode tests, as i386 has encoding of the AND
17210 ; instruction with 32-bit sign-extended immediate and thus the
17211 ; instruction size is unchanged, except in the %eax case for
17212 ; which it is increased by one byte, hence the ! optimize_size.
17213 (define_split
17214   [(set (match_operand 0 "flags_reg_operand")
17215         (match_operator 2 "compare_operator"
17216           [(and (match_operand 3 "aligned_operand")
17217                 (match_operand 4 "const_int_operand"))
17218            (const_int 0)]))
17219    (set (match_operand 1 "register_operand")
17220         (and (match_dup 3) (match_dup 4)))]
17221   "! TARGET_PARTIAL_REG_STALL && reload_completed
17222    && optimize_insn_for_speed_p ()
17223    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17224        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17225    /* Ensure that the operand will remain sign-extended immediate.  */
17226    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17227   [(parallel [(set (match_dup 0)
17228                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17229                                     (const_int 0)]))
17230               (set (match_dup 1)
17231                    (and:SI (match_dup 3) (match_dup 4)))])]
17233   operands[4]
17234     = gen_int_mode (INTVAL (operands[4])
17235                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17236   operands[1] = gen_lowpart (SImode, operands[1]);
17237   operands[3] = gen_lowpart (SImode, operands[3]);
17240 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17241 ; the TEST instruction with 32-bit sign-extended immediate and thus
17242 ; the instruction size would at least double, which is not what we
17243 ; want even with ! optimize_size.
17244 (define_split
17245   [(set (match_operand 0 "flags_reg_operand")
17246         (match_operator 1 "compare_operator"
17247           [(and (match_operand:HI 2 "aligned_operand")
17248                 (match_operand:HI 3 "const_int_operand"))
17249            (const_int 0)]))]
17250   "! TARGET_PARTIAL_REG_STALL && reload_completed
17251    && ! TARGET_FAST_PREFIX
17252    && optimize_insn_for_speed_p ()
17253    /* Ensure that the operand will remain sign-extended immediate.  */
17254    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17255   [(set (match_dup 0)
17256         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17257                          (const_int 0)]))]
17259   operands[3]
17260     = gen_int_mode (INTVAL (operands[3])
17261                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17262   operands[2] = gen_lowpart (SImode, operands[2]);
17265 (define_split
17266   [(set (match_operand 0 "register_operand")
17267         (neg (match_operand 1 "register_operand")))
17268    (clobber (reg:CC FLAGS_REG))]
17269   "! TARGET_PARTIAL_REG_STALL && reload_completed
17270    && (GET_MODE (operands[0]) == HImode
17271        || (GET_MODE (operands[0]) == QImode
17272            && (TARGET_PROMOTE_QImode
17273                || optimize_insn_for_size_p ())))"
17274   [(parallel [(set (match_dup 0)
17275                    (neg:SI (match_dup 1)))
17276               (clobber (reg:CC FLAGS_REG))])]
17278   operands[0] = gen_lowpart (SImode, operands[0]);
17279   operands[1] = gen_lowpart (SImode, operands[1]);
17282 ;; Do not split instructions with mask regs.
17283 (define_split
17284   [(set (match_operand 0 "general_reg_operand")
17285         (not (match_operand 1 "general_reg_operand")))]
17286   "! TARGET_PARTIAL_REG_STALL && reload_completed
17287    && (GET_MODE (operands[0]) == HImode
17288        || (GET_MODE (operands[0]) == QImode
17289            && (TARGET_PROMOTE_QImode
17290                || optimize_insn_for_size_p ())))"
17291   [(set (match_dup 0)
17292         (not:SI (match_dup 1)))]
17294   operands[0] = gen_lowpart (SImode, operands[0]);
17295   operands[1] = gen_lowpart (SImode, operands[1]);
17298 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17299 ;; transform a complex memory operation into two memory to register operations.
17301 ;; Don't push memory operands
17302 (define_peephole2
17303   [(set (match_operand:SWI 0 "push_operand")
17304         (match_operand:SWI 1 "memory_operand"))
17305    (match_scratch:SWI 2 "<r>")]
17306   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17307    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17308   [(set (match_dup 2) (match_dup 1))
17309    (set (match_dup 0) (match_dup 2))])
17311 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17312 ;; SImode pushes.
17313 (define_peephole2
17314   [(set (match_operand:SF 0 "push_operand")
17315         (match_operand:SF 1 "memory_operand"))
17316    (match_scratch:SF 2 "r")]
17317   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17318    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17319   [(set (match_dup 2) (match_dup 1))
17320    (set (match_dup 0) (match_dup 2))])
17322 ;; Don't move an immediate directly to memory when the instruction
17323 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17324 (define_peephole2
17325   [(match_scratch:SWI124 1 "<r>")
17326    (set (match_operand:SWI124 0 "memory_operand")
17327         (const_int 0))]
17328   "optimize_insn_for_speed_p ()
17329    && ((<MODE>mode == HImode
17330        && TARGET_LCP_STALL)
17331        || (!TARGET_USE_MOV0
17332           && TARGET_SPLIT_LONG_MOVES
17333           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17334    && peep2_regno_dead_p (0, FLAGS_REG)"
17335   [(parallel [(set (match_dup 2) (const_int 0))
17336               (clobber (reg:CC FLAGS_REG))])
17337    (set (match_dup 0) (match_dup 1))]
17338   "operands[2] = gen_lowpart (SImode, operands[1]);")
17340 (define_peephole2
17341   [(match_scratch:SWI124 2 "<r>")
17342    (set (match_operand:SWI124 0 "memory_operand")
17343         (match_operand:SWI124 1 "immediate_operand"))]
17344   "optimize_insn_for_speed_p ()
17345    && ((<MODE>mode == HImode
17346        && TARGET_LCP_STALL)
17347        || (TARGET_SPLIT_LONG_MOVES
17348           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17349   [(set (match_dup 2) (match_dup 1))
17350    (set (match_dup 0) (match_dup 2))])
17352 ;; Don't compare memory with zero, load and use a test instead.
17353 (define_peephole2
17354   [(set (match_operand 0 "flags_reg_operand")
17355         (match_operator 1 "compare_operator"
17356           [(match_operand:SI 2 "memory_operand")
17357            (const_int 0)]))
17358    (match_scratch:SI 3 "r")]
17359   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17360   [(set (match_dup 3) (match_dup 2))
17361    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17363 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17364 ;; Don't split NOTs with a displacement operand, because resulting XOR
17365 ;; will not be pairable anyway.
17367 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17368 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17369 ;; so this split helps here as well.
17371 ;; Note: Can't do this as a regular split because we can't get proper
17372 ;; lifetime information then.
17374 (define_peephole2
17375   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17376         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17377   "optimize_insn_for_speed_p ()
17378    && ((TARGET_NOT_UNPAIRABLE
17379         && (!MEM_P (operands[0])
17380             || !memory_displacement_operand (operands[0], <MODE>mode)))
17381        || (TARGET_NOT_VECTORMODE
17382            && long_memory_operand (operands[0], <MODE>mode)))
17383    && peep2_regno_dead_p (0, FLAGS_REG)"
17384   [(parallel [(set (match_dup 0)
17385                    (xor:SWI124 (match_dup 1) (const_int -1)))
17386               (clobber (reg:CC FLAGS_REG))])])
17388 ;; Non pairable "test imm, reg" instructions can be translated to
17389 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17390 ;; byte opcode instead of two, have a short form for byte operands),
17391 ;; so do it for other CPUs as well.  Given that the value was dead,
17392 ;; this should not create any new dependencies.  Pass on the sub-word
17393 ;; versions if we're concerned about partial register stalls.
17395 (define_peephole2
17396   [(set (match_operand 0 "flags_reg_operand")
17397         (match_operator 1 "compare_operator"
17398           [(and:SI (match_operand:SI 2 "register_operand")
17399                    (match_operand:SI 3 "immediate_operand"))
17400            (const_int 0)]))]
17401   "ix86_match_ccmode (insn, CCNOmode)
17402    && (true_regnum (operands[2]) != AX_REG
17403        || satisfies_constraint_K (operands[3]))
17404    && peep2_reg_dead_p (1, operands[2])"
17405   [(parallel
17406      [(set (match_dup 0)
17407            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17408                             (const_int 0)]))
17409       (set (match_dup 2)
17410            (and:SI (match_dup 2) (match_dup 3)))])])
17412 ;; We don't need to handle HImode case, because it will be promoted to SImode
17413 ;; on ! TARGET_PARTIAL_REG_STALL
17415 (define_peephole2
17416   [(set (match_operand 0 "flags_reg_operand")
17417         (match_operator 1 "compare_operator"
17418           [(and:QI (match_operand:QI 2 "register_operand")
17419                    (match_operand:QI 3 "immediate_operand"))
17420            (const_int 0)]))]
17421   "! TARGET_PARTIAL_REG_STALL
17422    && ix86_match_ccmode (insn, CCNOmode)
17423    && true_regnum (operands[2]) != AX_REG
17424    && peep2_reg_dead_p (1, operands[2])"
17425   [(parallel
17426      [(set (match_dup 0)
17427            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17428                             (const_int 0)]))
17429       (set (match_dup 2)
17430            (and:QI (match_dup 2) (match_dup 3)))])])
17432 (define_peephole2
17433   [(set (match_operand 0 "flags_reg_operand")
17434         (match_operator 1 "compare_operator"
17435           [(and:SI
17436              (zero_extract:SI
17437                (match_operand 2 "QIreg_operand")
17438                (const_int 8)
17439                (const_int 8))
17440              (match_operand 3 "const_int_operand"))
17441            (const_int 0)]))]
17442   "! TARGET_PARTIAL_REG_STALL
17443    && ix86_match_ccmode (insn, CCNOmode)
17444    && true_regnum (operands[2]) != AX_REG
17445    && peep2_reg_dead_p (1, operands[2])"
17446   [(parallel [(set (match_dup 0)
17447                    (match_op_dup 1
17448                      [(and:SI
17449                         (zero_extract:SI
17450                           (match_dup 2)
17451                           (const_int 8)
17452                           (const_int 8))
17453                         (match_dup 3))
17454                       (const_int 0)]))
17455               (set (zero_extract:SI (match_dup 2)
17456                                     (const_int 8)
17457                                     (const_int 8))
17458                    (and:SI
17459                      (zero_extract:SI
17460                        (match_dup 2)
17461                        (const_int 8)
17462                        (const_int 8))
17463                      (match_dup 3)))])])
17465 ;; Don't do logical operations with memory inputs.
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_dup 0)
17471                       (match_operand:SI 1 "memory_operand")]))
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 0) (match_dup 2)]))
17477               (clobber (reg:CC FLAGS_REG))])])
17479 (define_peephole2
17480   [(match_scratch:SI 2 "r")
17481    (parallel [(set (match_operand:SI 0 "register_operand")
17482                    (match_operator:SI 3 "arith_or_logical_operator"
17483                      [(match_operand:SI 1 "memory_operand")
17484                       (match_dup 0)]))
17485               (clobber (reg:CC FLAGS_REG))])]
17486   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17487   [(set (match_dup 2) (match_dup 1))
17488    (parallel [(set (match_dup 0)
17489                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17490               (clobber (reg:CC FLAGS_REG))])])
17492 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17493 ;; refers to the destination of the load!
17495 (define_peephole2
17496   [(set (match_operand:SI 0 "register_operand")
17497         (match_operand:SI 1 "register_operand"))
17498    (parallel [(set (match_dup 0)
17499                    (match_operator:SI 3 "commutative_operator"
17500                      [(match_dup 0)
17501                       (match_operand:SI 2 "memory_operand")]))
17502               (clobber (reg:CC FLAGS_REG))])]
17503   "REGNO (operands[0]) != REGNO (operands[1])
17504    && GENERAL_REGNO_P (REGNO (operands[0]))
17505    && GENERAL_REGNO_P (REGNO (operands[1]))"
17506   [(set (match_dup 0) (match_dup 4))
17507    (parallel [(set (match_dup 0)
17508                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17509               (clobber (reg:CC FLAGS_REG))])]
17510   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17512 (define_peephole2
17513   [(set (match_operand 0 "register_operand")
17514         (match_operand 1 "register_operand"))
17515    (set (match_dup 0)
17516                    (match_operator 3 "commutative_operator"
17517                      [(match_dup 0)
17518                       (match_operand 2 "memory_operand")]))]
17519   "REGNO (operands[0]) != REGNO (operands[1])
17520    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17521        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17522   [(set (match_dup 0) (match_dup 2))
17523    (set (match_dup 0)
17524         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17526 ; Don't do logical operations with memory outputs
17528 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17529 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17530 ; the same decoder scheduling characteristics as the original.
17532 (define_peephole2
17533   [(match_scratch:SI 2 "r")
17534    (parallel [(set (match_operand:SI 0 "memory_operand")
17535                    (match_operator:SI 3 "arith_or_logical_operator"
17536                      [(match_dup 0)
17537                       (match_operand:SI 1 "nonmemory_operand")]))
17538               (clobber (reg:CC FLAGS_REG))])]
17539   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17540    /* Do not split stack checking probes.  */
17541    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17542   [(set (match_dup 2) (match_dup 0))
17543    (parallel [(set (match_dup 2)
17544                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17545               (clobber (reg:CC FLAGS_REG))])
17546    (set (match_dup 0) (match_dup 2))])
17548 (define_peephole2
17549   [(match_scratch:SI 2 "r")
17550    (parallel [(set (match_operand:SI 0 "memory_operand")
17551                    (match_operator:SI 3 "arith_or_logical_operator"
17552                      [(match_operand:SI 1 "nonmemory_operand")
17553                       (match_dup 0)]))
17554               (clobber (reg:CC FLAGS_REG))])]
17555   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17556    /* Do not split stack checking probes.  */
17557    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17558   [(set (match_dup 2) (match_dup 0))
17559    (parallel [(set (match_dup 2)
17560                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17561               (clobber (reg:CC FLAGS_REG))])
17562    (set (match_dup 0) (match_dup 2))])
17564 ;; Attempt to use arith or logical operations with memory outputs with
17565 ;; setting of flags.
17566 (define_peephole2
17567   [(set (match_operand:SWI 0 "register_operand")
17568         (match_operand:SWI 1 "memory_operand"))
17569    (parallel [(set (match_dup 0)
17570                    (match_operator:SWI 3 "plusminuslogic_operator"
17571                      [(match_dup 0)
17572                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17573               (clobber (reg:CC FLAGS_REG))])
17574    (set (match_dup 1) (match_dup 0))
17575    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17576   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17577    && peep2_reg_dead_p (4, operands[0])
17578    && !reg_overlap_mentioned_p (operands[0], operands[1])
17579    && !reg_overlap_mentioned_p (operands[0], operands[2])
17580    && (<MODE>mode != QImode
17581        || immediate_operand (operands[2], QImode)
17582        || any_QIreg_operand (operands[2], QImode))
17583    && ix86_match_ccmode (peep2_next_insn (3),
17584                          (GET_CODE (operands[3]) == PLUS
17585                           || GET_CODE (operands[3]) == MINUS)
17586                          ? CCGOCmode : CCNOmode)"
17587   [(parallel [(set (match_dup 4) (match_dup 5))
17588               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17589                                                   (match_dup 2)]))])]
17591   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17592   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17593                                 copy_rtx (operands[1]),
17594                                 copy_rtx (operands[2]));
17595   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17596                                  operands[5], const0_rtx);
17599 (define_peephole2
17600   [(parallel [(set (match_operand:SWI 0 "register_operand")
17601                    (match_operator:SWI 2 "plusminuslogic_operator"
17602                      [(match_dup 0)
17603                       (match_operand:SWI 1 "memory_operand")]))
17604               (clobber (reg:CC FLAGS_REG))])
17605    (set (match_dup 1) (match_dup 0))
17606    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17607   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17608    && GET_CODE (operands[2]) != MINUS
17609    && peep2_reg_dead_p (3, operands[0])
17610    && !reg_overlap_mentioned_p (operands[0], operands[1])
17611    && ix86_match_ccmode (peep2_next_insn (2),
17612                          GET_CODE (operands[2]) == PLUS
17613                          ? CCGOCmode : CCNOmode)"
17614   [(parallel [(set (match_dup 3) (match_dup 4))
17615               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17616                                                   (match_dup 0)]))])]
17618   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17619   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17620                                 copy_rtx (operands[1]),
17621                                 copy_rtx (operands[0]));
17622   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17623                                  operands[4], const0_rtx);
17626 (define_peephole2
17627   [(set (match_operand:SWI12 0 "register_operand")
17628         (match_operand:SWI12 1 "memory_operand"))
17629    (parallel [(set (match_operand:SI 4 "register_operand")
17630                    (match_operator:SI 3 "plusminuslogic_operator"
17631                      [(match_dup 4)
17632                       (match_operand:SI 2 "nonmemory_operand")]))
17633               (clobber (reg:CC FLAGS_REG))])
17634    (set (match_dup 1) (match_dup 0))
17635    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17636   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17637    && REG_P (operands[0]) && REG_P (operands[4])
17638    && REGNO (operands[0]) == REGNO (operands[4])
17639    && peep2_reg_dead_p (4, operands[0])
17640    && (<MODE>mode != QImode
17641        || immediate_operand (operands[2], SImode)
17642        || any_QIreg_operand (operands[2], SImode))
17643    && !reg_overlap_mentioned_p (operands[0], operands[1])
17644    && !reg_overlap_mentioned_p (operands[0], operands[2])
17645    && ix86_match_ccmode (peep2_next_insn (3),
17646                          (GET_CODE (operands[3]) == PLUS
17647                           || GET_CODE (operands[3]) == MINUS)
17648                          ? CCGOCmode : CCNOmode)"
17649   [(parallel [(set (match_dup 4) (match_dup 5))
17650               (set (match_dup 1) (match_dup 6))])]
17652   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17653   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17654   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17655                                 copy_rtx (operands[1]), operands[2]);
17656   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17657                                  operands[5], const0_rtx);
17658   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17659                                 copy_rtx (operands[1]),
17660                                 copy_rtx (operands[2]));
17663 ;; Attempt to always use XOR for zeroing registers.
17664 (define_peephole2
17665   [(set (match_operand 0 "register_operand")
17666         (match_operand 1 "const0_operand"))]
17667   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17668    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17669    && GENERAL_REG_P (operands[0])
17670    && peep2_regno_dead_p (0, FLAGS_REG)"
17671   [(parallel [(set (match_dup 0) (const_int 0))
17672               (clobber (reg:CC FLAGS_REG))])]
17673   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17675 (define_peephole2
17676   [(set (strict_low_part (match_operand 0 "register_operand"))
17677         (const_int 0))]
17678   "(GET_MODE (operands[0]) == QImode
17679     || GET_MODE (operands[0]) == HImode)
17680    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17681    && peep2_regno_dead_p (0, FLAGS_REG)"
17682   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17683               (clobber (reg:CC FLAGS_REG))])])
17685 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17686 (define_peephole2
17687   [(set (match_operand:SWI248 0 "register_operand")
17688         (const_int -1))]
17689   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17690    && peep2_regno_dead_p (0, FLAGS_REG)"
17691   [(parallel [(set (match_dup 0) (const_int -1))
17692               (clobber (reg:CC FLAGS_REG))])]
17694   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17695     operands[0] = gen_lowpart (SImode, operands[0]);
17698 ;; Attempt to convert simple lea to add/shift.
17699 ;; These can be created by move expanders.
17700 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17701 ;; relevant lea instructions were already split.
17703 (define_peephole2
17704   [(set (match_operand:SWI48 0 "register_operand")
17705         (plus:SWI48 (match_dup 0)
17706                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17707   "!TARGET_OPT_AGU
17708    && peep2_regno_dead_p (0, FLAGS_REG)"
17709   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17710               (clobber (reg:CC FLAGS_REG))])])
17712 (define_peephole2
17713   [(set (match_operand:SWI48 0 "register_operand")
17714         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17715                     (match_dup 0)))]
17716   "!TARGET_OPT_AGU
17717    && peep2_regno_dead_p (0, FLAGS_REG)"
17718   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17719               (clobber (reg:CC FLAGS_REG))])])
17721 (define_peephole2
17722   [(set (match_operand:DI 0 "register_operand")
17723         (zero_extend:DI
17724           (plus:SI (match_operand:SI 1 "register_operand")
17725                    (match_operand:SI 2 "nonmemory_operand"))))]
17726   "TARGET_64BIT && !TARGET_OPT_AGU
17727    && REGNO (operands[0]) == REGNO (operands[1])
17728    && peep2_regno_dead_p (0, FLAGS_REG)"
17729   [(parallel [(set (match_dup 0)
17730                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17731               (clobber (reg:CC FLAGS_REG))])])
17733 (define_peephole2
17734   [(set (match_operand:DI 0 "register_operand")
17735         (zero_extend:DI
17736           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17737                    (match_operand:SI 2 "register_operand"))))]
17738   "TARGET_64BIT && !TARGET_OPT_AGU
17739    && REGNO (operands[0]) == REGNO (operands[2])
17740    && peep2_regno_dead_p (0, FLAGS_REG)"
17741   [(parallel [(set (match_dup 0)
17742                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17743               (clobber (reg:CC FLAGS_REG))])])
17745 (define_peephole2
17746   [(set (match_operand:SWI48 0 "register_operand")
17747         (mult:SWI48 (match_dup 0)
17748                     (match_operand:SWI48 1 "const_int_operand")))]
17749   "exact_log2 (INTVAL (operands[1])) >= 0
17750    && peep2_regno_dead_p (0, FLAGS_REG)"
17751   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17752               (clobber (reg:CC FLAGS_REG))])]
17753   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17755 (define_peephole2
17756   [(set (match_operand:DI 0 "register_operand")
17757         (zero_extend:DI
17758           (mult:SI (match_operand:SI 1 "register_operand")
17759                    (match_operand:SI 2 "const_int_operand"))))]
17760   "TARGET_64BIT
17761    && exact_log2 (INTVAL (operands[2])) >= 0
17762    && REGNO (operands[0]) == REGNO (operands[1])
17763    && peep2_regno_dead_p (0, FLAGS_REG)"
17764   [(parallel [(set (match_dup 0)
17765                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17766               (clobber (reg:CC FLAGS_REG))])]
17767   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17769 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17770 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17771 ;; On many CPUs it is also faster, since special hardware to avoid esp
17772 ;; dependencies is present.
17774 ;; While some of these conversions may be done using splitters, we use
17775 ;; peepholes in order to allow combine_stack_adjustments pass to see
17776 ;; nonobfuscated RTL.
17778 ;; Convert prologue esp subtractions to push.
17779 ;; We need register to push.  In order to keep verify_flow_info happy we have
17780 ;; two choices
17781 ;; - use scratch and clobber it in order to avoid dependencies
17782 ;; - use already live register
17783 ;; We can't use the second way right now, since there is no reliable way how to
17784 ;; verify that given register is live.  First choice will also most likely in
17785 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17786 ;; call clobbered registers are dead.  We may want to use base pointer as an
17787 ;; alternative when no register is available later.
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_SINGLE_PUSH || optimize_insn_for_size_p ())
17797    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17798   [(clobber (match_dup 1))
17799    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17800               (clobber (mem:BLK (scratch)))])])
17802 (define_peephole2
17803   [(match_scratch:W 1 "r")
17804    (parallel [(set (reg:P SP_REG)
17805                    (plus:P (reg:P SP_REG)
17806                            (match_operand:P 0 "const_int_operand")))
17807               (clobber (reg:CC FLAGS_REG))
17808               (clobber (mem:BLK (scratch)))])]
17809   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17810    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17811   [(clobber (match_dup 1))
17812    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17813    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17814               (clobber (mem:BLK (scratch)))])])
17816 ;; Convert esp subtractions to push.
17817 (define_peephole2
17818   [(match_scratch:W 1 "r")
17819    (parallel [(set (reg:P SP_REG)
17820                    (plus:P (reg:P SP_REG)
17821                            (match_operand:P 0 "const_int_operand")))
17822               (clobber (reg:CC FLAGS_REG))])]
17823   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17824    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17825   [(clobber (match_dup 1))
17826    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
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   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17835    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17836   [(clobber (match_dup 1))
17837    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17838    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17840 ;; Convert epilogue deallocator to pop.
17841 (define_peephole2
17842   [(match_scratch:W 1 "r")
17843    (parallel [(set (reg:P SP_REG)
17844                    (plus:P (reg:P SP_REG)
17845                            (match_operand:P 0 "const_int_operand")))
17846               (clobber (reg:CC FLAGS_REG))
17847               (clobber (mem:BLK (scratch)))])]
17848   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17849    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17850   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17851               (clobber (mem:BLK (scratch)))])])
17853 ;; Two pops case is tricky, since pop causes dependency
17854 ;; on destination register.  We use two registers if available.
17855 (define_peephole2
17856   [(match_scratch:W 1 "r")
17857    (match_scratch:W 2 "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   "(TARGET_DOUBLE_POP || 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 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17869 (define_peephole2
17870   [(match_scratch:W 1 "r")
17871    (parallel [(set (reg:P SP_REG)
17872                    (plus:P (reg:P SP_REG)
17873                            (match_operand:P 0 "const_int_operand")))
17874               (clobber (reg:CC FLAGS_REG))
17875               (clobber (mem:BLK (scratch)))])]
17876   "optimize_insn_for_size_p ()
17877    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17878   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17879               (clobber (mem:BLK (scratch)))])
17880    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17882 ;; Convert esp additions to pop.
17883 (define_peephole2
17884   [(match_scratch:W 1 "r")
17885    (parallel [(set (reg:P SP_REG)
17886                    (plus:P (reg:P SP_REG)
17887                            (match_operand:P 0 "const_int_operand")))
17888               (clobber (reg:CC FLAGS_REG))])]
17889   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17890   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17892 ;; Two pops case is tricky, since pop causes dependency
17893 ;; on destination register.  We use two registers if available.
17894 (define_peephole2
17895   [(match_scratch:W 1 "r")
17896    (match_scratch:W 2 "r")
17897    (parallel [(set (reg:P SP_REG)
17898                    (plus:P (reg:P SP_REG)
17899                            (match_operand:P 0 "const_int_operand")))
17900               (clobber (reg:CC FLAGS_REG))])]
17901   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17902   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17903    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17905 (define_peephole2
17906   [(match_scratch:W 1 "r")
17907    (parallel [(set (reg:P SP_REG)
17908                    (plus:P (reg:P SP_REG)
17909                            (match_operand:P 0 "const_int_operand")))
17910               (clobber (reg:CC FLAGS_REG))])]
17911   "optimize_insn_for_size_p ()
17912    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17913   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17914    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17916 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17917 ;; required and register dies.  Similarly for 128 to -128.
17918 (define_peephole2
17919   [(set (match_operand 0 "flags_reg_operand")
17920         (match_operator 1 "compare_operator"
17921           [(match_operand 2 "register_operand")
17922            (match_operand 3 "const_int_operand")]))]
17923   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17924      && incdec_operand (operands[3], GET_MODE (operands[3])))
17925     || (!TARGET_FUSE_CMP_AND_BRANCH
17926         && INTVAL (operands[3]) == 128))
17927    && ix86_match_ccmode (insn, CCGCmode)
17928    && peep2_reg_dead_p (1, operands[2])"
17929   [(parallel [(set (match_dup 0)
17930                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17931               (clobber (match_dup 2))])])
17933 ;; Convert imul by three, five and nine into lea
17934 (define_peephole2
17935   [(parallel
17936     [(set (match_operand:SWI48 0 "register_operand")
17937           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17938                       (match_operand:SWI48 2 "const359_operand")))
17939      (clobber (reg:CC FLAGS_REG))])]
17940   "!TARGET_PARTIAL_REG_STALL
17941    || <MODE>mode == SImode
17942    || optimize_function_for_size_p (cfun)"
17943   [(set (match_dup 0)
17944         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17945                     (match_dup 1)))]
17946   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17948 (define_peephole2
17949   [(parallel
17950     [(set (match_operand:SWI48 0 "register_operand")
17951           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17952                       (match_operand:SWI48 2 "const359_operand")))
17953      (clobber (reg:CC FLAGS_REG))])]
17954   "optimize_insn_for_speed_p ()
17955    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17956   [(set (match_dup 0) (match_dup 1))
17957    (set (match_dup 0)
17958         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17959                     (match_dup 0)))]
17960   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17962 ;; imul $32bit_imm, mem, reg is vector decoded, while
17963 ;; imul $32bit_imm, reg, reg is direct decoded.
17964 (define_peephole2
17965   [(match_scratch:SWI48 3 "r")
17966    (parallel [(set (match_operand:SWI48 0 "register_operand")
17967                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17968                                (match_operand:SWI48 2 "immediate_operand")))
17969               (clobber (reg:CC FLAGS_REG))])]
17970   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17971    && !satisfies_constraint_K (operands[2])"
17972   [(set (match_dup 3) (match_dup 1))
17973    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17974               (clobber (reg:CC FLAGS_REG))])])
17976 (define_peephole2
17977   [(match_scratch:SI 3 "r")
17978    (parallel [(set (match_operand:DI 0 "register_operand")
17979                    (zero_extend:DI
17980                      (mult:SI (match_operand:SI 1 "memory_operand")
17981                               (match_operand:SI 2 "immediate_operand"))))
17982               (clobber (reg:CC FLAGS_REG))])]
17983   "TARGET_64BIT
17984    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17985    && !satisfies_constraint_K (operands[2])"
17986   [(set (match_dup 3) (match_dup 1))
17987    (parallel [(set (match_dup 0)
17988                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17989               (clobber (reg:CC FLAGS_REG))])])
17991 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17992 ;; Convert it into imul reg, reg
17993 ;; It would be better to force assembler to encode instruction using long
17994 ;; immediate, but there is apparently no way to do so.
17995 (define_peephole2
17996   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17997                    (mult:SWI248
17998                     (match_operand:SWI248 1 "nonimmediate_operand")
17999                     (match_operand:SWI248 2 "const_int_operand")))
18000               (clobber (reg:CC FLAGS_REG))])
18001    (match_scratch:SWI248 3 "r")]
18002   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18003    && satisfies_constraint_K (operands[2])"
18004   [(set (match_dup 3) (match_dup 2))
18005    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18006               (clobber (reg:CC FLAGS_REG))])]
18008   if (!rtx_equal_p (operands[0], operands[1]))
18009     emit_move_insn (operands[0], operands[1]);
18012 ;; After splitting up read-modify operations, array accesses with memory
18013 ;; operands might end up in form:
18014 ;;  sall    $2, %eax
18015 ;;  movl    4(%esp), %edx
18016 ;;  addl    %edx, %eax
18017 ;; instead of pre-splitting:
18018 ;;  sall    $2, %eax
18019 ;;  addl    4(%esp), %eax
18020 ;; Turn it into:
18021 ;;  movl    4(%esp), %edx
18022 ;;  leal    (%edx,%eax,4), %eax
18024 (define_peephole2
18025   [(match_scratch:W 5 "r")
18026    (parallel [(set (match_operand 0 "register_operand")
18027                    (ashift (match_operand 1 "register_operand")
18028                            (match_operand 2 "const_int_operand")))
18029                (clobber (reg:CC FLAGS_REG))])
18030    (parallel [(set (match_operand 3 "register_operand")
18031                    (plus (match_dup 0)
18032                          (match_operand 4 "x86_64_general_operand")))
18033                    (clobber (reg:CC FLAGS_REG))])]
18034   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18035    /* Validate MODE for lea.  */
18036    && ((!TARGET_PARTIAL_REG_STALL
18037         && (GET_MODE (operands[0]) == QImode
18038             || GET_MODE (operands[0]) == HImode))
18039        || GET_MODE (operands[0]) == SImode
18040        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18041    && (rtx_equal_p (operands[0], operands[3])
18042        || peep2_reg_dead_p (2, operands[0]))
18043    /* We reorder load and the shift.  */
18044    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18045   [(set (match_dup 5) (match_dup 4))
18046    (set (match_dup 0) (match_dup 1))]
18048   machine_mode op1mode = GET_MODE (operands[1]);
18049   machine_mode mode = op1mode == DImode ? DImode : SImode;
18050   int scale = 1 << INTVAL (operands[2]);
18051   rtx index = gen_lowpart (word_mode, operands[1]);
18052   rtx base = gen_lowpart (word_mode, operands[5]);
18053   rtx dest = gen_lowpart (mode, operands[3]);
18055   operands[1] = gen_rtx_PLUS (word_mode, base,
18056                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18057   operands[5] = base;
18058   if (mode != word_mode)
18059     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18060   if (op1mode != word_mode)
18061     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
18062   operands[0] = dest;
18065 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18066 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18067 ;; caught for use by garbage collectors and the like.  Using an insn that
18068 ;; maps to SIGILL makes it more likely the program will rightfully die.
18069 ;; Keeping with tradition, "6" is in honor of #UD.
18070 (define_insn "trap"
18071   [(trap_if (const_int 1) (const_int 6))]
18072   ""
18074 #ifdef HAVE_AS_IX86_UD2
18075   return "ud2";
18076 #else
18077   return ASM_SHORT "0x0b0f";
18078 #endif
18080   [(set_attr "length" "2")])
18082 (define_expand "prefetch"
18083   [(prefetch (match_operand 0 "address_operand")
18084              (match_operand:SI 1 "const_int_operand")
18085              (match_operand:SI 2 "const_int_operand"))]
18086   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18088   bool write = INTVAL (operands[1]) != 0;
18089   int locality = INTVAL (operands[2]);
18091   gcc_assert (IN_RANGE (locality, 0, 3));
18093   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18094      supported by SSE counterpart or the SSE prefetch is not available
18095      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18096      of locality.  */
18097   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18098     operands[2] = const2_rtx;
18099   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18100     operands[2] = GEN_INT (3);
18101   else
18102     operands[1] = const0_rtx;
18105 (define_insn "*prefetch_sse"
18106   [(prefetch (match_operand 0 "address_operand" "p")
18107              (const_int 0)
18108              (match_operand:SI 1 "const_int_operand"))]
18109   "TARGET_PREFETCH_SSE"
18111   static const char * const patterns[4] = {
18112    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18113   };
18115   int locality = INTVAL (operands[1]);
18116   gcc_assert (IN_RANGE (locality, 0, 3));
18118   return patterns[locality];
18120   [(set_attr "type" "sse")
18121    (set_attr "atom_sse_attr" "prefetch")
18122    (set (attr "length_address")
18123         (symbol_ref "memory_address_length (operands[0], false)"))
18124    (set_attr "memory" "none")])
18126 (define_insn "*prefetch_3dnow"
18127   [(prefetch (match_operand 0 "address_operand" "p")
18128              (match_operand:SI 1 "const_int_operand" "n")
18129              (const_int 3))]
18130   "TARGET_PRFCHW"
18132   if (INTVAL (operands[1]) == 0)
18133     return "prefetch\t%a0";
18134   else
18135     return "prefetchw\t%a0";
18137   [(set_attr "type" "mmx")
18138    (set (attr "length_address")
18139         (symbol_ref "memory_address_length (operands[0], false)"))
18140    (set_attr "memory" "none")])
18142 (define_insn "*prefetch_prefetchwt1"
18143   [(prefetch (match_operand 0 "address_operand" "p")
18144              (const_int 1)
18145              (const_int 2))]
18146   "TARGET_PREFETCHWT1"
18147   "prefetchwt1\t%a0";
18148   [(set_attr "type" "sse")
18149    (set (attr "length_address")
18150         (symbol_ref "memory_address_length (operands[0], false)"))
18151    (set_attr "memory" "none")])
18153 (define_expand "stack_protect_set"
18154   [(match_operand 0 "memory_operand")
18155    (match_operand 1 "memory_operand")]
18156   "TARGET_SSP_TLS_GUARD"
18158   rtx (*insn)(rtx, rtx);
18160 #ifdef TARGET_THREAD_SSP_OFFSET
18161   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18162   insn = (TARGET_LP64
18163           ? gen_stack_tls_protect_set_di
18164           : gen_stack_tls_protect_set_si);
18165 #else
18166   insn = (TARGET_LP64
18167           ? gen_stack_protect_set_di
18168           : gen_stack_protect_set_si);
18169 #endif
18171   emit_insn (insn (operands[0], operands[1]));
18172   DONE;
18175 (define_insn "stack_protect_set_<mode>"
18176   [(set (match_operand:PTR 0 "memory_operand" "=m")
18177         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18178                     UNSPEC_SP_SET))
18179    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18180    (clobber (reg:CC FLAGS_REG))]
18181   "TARGET_SSP_TLS_GUARD"
18182   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18183   [(set_attr "type" "multi")])
18185 (define_insn "stack_tls_protect_set_<mode>"
18186   [(set (match_operand:PTR 0 "memory_operand" "=m")
18187         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18188                     UNSPEC_SP_TLS_SET))
18189    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18190    (clobber (reg:CC FLAGS_REG))]
18191   ""
18192   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18193   [(set_attr "type" "multi")])
18195 (define_expand "stack_protect_test"
18196   [(match_operand 0 "memory_operand")
18197    (match_operand 1 "memory_operand")
18198    (match_operand 2)]
18199   "TARGET_SSP_TLS_GUARD"
18201   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18203   rtx (*insn)(rtx, rtx, rtx);
18205 #ifdef TARGET_THREAD_SSP_OFFSET
18206   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18207   insn = (TARGET_LP64
18208           ? gen_stack_tls_protect_test_di
18209           : gen_stack_tls_protect_test_si);
18210 #else
18211   insn = (TARGET_LP64
18212           ? gen_stack_protect_test_di
18213           : gen_stack_protect_test_si);
18214 #endif
18216   emit_insn (insn (flags, operands[0], operands[1]));
18218   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18219                                   flags, const0_rtx, operands[2]));
18220   DONE;
18223 (define_insn "stack_protect_test_<mode>"
18224   [(set (match_operand:CCZ 0 "flags_reg_operand")
18225         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18226                      (match_operand:PTR 2 "memory_operand" "m")]
18227                     UNSPEC_SP_TEST))
18228    (clobber (match_scratch:PTR 3 "=&r"))]
18229   "TARGET_SSP_TLS_GUARD"
18230   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18231   [(set_attr "type" "multi")])
18233 (define_insn "stack_tls_protect_test_<mode>"
18234   [(set (match_operand:CCZ 0 "flags_reg_operand")
18235         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18236                      (match_operand:PTR 2 "const_int_operand" "i")]
18237                     UNSPEC_SP_TLS_TEST))
18238    (clobber (match_scratch:PTR 3 "=r"))]
18239   ""
18240   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18241   [(set_attr "type" "multi")])
18243 (define_insn "sse4_2_crc32<mode>"
18244   [(set (match_operand:SI 0 "register_operand" "=r")
18245         (unspec:SI
18246           [(match_operand:SI 1 "register_operand" "0")
18247            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18248           UNSPEC_CRC32))]
18249   "TARGET_SSE4_2 || TARGET_CRC32"
18250   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18251   [(set_attr "type" "sselog1")
18252    (set_attr "prefix_rep" "1")
18253    (set_attr "prefix_extra" "1")
18254    (set (attr "prefix_data16")
18255      (if_then_else (match_operand:HI 2)
18256        (const_string "1")
18257        (const_string "*")))
18258    (set (attr "prefix_rex")
18259      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18260        (const_string "1")
18261        (const_string "*")))
18262    (set_attr "mode" "SI")])
18264 (define_insn "sse4_2_crc32di"
18265   [(set (match_operand:DI 0 "register_operand" "=r")
18266         (unspec:DI
18267           [(match_operand:DI 1 "register_operand" "0")
18268            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18269           UNSPEC_CRC32))]
18270   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18271   "crc32{q}\t{%2, %0|%0, %2}"
18272   [(set_attr "type" "sselog1")
18273    (set_attr "prefix_rep" "1")
18274    (set_attr "prefix_extra" "1")
18275    (set_attr "mode" "DI")])
18277 (define_insn "rdpmc"
18278   [(set (match_operand:DI 0 "register_operand" "=A")
18279         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18280                             UNSPECV_RDPMC))]
18281   "!TARGET_64BIT"
18282   "rdpmc"
18283   [(set_attr "type" "other")
18284    (set_attr "length" "2")])
18286 (define_insn "rdpmc_rex64"
18287   [(set (match_operand:DI 0 "register_operand" "=a")
18288         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18289                             UNSPECV_RDPMC))
18290    (set (match_operand:DI 1 "register_operand" "=d")
18291         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18292   "TARGET_64BIT"
18293   "rdpmc"
18294   [(set_attr "type" "other")
18295    (set_attr "length" "2")])
18297 (define_insn "rdtsc"
18298   [(set (match_operand:DI 0 "register_operand" "=A")
18299         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18300   "!TARGET_64BIT"
18301   "rdtsc"
18302   [(set_attr "type" "other")
18303    (set_attr "length" "2")])
18305 (define_insn "rdtsc_rex64"
18306   [(set (match_operand:DI 0 "register_operand" "=a")
18307         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18308    (set (match_operand:DI 1 "register_operand" "=d")
18309         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18310   "TARGET_64BIT"
18311   "rdtsc"
18312   [(set_attr "type" "other")
18313    (set_attr "length" "2")])
18315 (define_insn "rdtscp"
18316   [(set (match_operand:DI 0 "register_operand" "=A")
18317         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18318    (set (match_operand:SI 1 "register_operand" "=c")
18319         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18320   "!TARGET_64BIT"
18321   "rdtscp"
18322   [(set_attr "type" "other")
18323    (set_attr "length" "3")])
18325 (define_insn "rdtscp_rex64"
18326   [(set (match_operand:DI 0 "register_operand" "=a")
18327         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18328    (set (match_operand:DI 1 "register_operand" "=d")
18329         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18330    (set (match_operand:SI 2 "register_operand" "=c")
18331         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18332   "TARGET_64BIT"
18333   "rdtscp"
18334   [(set_attr "type" "other")
18335    (set_attr "length" "3")])
18337 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18339 ;; FXSR, XSAVE and XSAVEOPT instructions
18341 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18343 (define_insn "fxsave"
18344   [(set (match_operand:BLK 0 "memory_operand" "=m")
18345         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18346   "TARGET_FXSR"
18347   "fxsave\t%0"
18348   [(set_attr "type" "other")
18349    (set_attr "memory" "store")
18350    (set (attr "length")
18351         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18353 (define_insn "fxsave64"
18354   [(set (match_operand:BLK 0 "memory_operand" "=m")
18355         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18356   "TARGET_64BIT && TARGET_FXSR"
18357   "fxsave64\t%0"
18358   [(set_attr "type" "other")
18359    (set_attr "memory" "store")
18360    (set (attr "length")
18361         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18363 (define_insn "fxrstor"
18364   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18365                     UNSPECV_FXRSTOR)]
18366   "TARGET_FXSR"
18367   "fxrstor\t%0"
18368   [(set_attr "type" "other")
18369    (set_attr "memory" "load")
18370    (set (attr "length")
18371         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18373 (define_insn "fxrstor64"
18374   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18375                     UNSPECV_FXRSTOR64)]
18376   "TARGET_64BIT && TARGET_FXSR"
18377   "fxrstor64\t%0"
18378   [(set_attr "type" "other")
18379    (set_attr "memory" "load")
18380    (set (attr "length")
18381         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18383 (define_int_iterator ANY_XSAVE
18384         [UNSPECV_XSAVE
18385          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18386          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18387          (UNSPECV_XSAVES "TARGET_XSAVES")])
18389 (define_int_iterator ANY_XSAVE64
18390         [UNSPECV_XSAVE64
18391          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18392          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18393          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18395 (define_int_attr xsave
18396         [(UNSPECV_XSAVE "xsave")
18397          (UNSPECV_XSAVE64 "xsave64")
18398          (UNSPECV_XSAVEOPT "xsaveopt")
18399          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18400          (UNSPECV_XSAVEC "xsavec")
18401          (UNSPECV_XSAVEC64 "xsavec64")
18402          (UNSPECV_XSAVES "xsaves")
18403          (UNSPECV_XSAVES64 "xsaves64")])
18405 (define_int_iterator ANY_XRSTOR
18406         [UNSPECV_XRSTOR
18407          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18409 (define_int_iterator ANY_XRSTOR64
18410         [UNSPECV_XRSTOR64
18411          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18413 (define_int_attr xrstor
18414         [(UNSPECV_XRSTOR "xrstor")
18415          (UNSPECV_XRSTOR64 "xrstor")
18416          (UNSPECV_XRSTORS "xrstors")
18417          (UNSPECV_XRSTORS64 "xrstors")])
18419 (define_insn "<xsave>"
18420   [(set (match_operand:BLK 0 "memory_operand" "=m")
18421         (unspec_volatile:BLK
18422          [(match_operand:DI 1 "register_operand" "A")]
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>_rex64"
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_XSAVE))]
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) + 3"))])
18444 (define_insn "<xsave>"
18445   [(set (match_operand:BLK 0 "memory_operand" "=m")
18446         (unspec_volatile:BLK
18447          [(match_operand:SI 1 "register_operand" "a")
18448           (match_operand:SI 2 "register_operand" "d")]
18449          ANY_XSAVE64))]
18450   "TARGET_64BIT && TARGET_XSAVE"
18451   "<xsave>\t%0"
18452   [(set_attr "type" "other")
18453    (set_attr "memory" "store")
18454    (set (attr "length")
18455         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18457 (define_insn "<xrstor>"
18458    [(unspec_volatile:BLK
18459      [(match_operand:BLK 0 "memory_operand" "m")
18460       (match_operand:DI 1 "register_operand" "A")]
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>_rex64"
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_XRSTOR)]
18475   "TARGET_64BIT && TARGET_XSAVE"
18476   "<xrstor>\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) + 3"))])
18482 (define_insn "<xrstor>64"
18483    [(unspec_volatile:BLK
18484      [(match_operand:BLK 0 "memory_operand" "m")
18485       (match_operand:SI 1 "register_operand" "a")
18486       (match_operand:SI 2 "register_operand" "d")]
18487      ANY_XRSTOR64)]
18488   "TARGET_64BIT && TARGET_XSAVE"
18489   "<xrstor>64\t%0"
18490   [(set_attr "type" "other")
18491    (set_attr "memory" "load")
18492    (set (attr "length")
18493         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18495 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18497 ;; Floating-point instructions for atomic compound assignments
18499 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18501 ; Clobber all floating-point registers on environment save and restore
18502 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18503 (define_insn "fnstenv"
18504   [(set (match_operand:BLK 0 "memory_operand" "=m")
18505         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18506    (clobber (reg:HI FPCR_REG))
18507    (clobber (reg:XF ST0_REG))
18508    (clobber (reg:XF ST1_REG))
18509    (clobber (reg:XF ST2_REG))
18510    (clobber (reg:XF ST3_REG))
18511    (clobber (reg:XF ST4_REG))
18512    (clobber (reg:XF ST5_REG))
18513    (clobber (reg:XF ST6_REG))
18514    (clobber (reg:XF ST7_REG))]
18515   "TARGET_80387"
18516   "fnstenv\t%0"
18517   [(set_attr "type" "other")
18518    (set_attr "memory" "store")
18519    (set (attr "length")
18520         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18522 (define_insn "fldenv"
18523   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18524                     UNSPECV_FLDENV)
18525    (clobber (reg:CCFP FPSR_REG))
18526    (clobber (reg:HI FPCR_REG))
18527    (clobber (reg:XF ST0_REG))
18528    (clobber (reg:XF ST1_REG))
18529    (clobber (reg:XF ST2_REG))
18530    (clobber (reg:XF ST3_REG))
18531    (clobber (reg:XF ST4_REG))
18532    (clobber (reg:XF ST5_REG))
18533    (clobber (reg:XF ST6_REG))
18534    (clobber (reg:XF ST7_REG))]
18535   "TARGET_80387"
18536   "fldenv\t%0"
18537   [(set_attr "type" "other")
18538    (set_attr "memory" "load")
18539    (set (attr "length")
18540         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18542 (define_insn "fnstsw"
18543   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18544         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18545   "TARGET_80387"
18546   "fnstsw\t%0"
18547   [(set_attr "type" "other,other")
18548    (set_attr "memory" "none,store")
18549    (set (attr "length")
18550         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18552 (define_insn "fnclex"
18553   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18554   "TARGET_80387"
18555   "fnclex"
18556   [(set_attr "type" "other")
18557    (set_attr "memory" "none")
18558    (set_attr "length" "2")])
18560 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18562 ;; LWP instructions
18564 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18566 (define_expand "lwp_llwpcb"
18567   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18568                     UNSPECV_LLWP_INTRINSIC)]
18569   "TARGET_LWP")
18571 (define_insn "*lwp_llwpcb<mode>1"
18572   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18573                     UNSPECV_LLWP_INTRINSIC)]
18574   "TARGET_LWP"
18575   "llwpcb\t%0"
18576   [(set_attr "type" "lwp")
18577    (set_attr "mode" "<MODE>")
18578    (set_attr "length" "5")])
18580 (define_expand "lwp_slwpcb"
18581   [(set (match_operand 0 "register_operand" "=r")
18582         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18583   "TARGET_LWP"
18585   rtx (*insn)(rtx);
18587   insn = (Pmode == DImode
18588           ? gen_lwp_slwpcbdi
18589           : gen_lwp_slwpcbsi);
18591   emit_insn (insn (operands[0]));
18592   DONE;
18595 (define_insn "lwp_slwpcb<mode>"
18596   [(set (match_operand:P 0 "register_operand" "=r")
18597         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18598   "TARGET_LWP"
18599   "slwpcb\t%0"
18600   [(set_attr "type" "lwp")
18601    (set_attr "mode" "<MODE>")
18602    (set_attr "length" "5")])
18604 (define_expand "lwp_lwpval<mode>3"
18605   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18606                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18607                      (match_operand:SI 3 "const_int_operand" "i")]
18608                     UNSPECV_LWPVAL_INTRINSIC)]
18609   "TARGET_LWP"
18610   ;; Avoid unused variable warning.
18611   "(void) operands[0];")
18613 (define_insn "*lwp_lwpval<mode>3_1"
18614   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18615                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18616                      (match_operand:SI 2 "const_int_operand" "i")]
18617                     UNSPECV_LWPVAL_INTRINSIC)]
18618   "TARGET_LWP"
18619   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18620   [(set_attr "type" "lwp")
18621    (set_attr "mode" "<MODE>")
18622    (set (attr "length")
18623         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18625 (define_expand "lwp_lwpins<mode>3"
18626   [(set (reg:CCC FLAGS_REG)
18627         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18628                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18629                               (match_operand:SI 3 "const_int_operand" "i")]
18630                              UNSPECV_LWPINS_INTRINSIC))
18631    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18632         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18633   "TARGET_LWP")
18635 (define_insn "*lwp_lwpins<mode>3_1"
18636   [(set (reg:CCC FLAGS_REG)
18637         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18638                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18639                               (match_operand:SI 2 "const_int_operand" "i")]
18640                              UNSPECV_LWPINS_INTRINSIC))]
18641   "TARGET_LWP"
18642   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18643   [(set_attr "type" "lwp")
18644    (set_attr "mode" "<MODE>")
18645    (set (attr "length")
18646         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18648 (define_int_iterator RDFSGSBASE
18649         [UNSPECV_RDFSBASE
18650          UNSPECV_RDGSBASE])
18652 (define_int_iterator WRFSGSBASE
18653         [UNSPECV_WRFSBASE
18654          UNSPECV_WRGSBASE])
18656 (define_int_attr fsgs
18657         [(UNSPECV_RDFSBASE "fs")
18658          (UNSPECV_RDGSBASE "gs")
18659          (UNSPECV_WRFSBASE "fs")
18660          (UNSPECV_WRGSBASE "gs")])
18662 (define_insn "rd<fsgs>base<mode>"
18663   [(set (match_operand:SWI48 0 "register_operand" "=r")
18664         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18665   "TARGET_64BIT && TARGET_FSGSBASE"
18666   "rd<fsgs>base\t%0"
18667   [(set_attr "type" "other")
18668    (set_attr "prefix_extra" "2")])
18670 (define_insn "wr<fsgs>base<mode>"
18671   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18672                     WRFSGSBASE)]
18673   "TARGET_64BIT && TARGET_FSGSBASE"
18674   "wr<fsgs>base\t%0"
18675   [(set_attr "type" "other")
18676    (set_attr "prefix_extra" "2")])
18678 (define_insn "rdrand<mode>_1"
18679   [(set (match_operand:SWI248 0 "register_operand" "=r")
18680         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18681    (set (reg:CCC FLAGS_REG)
18682         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18683   "TARGET_RDRND"
18684   "rdrand\t%0"
18685   [(set_attr "type" "other")
18686    (set_attr "prefix_extra" "1")])
18688 (define_insn "rdseed<mode>_1"
18689   [(set (match_operand:SWI248 0 "register_operand" "=r")
18690         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18691    (set (reg:CCC FLAGS_REG)
18692         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18693   "TARGET_RDSEED"
18694   "rdseed\t%0"
18695   [(set_attr "type" "other")
18696    (set_attr "prefix_extra" "1")])
18698 (define_expand "pause"
18699   [(set (match_dup 0)
18700         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18701   ""
18703   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18704   MEM_VOLATILE_P (operands[0]) = 1;
18707 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18708 ;; They have the same encoding.
18709 (define_insn "*pause"
18710   [(set (match_operand:BLK 0)
18711         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18712   ""
18713   "rep%; nop"
18714   [(set_attr "length" "2")
18715    (set_attr "memory" "unknown")])
18717 (define_expand "xbegin"
18718   [(set (match_operand:SI 0 "register_operand")
18719         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18720   "TARGET_RTM"
18722   rtx_code_label *label = gen_label_rtx ();
18724   /* xbegin is emitted as jump_insn, so reload won't be able
18725      to reload its operand.  Force the value into AX hard register.  */
18726   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18727   emit_move_insn (ax_reg, constm1_rtx);
18729   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18731   emit_label (label);
18732   LABEL_NUSES (label) = 1;
18734   emit_move_insn (operands[0], ax_reg);
18736   DONE;
18739 (define_insn "xbegin_1"
18740   [(set (pc)
18741         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18742                           (const_int 0))
18743                       (label_ref (match_operand 1))
18744                       (pc)))
18745    (set (match_operand:SI 0 "register_operand" "+a")
18746         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18747   "TARGET_RTM"
18748   "xbegin\t%l1"
18749   [(set_attr "type" "other")
18750    (set_attr "length" "6")])
18752 (define_insn "xend"
18753   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18754   "TARGET_RTM"
18755   "xend"
18756   [(set_attr "type" "other")
18757    (set_attr "length" "3")])
18759 (define_insn "xabort"
18760   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18761                     UNSPECV_XABORT)]
18762   "TARGET_RTM"
18763   "xabort\t%0"
18764   [(set_attr "type" "other")
18765    (set_attr "length" "3")])
18767 (define_expand "xtest"
18768   [(set (match_operand:QI 0 "register_operand")
18769         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18770   "TARGET_RTM"
18772   emit_insn (gen_xtest_1 ());
18774   ix86_expand_setcc (operands[0], NE,
18775                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18776   DONE;
18779 (define_insn "xtest_1"
18780   [(set (reg:CCZ FLAGS_REG)
18781         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18782   "TARGET_RTM"
18783   "xtest"
18784   [(set_attr "type" "other")
18785    (set_attr "length" "3")])
18787 (define_insn "pcommit"
18788   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18789   "TARGET_PCOMMIT"
18790   "pcommit"
18791   [(set_attr "type" "other")
18792    (set_attr "length" "4")])
18794 (define_insn "clwb"
18795   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18796                    UNSPECV_CLWB)]
18797   "TARGET_CLWB"
18798   "clwb\t%a0"
18799   [(set_attr "type" "sse")
18800    (set_attr "atom_sse_attr" "fence")
18801    (set_attr "memory" "unknown")])
18803 (define_insn "clflushopt"
18804   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18805                    UNSPECV_CLFLUSHOPT)]
18806   "TARGET_CLFLUSHOPT"
18807   "clflushopt\t%a0"
18808   [(set_attr "type" "sse")
18809    (set_attr "atom_sse_attr" "fence")
18810    (set_attr "memory" "unknown")])
18812 ;; MPX instructions
18814 (define_expand "<mode>_mk"
18815   [(set (match_operand:BND 0 "register_operand")
18816     (unspec:BND
18817       [(mem:<bnd_ptr>
18818        (match_par_dup 3
18819         [(match_operand:<bnd_ptr> 1 "register_operand")
18820          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18821       UNSPEC_BNDMK))]
18822   "TARGET_MPX"
18824   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18825                                                   operands[2]),
18826                                 UNSPEC_BNDMK_ADDR);
18829 (define_insn "*<mode>_mk"
18830   [(set (match_operand:BND 0 "register_operand" "=w")
18831     (unspec:BND
18832       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18833         [(unspec:<bnd_ptr>
18834            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18835             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18836            UNSPEC_BNDMK_ADDR)])]
18837       UNSPEC_BNDMK))]
18838   "TARGET_MPX"
18839   "bndmk\t{%3, %0|%0, %3}"
18840   [(set_attr "type" "mpxmk")])
18842 (define_expand "mov<mode>"
18843   [(set (match_operand:BND 0 "general_operand")
18844         (match_operand:BND 1 "general_operand"))]
18845   "TARGET_MPX"
18847   ix86_expand_move (<MODE>mode, operands);DONE;
18850 (define_insn "*mov<mode>_internal_mpx"
18851   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18852         (match_operand:BND 1 "general_operand" "wm,w"))]
18853   "TARGET_MPX"
18854   "bndmov\t{%1, %0|%0, %1}"
18855   [(set_attr "type" "mpxmov")])
18857 (define_expand "<mode>_<bndcheck>"
18858   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18859                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18860               (set (match_dup 2)
18861                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18862   "TARGET_MPX"
18864   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18865   MEM_VOLATILE_P (operands[2]) = 1;
18868 (define_insn "*<mode>_<bndcheck>"
18869   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18870                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18871               (set (match_operand:BLK 2 "bnd_mem_operator")
18872                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18873   "TARGET_MPX"
18874   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18875   [(set_attr "type" "mpxchk")])
18877 (define_expand "<mode>_ldx"
18878   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18879                        (unspec:BND
18880                          [(mem:<bnd_ptr>
18881                            (match_par_dup 3
18882                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18883                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18884                          UNSPEC_BNDLDX))
18885               (use (mem:BLK (match_dup 1)))])]
18886   "TARGET_MPX"
18888   /* Avoid registers which connot be used as index.  */
18889   if (!index_register_operand (operands[2], Pmode))
18890     {
18891       rtx temp = gen_reg_rtx (Pmode);
18892       emit_move_insn (temp, operands[2]);
18893       operands[2] = temp;
18894     }
18896   /* If it was a register originally then it may have
18897      mode other than Pmode.  We need to extend in such
18898      case because bndldx may work only with Pmode regs.  */
18899   if (GET_MODE (operands[2]) != Pmode)
18900     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18902   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18903                                                   operands[2]),
18904                                 UNSPEC_BNDLDX_ADDR);
18907 (define_insn "*<mode>_ldx"
18908   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18909                        (unspec:BND
18910                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18911                            [(unspec:<bnd_ptr>
18912                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18913                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18914                             UNSPEC_BNDLDX_ADDR)])]
18915                          UNSPEC_BNDLDX))
18916               (use (mem:BLK (match_dup 1)))])]
18917   "TARGET_MPX"
18918   "bndldx\t{%3, %0|%0, %3}"
18919   [(set_attr "type" "mpxld")])
18921 (define_expand "<mode>_stx"
18922   [(parallel [(unspec [(mem:<bnd_ptr>
18923                          (match_par_dup 3
18924                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18925                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18926                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18927               (set (match_dup 4)
18928                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18929   "TARGET_MPX"
18931   /* Avoid registers which connot be used as index.  */
18932   if (!index_register_operand (operands[1], Pmode))
18933     {
18934       rtx temp = gen_reg_rtx (Pmode);
18935       emit_move_insn (temp, operands[1]);
18936       operands[1] = temp;
18937     }
18939   /* If it was a register originally then it may have
18940      mode other than Pmode.  We need to extend in such
18941      case because bndstx may work only with Pmode regs.  */
18942   if (GET_MODE (operands[1]) != Pmode)
18943     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18945   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18946                                                   operands[1]),
18947                                 UNSPEC_BNDLDX_ADDR);
18948   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18949   MEM_VOLATILE_P (operands[4]) = 1;
18952 (define_insn "*<mode>_stx"
18953   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18954                          [(unspec:<bnd_ptr>
18955                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18956                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18957                          UNSPEC_BNDLDX_ADDR)])
18958                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18959               (set (match_operand:BLK 4 "bnd_mem_operator")
18960                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18961   "TARGET_MPX"
18962   "bndstx\t{%2, %3|%3, %2}"
18963   [(set_attr "type" "mpxst")])
18965 (define_insn "move_size_reloc_<mode>"
18966   [(set (match_operand:SWI48 0 "register_operand" "=r")
18967        (unspec:SWI48
18968         [(match_operand:SWI48 1 "symbol_operand")]
18969         UNSPEC_SIZEOF))]
18970   "TARGET_MPX"
18972   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18973     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18974   else
18975     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18977   [(set_attr "type" "imov")
18978    (set_attr "mode" "<MODE>")])
18980 (include "mmx.md")
18981 (include "sse.md")
18982 (include "sync.md")