[AVX-512] Enable QI-mode mask logic patterns on non-AVX-512DQ targets.
[official-gcc.git] / gcc / config / i386 / i386.md
blobcbb9ffd86af5f199768640860e0f1b5cd5d71fe6
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_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
114   UNSPEC_PEEPSIB
115   UNSPEC_INSN_FALSE_DEP
117   ;; For SSE/MMX support:
118   UNSPEC_FIX_NOTRUNC
119   UNSPEC_MASKMOV
120   UNSPEC_MOVMSK
121   UNSPEC_RCP
122   UNSPEC_RSQRT
123   UNSPEC_PSADBW
125   ;; Generic math support
126   UNSPEC_COPYSIGN
127   UNSPEC_IEEE_MIN       ; not commutative
128   UNSPEC_IEEE_MAX       ; not commutative
130   ;; x87 Floating point
131   UNSPEC_SIN
132   UNSPEC_COS
133   UNSPEC_FPATAN
134   UNSPEC_FYL2X
135   UNSPEC_FYL2XP1
136   UNSPEC_FRNDINT
137   UNSPEC_FIST
138   UNSPEC_F2XM1
139   UNSPEC_TAN
140   UNSPEC_FXAM
142   ;; x87 Rounding
143   UNSPEC_FRNDINT_FLOOR
144   UNSPEC_FRNDINT_CEIL
145   UNSPEC_FRNDINT_TRUNC
146   UNSPEC_FRNDINT_MASK_PM
147   UNSPEC_FIST_FLOOR
148   UNSPEC_FIST_CEIL
150   ;; x87 Double output FP
151   UNSPEC_SINCOS_COS
152   UNSPEC_SINCOS_SIN
153   UNSPEC_XTRACT_FRACT
154   UNSPEC_XTRACT_EXP
155   UNSPEC_FSCALE_FRACT
156   UNSPEC_FSCALE_EXP
157   UNSPEC_FPREM_F
158   UNSPEC_FPREM_U
159   UNSPEC_FPREM1_F
160   UNSPEC_FPREM1_U
162   UNSPEC_C2_FLAG
163   UNSPEC_FXAM_MEM
165   ;; SSP patterns
166   UNSPEC_SP_SET
167   UNSPEC_SP_TEST
168   UNSPEC_SP_TLS_SET
169   UNSPEC_SP_TLS_TEST
171   ;; For ROUND support
172   UNSPEC_ROUND
174   ;; For CRC32 support
175   UNSPEC_CRC32
177   ;; For BMI support
178   UNSPEC_BEXTR
180   ;; For BMI2 support
181   UNSPEC_PDEP
182   UNSPEC_PEXT
184   ;; For AVX512F support
185   UNSPEC_KMOV
187   UNSPEC_BNDMK
188   UNSPEC_BNDMK_ADDR
189   UNSPEC_BNDSTX
190   UNSPEC_BNDLDX
191   UNSPEC_BNDLDX_ADDR
192   UNSPEC_BNDCL
193   UNSPEC_BNDCU
194   UNSPEC_BNDCN
195   UNSPEC_MPX_FENCE
198 (define_c_enum "unspecv" [
199   UNSPECV_BLOCKAGE
200   UNSPECV_STACK_PROBE
201   UNSPECV_PROBE_STACK_RANGE
202   UNSPECV_ALIGN
203   UNSPECV_PROLOGUE_USE
204   UNSPECV_SPLIT_STACK_RETURN
205   UNSPECV_CLD
206   UNSPECV_NOPS
207   UNSPECV_RDTSC
208   UNSPECV_RDTSCP
209   UNSPECV_RDPMC
210   UNSPECV_LLWP_INTRINSIC
211   UNSPECV_SLWP_INTRINSIC
212   UNSPECV_LWPVAL_INTRINSIC
213   UNSPECV_LWPINS_INTRINSIC
214   UNSPECV_RDFSBASE
215   UNSPECV_RDGSBASE
216   UNSPECV_WRFSBASE
217   UNSPECV_WRGSBASE
218   UNSPECV_FXSAVE
219   UNSPECV_FXRSTOR
220   UNSPECV_FXSAVE64
221   UNSPECV_FXRSTOR64
222   UNSPECV_XSAVE
223   UNSPECV_XRSTOR
224   UNSPECV_XSAVE64
225   UNSPECV_XRSTOR64
226   UNSPECV_XSAVEOPT
227   UNSPECV_XSAVEOPT64
228   UNSPECV_XSAVES
229   UNSPECV_XRSTORS
230   UNSPECV_XSAVES64
231   UNSPECV_XRSTORS64
232   UNSPECV_XSAVEC
233   UNSPECV_XSAVEC64
235   ;; For atomic compound assignments.
236   UNSPECV_FNSTENV
237   UNSPECV_FLDENV
238   UNSPECV_FNSTSW
239   UNSPECV_FNCLEX
241   ;; For RDRAND support
242   UNSPECV_RDRAND
244   ;; For RDSEED support
245   UNSPECV_RDSEED
247   ;; For RTM support
248   UNSPECV_XBEGIN
249   UNSPECV_XEND
250   UNSPECV_XABORT
251   UNSPECV_XTEST
253   UNSPECV_NLGR
255   ;; For CLWB support
256   UNSPECV_CLWB
258   ;; For PCOMMIT support
259   UNSPECV_PCOMMIT
261   ;; For CLFLUSHOPT support
262   UNSPECV_CLFLUSHOPT
264   ;; For MONITORX and MWAITX support 
265   UNSPECV_MONITORX
266   UNSPECV_MWAITX
270 ;; Constants to represent rounding modes in the ROUND instruction
271 (define_constants
272   [(ROUND_FLOOR                 0x1)
273    (ROUND_CEIL                  0x2)
274    (ROUND_TRUNC                 0x3)
275    (ROUND_MXCSR                 0x4)
276    (ROUND_NO_EXC                0x8)
277   ])
279 ;; Constants to represent AVX512F embeded rounding
280 (define_constants
281   [(ROUND_NEAREST_INT                   0)
282    (ROUND_NEG_INF                       1)
283    (ROUND_POS_INF                       2)
284    (ROUND_ZERO                          3)
285    (NO_ROUND                            4)
286    (ROUND_SAE                           8)
287   ])
289 ;; Constants to represent pcomtrue/pcomfalse variants
290 (define_constants
291   [(PCOM_FALSE                  0)
292    (PCOM_TRUE                   1)
293    (COM_FALSE_S                 2)
294    (COM_FALSE_P                 3)
295    (COM_TRUE_S                  4)
296    (COM_TRUE_P                  5)
297   ])
299 ;; Constants used in the XOP pperm instruction
300 (define_constants
301   [(PPERM_SRC                   0x00)   /* copy source */
302    (PPERM_INVERT                0x20)   /* invert source */
303    (PPERM_REVERSE               0x40)   /* bit reverse source */
304    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
305    (PPERM_ZERO                  0x80)   /* all 0's */
306    (PPERM_ONES                  0xa0)   /* all 1's */
307    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
308    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
309    (PPERM_SRC1                  0x00)   /* use first source byte */
310    (PPERM_SRC2                  0x10)   /* use second source byte */
311    ])
313 ;; Registers by name.
314 (define_constants
315   [(AX_REG                       0)
316    (DX_REG                       1)
317    (CX_REG                       2)
318    (BX_REG                       3)
319    (SI_REG                       4)
320    (DI_REG                       5)
321    (BP_REG                       6)
322    (SP_REG                       7)
323    (ST0_REG                      8)
324    (ST1_REG                      9)
325    (ST2_REG                     10)
326    (ST3_REG                     11)
327    (ST4_REG                     12)
328    (ST5_REG                     13)
329    (ST6_REG                     14)
330    (ST7_REG                     15)
331    (ARGP_REG                    16)
332    (FLAGS_REG                   17)
333    (FPSR_REG                    18)
334    (FPCR_REG                    19)
335    (FRAME_REG                   20)
336    (XMM0_REG                    21)
337    (XMM1_REG                    22)
338    (XMM2_REG                    23)
339    (XMM3_REG                    24)
340    (XMM4_REG                    25)
341    (XMM5_REG                    26)
342    (XMM6_REG                    27)
343    (XMM7_REG                    28)
344    (MM0_REG                     29)
345    (MM1_REG                     30)
346    (MM2_REG                     31)
347    (MM3_REG                     32)
348    (MM4_REG                     33)
349    (MM5_REG                     34)
350    (MM6_REG                     35)
351    (MM7_REG                     36)
352    (R8_REG                      37)
353    (R9_REG                      38)
354    (R10_REG                     39)
355    (R11_REG                     40)
356    (R12_REG                     41)
357    (R13_REG                     42)
358    (R14_REG                     43)
359    (R15_REG                     44)
360    (XMM8_REG                    45)
361    (XMM9_REG                    46)
362    (XMM10_REG                   47)
363    (XMM11_REG                   48)
364    (XMM12_REG                   49)
365    (XMM13_REG                   50)
366    (XMM14_REG                   51)
367    (XMM15_REG                   52)
368    (XMM16_REG                   53)
369    (XMM17_REG                   54)
370    (XMM18_REG                   55)
371    (XMM19_REG                   56)
372    (XMM20_REG                   57)
373    (XMM21_REG                   58)
374    (XMM22_REG                   59)
375    (XMM23_REG                   60)
376    (XMM24_REG                   61)
377    (XMM25_REG                   62)
378    (XMM26_REG                   63)
379    (XMM27_REG                   64)
380    (XMM28_REG                   65)
381    (XMM29_REG                   66)
382    (XMM30_REG                   67)
383    (XMM31_REG                   68)
384    (MASK0_REG                   69)
385    (MASK1_REG                   70)
386    (MASK2_REG                   71)
387    (MASK3_REG                   72)
388    (MASK4_REG                   73)
389    (MASK5_REG                   74)
390    (MASK6_REG                   75)
391    (MASK7_REG                   76)
392    (BND0_REG                    77)
393    (BND1_REG                    78)
394    (BND2_REG                    79)
395    (BND3_REG                    80)
396    (FIRST_PSEUDO_REG            81)
397   ])
399 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
400 ;; from i386.c.
402 ;; In C guard expressions, put expressions which may be compile-time
403 ;; constants first.  This allows for better optimization.  For
404 ;; example, write "TARGET_64BIT && reload_completed", not
405 ;; "reload_completed && TARGET_64BIT".
408 ;; Processor type.
409 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
410                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
411                     bdver4,btver2,znver1"
412   (const (symbol_ref "ix86_schedule")))
414 ;; A basic instruction type.  Refinements due to arguments to be
415 ;; provided in other attributes.
416 (define_attr "type"
417   "other,multi,
418    alu,alu1,negnot,imov,imovx,lea,
419    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
420    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
421    push,pop,call,callv,leave,
422    str,bitmanip,
423    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
424    fxch,fistp,fisttp,frndint,
425    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
426    ssemul,sseimul,ssediv,sselog,sselog1,
427    sseishft,sseishft1,ssecmp,ssecomi,
428    ssecvt,ssecvt1,sseicvt,sseins,
429    sseshuf,sseshuf1,ssemuladd,sse4arg,
430    lwp,mskmov,msklog,
431    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
432    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
433   (const_string "other"))
435 ;; Main data type used by the insn
436 (define_attr "mode"
437   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
438   V2DF,V2SF,V1DF,V8DF"
439   (const_string "unknown"))
441 ;; The CPU unit operations uses.
442 (define_attr "unit" "integer,i387,sse,mmx,unknown"
443   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
444                           fxch,fistp,fisttp,frndint")
445            (const_string "i387")
446          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
447                           ssemul,sseimul,ssediv,sselog,sselog1,
448                           sseishft,sseishft1,ssecmp,ssecomi,
449                           ssecvt,ssecvt1,sseicvt,sseins,
450                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
451            (const_string "sse")
452          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
453            (const_string "mmx")
454          (eq_attr "type" "other")
455            (const_string "unknown")]
456          (const_string "integer")))
458 ;; The minimum required alignment of vector mode memory operands of the SSE
459 ;; (non-VEX/EVEX) instruction in bits, if it is different from
460 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
461 ;; multiple alternatives, this should be conservative maximum of those minimum
462 ;; required alignments.
463 (define_attr "ssememalign" "" (const_int 0))
465 ;; The (bounding maximum) length of an instruction immediate.
466 (define_attr "length_immediate" ""
467   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
468                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
469                           mpxld,mpxst")
470            (const_int 0)
471          (eq_attr "unit" "i387,sse,mmx")
472            (const_int 0)
473          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
474                           rotate,rotatex,rotate1,imul,icmp,push,pop")
475            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
476          (eq_attr "type" "imov,test")
477            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
478          (eq_attr "type" "call")
479            (if_then_else (match_operand 0 "constant_call_address_operand")
480              (const_int 4)
481              (const_int 0))
482          (eq_attr "type" "callv")
483            (if_then_else (match_operand 1 "constant_call_address_operand")
484              (const_int 4)
485              (const_int 0))
486          ;; We don't know the size before shorten_branches.  Expect
487          ;; the instruction to fit for better scheduling.
488          (eq_attr "type" "ibr")
489            (const_int 1)
490          ]
491          (symbol_ref "/* Update immediate_length and other attributes! */
492                       gcc_unreachable (),1")))
494 ;; The (bounding maximum) length of an instruction address.
495 (define_attr "length_address" ""
496   (cond [(eq_attr "type" "str,other,multi,fxch")
497            (const_int 0)
498          (and (eq_attr "type" "call")
499               (match_operand 0 "constant_call_address_operand"))
500              (const_int 0)
501          (and (eq_attr "type" "callv")
502               (match_operand 1 "constant_call_address_operand"))
503              (const_int 0)
504          ]
505          (symbol_ref "ix86_attr_length_address_default (insn)")))
507 ;; Set when length prefix is used.
508 (define_attr "prefix_data16" ""
509   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
510            (const_int 0)
511          (eq_attr "mode" "HI")
512            (const_int 1)
513          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
514            (const_int 1)
515         ]
516         (const_int 0)))
518 ;; Set when string REP prefix is used.
519 (define_attr "prefix_rep" ""
520   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
521            (const_int 0)
522          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
523            (const_int 1)
524          (and (eq_attr "type" "ibr,call,callv")
525               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
526            (const_int 1)
527         ]
528         (const_int 0)))
530 ;; Set when 0f opcode prefix is used.
531 (define_attr "prefix_0f" ""
532   (if_then_else
533     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
534                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
535          (eq_attr "unit" "sse,mmx"))
536     (const_int 1)
537     (const_int 0)))
539 ;; Set when REX opcode prefix is used.
540 (define_attr "prefix_rex" ""
541   (cond [(not (match_test "TARGET_64BIT"))
542            (const_int 0)
543          (and (eq_attr "mode" "DI")
544               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
545                    (eq_attr "unit" "!mmx")))
546            (const_int 1)
547          (and (eq_attr "mode" "QI")
548               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
549            (const_int 1)
550          (match_test "x86_extended_reg_mentioned_p (insn)")
551            (const_int 1)
552          (and (eq_attr "type" "imovx")
553               (match_operand:QI 1 "ext_QIreg_operand"))
554            (const_int 1)
555         ]
556         (const_int 0)))
558 ;; There are also additional prefixes in 3DNOW, SSSE3.
559 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
560 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
561 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
562 (define_attr "prefix_extra" ""
563   (cond [(eq_attr "type" "ssemuladd,sse4arg")
564            (const_int 2)
565          (eq_attr "type" "sseiadd1,ssecvt1")
566            (const_int 1)
567         ]
568         (const_int 0)))
570 ;; Set when BND opcode prefix may be used.
571 (define_attr "maybe_prefix_bnd" "" (const_int 0))
573 ;; Prefix used: original, VEX or maybe VEX.
574 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
575   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
576            (const_string "vex")
577          (eq_attr "mode" "XI,V16SF,V8DF")
578            (const_string "evex")
579         ]
580         (const_string "orig")))
582 ;; VEX W bit is used.
583 (define_attr "prefix_vex_w" "" (const_int 0))
585 ;; The length of VEX prefix
586 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
587 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
588 ;; still prefix_0f 1, with prefix_extra 1.
589 (define_attr "length_vex" ""
590   (if_then_else (and (eq_attr "prefix_0f" "1")
591                      (eq_attr "prefix_extra" "0"))
592     (if_then_else (eq_attr "prefix_vex_w" "1")
593       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
594       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
595     (if_then_else (eq_attr "prefix_vex_w" "1")
596       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
597       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
599 ;; 4-bytes evex prefix and 1 byte opcode.
600 (define_attr "length_evex" "" (const_int 5))
602 ;; Set when modrm byte is used.
603 (define_attr "modrm" ""
604   (cond [(eq_attr "type" "str,leave")
605            (const_int 0)
606          (eq_attr "unit" "i387")
607            (const_int 0)
608          (and (eq_attr "type" "incdec")
609               (and (not (match_test "TARGET_64BIT"))
610                    (ior (match_operand:SI 1 "register_operand")
611                         (match_operand:HI 1 "register_operand"))))
612            (const_int 0)
613          (and (eq_attr "type" "push")
614               (not (match_operand 1 "memory_operand")))
615            (const_int 0)
616          (and (eq_attr "type" "pop")
617               (not (match_operand 0 "memory_operand")))
618            (const_int 0)
619          (and (eq_attr "type" "imov")
620               (and (not (eq_attr "mode" "DI"))
621                    (ior (and (match_operand 0 "register_operand")
622                              (match_operand 1 "immediate_operand"))
623                         (ior (and (match_operand 0 "ax_reg_operand")
624                                   (match_operand 1 "memory_displacement_only_operand"))
625                              (and (match_operand 0 "memory_displacement_only_operand")
626                                   (match_operand 1 "ax_reg_operand"))))))
627            (const_int 0)
628          (and (eq_attr "type" "call")
629               (match_operand 0 "constant_call_address_operand"))
630              (const_int 0)
631          (and (eq_attr "type" "callv")
632               (match_operand 1 "constant_call_address_operand"))
633              (const_int 0)
634          (and (eq_attr "type" "alu,alu1,icmp,test")
635               (match_operand 0 "ax_reg_operand"))
636              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
637          ]
638          (const_int 1)))
640 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
641   (cond [(eq_attr "modrm" "0")
642            (const_string "none")
643          (eq_attr "type" "alu,imul,ishift")
644            (const_string "op02")
645          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
646            (const_string "op01")
647          (eq_attr "type" "incdec")
648            (const_string "incdec")
649          (eq_attr "type" "push,pop")
650            (const_string "pushpop")]
651          (const_string "unknown")))
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
656 ;; other insns.
657 (define_attr "length" ""
658   (cond [(eq_attr "type" "other,multi,fistp,frndint")
659            (const_int 16)
660          (eq_attr "type" "fcmp")
661            (const_int 4)
662          (eq_attr "unit" "i387")
663            (plus (const_int 2)
664                  (plus (attr "prefix_data16")
665                        (attr "length_address")))
666          (ior (eq_attr "prefix" "evex")
667               (and (ior (eq_attr "prefix" "maybe_evex")
668                         (eq_attr "prefix" "maybe_vex"))
669                    (match_test "TARGET_AVX512F")))
670            (plus (attr "length_evex")
671                  (plus (attr "length_immediate")
672                        (plus (attr "modrm")
673                              (attr "length_address"))))
674          (ior (eq_attr "prefix" "vex")
675               (and (ior (eq_attr "prefix" "maybe_vex")
676                         (eq_attr "prefix" "maybe_evex"))
677                    (match_test "TARGET_AVX")))
678            (plus (attr "length_vex")
679                  (plus (attr "length_immediate")
680                        (plus (attr "modrm")
681                              (attr "length_address"))))]
682          (plus (plus (attr "modrm")
683                      (plus (attr "prefix_0f")
684                            (plus (attr "prefix_rex")
685                                  (plus (attr "prefix_extra")
686                                        (const_int 1)))))
687                (plus (attr "prefix_rep")
688                      (plus (attr "prefix_data16")
689                            (plus (attr "length_immediate")
690                                  (attr "length_address")))))))
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
696 (define_attr "memory" "none,load,store,both,unknown"
697   (cond [(eq_attr "type" "other,multi,str,lwp")
698            (const_string "unknown")
699          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
700            (const_string "none")
701          (eq_attr "type" "fistp,leave")
702            (const_string "both")
703          (eq_attr "type" "frndint")
704            (const_string "load")
705          (eq_attr "type" "mpxld")
706            (const_string "load")
707          (eq_attr "type" "mpxst")
708            (const_string "store")
709          (eq_attr "type" "push")
710            (if_then_else (match_operand 1 "memory_operand")
711              (const_string "both")
712              (const_string "store"))
713          (eq_attr "type" "pop")
714            (if_then_else (match_operand 0 "memory_operand")
715              (const_string "both")
716              (const_string "load"))
717          (eq_attr "type" "setcc")
718            (if_then_else (match_operand 0 "memory_operand")
719              (const_string "store")
720              (const_string "none"))
721          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
722            (if_then_else (ior (match_operand 0 "memory_operand")
723                               (match_operand 1 "memory_operand"))
724              (const_string "load")
725              (const_string "none"))
726          (eq_attr "type" "ibr")
727            (if_then_else (match_operand 0 "memory_operand")
728              (const_string "load")
729              (const_string "none"))
730          (eq_attr "type" "call")
731            (if_then_else (match_operand 0 "constant_call_address_operand")
732              (const_string "none")
733              (const_string "load"))
734          (eq_attr "type" "callv")
735            (if_then_else (match_operand 1 "constant_call_address_operand")
736              (const_string "none")
737              (const_string "load"))
738          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
739               (match_operand 1 "memory_operand"))
740            (const_string "both")
741          (and (match_operand 0 "memory_operand")
742               (match_operand 1 "memory_operand"))
743            (const_string "both")
744          (match_operand 0 "memory_operand")
745            (const_string "store")
746          (match_operand 1 "memory_operand")
747            (const_string "load")
748          (and (eq_attr "type"
749                  "!alu1,negnot,ishift1,
750                    imov,imovx,icmp,test,bitmanip,
751                    fmov,fcmp,fsgn,
752                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
753                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
754                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
755               (match_operand 2 "memory_operand"))
756            (const_string "load")
757          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
758               (match_operand 3 "memory_operand"))
759            (const_string "load")
760         ]
761         (const_string "none")))
763 ;; Indicates if an instruction has both an immediate and a displacement.
765 (define_attr "imm_disp" "false,true,unknown"
766   (cond [(eq_attr "type" "other,multi")
767            (const_string "unknown")
768          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
769               (and (match_operand 0 "memory_displacement_operand")
770                    (match_operand 1 "immediate_operand")))
771            (const_string "true")
772          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
773               (and (match_operand 0 "memory_displacement_operand")
774                    (match_operand 2 "immediate_operand")))
775            (const_string "true")
776         ]
777         (const_string "false")))
779 ;; Indicates if an FP operation has an integer source.
781 (define_attr "fp_int_src" "false,true"
782   (const_string "false"))
784 ;; Defines rounding mode of an FP operation.
786 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
787   (const_string "any"))
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
800                     avx512vl,noavx512vl"
801   (const_string "base"))
803 (define_attr "enabled" ""
804   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
805          (eq_attr "isa" "x64_sse4")
806            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
807          (eq_attr "isa" "x64_sse4_noavx")
808            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
809          (eq_attr "isa" "x64_avx")
810            (symbol_ref "TARGET_64BIT && TARGET_AVX")
811          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
812          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
813          (eq_attr "isa" "sse2_noavx")
814            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
815          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
816          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
817          (eq_attr "isa" "sse4_noavx")
818            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
819          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
820          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
821          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
822          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
823          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
824          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
825          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
826          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
827          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
828          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
829          (eq_attr "isa" "fma_avx512f")
830            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
831          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
832          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
833          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
834          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
835          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
836          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
837         ]
838         (const_int 1)))
840 (define_attr "preferred_for_size" "" (const_int 1))
841 (define_attr "preferred_for_speed" "" (const_int 1))
843 ;; Describe a user's asm statement.
844 (define_asm_attributes
845   [(set_attr "length" "128")
846    (set_attr "type" "multi")])
848 (define_code_iterator plusminus [plus minus])
850 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
852 (define_code_iterator multdiv [mult div])
854 ;; Base name for define_insn
855 (define_code_attr plusminus_insn
856   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
857    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
859 ;; Base name for insn mnemonic.
860 (define_code_attr plusminus_mnemonic
861   [(plus "add") (ss_plus "adds") (us_plus "addus")
862    (minus "sub") (ss_minus "subs") (us_minus "subus")])
863 (define_code_attr multdiv_mnemonic
864   [(mult "mul") (div "div")])
866 ;; Mark commutative operators as such in constraints.
867 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
868                         (minus "") (ss_minus "") (us_minus "")])
870 ;; Mapping of max and min
871 (define_code_iterator maxmin [smax smin umax umin])
873 ;; Mapping of signed max and min
874 (define_code_iterator smaxmin [smax smin])
876 ;; Mapping of unsigned max and min
877 (define_code_iterator umaxmin [umax umin])
879 ;; Base name for integer and FP insn mnemonic
880 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
881                               (umax "maxu") (umin "minu")])
882 (define_code_attr maxmin_float [(smax "max") (smin "min")])
884 ;; Mapping of logic operators
885 (define_code_iterator any_logic [and ior xor])
886 (define_code_iterator any_or [ior xor])
887 (define_code_iterator fpint_logic [and xor])
889 ;; Base name for insn mnemonic.
890 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
892 ;; Mapping of logic-shift operators
893 (define_code_iterator any_lshift [ashift lshiftrt])
895 ;; Mapping of shift-right operators
896 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
898 ;; Mapping of all shift operators
899 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
901 ;; Base name for define_insn
902 (define_code_attr shift_insn
903   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
905 ;; Base name for insn mnemonic.
906 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
907 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
909 ;; Mask variant left right mnemonics
910 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
912 ;; Mapping of rotate operators
913 (define_code_iterator any_rotate [rotate rotatert])
915 ;; Base name for define_insn
916 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
918 ;; Base name for insn mnemonic.
919 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
921 ;; Mapping of abs neg operators
922 (define_code_iterator absneg [abs neg])
924 ;; Base name for x87 insn mnemonic.
925 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
927 ;; Used in signed and unsigned widening multiplications.
928 (define_code_iterator any_extend [sign_extend zero_extend])
930 ;; Prefix for insn menmonic.
931 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
933 ;; Prefix for define_insn
934 (define_code_attr u [(sign_extend "") (zero_extend "u")])
935 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
936 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
938 ;; Used in signed and unsigned truncations.
939 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
940 ;; Instruction suffix for truncations.
941 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
943 ;; Used in signed and unsigned fix.
944 (define_code_iterator any_fix [fix unsigned_fix])
945 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
947 ;; Used in signed and unsigned float.
948 (define_code_iterator any_float [float unsigned_float])
949 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
951 ;; All integer modes.
952 (define_mode_iterator SWI1248x [QI HI SI DI])
954 ;; All integer modes with AVX512BW/DQ.
955 (define_mode_iterator SWI1248_AVX512BWDQ
956   [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
958 ;; All integer modes without QImode.
959 (define_mode_iterator SWI248x [HI SI DI])
961 ;; All integer modes without QImode and HImode.
962 (define_mode_iterator SWI48x [SI DI])
964 ;; All integer modes without SImode and DImode.
965 (define_mode_iterator SWI12 [QI HI])
967 ;; All integer modes without DImode.
968 (define_mode_iterator SWI124 [QI HI SI])
970 ;; All integer modes without QImode and DImode.
971 (define_mode_iterator SWI24 [HI SI])
973 ;; Single word integer modes.
974 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
976 ;; Single word integer modes without QImode.
977 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
979 ;; Single word integer modes without QImode and HImode.
980 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
982 ;; All math-dependant single and double word integer modes.
983 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
984                              (HI "TARGET_HIMODE_MATH")
985                              SI DI (TI "TARGET_64BIT")])
987 ;; Math-dependant single word integer modes.
988 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
989                             (HI "TARGET_HIMODE_MATH")
990                             SI (DI "TARGET_64BIT")])
992 ;; Math-dependant integer modes without DImode.
993 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
994                                (HI "TARGET_HIMODE_MATH")
995                                SI])
997 ;; Math-dependant integer modes with DImode.
998 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
999                                  (HI "TARGET_HIMODE_MATH")
1000                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1002 ;; Math-dependant single word integer modes without QImode.
1003 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1004                                SI (DI "TARGET_64BIT")])
1006 ;; Double word integer modes.
1007 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1008                            (TI "TARGET_64BIT")])
1010 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1011 ;; compile time constant, it is faster to use <MODE_SIZE> than
1012 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1013 ;; command line options just use GET_MODE_SIZE macro.
1014 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1015                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1016                              (V16QI "16") (V32QI "32") (V64QI "64")
1017                              (V8HI "16") (V16HI "32") (V32HI "64")
1018                              (V4SI "16") (V8SI "32") (V16SI "64")
1019                              (V2DI "16") (V4DI "32") (V8DI "64")
1020                              (V1TI "16") (V2TI "32") (V4TI "64")
1021                              (V2DF "16") (V4DF "32") (V8DF "64")
1022                              (V4SF "16") (V8SF "32") (V16SF "64")])
1024 ;; Double word integer modes as mode attribute.
1025 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1026 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1028 ;; Half mode for double word integer modes.
1029 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1030                             (DI "TARGET_64BIT")])
1032 ;; Bound modes.
1033 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1034                            (BND64 "TARGET_LP64")])
1036 ;; Pointer mode corresponding to bound mode.
1037 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1039 ;; MPX check types
1040 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1042 ;; Check name
1043 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1044                            (UNSPEC_BNDCU "cu")
1045                            (UNSPEC_BNDCN "cn")])
1047 ;; Instruction suffix for integer modes.
1048 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1050 ;; Instruction suffix for masks.
1051 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1053 ;; Pointer size prefix for integer modes (Intel asm dialect)
1054 (define_mode_attr iptrsize [(QI "BYTE")
1055                             (HI "WORD")
1056                             (SI "DWORD")
1057                             (DI "QWORD")])
1059 ;; Register class for integer modes.
1060 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1062 ;; Immediate operand constraint for integer modes.
1063 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1065 ;; General operand constraint for word modes.
1066 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1068 ;; Immediate operand constraint for double integer modes.
1069 (define_mode_attr di [(SI "nF") (DI "e")])
1071 ;; Immediate operand constraint for shifts.
1072 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1074 ;; General operand predicate for integer modes.
1075 (define_mode_attr general_operand
1076         [(QI "general_operand")
1077          (HI "general_operand")
1078          (SI "x86_64_general_operand")
1079          (DI "x86_64_general_operand")
1080          (TI "x86_64_general_operand")])
1082 ;; General sign extend operand predicate for integer modes,
1083 ;; which disallows VOIDmode operands and thus it is suitable
1084 ;; for use inside sign_extend.
1085 (define_mode_attr general_sext_operand
1086         [(QI "sext_operand")
1087          (HI "sext_operand")
1088          (SI "x86_64_sext_operand")
1089          (DI "x86_64_sext_operand")])
1091 ;; General sign/zero extend operand predicate for integer modes.
1092 (define_mode_attr general_szext_operand
1093         [(QI "general_operand")
1094          (HI "general_operand")
1095          (SI "x86_64_szext_general_operand")
1096          (DI "x86_64_szext_general_operand")])
1098 ;; Immediate operand predicate for integer modes.
1099 (define_mode_attr immediate_operand
1100         [(QI "immediate_operand")
1101          (HI "immediate_operand")
1102          (SI "x86_64_immediate_operand")
1103          (DI "x86_64_immediate_operand")])
1105 ;; Nonmemory operand predicate for integer modes.
1106 (define_mode_attr nonmemory_operand
1107         [(QI "nonmemory_operand")
1108          (HI "nonmemory_operand")
1109          (SI "x86_64_nonmemory_operand")
1110          (DI "x86_64_nonmemory_operand")])
1112 ;; Operand predicate for shifts.
1113 (define_mode_attr shift_operand
1114         [(QI "nonimmediate_operand")
1115          (HI "nonimmediate_operand")
1116          (SI "nonimmediate_operand")
1117          (DI "shiftdi_operand")
1118          (TI "register_operand")])
1120 ;; Operand predicate for shift argument.
1121 (define_mode_attr shift_immediate_operand
1122         [(QI "const_1_to_31_operand")
1123          (HI "const_1_to_31_operand")
1124          (SI "const_1_to_31_operand")
1125          (DI "const_1_to_63_operand")])
1127 ;; Input operand predicate for arithmetic left shifts.
1128 (define_mode_attr ashl_input_operand
1129         [(QI "nonimmediate_operand")
1130          (HI "nonimmediate_operand")
1131          (SI "nonimmediate_operand")
1132          (DI "ashldi_input_operand")
1133          (TI "reg_or_pm1_operand")])
1135 ;; SSE and x87 SFmode and DFmode floating point modes
1136 (define_mode_iterator MODEF [SF DF])
1138 ;; All x87 floating point modes
1139 (define_mode_iterator X87MODEF [SF DF XF])
1141 ;; SSE instruction suffix for various modes
1142 (define_mode_attr ssemodesuffix
1143   [(SF "ss") (DF "sd")
1144    (V16SF "ps") (V8DF "pd")
1145    (V8SF "ps") (V4DF "pd")
1146    (V4SF "ps") (V2DF "pd")
1147    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1148    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1149    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1151 ;; SSE vector suffix for floating point modes
1152 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1154 ;; SSE vector mode corresponding to a scalar mode
1155 (define_mode_attr ssevecmode
1156   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1157 (define_mode_attr ssevecmodelower
1158   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1160 ;; Instruction suffix for REX 64bit operators.
1161 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1163 ;; This mode iterator allows :P to be used for patterns that operate on
1164 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1165 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1167 ;; This mode iterator allows :W to be used for patterns that operate on
1168 ;; word_mode sized quantities.
1169 (define_mode_iterator W
1170   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1172 ;; This mode iterator allows :PTR to be used for patterns that operate on
1173 ;; ptr_mode sized quantities.
1174 (define_mode_iterator PTR
1175   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1177 ;; Scheduling descriptions
1179 (include "pentium.md")
1180 (include "ppro.md")
1181 (include "k6.md")
1182 (include "athlon.md")
1183 (include "bdver1.md")
1184 (include "bdver3.md")
1185 (include "btver2.md")
1186 (include "znver1.md")
1187 (include "geode.md")
1188 (include "atom.md")
1189 (include "slm.md")
1190 (include "core2.md")
1191 (include "haswell.md")
1194 ;; Operand and operator predicates and constraints
1196 (include "predicates.md")
1197 (include "constraints.md")
1200 ;; Compare and branch/compare and store instructions.
1202 (define_expand "cbranch<mode>4"
1203   [(set (reg:CC FLAGS_REG)
1204         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1205                     (match_operand:SDWIM 2 "<general_operand>")))
1206    (set (pc) (if_then_else
1207                (match_operator 0 "ordered_comparison_operator"
1208                 [(reg:CC FLAGS_REG) (const_int 0)])
1209                (label_ref (match_operand 3))
1210                (pc)))]
1211   ""
1213   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1214     operands[1] = force_reg (<MODE>mode, operands[1]);
1215   ix86_expand_branch (GET_CODE (operands[0]),
1216                       operands[1], operands[2], operands[3]);
1217   DONE;
1220 (define_expand "cstore<mode>4"
1221   [(set (reg:CC FLAGS_REG)
1222         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1223                     (match_operand:SWIM 3 "<general_operand>")))
1224    (set (match_operand:QI 0 "register_operand")
1225         (match_operator 1 "ordered_comparison_operator"
1226           [(reg:CC FLAGS_REG) (const_int 0)]))]
1227   ""
1229   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1230     operands[2] = force_reg (<MODE>mode, operands[2]);
1231   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1232                      operands[2], operands[3]);
1233   DONE;
1236 (define_expand "cmp<mode>_1"
1237   [(set (reg:CC FLAGS_REG)
1238         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1239                     (match_operand:SWI48 1 "<general_operand>")))])
1241 (define_insn "*cmp<mode>_ccno_1"
1242   [(set (reg FLAGS_REG)
1243         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1244                  (match_operand:SWI 1 "const0_operand")))]
1245   "ix86_match_ccmode (insn, CCNOmode)"
1246   "@
1247    test{<imodesuffix>}\t%0, %0
1248    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1249   [(set_attr "type" "test,icmp")
1250    (set_attr "length_immediate" "0,1")
1251    (set_attr "modrm_class" "op0,unknown")
1252    (set_attr "mode" "<MODE>")])
1254 (define_insn "*cmp<mode>_1"
1255   [(set (reg FLAGS_REG)
1256         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1257                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1258   "ix86_match_ccmode (insn, CCmode)"
1259   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1260   [(set_attr "type" "icmp")
1261    (set_attr "mode" "<MODE>")])
1263 (define_insn "*cmp<mode>_minus_1"
1264   [(set (reg FLAGS_REG)
1265         (compare
1266           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1267                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1268           (const_int 0)))]
1269   "ix86_match_ccmode (insn, CCGOCmode)"
1270   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1271   [(set_attr "type" "icmp")
1272    (set_attr "mode" "<MODE>")])
1274 (define_insn "*cmpqi_ext_1"
1275   [(set (reg FLAGS_REG)
1276         (compare
1277           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1278           (subreg:QI
1279             (zero_extract:SI
1280               (match_operand 1 "ext_register_operand" "Q,Q")
1281               (const_int 8)
1282               (const_int 8)) 0)))]
1283   "ix86_match_ccmode (insn, CCmode)"
1284   "cmp{b}\t{%h1, %0|%0, %h1}"
1285   [(set_attr "isa" "*,nox64")
1286    (set_attr "type" "icmp")
1287    (set_attr "mode" "QI")])
1289 (define_insn "*cmpqi_ext_2"
1290   [(set (reg FLAGS_REG)
1291         (compare
1292           (subreg:QI
1293             (zero_extract:SI
1294               (match_operand 0 "ext_register_operand" "Q")
1295               (const_int 8)
1296               (const_int 8)) 0)
1297           (match_operand:QI 1 "const0_operand")))]
1298   "ix86_match_ccmode (insn, CCNOmode)"
1299   "test{b}\t%h0, %h0"
1300   [(set_attr "type" "test")
1301    (set_attr "length_immediate" "0")
1302    (set_attr "mode" "QI")])
1304 (define_expand "cmpqi_ext_3"
1305   [(set (reg:CC FLAGS_REG)
1306         (compare:CC
1307           (subreg:QI
1308             (zero_extract:SI
1309               (match_operand 0 "ext_register_operand")
1310               (const_int 8)
1311               (const_int 8)) 0)
1312           (match_operand:QI 1 "const_int_operand")))])
1314 (define_insn "*cmpqi_ext_3"
1315   [(set (reg FLAGS_REG)
1316         (compare
1317           (subreg:QI
1318             (zero_extract:SI
1319               (match_operand 0 "ext_register_operand" "Q,Q")
1320               (const_int 8)
1321               (const_int 8)) 0)
1322           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1323   "ix86_match_ccmode (insn, CCmode)"
1324   "cmp{b}\t{%1, %h0|%h0, %1}"
1325   [(set_attr "isa" "*,nox64")
1326    (set_attr "type" "icmp")
1327    (set_attr "modrm" "1")
1328    (set_attr "mode" "QI")])
1330 (define_insn "*cmpqi_ext_4"
1331   [(set (reg FLAGS_REG)
1332         (compare
1333           (subreg:QI
1334             (zero_extract:SI
1335               (match_operand 0 "ext_register_operand" "Q")
1336               (const_int 8)
1337               (const_int 8)) 0)
1338           (subreg:QI
1339             (zero_extract:SI
1340               (match_operand 1 "ext_register_operand" "Q")
1341               (const_int 8)
1342               (const_int 8)) 0)))]
1343   "ix86_match_ccmode (insn, CCmode)"
1344   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1345   [(set_attr "type" "icmp")
1346    (set_attr "mode" "QI")])
1348 ;; These implement float point compares.
1349 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1350 ;; which would allow mix and match FP modes on the compares.  Which is what
1351 ;; the old patterns did, but with many more of them.
1353 (define_expand "cbranchxf4"
1354   [(set (reg:CC FLAGS_REG)
1355         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1356                     (match_operand:XF 2 "nonmemory_operand")))
1357    (set (pc) (if_then_else
1358               (match_operator 0 "ix86_fp_comparison_operator"
1359                [(reg:CC FLAGS_REG)
1360                 (const_int 0)])
1361               (label_ref (match_operand 3))
1362               (pc)))]
1363   "TARGET_80387"
1365   ix86_expand_branch (GET_CODE (operands[0]),
1366                       operands[1], operands[2], operands[3]);
1367   DONE;
1370 (define_expand "cstorexf4"
1371   [(set (reg:CC FLAGS_REG)
1372         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1373                     (match_operand:XF 3 "nonmemory_operand")))
1374    (set (match_operand:QI 0 "register_operand")
1375               (match_operator 1 "ix86_fp_comparison_operator"
1376                [(reg:CC FLAGS_REG)
1377                 (const_int 0)]))]
1378   "TARGET_80387"
1380   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1381                      operands[2], operands[3]);
1382   DONE;
1385 (define_expand "cbranch<mode>4"
1386   [(set (reg:CC FLAGS_REG)
1387         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1388                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1389    (set (pc) (if_then_else
1390               (match_operator 0 "ix86_fp_comparison_operator"
1391                [(reg:CC FLAGS_REG)
1392                 (const_int 0)])
1393               (label_ref (match_operand 3))
1394               (pc)))]
1395   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1397   ix86_expand_branch (GET_CODE (operands[0]),
1398                       operands[1], operands[2], operands[3]);
1399   DONE;
1402 (define_expand "cstore<mode>4"
1403   [(set (reg:CC FLAGS_REG)
1404         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1405                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1406    (set (match_operand:QI 0 "register_operand")
1407               (match_operator 1 "ix86_fp_comparison_operator"
1408                [(reg:CC FLAGS_REG)
1409                 (const_int 0)]))]
1410   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1412   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1413                      operands[2], operands[3]);
1414   DONE;
1417 (define_expand "cbranchcc4"
1418   [(set (pc) (if_then_else
1419               (match_operator 0 "comparison_operator"
1420                [(match_operand 1 "flags_reg_operand")
1421                 (match_operand 2 "const0_operand")])
1422               (label_ref (match_operand 3))
1423               (pc)))]
1424   ""
1426   ix86_expand_branch (GET_CODE (operands[0]),
1427                       operands[1], operands[2], operands[3]);
1428   DONE;
1431 (define_expand "cstorecc4"
1432   [(set (match_operand:QI 0 "register_operand")
1433               (match_operator 1 "comparison_operator"
1434                [(match_operand 2 "flags_reg_operand")
1435                 (match_operand 3 "const0_operand")]))]
1436   ""
1438   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1439                      operands[2], operands[3]);
1440   DONE;
1444 ;; FP compares, step 1:
1445 ;; Set the FP condition codes.
1447 ;; CCFPmode     compare with exceptions
1448 ;; CCFPUmode    compare with no exceptions
1450 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1451 ;; used to manage the reg stack popping would not be preserved.
1453 (define_insn "*cmp<mode>_0_i387"
1454   [(set (match_operand:HI 0 "register_operand" "=a")
1455         (unspec:HI
1456           [(compare:CCFP
1457              (match_operand:X87MODEF 1 "register_operand" "f")
1458              (match_operand:X87MODEF 2 "const0_operand"))]
1459         UNSPEC_FNSTSW))]
1460   "TARGET_80387"
1461   "* return output_fp_compare (insn, operands, false, false);"
1462   [(set_attr "type" "multi")
1463    (set_attr "unit" "i387")
1464    (set_attr "mode" "<MODE>")])
1466 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1467   [(set (reg:CCFP FLAGS_REG)
1468         (compare:CCFP
1469           (match_operand:X87MODEF 1 "register_operand" "f")
1470           (match_operand:X87MODEF 2 "const0_operand")))
1471    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1472   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1473   "#"
1474   "&& reload_completed"
1475   [(set (match_dup 0)
1476         (unspec:HI
1477           [(compare:CCFP (match_dup 1)(match_dup 2))]
1478         UNSPEC_FNSTSW))
1479    (set (reg:CC FLAGS_REG)
1480         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1481   ""
1482   [(set_attr "type" "multi")
1483    (set_attr "unit" "i387")
1484    (set_attr "mode" "<MODE>")])
1486 (define_insn "*cmpxf_i387"
1487   [(set (match_operand:HI 0 "register_operand" "=a")
1488         (unspec:HI
1489           [(compare:CCFP
1490              (match_operand:XF 1 "register_operand" "f")
1491              (match_operand:XF 2 "register_operand" "f"))]
1492           UNSPEC_FNSTSW))]
1493   "TARGET_80387"
1494   "* return output_fp_compare (insn, operands, false, false);"
1495   [(set_attr "type" "multi")
1496    (set_attr "unit" "i387")
1497    (set_attr "mode" "XF")])
1499 (define_insn_and_split "*cmpxf_cc_i387"
1500   [(set (reg:CCFP FLAGS_REG)
1501         (compare:CCFP
1502           (match_operand:XF 1 "register_operand" "f")
1503           (match_operand:XF 2 "register_operand" "f")))
1504    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1505   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1506   "#"
1507   "&& reload_completed"
1508   [(set (match_dup 0)
1509         (unspec:HI
1510           [(compare:CCFP (match_dup 1)(match_dup 2))]
1511         UNSPEC_FNSTSW))
1512    (set (reg:CC FLAGS_REG)
1513         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1514   ""
1515   [(set_attr "type" "multi")
1516    (set_attr "unit" "i387")
1517    (set_attr "mode" "XF")])
1519 (define_insn "*cmp<mode>_i387"
1520   [(set (match_operand:HI 0 "register_operand" "=a")
1521         (unspec:HI
1522           [(compare:CCFP
1523              (match_operand:MODEF 1 "register_operand" "f")
1524              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1525           UNSPEC_FNSTSW))]
1526   "TARGET_80387"
1527   "* return output_fp_compare (insn, operands, false, false);"
1528   [(set_attr "type" "multi")
1529    (set_attr "unit" "i387")
1530    (set_attr "mode" "<MODE>")])
1532 (define_insn_and_split "*cmp<mode>_cc_i387"
1533   [(set (reg:CCFP FLAGS_REG)
1534         (compare:CCFP
1535           (match_operand:MODEF 1 "register_operand" "f")
1536           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1537    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1538   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1539   "#"
1540   "&& reload_completed"
1541   [(set (match_dup 0)
1542         (unspec:HI
1543           [(compare:CCFP (match_dup 1)(match_dup 2))]
1544         UNSPEC_FNSTSW))
1545    (set (reg:CC FLAGS_REG)
1546         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1547   ""
1548   [(set_attr "type" "multi")
1549    (set_attr "unit" "i387")
1550    (set_attr "mode" "<MODE>")])
1552 (define_insn "*cmpu<mode>_i387"
1553   [(set (match_operand:HI 0 "register_operand" "=a")
1554         (unspec:HI
1555           [(compare:CCFPU
1556              (match_operand:X87MODEF 1 "register_operand" "f")
1557              (match_operand:X87MODEF 2 "register_operand" "f"))]
1558           UNSPEC_FNSTSW))]
1559   "TARGET_80387"
1560   "* return output_fp_compare (insn, operands, false, true);"
1561   [(set_attr "type" "multi")
1562    (set_attr "unit" "i387")
1563    (set_attr "mode" "<MODE>")])
1565 (define_insn_and_split "*cmpu<mode>_cc_i387"
1566   [(set (reg:CCFPU FLAGS_REG)
1567         (compare:CCFPU
1568           (match_operand:X87MODEF 1 "register_operand" "f")
1569           (match_operand:X87MODEF 2 "register_operand" "f")))
1570    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1571   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1572   "#"
1573   "&& reload_completed"
1574   [(set (match_dup 0)
1575         (unspec:HI
1576           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1577         UNSPEC_FNSTSW))
1578    (set (reg:CC FLAGS_REG)
1579         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1580   ""
1581   [(set_attr "type" "multi")
1582    (set_attr "unit" "i387")
1583    (set_attr "mode" "<MODE>")])
1585 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1586   [(set (match_operand:HI 0 "register_operand" "=a")
1587         (unspec:HI
1588           [(compare:CCFP
1589              (match_operand:X87MODEF 1 "register_operand" "f")
1590              (match_operator:X87MODEF 3 "float_operator"
1591                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1592           UNSPEC_FNSTSW))]
1593   "TARGET_80387
1594    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1595        || optimize_function_for_size_p (cfun))"
1596   "* return output_fp_compare (insn, operands, false, false);"
1597   [(set_attr "type" "multi")
1598    (set_attr "unit" "i387")
1599    (set_attr "fp_int_src" "true")
1600    (set_attr "mode" "<SWI24:MODE>")])
1602 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1603   [(set (reg:CCFP FLAGS_REG)
1604         (compare:CCFP
1605           (match_operand:X87MODEF 1 "register_operand" "f")
1606           (match_operator:X87MODEF 3 "float_operator"
1607             [(match_operand:SWI24 2 "memory_operand" "m")])))
1608    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1609   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1610    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1611        || optimize_function_for_size_p (cfun))"
1612   "#"
1613   "&& reload_completed"
1614   [(set (match_dup 0)
1615         (unspec:HI
1616           [(compare:CCFP
1617              (match_dup 1)
1618              (match_op_dup 3 [(match_dup 2)]))]
1619         UNSPEC_FNSTSW))
1620    (set (reg:CC FLAGS_REG)
1621         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1622   ""
1623   [(set_attr "type" "multi")
1624    (set_attr "unit" "i387")
1625    (set_attr "fp_int_src" "true")
1626    (set_attr "mode" "<SWI24:MODE>")])
1628 ;; FP compares, step 2
1629 ;; Move the fpsw to ax.
1631 (define_insn "x86_fnstsw_1"
1632   [(set (match_operand:HI 0 "register_operand" "=a")
1633         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1634   "TARGET_80387"
1635   "fnstsw\t%0"
1636   [(set_attr "length" "2")
1637    (set_attr "mode" "SI")
1638    (set_attr "unit" "i387")])
1640 ;; FP compares, step 3
1641 ;; Get ax into flags, general case.
1643 (define_insn "x86_sahf_1"
1644   [(set (reg:CC FLAGS_REG)
1645         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1646                    UNSPEC_SAHF))]
1647   "TARGET_SAHF"
1649 #ifndef HAVE_AS_IX86_SAHF
1650   if (TARGET_64BIT)
1651     return ASM_BYTE "0x9e";
1652   else
1653 #endif
1654   return "sahf";
1656   [(set_attr "length" "1")
1657    (set_attr "athlon_decode" "vector")
1658    (set_attr "amdfam10_decode" "direct")
1659    (set_attr "bdver1_decode" "direct")
1660    (set_attr "mode" "SI")])
1662 ;; Pentium Pro can do steps 1 through 3 in one go.
1663 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1664 ;; (these i387 instructions set flags directly)
1666 (define_mode_iterator FPCMP [CCFP CCFPU])
1667 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1669 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1670   [(set (reg:FPCMP FLAGS_REG)
1671         (compare:FPCMP
1672           (match_operand:MODEF 0 "register_operand" "f,v")
1673           (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1674   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1675   "* return output_fp_compare (insn, operands, true,
1676                                <FPCMP:MODE>mode == CCFPUmode);"
1677   [(set_attr "type" "fcmp,ssecomi")
1678    (set_attr "prefix" "orig,maybe_vex")
1679    (set_attr "mode" "<MODEF:MODE>")
1680    (set_attr "prefix_rep" "*,0")
1681    (set (attr "prefix_data16")
1682         (cond [(eq_attr "alternative" "0")
1683                  (const_string "*")
1684                (eq_attr "mode" "DF")
1685                  (const_string "1")
1686               ]
1687               (const_string "0")))
1688    (set_attr "athlon_decode" "vector")
1689    (set_attr "amdfam10_decode" "direct")
1690    (set_attr "bdver1_decode" "double")
1691    (set_attr "znver1_decode" "double")
1692    (set (attr "enabled")
1693      (cond [(eq_attr "alternative" "0")
1694               (symbol_ref "TARGET_MIX_SSE_I387")
1695            ]
1696            (symbol_ref "true")))])
1698 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1699   [(set (reg:FPCMP FLAGS_REG)
1700         (compare:FPCMP
1701           (match_operand:X87MODEF 0 "register_operand" "f")
1702           (match_operand:X87MODEF 1 "register_operand" "f")))]
1703   "TARGET_80387 && TARGET_CMOVE
1704    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1705   "* return output_fp_compare (insn, operands, true,
1706                                <FPCMP:MODE>mode == CCFPUmode);"
1707   [(set_attr "type" "fcmp")
1708    (set_attr "mode" "<X87MODEF:MODE>")
1709    (set_attr "athlon_decode" "vector")
1710    (set_attr "amdfam10_decode" "direct")
1711    (set_attr "bdver1_decode" "double")
1712    (set_attr "znver1_decode" "double")])
1714 ;; Push/pop instructions.
1716 (define_insn "*push<mode>2"
1717   [(set (match_operand:DWI 0 "push_operand" "=<")
1718         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1719   ""
1720   "#"
1721   [(set_attr "type" "multi")
1722    (set_attr "mode" "<MODE>")])
1724 (define_split
1725   [(set (match_operand:TI 0 "push_operand")
1726         (match_operand:TI 1 "general_operand"))]
1727   "TARGET_64BIT && reload_completed
1728    && !SSE_REG_P (operands[1])"
1729   [(const_int 0)]
1730   "ix86_split_long_move (operands); DONE;")
1732 (define_insn "*pushdi2_rex64"
1733   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1734         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1735   "TARGET_64BIT"
1736   "@
1737    push{q}\t%1
1738    #"
1739   [(set_attr "type" "push,multi")
1740    (set_attr "mode" "DI")])
1742 ;; Convert impossible pushes of immediate to existing instructions.
1743 ;; First try to get scratch register and go through it.  In case this
1744 ;; fails, push sign extended lower part first and then overwrite
1745 ;; upper part by 32bit move.
1746 (define_peephole2
1747   [(match_scratch:DI 2 "r")
1748    (set (match_operand:DI 0 "push_operand")
1749         (match_operand:DI 1 "immediate_operand"))]
1750   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1751    && !x86_64_immediate_operand (operands[1], DImode)"
1752   [(set (match_dup 2) (match_dup 1))
1753    (set (match_dup 0) (match_dup 2))])
1755 ;; We need to define this as both peepholer and splitter for case
1756 ;; peephole2 pass is not run.
1757 ;; "&& 1" is needed to keep it from matching the previous pattern.
1758 (define_peephole2
1759   [(set (match_operand:DI 0 "push_operand")
1760         (match_operand:DI 1 "immediate_operand"))]
1761   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1762    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1763   [(set (match_dup 0) (match_dup 1))
1764    (set (match_dup 2) (match_dup 3))]
1766   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1768   operands[1] = gen_lowpart (DImode, operands[2]);
1769   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1770                                                    GEN_INT (4)));
1773 (define_split
1774   [(set (match_operand:DI 0 "push_operand")
1775         (match_operand:DI 1 "immediate_operand"))]
1776   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1777                     ? epilogue_completed : reload_completed)
1778    && !symbolic_operand (operands[1], DImode)
1779    && !x86_64_immediate_operand (operands[1], DImode)"
1780   [(set (match_dup 0) (match_dup 1))
1781    (set (match_dup 2) (match_dup 3))]
1783   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1785   operands[1] = gen_lowpart (DImode, operands[2]);
1786   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1787                                                    GEN_INT (4)));
1790 (define_split
1791   [(set (match_operand:DI 0 "push_operand")
1792         (match_operand:DI 1 "general_operand"))]
1793   "!TARGET_64BIT && reload_completed
1794    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1795   [(const_int 0)]
1796   "ix86_split_long_move (operands); DONE;")
1798 (define_insn "*pushsi2"
1799   [(set (match_operand:SI 0 "push_operand" "=<")
1800         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1801   "!TARGET_64BIT"
1802   "push{l}\t%1"
1803   [(set_attr "type" "push")
1804    (set_attr "mode" "SI")])
1806 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1807 ;; "push a byte/word".  But actually we use pushl, which has the effect
1808 ;; of rounding the amount pushed up to a word.
1810 ;; For TARGET_64BIT we always round up to 8 bytes.
1811 (define_insn "*push<mode>2_rex64"
1812   [(set (match_operand:SWI124 0 "push_operand" "=X")
1813         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1814   "TARGET_64BIT"
1815   "push{q}\t%q1"
1816   [(set_attr "type" "push")
1817    (set_attr "mode" "DI")])
1819 (define_insn "*push<mode>2"
1820   [(set (match_operand:SWI12 0 "push_operand" "=X")
1821         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1822   "!TARGET_64BIT"
1823   "push{l}\t%k1"
1824   [(set_attr "type" "push")
1825    (set_attr "mode" "SI")])
1827 (define_insn "*push<mode>2_prologue"
1828   [(set (match_operand:W 0 "push_operand" "=<")
1829         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1830    (clobber (mem:BLK (scratch)))]
1831   ""
1832   "push{<imodesuffix>}\t%1"
1833   [(set_attr "type" "push")
1834    (set_attr "mode" "<MODE>")])
1836 (define_insn "*pop<mode>1"
1837   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1838         (match_operand:W 1 "pop_operand" ">"))]
1839   ""
1840   "pop{<imodesuffix>}\t%0"
1841   [(set_attr "type" "pop")
1842    (set_attr "mode" "<MODE>")])
1844 (define_insn "*pop<mode>1_epilogue"
1845   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1846         (match_operand:W 1 "pop_operand" ">"))
1847    (clobber (mem:BLK (scratch)))]
1848   ""
1849   "pop{<imodesuffix>}\t%0"
1850   [(set_attr "type" "pop")
1851    (set_attr "mode" "<MODE>")])
1853 (define_insn "*pushfl<mode>2"
1854   [(set (match_operand:W 0 "push_operand" "=<")
1855         (match_operand:W 1 "flags_reg_operand"))]
1856   ""
1857   "pushf{<imodesuffix>}"
1858   [(set_attr "type" "push")
1859    (set_attr "mode" "<MODE>")])
1861 (define_insn "*popfl<mode>1"
1862   [(set (match_operand:W 0 "flags_reg_operand")
1863         (match_operand:W 1 "pop_operand" ">"))]
1864   ""
1865   "popf{<imodesuffix>}"
1866   [(set_attr "type" "pop")
1867    (set_attr "mode" "<MODE>")])
1870 ;; Move instructions.
1872 (define_expand "movxi"
1873   [(set (match_operand:XI 0 "nonimmediate_operand")
1874         (match_operand:XI 1 "general_operand"))]
1875   "TARGET_AVX512F"
1876   "ix86_expand_move (XImode, operands); DONE;")
1878 ;; Reload patterns to support multi-word load/store
1879 ;; with non-offsetable address.
1880 (define_expand "reload_noff_store"
1881   [(parallel [(match_operand 0 "memory_operand" "=m")
1882               (match_operand 1 "register_operand" "r")
1883               (match_operand:DI 2 "register_operand" "=&r")])]
1884   "TARGET_64BIT"
1886   rtx mem = operands[0];
1887   rtx addr = XEXP (mem, 0);
1889   emit_move_insn (operands[2], addr);
1890   mem = replace_equiv_address_nv (mem, operands[2]);
1892   emit_insn (gen_rtx_SET (mem, operands[1]));
1893   DONE;
1896 (define_expand "reload_noff_load"
1897   [(parallel [(match_operand 0 "register_operand" "=r")
1898               (match_operand 1 "memory_operand" "m")
1899               (match_operand:DI 2 "register_operand" "=r")])]
1900   "TARGET_64BIT"
1902   rtx mem = operands[1];
1903   rtx addr = XEXP (mem, 0);
1905   emit_move_insn (operands[2], addr);
1906   mem = replace_equiv_address_nv (mem, operands[2]);
1908   emit_insn (gen_rtx_SET (operands[0], mem));
1909   DONE;
1912 (define_expand "movoi"
1913   [(set (match_operand:OI 0 "nonimmediate_operand")
1914         (match_operand:OI 1 "general_operand"))]
1915   "TARGET_AVX"
1916   "ix86_expand_move (OImode, operands); DONE;")
1918 (define_expand "movti"
1919   [(set (match_operand:TI 0 "nonimmediate_operand")
1920         (match_operand:TI 1 "nonimmediate_operand"))]
1921   "TARGET_64BIT || TARGET_SSE"
1923   if (TARGET_64BIT)
1924     ix86_expand_move (TImode, operands);
1925   else
1926     ix86_expand_vector_move (TImode, operands);
1927   DONE;
1930 ;; This expands to what emit_move_complex would generate if we didn't
1931 ;; have a movti pattern.  Having this avoids problems with reload on
1932 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1933 ;; to have around all the time.
1934 (define_expand "movcdi"
1935   [(set (match_operand:CDI 0 "nonimmediate_operand")
1936         (match_operand:CDI 1 "general_operand"))]
1937   ""
1939   if (push_operand (operands[0], CDImode))
1940     emit_move_complex_push (CDImode, operands[0], operands[1]);
1941   else
1942     emit_move_complex_parts (operands[0], operands[1]);
1943   DONE;
1946 (define_expand "mov<mode>"
1947   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1948         (match_operand:SWI1248x 1 "general_operand"))]
1949   ""
1950   "ix86_expand_move (<MODE>mode, operands); DONE;")
1952 (define_insn "*mov<mode>_xor"
1953   [(set (match_operand:SWI48 0 "register_operand" "=r")
1954         (match_operand:SWI48 1 "const0_operand"))
1955    (clobber (reg:CC FLAGS_REG))]
1956   "reload_completed"
1957   "xor{l}\t%k0, %k0"
1958   [(set_attr "type" "alu1")
1959    (set_attr "modrm_class" "op0")
1960    (set_attr "mode" "SI")
1961    (set_attr "length_immediate" "0")])
1963 (define_insn "*mov<mode>_or"
1964   [(set (match_operand:SWI48 0 "register_operand" "=r")
1965         (match_operand:SWI48 1 "const_int_operand"))
1966    (clobber (reg:CC FLAGS_REG))]
1967   "reload_completed
1968    && operands[1] == constm1_rtx"
1969   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1970   [(set_attr "type" "alu1")
1971    (set_attr "mode" "<MODE>")
1972    (set_attr "length_immediate" "1")])
1974 (define_insn "*movxi_internal_avx512f"
1975   [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1976         (match_operand:XI 1 "vector_move_operand"  "C ,vm,v"))]
1977   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1979   switch (which_alternative)
1980     {
1981     case 0:
1982       return standard_sse_constant_opcode (insn, operands[1]);
1983     case 1:
1984     case 2:
1985       if (misaligned_operand (operands[0], XImode)
1986           || misaligned_operand (operands[1], XImode))
1987         return "vmovdqu32\t{%1, %0|%0, %1}";
1988       else
1989         return "vmovdqa32\t{%1, %0|%0, %1}";
1990     default:
1991       gcc_unreachable ();
1992     }
1994   [(set_attr "type" "sselog1,ssemov,ssemov")
1995    (set_attr "prefix" "evex")
1996    (set_attr "mode" "XI")])
1998 (define_insn "*movoi_internal_avx"
1999   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
2000         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
2001   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_SSELOG1:
2006       return standard_sse_constant_opcode (insn, operands[1]);
2008     case TYPE_SSEMOV:
2009       if (misaligned_operand (operands[0], OImode)
2010           || misaligned_operand (operands[1], OImode))
2011         {
2012           if (get_attr_mode (insn) == MODE_V8SF)
2013             return "vmovups\t{%1, %0|%0, %1}";
2014           else if (get_attr_mode (insn) == MODE_XI)
2015             return "vmovdqu32\t{%1, %0|%0, %1}";
2016           else
2017             return "vmovdqu\t{%1, %0|%0, %1}";
2018         }
2019       else
2020         {
2021           if (get_attr_mode (insn) == MODE_V8SF)
2022             return "vmovaps\t{%1, %0|%0, %1}";
2023           else if (get_attr_mode (insn) == MODE_XI)
2024             return "vmovdqa32\t{%1, %0|%0, %1}";
2025           else
2026             return "vmovdqa\t{%1, %0|%0, %1}";
2027         }
2029     default:
2030       gcc_unreachable ();
2031     }
2033   [(set_attr "type" "sselog1,ssemov,ssemov")
2034    (set_attr "prefix" "vex")
2035    (set (attr "mode")
2036         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2037                     (match_operand 1 "ext_sse_reg_operand"))
2038                  (const_string "XI")
2039                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2040                  (const_string "V8SF")
2041                (and (eq_attr "alternative" "2")
2042                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2043                  (const_string "V8SF")
2044               ]
2045               (const_string "OI")))])
2047 (define_insn "*movti_internal"
2048   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2049         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2050   "(TARGET_64BIT || TARGET_SSE)
2051    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2053   switch (get_attr_type (insn))
2054     {
2055     case TYPE_MULTI:
2056       return "#";
2058     case TYPE_SSELOG1:
2059       return standard_sse_constant_opcode (insn, operands[1]);
2061     case TYPE_SSEMOV:
2062       /* TDmode values are passed as TImode on the stack.  Moving them
2063          to stack may result in unaligned memory access.  */
2064       if (misaligned_operand (operands[0], TImode)
2065           || misaligned_operand (operands[1], TImode))
2066         {
2067           if (get_attr_mode (insn) == MODE_V4SF)
2068             return "%vmovups\t{%1, %0|%0, %1}";
2069           else if (get_attr_mode (insn) == MODE_XI)
2070             return "vmovdqu32\t{%1, %0|%0, %1}";
2071           else
2072             return "%vmovdqu\t{%1, %0|%0, %1}";
2073         }
2074       else
2075         {
2076           if (get_attr_mode (insn) == MODE_V4SF)
2077             return "%vmovaps\t{%1, %0|%0, %1}";
2078           else if (get_attr_mode (insn) == MODE_XI)
2079             return "vmovdqa32\t{%1, %0|%0, %1}";
2080           else
2081             return "%vmovdqa\t{%1, %0|%0, %1}";
2082         }
2084     default:
2085       gcc_unreachable ();
2086     }
2088   [(set_attr "isa" "x64,x64,*,*,*")
2089    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2090    (set (attr "prefix")
2091      (if_then_else (eq_attr "type" "sselog1,ssemov")
2092        (const_string "maybe_vex")
2093        (const_string "orig")))
2094    (set (attr "mode")
2095         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2096                     (match_operand 1 "ext_sse_reg_operand"))
2097                  (const_string "XI")
2098                (eq_attr "alternative" "0,1")
2099                  (const_string "DI")
2100                (ior (not (match_test "TARGET_SSE2"))
2101                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2102                  (const_string "V4SF")
2103                (and (eq_attr "alternative" "4")
2104                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2105                  (const_string "V4SF")
2106                (match_test "TARGET_AVX")
2107                  (const_string "TI")
2108                (match_test "optimize_function_for_size_p (cfun)")
2109                  (const_string "V4SF")
2110                ]
2111                (const_string "TI")))])
2113 (define_split
2114   [(set (match_operand:TI 0 "nonimmediate_operand")
2115         (match_operand:TI 1 "general_operand"))]
2116   "reload_completed
2117    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2118   [(const_int 0)]
2119   "ix86_split_long_move (operands); DONE;")
2121 (define_insn "*movdi_internal"
2122   [(set (match_operand:DI 0 "nonimmediate_operand"
2123     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2124         (match_operand:DI 1 "general_operand"
2125     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2126   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2128   switch (get_attr_type (insn))
2129     {
2130     case TYPE_MSKMOV:
2131       return "kmovq\t{%1, %0|%0, %1}";
2133     case TYPE_MULTI:
2134       return "#";
2136     case TYPE_MMX:
2137       return "pxor\t%0, %0";
2139     case TYPE_MMXMOV:
2140       /* Handle broken assemblers that require movd instead of movq.  */
2141       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2142           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2143         return "movd\t{%1, %0|%0, %1}";
2144       return "movq\t{%1, %0|%0, %1}";
2146     case TYPE_SSELOG1:
2147       if (GENERAL_REG_P (operands[0]))
2148         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2150       return standard_sse_constant_opcode (insn, operands[1]);
2152     case TYPE_SSEMOV:
2153       switch (get_attr_mode (insn))
2154         {
2155         case MODE_DI:
2156           /* Handle broken assemblers that require movd instead of movq.  */
2157           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2158               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2159             return "%vmovd\t{%1, %0|%0, %1}";
2160           return "%vmovq\t{%1, %0|%0, %1}";
2161         case MODE_TI:
2162           return "%vmovdqa\t{%1, %0|%0, %1}";
2163         case MODE_XI:
2164           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2166         case MODE_V2SF:
2167           gcc_assert (!TARGET_AVX);
2168           return "movlps\t{%1, %0|%0, %1}";
2169         case MODE_V4SF:
2170           return "%vmovaps\t{%1, %0|%0, %1}";
2172         default:
2173           gcc_unreachable ();
2174         }
2176     case TYPE_SSECVT:
2177       if (SSE_REG_P (operands[0]))
2178         return "movq2dq\t{%1, %0|%0, %1}";
2179       else
2180         return "movdq2q\t{%1, %0|%0, %1}";
2182     case TYPE_LEA:
2183       return "lea{q}\t{%E1, %0|%0, %E1}";
2185     case TYPE_IMOV:
2186       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2187       if (get_attr_mode (insn) == MODE_SI)
2188         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2189       else if (which_alternative == 4)
2190         return "movabs{q}\t{%1, %0|%0, %1}";
2191       else if (ix86_use_lea_for_mov (insn, operands))
2192         return "lea{q}\t{%E1, %0|%0, %E1}";
2193       else
2194         return "mov{q}\t{%1, %0|%0, %1}";
2196     default:
2197       gcc_unreachable ();
2198     }
2200   [(set (attr "isa")
2201      (cond [(eq_attr "alternative" "0,1")
2202               (const_string "nox64")
2203             (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2204               (const_string "x64")
2205             (eq_attr "alternative" "18")
2206               (const_string "x64_sse4")
2207            ]
2208            (const_string "*")))
2209    (set (attr "type")
2210      (cond [(eq_attr "alternative" "0,1")
2211               (const_string "multi")
2212             (eq_attr "alternative" "6")
2213               (const_string "mmx")
2214             (eq_attr "alternative" "7,8,9,10,11")
2215               (const_string "mmxmov")
2216             (eq_attr "alternative" "12,18")
2217               (const_string "sselog1")
2218             (eq_attr "alternative" "13,14,15,16,17,19")
2219               (const_string "ssemov")
2220             (eq_attr "alternative" "20,21")
2221               (const_string "ssecvt")
2222             (eq_attr "alternative" "22,23,24,25")
2223               (const_string "mskmov")
2224             (and (match_operand 0 "register_operand")
2225                  (match_operand 1 "pic_32bit_operand"))
2226               (const_string "lea")
2227            ]
2228            (const_string "imov")))
2229    (set (attr "modrm")
2230      (if_then_else
2231        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2232          (const_string "0")
2233          (const_string "*")))
2234    (set (attr "length_immediate")
2235      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2236               (const_string "8")
2237             (eq_attr "alternative" "18")
2238               (const_string "1")
2239            ]
2240            (const_string "*")))
2241    (set (attr "prefix_rex")
2242      (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2243        (const_string "1")
2244        (const_string "*")))
2245    (set (attr "prefix_extra")
2246      (if_then_else (eq_attr "alternative" "18")
2247        (const_string "1")
2248        (const_string "*")))
2249    (set (attr "prefix")
2250      (if_then_else (eq_attr "type" "sselog1,ssemov")
2251        (const_string "maybe_vex")
2252        (const_string "orig")))
2253    (set (attr "prefix_data16")
2254      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2255        (const_string "1")
2256        (const_string "*")))
2257    (set (attr "mode")
2258      (cond [(eq_attr "alternative" "2")
2259               (const_string "SI")
2260             (eq_attr "alternative" "12,13")
2261               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2262                           (match_operand 1 "ext_sse_reg_operand"))
2263                        (const_string "XI")
2264                      (ior (not (match_test "TARGET_SSE2"))
2265                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2266                        (const_string "V4SF")
2267                      (match_test "TARGET_AVX")
2268                        (const_string "TI")
2269                      (match_test "optimize_function_for_size_p (cfun)")
2270                        (const_string "V4SF")
2271                     ]
2272                     (const_string "TI"))
2274             (and (eq_attr "alternative" "14,15,16")
2275                  (not (match_test "TARGET_SSE2")))
2276               (const_string "V2SF")
2277             (eq_attr "alternative" "18")
2278               (const_string "TI")
2279            ]
2280            (const_string "DI")))
2281    (set (attr "enabled")
2282      (cond [(eq_attr "alternative" "15")
2283               (if_then_else
2284                 (match_test "TARGET_STV && TARGET_SSE2")
2285                 (symbol_ref "false")
2286                 (const_string "*"))
2287             (eq_attr "alternative" "16")
2288               (if_then_else
2289                 (match_test "TARGET_STV && TARGET_SSE2")
2290                 (symbol_ref "true")
2291                 (symbol_ref "false"))
2292            ]
2293            (const_string "*")))])
2295 (define_split
2296   [(set (match_operand:DI 0 "nonimmediate_operand")
2297         (match_operand:DI 1 "general_operand"))]
2298   "!TARGET_64BIT && reload_completed
2299    && !(MMX_REG_P (operands[0])
2300         || SSE_REG_P (operands[0])
2301         || MASK_REG_P (operands[0]))
2302    && !(MMX_REG_P (operands[1])
2303         || SSE_REG_P (operands[1])
2304         || MASK_REG_P (operands[1]))"
2305   [(const_int 0)]
2306   "ix86_split_long_move (operands); DONE;")
2308 (define_insn "*movsi_internal"
2309   [(set (match_operand:SI 0 "nonimmediate_operand"
2310                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2311         (match_operand:SI 1 "general_operand"
2312                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2313   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2315   switch (get_attr_type (insn))
2316     {
2317     case TYPE_SSELOG1:
2318       if (GENERAL_REG_P (operands[0]))
2319         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2321       return standard_sse_constant_opcode (insn, operands[1]);
2323     case TYPE_MSKMOV:
2324       return "kmovd\t{%1, %0|%0, %1}";
2326     case TYPE_SSEMOV:
2327       switch (get_attr_mode (insn))
2328         {
2329         case MODE_SI:
2330           return "%vmovd\t{%1, %0|%0, %1}";
2331         case MODE_TI:
2332           return "%vmovdqa\t{%1, %0|%0, %1}";
2333         case MODE_XI:
2334           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2336         case MODE_V4SF:
2337           return "%vmovaps\t{%1, %0|%0, %1}";
2339         case MODE_SF:
2340           gcc_assert (!TARGET_AVX);
2341           return "movss\t{%1, %0|%0, %1}";
2343         default:
2344           gcc_unreachable ();
2345         }
2347     case TYPE_MMX:
2348       return "pxor\t%0, %0";
2350     case TYPE_MMXMOV:
2351       switch (get_attr_mode (insn))
2352         {
2353         case MODE_DI:
2354           return "movq\t{%1, %0|%0, %1}";
2355         case MODE_SI:
2356           return "movd\t{%1, %0|%0, %1}";
2358         default:
2359           gcc_unreachable ();
2360         }
2362     case TYPE_LEA:
2363       return "lea{l}\t{%E1, %0|%0, %E1}";
2365     case TYPE_IMOV:
2366       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2367       if (ix86_use_lea_for_mov (insn, operands))
2368         return "lea{l}\t{%E1, %0|%0, %E1}";
2369       else
2370         return "mov{l}\t{%1, %0|%0, %1}";
2372     default:
2373       gcc_unreachable ();
2374     }
2376   [(set (attr "isa")
2377      (if_then_else (eq_attr "alternative" "11")
2378        (const_string "sse4")
2379        (const_string "*")))
2380    (set (attr "type")
2381      (cond [(eq_attr "alternative" "2")
2382               (const_string "mmx")
2383             (eq_attr "alternative" "3,4,5")
2384               (const_string "mmxmov")
2385             (eq_attr "alternative" "6,11")
2386               (const_string "sselog1")
2387             (eq_attr "alternative" "7,8,9,10,12")
2388               (const_string "ssemov")
2389             (eq_attr "alternative" "13,14")
2390               (const_string "mskmov")
2391             (and (match_operand 0 "register_operand")
2392                  (match_operand 1 "pic_32bit_operand"))
2393               (const_string "lea")
2394            ]
2395            (const_string "imov")))
2396    (set (attr "length_immediate")
2397      (if_then_else (eq_attr "alternative" "11")
2398        (const_string "1")
2399        (const_string "*")))
2400    (set (attr "prefix_extra")
2401      (if_then_else (eq_attr "alternative" "11")
2402        (const_string "1")
2403        (const_string "*")))
2404    (set (attr "prefix")
2405      (if_then_else (eq_attr "type" "sselog1,ssemov")
2406        (const_string "maybe_vex")
2407        (const_string "orig")))
2408    (set (attr "prefix_data16")
2409      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2410        (const_string "1")
2411        (const_string "*")))
2412    (set (attr "mode")
2413      (cond [(eq_attr "alternative" "2,3")
2414               (const_string "DI")
2415             (eq_attr "alternative" "6,7")
2416               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2417                           (match_operand 1 "ext_sse_reg_operand"))
2418                        (const_string "XI")
2419                      (ior (not (match_test "TARGET_SSE2"))
2420                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2421                        (const_string "V4SF")
2422                      (match_test "TARGET_AVX")
2423                        (const_string "TI")
2424                      (match_test "optimize_function_for_size_p (cfun)")
2425                        (const_string "V4SF")
2426                     ]
2427                     (const_string "TI"))
2429             (and (eq_attr "alternative" "8,9")
2430                  (not (match_test "TARGET_SSE2")))
2431               (const_string "SF")
2432             (eq_attr "alternative" "11")
2433               (const_string "TI")
2434            ]
2435            (const_string "SI")))])
2437 (define_insn "kmovw"
2438   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2439         (unspec:HI
2440           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2441           UNSPEC_KMOV))]
2442   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2443   "@
2444    kmovw\t{%k1, %0|%0, %k1}
2445    kmovw\t{%1, %0|%0, %1}";
2446   [(set_attr "mode" "HI")
2447    (set_attr "type" "mskmov")
2448    (set_attr "prefix" "vex")])
2451 (define_insn "*movhi_internal"
2452   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2453         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2454   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456   switch (get_attr_type (insn))
2457     {
2458     case TYPE_IMOVX:
2459       /* movzwl is faster than movw on p2 due to partial word stalls,
2460          though not as fast as an aligned movl.  */
2461       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2463     case TYPE_MSKMOV:
2464       switch (which_alternative)
2465         {
2466         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2467         case 5: return "kmovw\t{%1, %0|%0, %1}";
2468         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2469         default: gcc_unreachable ();
2470         }
2472     default:
2473       if (get_attr_mode (insn) == MODE_SI)
2474         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2475       else
2476         return "mov{w}\t{%1, %0|%0, %1}";
2477     }
2479   [(set (attr "type")
2480      (cond [(eq_attr "alternative" "4,5,6")
2481               (const_string "mskmov")
2482             (match_test "optimize_function_for_size_p (cfun)")
2483               (const_string "imov")
2484             (and (eq_attr "alternative" "0")
2485                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2486                       (not (match_test "TARGET_HIMODE_MATH"))))
2487               (const_string "imov")
2488             (and (eq_attr "alternative" "1,2")
2489                  (match_operand:HI 1 "aligned_operand"))
2490               (const_string "imov")
2491             (and (match_test "TARGET_MOVX")
2492                  (eq_attr "alternative" "0,2"))
2493               (const_string "imovx")
2494            ]
2495            (const_string "imov")))
2496     (set (attr "prefix")
2497       (if_then_else (eq_attr "alternative" "4,5,6")
2498         (const_string "vex")
2499         (const_string "orig")))
2500     (set (attr "mode")
2501       (cond [(eq_attr "type" "imovx")
2502                (const_string "SI")
2503              (and (eq_attr "alternative" "1,2")
2504                   (match_operand:HI 1 "aligned_operand"))
2505                (const_string "SI")
2506              (and (eq_attr "alternative" "0")
2507                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2508                        (not (match_test "TARGET_HIMODE_MATH"))))
2509                (const_string "SI")
2510             ]
2511             (const_string "HI")))])
2513 ;; Situation is quite tricky about when to choose full sized (SImode) move
2514 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2515 ;; partial register dependency machines (such as AMD Athlon), where QImode
2516 ;; moves issue extra dependency and for partial register stalls machines
2517 ;; that don't use QImode patterns (and QImode move cause stall on the next
2518 ;; instruction).
2520 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2521 ;; register stall machines with, where we use QImode instructions, since
2522 ;; partial register stall can be caused there.  Then we use movzx.
2524 (define_insn "*movqi_internal"
2525   [(set (match_operand:QI 0 "nonimmediate_operand"
2526                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2527         (match_operand:QI 1 "general_operand"
2528                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2529   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2531   switch (get_attr_type (insn))
2532     {
2533     case TYPE_IMOVX:
2534       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2535       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2537     case TYPE_MSKMOV:
2538       switch (which_alternative)
2539         {
2540         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2541                                        : "kmovw\t{%k1, %0|%0, %k1}";
2542         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2543                                        : "kmovw\t{%1, %0|%0, %1}";
2544         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2545                                        : "kmovw\t{%1, %k0|%k0, %1}";
2546         case 10:
2547         case 11:
2548           gcc_assert (TARGET_AVX512DQ);
2549           return "kmovb\t{%1, %0|%0, %1}";
2550         default: gcc_unreachable ();
2551         }
2553     default:
2554       if (get_attr_mode (insn) == MODE_SI)
2555         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2556       else
2557         return "mov{b}\t{%1, %0|%0, %1}";
2558     }
2560   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2561    (set (attr "type")
2562      (cond [(eq_attr "alternative" "7,8,9,10,11")
2563               (const_string "mskmov")
2564             (and (eq_attr "alternative" "5")
2565                  (not (match_operand:QI 1 "aligned_operand")))
2566               (const_string "imovx")
2567             (match_test "optimize_function_for_size_p (cfun)")
2568               (const_string "imov")
2569             (and (eq_attr "alternative" "3")
2570                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2571                       (not (match_test "TARGET_QIMODE_MATH"))))
2572               (const_string "imov")
2573             (eq_attr "alternative" "3,5")
2574               (const_string "imovx")
2575             (and (match_test "TARGET_MOVX")
2576                  (eq_attr "alternative" "2"))
2577               (const_string "imovx")
2578            ]
2579            (const_string "imov")))
2580    (set (attr "prefix")
2581      (if_then_else (eq_attr "alternative" "7,8,9")
2582        (const_string "vex")
2583        (const_string "orig")))
2584    (set (attr "mode")
2585       (cond [(eq_attr "alternative" "3,4,5")
2586                (const_string "SI")
2587              (eq_attr "alternative" "6")
2588                (const_string "QI")
2589              (eq_attr "type" "imovx")
2590                (const_string "SI")
2591              (and (eq_attr "type" "imov")
2592                   (and (eq_attr "alternative" "0,1")
2593                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2594                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2595                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2596                (const_string "SI")
2597              ;; Avoid partial register stalls when not using QImode arithmetic
2598              (and (eq_attr "type" "imov")
2599                   (and (eq_attr "alternative" "0,1")
2600                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2601                             (not (match_test "TARGET_QIMODE_MATH")))))
2602                (const_string "SI")
2603            ]
2604            (const_string "QI")))])
2606 ;; Stores and loads of ax to arbitrary constant address.
2607 ;; We fake an second form of instruction to force reload to load address
2608 ;; into register when rax is not available
2609 (define_insn "*movabs<mode>_1"
2610   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2611         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2612   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2614   /* Recover the full memory rtx.  */
2615   operands[0] = SET_DEST (PATTERN (insn));
2616   switch (which_alternative)
2617     {
2618     case 0:
2619       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2620     case 1:
2621       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2622     default:
2623       gcc_unreachable ();
2624     }
2626   [(set_attr "type" "imov")
2627    (set_attr "modrm" "0,*")
2628    (set_attr "length_address" "8,0")
2629    (set_attr "length_immediate" "0,*")
2630    (set_attr "memory" "store")
2631    (set_attr "mode" "<MODE>")])
2633 (define_insn "*movabs<mode>_2"
2634   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2635         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2636   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2638   /* Recover the full memory rtx.  */
2639   operands[1] = SET_SRC (PATTERN (insn));
2640   switch (which_alternative)
2641     {
2642     case 0:
2643       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2644     case 1:
2645       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2646     default:
2647       gcc_unreachable ();
2648     }
2650   [(set_attr "type" "imov")
2651    (set_attr "modrm" "0,*")
2652    (set_attr "length_address" "8,0")
2653    (set_attr "length_immediate" "0")
2654    (set_attr "memory" "load")
2655    (set_attr "mode" "<MODE>")])
2657 (define_insn "*swap<mode>"
2658   [(set (match_operand:SWI48 0 "register_operand" "+r")
2659         (match_operand:SWI48 1 "register_operand" "+r"))
2660    (set (match_dup 1)
2661         (match_dup 0))]
2662   ""
2663   "xchg{<imodesuffix>}\t%1, %0"
2664   [(set_attr "type" "imov")
2665    (set_attr "mode" "<MODE>")
2666    (set_attr "pent_pair" "np")
2667    (set_attr "athlon_decode" "vector")
2668    (set_attr "amdfam10_decode" "double")
2669    (set_attr "bdver1_decode" "double")])
2671 (define_insn "*swap<mode>_1"
2672   [(set (match_operand:SWI12 0 "register_operand" "+r")
2673         (match_operand:SWI12 1 "register_operand" "+r"))
2674    (set (match_dup 1)
2675         (match_dup 0))]
2676   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2677   "xchg{l}\t%k1, %k0"
2678   [(set_attr "type" "imov")
2679    (set_attr "mode" "SI")
2680    (set_attr "pent_pair" "np")
2681    (set_attr "athlon_decode" "vector")
2682    (set_attr "amdfam10_decode" "double")
2683    (set_attr "bdver1_decode" "double")])
2685 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2686 ;; is disabled for AMDFAM10
2687 (define_insn "*swap<mode>_2"
2688   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2689         (match_operand:SWI12 1 "register_operand" "+<r>"))
2690    (set (match_dup 1)
2691         (match_dup 0))]
2692   "TARGET_PARTIAL_REG_STALL"
2693   "xchg{<imodesuffix>}\t%1, %0"
2694   [(set_attr "type" "imov")
2695    (set_attr "mode" "<MODE>")
2696    (set_attr "pent_pair" "np")
2697    (set_attr "athlon_decode" "vector")])
2699 (define_expand "movstrict<mode>"
2700   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2701         (match_operand:SWI12 1 "general_operand"))]
2702   ""
2704   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2705     FAIL;
2706   if (SUBREG_P (operands[0])
2707       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2708     FAIL;
2709   /* Don't generate memory->memory moves, go through a register */
2710   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2711     operands[1] = force_reg (<MODE>mode, operands[1]);
2714 (define_insn "*movstrict<mode>_1"
2715   [(set (strict_low_part
2716           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2717         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2718   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2719    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2720   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2721   [(set_attr "type" "imov")
2722    (set_attr "mode" "<MODE>")])
2724 (define_insn "*movstrict<mode>_xor"
2725   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2726         (match_operand:SWI12 1 "const0_operand"))
2727    (clobber (reg:CC FLAGS_REG))]
2728   "reload_completed"
2729   "xor{<imodesuffix>}\t%0, %0"
2730   [(set_attr "type" "alu1")
2731    (set_attr "modrm_class" "op0")
2732    (set_attr "mode" "<MODE>")
2733    (set_attr "length_immediate" "0")])
2735 (define_expand "extv<mode>"
2736   [(set (match_operand:SWI24 0 "register_operand")
2737         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2738                             (match_operand:SI 2 "const_int_operand")
2739                             (match_operand:SI 3 "const_int_operand")))]
2740   ""
2742   /* Handle extractions from %ah et al.  */
2743   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2744     FAIL;
2746   if (! ext_register_operand (operands[1], VOIDmode))
2747     operands[1] = copy_to_reg (operands[1]);
2750 (define_insn "*extv<mode>"
2751   [(set (match_operand:SWI24 0 "register_operand" "=R")
2752         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2753                             (const_int 8)
2754                             (const_int 8)))]
2755   ""
2756   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2757   [(set_attr "type" "imovx")
2758    (set_attr "mode" "SI")])
2760 (define_insn "*extvqi"
2761   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2762         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2763                          (const_int 8)
2764                          (const_int 8)))]
2765   ""
2767   switch (get_attr_type (insn))
2768     {
2769     case TYPE_IMOVX:
2770       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2771     default:
2772       return "mov{b}\t{%h1, %0|%0, %h1}";
2773     }
2775   [(set_attr "isa" "*,*,nox64")
2776    (set (attr "type")
2777      (if_then_else (and (match_operand:QI 0 "register_operand")
2778                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2779                              (match_test "TARGET_MOVX")))
2780         (const_string "imovx")
2781         (const_string "imov")))
2782    (set (attr "mode")
2783      (if_then_else (eq_attr "type" "imovx")
2784         (const_string "SI")
2785         (const_string "QI")))])
2787 (define_expand "extzv<mode>"
2788   [(set (match_operand:SWI248 0 "register_operand")
2789         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2790                              (match_operand:SI 2 "const_int_operand")
2791                              (match_operand:SI 3 "const_int_operand")))]
2792   ""
2794   if (ix86_expand_pextr (operands))
2795     DONE;
2797   /* Handle extractions from %ah et al.  */
2798   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2799     FAIL;
2801   if (! ext_register_operand (operands[1], VOIDmode))
2802     operands[1] = copy_to_reg (operands[1]);
2805 (define_insn "*extzv<mode>"
2806   [(set (match_operand:SWI248 0 "register_operand" "=R")
2807         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2808                              (const_int 8)
2809                              (const_int 8)))]
2810   ""
2811   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2812   [(set_attr "type" "imovx")
2813    (set_attr "mode" "SI")])
2815 (define_insn "*extzvqi"
2816   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2817         (subreg:QI
2818           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2819                            (const_int 8)
2820                            (const_int 8)) 0))]
2821   ""
2823   switch (get_attr_type (insn))
2824     {
2825     case TYPE_IMOVX:
2826       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2827     default:
2828       return "mov{b}\t{%h1, %0|%0, %h1}";
2829     }
2831   [(set_attr "isa" "*,*,nox64")
2832    (set (attr "type")
2833      (if_then_else (and (match_operand:QI 0 "register_operand")
2834                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2835                              (match_test "TARGET_MOVX")))
2836         (const_string "imovx")
2837         (const_string "imov")))
2838    (set (attr "mode")
2839      (if_then_else (eq_attr "type" "imovx")
2840         (const_string "SI")
2841         (const_string "QI")))])
2843 (define_expand "insv<mode>"
2844   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2845                              (match_operand:SI 1 "const_int_operand")
2846                              (match_operand:SI 2 "const_int_operand"))
2847         (match_operand:SWI248 3 "register_operand"))]
2848   ""
2850   rtx dst;
2852   if (ix86_expand_pinsr (operands))
2853     DONE;
2855   /* Handle insertions to %ah et al.  */
2856   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2857     FAIL;
2859   dst = operands[0];
2860   
2861   if (!ext_register_operand (dst, VOIDmode))
2862     dst = copy_to_reg (dst);
2864   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2866   /* Fix up the destination if needed.  */
2867   if (dst != operands[0])
2868     emit_move_insn (operands[0], dst);
2870   DONE;
2873 (define_insn "insv<mode>_1"
2874   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2875                              (const_int 8)
2876                              (const_int 8))
2877         (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2878   ""
2880   if (CONST_INT_P (operands[1]))
2881     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2882   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2884   [(set_attr "isa" "*,nox64")
2885    (set_attr "type" "imov")
2886    (set_attr "mode" "QI")])
2888 (define_insn "*insvqi"
2889   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2890                          (const_int 8)
2891                          (const_int 8))
2892         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2893                      (const_int 8)))]
2894   ""
2895   "mov{b}\t{%h1, %h0|%h0, %h1}"
2896   [(set_attr "type" "imov")
2897    (set_attr "mode" "QI")])
2899 ;; Floating point push instructions.
2901 (define_insn "*pushtf"
2902   [(set (match_operand:TF 0 "push_operand" "=<,<")
2903         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2904   "TARGET_64BIT || TARGET_SSE"
2906   /* This insn should be already split before reg-stack.  */
2907   gcc_unreachable ();
2909   [(set_attr "isa" "*,x64")
2910    (set_attr "type" "multi")
2911    (set_attr "unit" "sse,*")
2912    (set_attr "mode" "TF,DI")])
2914 ;; %%% Kill this when call knows how to work this out.
2915 (define_split
2916   [(set (match_operand:TF 0 "push_operand")
2917         (match_operand:TF 1 "sse_reg_operand"))]
2918   "TARGET_SSE && reload_completed"
2919   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2920    (set (match_dup 0) (match_dup 1))]
2922   /* Preserve memory attributes. */
2923   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2926 (define_insn "*pushxf"
2927   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2928         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2929   ""
2931   /* This insn should be already split before reg-stack.  */
2932   gcc_unreachable ();
2934   [(set_attr "type" "multi")
2935    (set_attr "unit" "i387,*,*,*")
2936    (set (attr "mode")
2937         (cond [(eq_attr "alternative" "1,2,3")
2938                  (if_then_else (match_test "TARGET_64BIT")
2939                    (const_string "DI")
2940                    (const_string "SI"))
2941               ]
2942               (const_string "XF")))
2943    (set (attr "preferred_for_size")
2944      (cond [(eq_attr "alternative" "1")
2945               (symbol_ref "false")]
2946            (symbol_ref "true")))])
2948 ;; %%% Kill this when call knows how to work this out.
2949 (define_split
2950   [(set (match_operand:XF 0 "push_operand")
2951         (match_operand:XF 1 "fp_register_operand"))]
2952   "reload_completed"
2953   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2954    (set (match_dup 0) (match_dup 1))]
2956   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2957   /* Preserve memory attributes. */
2958   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2961 (define_insn "*pushdf"
2962   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2963         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2964   ""
2966   /* This insn should be already split before reg-stack.  */
2967   gcc_unreachable ();
2969   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2970    (set_attr "type" "multi")
2971    (set_attr "unit" "i387,*,*,*,*,sse")
2972    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2973    (set (attr "preferred_for_size")
2974      (cond [(eq_attr "alternative" "1")
2975               (symbol_ref "false")]
2976            (symbol_ref "true")))
2977    (set (attr "preferred_for_speed")
2978      (cond [(eq_attr "alternative" "1")
2979               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2980            (symbol_ref "true")))])
2981    
2982 ;; %%% Kill this when call knows how to work this out.
2983 (define_split
2984   [(set (match_operand:DF 0 "push_operand")
2985         (match_operand:DF 1 "any_fp_register_operand"))]
2986   "reload_completed"
2987   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2988    (set (match_dup 0) (match_dup 1))]
2990   /* Preserve memory attributes. */
2991   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2994 (define_insn "*pushsf_rex64"
2995   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2996         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2997   "TARGET_64BIT"
2999   /* Anything else should be already split before reg-stack.  */
3000   gcc_assert (which_alternative == 1);
3001   return "push{q}\t%q1";
3003   [(set_attr "type" "multi,push,multi")
3004    (set_attr "unit" "i387,*,*")
3005    (set_attr "mode" "SF,DI,SF")])
3007 (define_insn "*pushsf"
3008   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3009         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3010   "!TARGET_64BIT"
3012   /* Anything else should be already split before reg-stack.  */
3013   gcc_assert (which_alternative == 1);
3014   return "push{l}\t%1";
3016   [(set_attr "type" "multi,push,multi")
3017    (set_attr "unit" "i387,*,*")
3018    (set_attr "mode" "SF,SI,SF")])
3020 ;; %%% Kill this when call knows how to work this out.
3021 (define_split
3022   [(set (match_operand:SF 0 "push_operand")
3023         (match_operand:SF 1 "any_fp_register_operand"))]
3024   "reload_completed"
3025   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3026    (set (match_dup 0) (match_dup 1))]
3028   rtx op = XEXP (operands[0], 0);
3029   if (GET_CODE (op) == PRE_DEC)
3030     {
3031       gcc_assert (!TARGET_64BIT);
3032       op = GEN_INT (-4);
3033     }
3034   else
3035     {
3036       op = XEXP (XEXP (op, 1), 1);
3037       gcc_assert (CONST_INT_P (op));
3038     }
3039   operands[2] = op;
3040   /* Preserve memory attributes. */
3041   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3044 (define_split
3045   [(set (match_operand:SF 0 "push_operand")
3046         (match_operand:SF 1 "memory_operand"))]
3047   "reload_completed"
3048   [(set (match_dup 0) (match_dup 2))]
3050   operands[2] = find_constant_src (curr_insn);
3052   if (operands[2] == NULL_RTX)
3053     FAIL;
3056 (define_split
3057   [(set (match_operand 0 "push_operand")
3058         (match_operand 1 "general_operand"))]
3059   "reload_completed
3060    && (GET_MODE (operands[0]) == TFmode
3061        || GET_MODE (operands[0]) == XFmode
3062        || GET_MODE (operands[0]) == DFmode)
3063    && !ANY_FP_REG_P (operands[1])"
3064   [(const_int 0)]
3065   "ix86_split_long_move (operands); DONE;")
3067 ;; Floating point move instructions.
3069 (define_expand "movtf"
3070   [(set (match_operand:TF 0 "nonimmediate_operand")
3071         (match_operand:TF 1 "nonimmediate_operand"))]
3072   "TARGET_64BIT || TARGET_SSE"
3073   "ix86_expand_move (TFmode, operands); DONE;")
3075 (define_expand "mov<mode>"
3076   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3077         (match_operand:X87MODEF 1 "general_operand"))]
3078   ""
3079   "ix86_expand_move (<MODE>mode, operands); DONE;")
3081 (define_insn "*movtf_internal"
3082   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3083         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
3084   "(TARGET_64BIT || TARGET_SSE)
3085    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3086    && (!can_create_pseudo_p ()
3087        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3088        || !CONST_DOUBLE_P (operands[1])
3089        || (optimize_function_for_size_p (cfun)
3090            && standard_sse_constant_p (operands[1])
3091            && !memory_operand (operands[0], TFmode))
3092        || (!TARGET_MEMORY_MISMATCH_STALL
3093            && memory_operand (operands[0], TFmode)))"
3095   switch (get_attr_type (insn))
3096     {
3097     case TYPE_SSELOG1:
3098       return standard_sse_constant_opcode (insn, operands[1]);
3100     case TYPE_SSEMOV:
3101       /* Handle misaligned load/store since we
3102          don't have movmisaligntf pattern. */
3103       if (misaligned_operand (operands[0], TFmode)
3104           || misaligned_operand (operands[1], TFmode))
3105         {
3106           if (get_attr_mode (insn) == MODE_V4SF)
3107             return "%vmovups\t{%1, %0|%0, %1}";
3108           else
3109             return "%vmovdqu\t{%1, %0|%0, %1}";
3110         }
3111       else
3112         {
3113           if (get_attr_mode (insn) == MODE_V4SF)
3114             return "%vmovaps\t{%1, %0|%0, %1}";
3115           else
3116             return "%vmovdqa\t{%1, %0|%0, %1}";
3117         }
3119     case TYPE_MULTI:
3120         return "#";
3122     default:
3123       gcc_unreachable ();
3124     }
3126   [(set_attr "isa" "*,*,*,x64,x64")
3127    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3128    (set (attr "prefix")
3129      (if_then_else (eq_attr "type" "sselog1,ssemov")
3130        (const_string "maybe_vex")
3131        (const_string "orig")))
3132    (set (attr "mode")
3133         (cond [(eq_attr "alternative" "3,4")
3134                  (const_string "DI")
3135                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3136                  (const_string "V4SF")
3137                (and (eq_attr "alternative" "2")
3138                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3139                  (const_string "V4SF")
3140                (match_test "TARGET_AVX")
3141                  (const_string "TI")
3142                (ior (not (match_test "TARGET_SSE2"))
3143                     (match_test "optimize_function_for_size_p (cfun)"))
3144                  (const_string "V4SF")
3145                ]
3146                (const_string "TI")))])
3148 (define_split
3149   [(set (match_operand:TF 0 "nonimmediate_operand")
3150         (match_operand:TF 1 "general_operand"))]
3151   "reload_completed
3152    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3153   [(const_int 0)]
3154   "ix86_split_long_move (operands); DONE;")
3156 ;; Possible store forwarding (partial memory) stall
3157 ;; in alternatives 4, 6, 7 and 8.
3158 (define_insn "*movxf_internal"
3159   [(set (match_operand:XF 0 "nonimmediate_operand"
3160          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o")
3161         (match_operand:XF 1 "general_operand"
3162          "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3164    && (!can_create_pseudo_p ()
3165        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3166        || !CONST_DOUBLE_P (operands[1])
3167        || (optimize_function_for_size_p (cfun)
3168            && standard_80387_constant_p (operands[1]) > 0
3169            && !memory_operand (operands[0], XFmode))
3170        || (!TARGET_MEMORY_MISMATCH_STALL
3171            && memory_operand (operands[0], XFmode))
3172        || !TARGET_HARD_XF_REGS)"
3174   switch (get_attr_type (insn))
3175     {
3176     case TYPE_FMOV:
3177       if (which_alternative == 2)
3178         return standard_80387_constant_opcode (operands[1]);
3179       return output_387_reg_move (insn, operands);
3181     case TYPE_MULTI:
3182       return "#";
3184     default:
3185       gcc_unreachable ();
3186     }
3188   [(set (attr "isa")
3189         (cond [(eq_attr "alternative" "7")
3190                  (const_string "nox64")
3191                (eq_attr "alternative" "8")
3192                  (const_string "x64")
3193               ]
3194               (const_string "*")))
3195    (set (attr "type")
3196         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3197                  (const_string "multi")
3198               ]
3199               (const_string "fmov")))
3200    (set (attr "mode")
3201         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3202                  (if_then_else (match_test "TARGET_64BIT")
3203                    (const_string "DI")
3204                    (const_string "SI"))
3205               ]
3206               (const_string "XF")))
3207    (set (attr "preferred_for_size")
3208      (cond [(eq_attr "alternative" "3,4")
3209               (symbol_ref "false")]
3210            (symbol_ref "true")))
3211    (set (attr "enabled")
3212      (cond [(eq_attr "alternative" "9,10")
3213               (if_then_else
3214                 (match_test "TARGET_HARD_XF_REGS")
3215                 (symbol_ref "false")
3216                 (const_string "*"))
3217             (not (match_test "TARGET_HARD_XF_REGS"))
3218               (symbol_ref "false")
3219            ]
3220            (const_string "*")))])
3221    
3222 (define_split
3223   [(set (match_operand:XF 0 "nonimmediate_operand")
3224         (match_operand:XF 1 "general_operand"))]
3225   "reload_completed
3226    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3227   [(const_int 0)]
3228   "ix86_split_long_move (operands); DONE;")
3230 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3231 (define_insn "*movdf_internal"
3232   [(set (match_operand:DF 0 "nonimmediate_operand"
3233     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
3234         (match_operand:DF 1 "general_operand"
3235     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3236   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3237    && (!can_create_pseudo_p ()
3238        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3239        || !CONST_DOUBLE_P (operands[1])
3240        || (optimize_function_for_size_p (cfun)
3241            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3242                 && standard_80387_constant_p (operands[1]) > 0)
3243                || (TARGET_SSE2 && TARGET_SSE_MATH
3244                    && standard_sse_constant_p (operands[1])))
3245            && !memory_operand (operands[0], DFmode))
3246        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3247            && memory_operand (operands[0], DFmode))
3248        || !TARGET_HARD_DF_REGS)"
3250   switch (get_attr_type (insn))
3251     {
3252     case TYPE_FMOV:
3253       if (which_alternative == 2)
3254         return standard_80387_constant_opcode (operands[1]);
3255       return output_387_reg_move (insn, operands);
3257     case TYPE_MULTI:
3258       return "#";
3260     case TYPE_IMOV:
3261       if (get_attr_mode (insn) == MODE_SI)
3262         return "mov{l}\t{%1, %k0|%k0, %1}";
3263       else if (which_alternative == 11)
3264         return "movabs{q}\t{%1, %0|%0, %1}";
3265       else
3266         return "mov{q}\t{%1, %0|%0, %1}";
3268     case TYPE_SSELOG1:
3269       return standard_sse_constant_opcode (insn, operands[1]);
3271     case TYPE_SSEMOV:
3272       switch (get_attr_mode (insn))
3273         {
3274         case MODE_DF:
3275           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3276             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3277           return "%vmovsd\t{%1, %0|%0, %1}";
3279         case MODE_V4SF:
3280           return "%vmovaps\t{%1, %0|%0, %1}";
3281         case MODE_V8DF:
3282           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3283         case MODE_V2DF:
3284           return "%vmovapd\t{%1, %0|%0, %1}";
3286         case MODE_V2SF:
3287           gcc_assert (!TARGET_AVX);
3288           return "movlps\t{%1, %0|%0, %1}";
3289         case MODE_V1DF:
3290           gcc_assert (!TARGET_AVX);
3291           return "movlpd\t{%1, %0|%0, %1}";
3293         case MODE_DI:
3294           /* Handle broken assemblers that require movd instead of movq.  */
3295           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3296               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3297             return "%vmovd\t{%1, %0|%0, %1}";
3298           return "%vmovq\t{%1, %0|%0, %1}";
3300         default:
3301           gcc_unreachable ();
3302         }
3304     default:
3305       gcc_unreachable ();
3306     }
3308   [(set (attr "isa")
3309         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3310                  (const_string "nox64")
3311                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3312                  (const_string "x64")
3313                (eq_attr "alternative" "12,13,14,15")
3314                  (const_string "sse2")
3315               ]
3316               (const_string "*")))
3317    (set (attr "type")
3318         (cond [(eq_attr "alternative" "0,1,2")
3319                  (const_string "fmov")
3320                (eq_attr "alternative" "3,4,5,6,7,22,23")
3321                  (const_string "multi")
3322                (eq_attr "alternative" "8,9,10,11,24,25")
3323                  (const_string "imov")
3324                (eq_attr "alternative" "12,16")
3325                  (const_string "sselog1")
3326               ]
3327               (const_string "ssemov")))
3328    (set (attr "modrm")
3329      (if_then_else (eq_attr "alternative" "11")
3330        (const_string "0")
3331        (const_string "*")))
3332    (set (attr "length_immediate")
3333      (if_then_else (eq_attr "alternative" "11")
3334        (const_string "8")
3335        (const_string "*")))
3336    (set (attr "prefix")
3337      (if_then_else (eq_attr "type" "sselog1,ssemov")
3338        (const_string "maybe_vex")
3339        (const_string "orig")))
3340    (set (attr "prefix_data16")
3341      (if_then_else
3342        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3343             (eq_attr "mode" "V1DF"))
3344        (const_string "1")
3345        (const_string "*")))
3346    (set (attr "mode")
3347         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3348                  (const_string "SI")
3349                (eq_attr "alternative" "8,9,11,20,21,24,25")
3350                  (const_string "DI")
3352                /* xorps is one byte shorter for non-AVX targets.  */
3353                (eq_attr "alternative" "12,16")
3354                  (cond [(not (match_test "TARGET_SSE2"))
3355                           (const_string "V4SF")
3356                         (match_test "TARGET_AVX512F")
3357                           (const_string "XI")
3358                         (match_test "TARGET_AVX")
3359                           (const_string "V2DF")
3360                         (match_test "optimize_function_for_size_p (cfun)")
3361                           (const_string "V4SF")
3362                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3363                           (const_string "TI")
3364                        ]
3365                        (const_string "V2DF"))
3367                /* For architectures resolving dependencies on
3368                   whole SSE registers use movapd to break dependency
3369                   chains, otherwise use short move to avoid extra work.  */
3371                /* movaps is one byte shorter for non-AVX targets.  */
3372                (eq_attr "alternative" "13,17")
3373                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3374                              (match_operand 1 "ext_sse_reg_operand"))
3375                           (const_string "V8DF")
3376                         (ior (not (match_test "TARGET_SSE2"))
3377                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3378                           (const_string "V4SF")
3379                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3380                           (const_string "V2DF")
3381                         (match_test "TARGET_AVX")
3382                           (const_string "DF")
3383                         (match_test "optimize_function_for_size_p (cfun)")
3384                           (const_string "V4SF")
3385                        ]
3386                        (const_string "DF"))
3388                /* For architectures resolving dependencies on register
3389                   parts we may avoid extra work to zero out upper part
3390                   of register.  */
3391                (eq_attr "alternative" "14,18")
3392                  (cond [(not (match_test "TARGET_SSE2"))
3393                           (const_string "V2SF")
3394                         (match_test "TARGET_AVX")
3395                           (const_string "DF")
3396                         (match_test "TARGET_SSE_SPLIT_REGS")
3397                           (const_string "V1DF")
3398                        ]
3399                        (const_string "DF"))
3401                (and (eq_attr "alternative" "15,19")
3402                     (not (match_test "TARGET_SSE2")))
3403                  (const_string "V2SF")
3404               ]
3405               (const_string "DF")))
3406    (set (attr "preferred_for_size")
3407      (cond [(eq_attr "alternative" "3,4")
3408               (symbol_ref "false")]
3409            (symbol_ref "true")))
3410    (set (attr "preferred_for_speed")
3411      (cond [(eq_attr "alternative" "3,4")
3412               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3413            (symbol_ref "true")))
3414    (set (attr "enabled")
3415      (cond [(eq_attr "alternative" "22,23,24,25")
3416               (if_then_else
3417                 (match_test "TARGET_HARD_DF_REGS")
3418                 (symbol_ref "false")
3419                 (const_string "*"))
3420             (not (match_test "TARGET_HARD_DF_REGS"))
3421               (symbol_ref "false")
3422            ]
3423            (const_string "*")))])
3425 (define_split
3426   [(set (match_operand:DF 0 "nonimmediate_operand")
3427         (match_operand:DF 1 "general_operand"))]
3428   "!TARGET_64BIT && reload_completed
3429    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3430   [(const_int 0)]
3431   "ix86_split_long_move (operands); DONE;")
3433 (define_insn "*movsf_internal"
3434   [(set (match_operand:SF 0 "nonimmediate_operand"
3435           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3436         (match_operand:SF 1 "general_operand"
3437           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3438   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3439    && (!can_create_pseudo_p ()
3440        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3441        || !CONST_DOUBLE_P (operands[1])
3442        || (optimize_function_for_size_p (cfun)
3443            && ((!TARGET_SSE_MATH
3444                 && standard_80387_constant_p (operands[1]) > 0)
3445                || (TARGET_SSE_MATH
3446                    && standard_sse_constant_p (operands[1]))))
3447        || memory_operand (operands[0], SFmode)
3448        || !TARGET_HARD_SF_REGS)"
3450   switch (get_attr_type (insn))
3451     {
3452     case TYPE_FMOV:
3453       if (which_alternative == 2)
3454         return standard_80387_constant_opcode (operands[1]);
3455       return output_387_reg_move (insn, operands);
3457     case TYPE_IMOV:
3458       return "mov{l}\t{%1, %0|%0, %1}";
3460     case TYPE_SSELOG1:
3461       return standard_sse_constant_opcode (insn, operands[1]);
3463     case TYPE_SSEMOV:
3464       switch (get_attr_mode (insn))
3465         {
3466         case MODE_SF:
3467           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3468             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3469           return "%vmovss\t{%1, %0|%0, %1}";
3471         case MODE_V16SF:
3472           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3473         case MODE_V4SF:
3474           return "%vmovaps\t{%1, %0|%0, %1}";
3476         case MODE_SI:
3477           return "%vmovd\t{%1, %0|%0, %1}";
3479         default:
3480           gcc_unreachable ();
3481         }
3483     case TYPE_MMXMOV:
3484       switch (get_attr_mode (insn))
3485         {
3486         case MODE_DI:
3487           return "movq\t{%1, %0|%0, %1}";
3488         case MODE_SI:
3489           return "movd\t{%1, %0|%0, %1}";
3491         default:
3492           gcc_unreachable ();
3493         }
3495     default:
3496       gcc_unreachable ();
3497     }
3499   [(set (attr "type")
3500         (cond [(eq_attr "alternative" "0,1,2")
3501                  (const_string "fmov")
3502                (eq_attr "alternative" "3,4,16,17")
3503                  (const_string "imov")
3504                (eq_attr "alternative" "5")
3505                  (const_string "sselog1")
3506                (eq_attr "alternative" "11,12,13,14,15")
3507                  (const_string "mmxmov")
3508               ]
3509               (const_string "ssemov")))
3510    (set (attr "prefix")
3511      (if_then_else (eq_attr "type" "sselog1,ssemov")
3512        (const_string "maybe_vex")
3513        (const_string "orig")))
3514    (set (attr "prefix_data16")
3515      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3516        (const_string "1")
3517        (const_string "*")))
3518    (set (attr "mode")
3519         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3520                  (const_string "SI")
3521                (eq_attr "alternative" "11")
3522                  (const_string "DI")
3523                (eq_attr "alternative" "5")
3524                  (cond [(not (match_test "TARGET_SSE2"))
3525                           (const_string "V4SF")
3526                         (match_test "TARGET_AVX512F")
3527                           (const_string "V16SF")
3528                         (match_test "TARGET_AVX")
3529                           (const_string "V4SF")
3530                         (match_test "optimize_function_for_size_p (cfun)")
3531                           (const_string "V4SF")
3532                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3533                           (const_string "TI")
3534                        ]
3535                        (const_string "V4SF"))
3537                /* For architectures resolving dependencies on
3538                   whole SSE registers use APS move to break dependency
3539                   chains, otherwise use short move to avoid extra work.
3541                   Do the same for architectures resolving dependencies on
3542                   the parts.  While in DF mode it is better to always handle
3543                   just register parts, the SF mode is different due to lack
3544                   of instructions to load just part of the register.  It is
3545                   better to maintain the whole registers in single format
3546                   to avoid problems on using packed logical operations.  */
3547                (eq_attr "alternative" "6")
3548                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3549                               (match_operand 1 "ext_sse_reg_operand"))
3550                           (const_string "V16SF")
3551                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3552                              (match_test "TARGET_SSE_SPLIT_REGS"))
3553                           (const_string "V4SF")
3554                        ]
3555                        (const_string "SF"))
3556               ]
3557               (const_string "SF")))
3558    (set (attr "enabled")
3559      (cond [(eq_attr "alternative" "16,17")
3560               (if_then_else
3561                 (match_test "TARGET_HARD_SF_REGS")
3562                 (symbol_ref "false")
3563                 (const_string "*"))
3564             (not (match_test "TARGET_HARD_SF_REGS"))
3565               (symbol_ref "false")
3566            ]
3567            (const_string "*")))])
3569 (define_split
3570   [(set (match_operand 0 "any_fp_register_operand")
3571         (match_operand 1 "memory_operand"))]
3572   "reload_completed
3573    && (GET_MODE (operands[0]) == TFmode
3574        || GET_MODE (operands[0]) == XFmode
3575        || GET_MODE (operands[0]) == DFmode
3576        || GET_MODE (operands[0]) == SFmode)"
3577   [(set (match_dup 0) (match_dup 2))]
3579   operands[2] = find_constant_src (curr_insn);
3581   if (operands[2] == NULL_RTX
3582       || (SSE_REGNO_P (REGNO (operands[0]))
3583           && !standard_sse_constant_p (operands[2]))
3584       || (STACK_REGNO_P (REGNO (operands[0]))
3585            && standard_80387_constant_p (operands[2]) < 1))
3586     FAIL;
3589 (define_split
3590   [(set (match_operand 0 "any_fp_register_operand")
3591         (float_extend (match_operand 1 "memory_operand")))]
3592   "reload_completed
3593    && (GET_MODE (operands[0]) == TFmode
3594        || GET_MODE (operands[0]) == XFmode
3595        || GET_MODE (operands[0]) == DFmode)"
3596   [(set (match_dup 0) (match_dup 2))]
3598   operands[2] = find_constant_src (curr_insn);
3600   if (operands[2] == NULL_RTX
3601       || (SSE_REGNO_P (REGNO (operands[0]))
3602           && !standard_sse_constant_p (operands[2]))
3603       || (STACK_REGNO_P (REGNO (operands[0]))
3604            && standard_80387_constant_p (operands[2]) < 1))
3605     FAIL;
3608 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3609 (define_split
3610   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3611         (match_operand:X87MODEF 1 "immediate_operand"))]
3612   "reload_completed
3613    && (standard_80387_constant_p (operands[1]) == 8
3614        || standard_80387_constant_p (operands[1]) == 9)"
3615   [(set (match_dup 0)(match_dup 1))
3616    (set (match_dup 0)
3617         (neg:X87MODEF (match_dup 0)))]
3619   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3620     operands[1] = CONST0_RTX (<MODE>mode);
3621   else
3622     operands[1] = CONST1_RTX (<MODE>mode);
3625 (define_insn "swapxf"
3626   [(set (match_operand:XF 0 "register_operand" "+f")
3627         (match_operand:XF 1 "register_operand" "+f"))
3628    (set (match_dup 1)
3629         (match_dup 0))]
3630   "TARGET_80387"
3632   if (STACK_TOP_P (operands[0]))
3633     return "fxch\t%1";
3634   else
3635     return "fxch\t%0";
3637   [(set_attr "type" "fxch")
3638    (set_attr "mode" "XF")])
3640 (define_insn "*swap<mode>"
3641   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3642         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3643    (set (match_dup 1)
3644         (match_dup 0))]
3645   "TARGET_80387 || reload_completed"
3647   if (STACK_TOP_P (operands[0]))
3648     return "fxch\t%1";
3649   else
3650     return "fxch\t%0";
3652   [(set_attr "type" "fxch")
3653    (set_attr "mode" "<MODE>")])
3655 ;; Zero extension instructions
3657 (define_expand "zero_extendsidi2"
3658   [(set (match_operand:DI 0 "nonimmediate_operand")
3659         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3661 (define_insn "*zero_extendsidi2"
3662   [(set (match_operand:DI 0 "nonimmediate_operand"
3663                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3664         (zero_extend:DI
3665          (match_operand:SI 1 "x86_64_zext_operand"
3666                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3667   ""
3669   switch (get_attr_type (insn))
3670     {
3671     case TYPE_IMOVX:
3672       if (ix86_use_lea_for_mov (insn, operands))
3673         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3674       else
3675         return "mov{l}\t{%1, %k0|%k0, %1}";
3677     case TYPE_MULTI:
3678       return "#";
3680     case TYPE_MMXMOV:
3681       return "movd\t{%1, %0|%0, %1}";
3683     case TYPE_SSELOG1:
3684       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3686     case TYPE_SSEMOV:
3687       if (GENERAL_REG_P (operands[0]))
3688         return "%vmovd\t{%1, %k0|%k0, %1}";
3690       return "%vmovd\t{%1, %0|%0, %1}";
3692     default:
3693       gcc_unreachable ();
3694     }
3696   [(set (attr "isa")
3697      (cond [(eq_attr "alternative" "0,1,2")
3698               (const_string "nox64")
3699             (eq_attr "alternative" "3,7")
3700               (const_string "x64")
3701             (eq_attr "alternative" "8")
3702               (const_string "x64_sse4")
3703             (eq_attr "alternative" "10")
3704               (const_string "sse2")
3705            ]
3706            (const_string "*")))
3707    (set (attr "type")
3708      (cond [(eq_attr "alternative" "0,1,2,4")
3709               (const_string "multi")
3710             (eq_attr "alternative" "5,6")
3711               (const_string "mmxmov")
3712             (eq_attr "alternative" "7,9,10")
3713               (const_string "ssemov")
3714             (eq_attr "alternative" "8")
3715               (const_string "sselog1")
3716            ]
3717            (const_string "imovx")))
3718    (set (attr "prefix_extra")
3719      (if_then_else (eq_attr "alternative" "8")
3720        (const_string "1")
3721        (const_string "*")))
3722    (set (attr "length_immediate")
3723      (if_then_else (eq_attr "alternative" "8")
3724        (const_string "1")
3725        (const_string "*")))
3726    (set (attr "prefix")
3727      (if_then_else (eq_attr "type" "ssemov,sselog1")
3728        (const_string "maybe_vex")
3729        (const_string "orig")))
3730    (set (attr "prefix_0f")
3731      (if_then_else (eq_attr "type" "imovx")
3732        (const_string "0")
3733        (const_string "*")))
3734    (set (attr "mode")
3735      (cond [(eq_attr "alternative" "5,6")
3736               (const_string "DI")
3737             (eq_attr "alternative" "7,8,9")
3738               (const_string "TI")
3739            ]
3740            (const_string "SI")))])
3742 (define_split
3743   [(set (match_operand:DI 0 "memory_operand")
3744         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3745   "reload_completed"
3746   [(set (match_dup 4) (const_int 0))]
3747   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3749 (define_split
3750   [(set (match_operand:DI 0 "register_operand")
3751         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3752   "!TARGET_64BIT && reload_completed
3753    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3754    && true_regnum (operands[0]) == true_regnum (operands[1])"
3755   [(set (match_dup 4) (const_int 0))]
3756   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3758 (define_split
3759   [(set (match_operand:DI 0 "nonimmediate_operand")
3760         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3761   "!TARGET_64BIT && reload_completed
3762    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3763    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3764   [(set (match_dup 3) (match_dup 1))
3765    (set (match_dup 4) (const_int 0))]
3766   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3768 (define_insn "zero_extend<mode>di2"
3769   [(set (match_operand:DI 0 "register_operand" "=r")
3770         (zero_extend:DI
3771          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3772   "TARGET_64BIT"
3773   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3774   [(set_attr "type" "imovx")
3775    (set_attr "mode" "SI")])
3777 (define_expand "zero_extend<mode>si2"
3778   [(set (match_operand:SI 0 "register_operand")
3779         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3780   ""
3782   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3783     {
3784       operands[1] = force_reg (<MODE>mode, operands[1]);
3785       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3786       DONE;
3787     }
3790 (define_insn_and_split "zero_extend<mode>si2_and"
3791   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3792         (zero_extend:SI
3793           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3794    (clobber (reg:CC FLAGS_REG))]
3795   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3796   "#"
3797   "&& reload_completed"
3798   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3799               (clobber (reg:CC FLAGS_REG))])]
3801   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3802     {
3803       ix86_expand_clear (operands[0]);
3805       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3806       emit_insn (gen_movstrict<mode>
3807                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3808       DONE;
3809     }
3811   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3813   [(set_attr "type" "alu1")
3814    (set_attr "mode" "SI")])
3816 (define_insn "*zero_extend<mode>si2"
3817   [(set (match_operand:SI 0 "register_operand" "=r")
3818         (zero_extend:SI
3819           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3820   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3821   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3822   [(set_attr "type" "imovx")
3823    (set_attr "mode" "SI")])
3825 (define_expand "zero_extendqihi2"
3826   [(set (match_operand:HI 0 "register_operand")
3827         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3828   ""
3830   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3831     {
3832       operands[1] = force_reg (QImode, operands[1]);
3833       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3834       DONE;
3835     }
3838 (define_insn_and_split "zero_extendqihi2_and"
3839   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3840         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3841    (clobber (reg:CC FLAGS_REG))]
3842   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3843   "#"
3844   "&& reload_completed"
3845   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3846               (clobber (reg:CC FLAGS_REG))])]
3848   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3849     {
3850       ix86_expand_clear (operands[0]);
3852       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3853       emit_insn (gen_movstrictqi
3854                   (gen_lowpart (QImode, operands[0]), operands[1]));
3855       DONE;
3856     }
3858   operands[0] = gen_lowpart (SImode, operands[0]);
3860   [(set_attr "type" "alu1")
3861    (set_attr "mode" "SI")])
3863 ; zero extend to SImode to avoid partial register stalls
3864 (define_insn "*zero_extendqihi2"
3865   [(set (match_operand:HI 0 "register_operand" "=r")
3866         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3867   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3868   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3869   [(set_attr "type" "imovx")
3870    (set_attr "mode" "SI")])
3872 (define_insn_and_split "*zext<mode>_doubleword"
3873   [(set (match_operand:DI 0 "register_operand" "=r")
3874         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3875   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3876   "#"
3877   "&& reload_completed && GENERAL_REG_P (operands[0])"
3878   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3879    (set (match_dup 2) (const_int 0))]
3880   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3882 (define_insn_and_split "*zextsi_doubleword"
3883   [(set (match_operand:DI 0 "register_operand" "=r")
3884         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3885   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3886   "#"
3887   "&& reload_completed && GENERAL_REG_P (operands[0])"
3888   [(set (match_dup 0) (match_dup 1))
3889    (set (match_dup 2) (const_int 0))]
3890   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3892 ;; Sign extension instructions
3894 (define_expand "extendsidi2"
3895   [(set (match_operand:DI 0 "register_operand")
3896         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3897   ""
3899   if (!TARGET_64BIT)
3900     {
3901       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3902       DONE;
3903     }
3906 (define_insn "*extendsidi2_rex64"
3907   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3908         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3909   "TARGET_64BIT"
3910   "@
3911    {cltq|cdqe}
3912    movs{lq|x}\t{%1, %0|%0, %1}"
3913   [(set_attr "type" "imovx")
3914    (set_attr "mode" "DI")
3915    (set_attr "prefix_0f" "0")
3916    (set_attr "modrm" "0,1")])
3918 (define_insn "extendsidi2_1"
3919   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3920         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3921    (clobber (reg:CC FLAGS_REG))
3922    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3923   "!TARGET_64BIT"
3924   "#")
3926 ;; Split the memory case.  If the source register doesn't die, it will stay
3927 ;; this way, if it does die, following peephole2s take care of it.
3928 (define_split
3929   [(set (match_operand:DI 0 "memory_operand")
3930         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3931    (clobber (reg:CC FLAGS_REG))
3932    (clobber (match_operand:SI 2 "register_operand"))]
3933   "reload_completed"
3934   [(const_int 0)]
3936   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3938   emit_move_insn (operands[3], operands[1]);
3940   /* Generate a cltd if possible and doing so it profitable.  */
3941   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3942       && true_regnum (operands[1]) == AX_REG
3943       && true_regnum (operands[2]) == DX_REG)
3944     {
3945       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3946     }
3947   else
3948     {
3949       emit_move_insn (operands[2], operands[1]);
3950       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3951     }
3952   emit_move_insn (operands[4], operands[2]);
3953   DONE;
3956 ;; Peepholes for the case where the source register does die, after
3957 ;; being split with the above splitter.
3958 (define_peephole2
3959   [(set (match_operand:SI 0 "memory_operand")
3960         (match_operand:SI 1 "register_operand"))
3961    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3962    (parallel [(set (match_dup 2)
3963                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3964                (clobber (reg:CC FLAGS_REG))])
3965    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3966   "REGNO (operands[1]) != REGNO (operands[2])
3967    && peep2_reg_dead_p (2, operands[1])
3968    && peep2_reg_dead_p (4, operands[2])
3969    && !reg_mentioned_p (operands[2], operands[3])"
3970   [(set (match_dup 0) (match_dup 1))
3971    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3972               (clobber (reg:CC FLAGS_REG))])
3973    (set (match_dup 3) (match_dup 1))])
3975 (define_peephole2
3976   [(set (match_operand:SI 0 "memory_operand")
3977         (match_operand:SI 1 "register_operand"))
3978    (parallel [(set (match_operand:SI 2 "register_operand")
3979                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3980                (clobber (reg:CC FLAGS_REG))])
3981    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3982   "/* cltd is shorter than sarl $31, %eax */
3983    !optimize_function_for_size_p (cfun)
3984    && true_regnum (operands[1]) == AX_REG
3985    && true_regnum (operands[2]) == DX_REG
3986    && peep2_reg_dead_p (2, operands[1])
3987    && peep2_reg_dead_p (3, operands[2])
3988    && !reg_mentioned_p (operands[2], operands[3])"
3989   [(set (match_dup 0) (match_dup 1))
3990    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3991               (clobber (reg:CC FLAGS_REG))])
3992    (set (match_dup 3) (match_dup 1))])
3994 ;; Extend to register case.  Optimize case where source and destination
3995 ;; registers match and cases where we can use cltd.
3996 (define_split
3997   [(set (match_operand:DI 0 "register_operand")
3998         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3999    (clobber (reg:CC FLAGS_REG))
4000    (clobber (match_scratch:SI 2))]
4001   "reload_completed"
4002   [(const_int 0)]
4004   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4006   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4007     emit_move_insn (operands[3], operands[1]);
4009   /* Generate a cltd if possible and doing so it profitable.  */
4010   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4011       && true_regnum (operands[3]) == AX_REG
4012       && true_regnum (operands[4]) == DX_REG)
4013     {
4014       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4015       DONE;
4016     }
4018   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4019     emit_move_insn (operands[4], operands[1]);
4021   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4022   DONE;
4025 (define_insn "extend<mode>di2"
4026   [(set (match_operand:DI 0 "register_operand" "=r")
4027         (sign_extend:DI
4028          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4029   "TARGET_64BIT"
4030   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4031   [(set_attr "type" "imovx")
4032    (set_attr "mode" "DI")])
4034 (define_insn "extendhisi2"
4035   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4036         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4037   ""
4039   switch (get_attr_prefix_0f (insn))
4040     {
4041     case 0:
4042       return "{cwtl|cwde}";
4043     default:
4044       return "movs{wl|x}\t{%1, %0|%0, %1}";
4045     }
4047   [(set_attr "type" "imovx")
4048    (set_attr "mode" "SI")
4049    (set (attr "prefix_0f")
4050      ;; movsx is short decodable while cwtl is vector decoded.
4051      (if_then_else (and (eq_attr "cpu" "!k6")
4052                         (eq_attr "alternative" "0"))
4053         (const_string "0")
4054         (const_string "1")))
4055    (set (attr "znver1_decode")
4056      (if_then_else (eq_attr "prefix_0f" "0")
4057         (const_string "double")
4058         (const_string "direct")))
4059    (set (attr "modrm")
4060      (if_then_else (eq_attr "prefix_0f" "0")
4061         (const_string "0")
4062         (const_string "1")))])
4064 (define_insn "*extendhisi2_zext"
4065   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4066         (zero_extend:DI
4067          (sign_extend:SI
4068           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4069   "TARGET_64BIT"
4071   switch (get_attr_prefix_0f (insn))
4072     {
4073     case 0:
4074       return "{cwtl|cwde}";
4075     default:
4076       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4077     }
4079   [(set_attr "type" "imovx")
4080    (set_attr "mode" "SI")
4081    (set (attr "prefix_0f")
4082      ;; movsx is short decodable while cwtl is vector decoded.
4083      (if_then_else (and (eq_attr "cpu" "!k6")
4084                         (eq_attr "alternative" "0"))
4085         (const_string "0")
4086         (const_string "1")))
4087    (set (attr "modrm")
4088      (if_then_else (eq_attr "prefix_0f" "0")
4089         (const_string "0")
4090         (const_string "1")))])
4092 (define_insn "extendqisi2"
4093   [(set (match_operand:SI 0 "register_operand" "=r")
4094         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4095   ""
4096   "movs{bl|x}\t{%1, %0|%0, %1}"
4097    [(set_attr "type" "imovx")
4098     (set_attr "mode" "SI")])
4100 (define_insn "*extendqisi2_zext"
4101   [(set (match_operand:DI 0 "register_operand" "=r")
4102         (zero_extend:DI
4103           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4104   "TARGET_64BIT"
4105   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4106    [(set_attr "type" "imovx")
4107     (set_attr "mode" "SI")])
4109 (define_insn "extendqihi2"
4110   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4111         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4112   ""
4114   switch (get_attr_prefix_0f (insn))
4115     {
4116     case 0:
4117       return "{cbtw|cbw}";
4118     default:
4119       return "movs{bw|x}\t{%1, %0|%0, %1}";
4120     }
4122   [(set_attr "type" "imovx")
4123    (set_attr "mode" "HI")
4124    (set (attr "prefix_0f")
4125      ;; movsx is short decodable while cwtl is vector decoded.
4126      (if_then_else (and (eq_attr "cpu" "!k6")
4127                         (eq_attr "alternative" "0"))
4128         (const_string "0")
4129         (const_string "1")))
4130    (set (attr "modrm")
4131      (if_then_else (eq_attr "prefix_0f" "0")
4132         (const_string "0")
4133         (const_string "1")))])
4135 ;; Conversions between float and double.
4137 ;; These are all no-ops in the model used for the 80387.
4138 ;; So just emit moves.
4140 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4141 (define_split
4142   [(set (match_operand:DF 0 "push_operand")
4143         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4144   "reload_completed"
4145   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4146    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4148 (define_split
4149   [(set (match_operand:XF 0 "push_operand")
4150         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4151   "reload_completed"
4152   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4153    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4154   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4156 (define_expand "extendsfdf2"
4157   [(set (match_operand:DF 0 "nonimmediate_operand")
4158         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4159   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4161   /* ??? Needed for compress_float_constant since all fp constants
4162      are TARGET_LEGITIMATE_CONSTANT_P.  */
4163   if (CONST_DOUBLE_P (operands[1]))
4164     {
4165       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4166           && standard_80387_constant_p (operands[1]) > 0)
4167         {
4168           operands[1] = simplify_const_unary_operation
4169             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4170           emit_move_insn_1 (operands[0], operands[1]);
4171           DONE;
4172         }
4173       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4174     }
4177 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4178    cvtss2sd:
4179       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4180       cvtps2pd xmm2,xmm1
4181    We do the conversion post reload to avoid producing of 128bit spills
4182    that might lead to ICE on 32bit target.  The sequence unlikely combine
4183    anyway.  */
4184 (define_split
4185   [(set (match_operand:DF 0 "register_operand")
4186         (float_extend:DF
4187           (match_operand:SF 1 "nonimmediate_operand")))]
4188   "TARGET_USE_VECTOR_FP_CONVERTS
4189    && optimize_insn_for_speed_p ()
4190    && reload_completed && SSE_REG_P (operands[0])
4191    && (!EXT_REX_SSE_REG_P (operands[0])
4192        || TARGET_AVX512VL)"
4193    [(set (match_dup 2)
4194          (float_extend:V2DF
4195            (vec_select:V2SF
4196              (match_dup 3)
4197              (parallel [(const_int 0) (const_int 1)]))))]
4199   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4200   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4201   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4202      Try to avoid move when unpacking can be done in source.  */
4203   if (REG_P (operands[1]))
4204     {
4205       /* If it is unsafe to overwrite upper half of source, we need
4206          to move to destination and unpack there.  */
4207       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4208            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4209           && true_regnum (operands[0]) != true_regnum (operands[1]))
4210         {
4211           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4212           emit_move_insn (tmp, operands[1]);
4213         }
4214       else
4215         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4216       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4217                                              operands[3]));
4218     }
4219   else
4220     emit_insn (gen_vec_setv4sf_0 (operands[3],
4221                                   CONST0_RTX (V4SFmode), operands[1]));
4224 ;; It's more profitable to split and then extend in the same register.
4225 (define_peephole2
4226   [(set (match_operand:DF 0 "register_operand")
4227         (float_extend:DF
4228           (match_operand:SF 1 "memory_operand")))]
4229   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4230    && optimize_insn_for_speed_p ()
4231    && SSE_REG_P (operands[0])"
4232   [(set (match_dup 2) (match_dup 1))
4233    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4234   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4236 (define_insn "*extendsfdf2_mixed"
4237   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4238         (float_extend:DF
4239           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4240   "TARGET_SSE2 && TARGET_SSE_MATH"
4242   switch (which_alternative)
4243     {
4244     case 0:
4245     case 1:
4246       return output_387_reg_move (insn, operands);
4248     case 2:
4249       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4251     default:
4252       gcc_unreachable ();
4253     }
4255   [(set_attr "type" "fmov,fmov,ssecvt")
4256    (set_attr "prefix" "orig,orig,maybe_vex")
4257    (set_attr "mode" "SF,XF,DF")
4258    (set (attr "enabled")
4259      (cond [(eq_attr "alternative" "0,1")
4260               (symbol_ref "TARGET_MIX_SSE_I387")
4261            ]
4262            (symbol_ref "true")))])
4264 (define_insn "*extendsfdf2_i387"
4265   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4266         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4267   "TARGET_80387"
4268   "* return output_387_reg_move (insn, operands);"
4269   [(set_attr "type" "fmov")
4270    (set_attr "mode" "SF,XF")])
4272 (define_expand "extend<mode>xf2"
4273   [(set (match_operand:XF 0 "nonimmediate_operand")
4274         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4275   "TARGET_80387"
4277   /* ??? Needed for compress_float_constant since all fp constants
4278      are TARGET_LEGITIMATE_CONSTANT_P.  */
4279   if (CONST_DOUBLE_P (operands[1]))
4280     {
4281       if (standard_80387_constant_p (operands[1]) > 0)
4282         {
4283           operands[1] = simplify_const_unary_operation
4284             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4285           emit_move_insn_1 (operands[0], operands[1]);
4286           DONE;
4287         }
4288       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4289     }
4292 (define_insn "*extend<mode>xf2_i387"
4293   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4294         (float_extend:XF
4295           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4296   "TARGET_80387"
4297   "* return output_387_reg_move (insn, operands);"
4298   [(set_attr "type" "fmov")
4299    (set_attr "mode" "<MODE>,XF")])
4301 ;; %%% This seems like bad news.
4302 ;; This cannot output into an f-reg because there is no way to be sure
4303 ;; of truncating in that case.  Otherwise this is just like a simple move
4304 ;; insn.  So we pretend we can output to a reg in order to get better
4305 ;; register preferencing, but we really use a stack slot.
4307 ;; Conversion from DFmode to SFmode.
4309 (define_expand "truncdfsf2"
4310   [(set (match_operand:SF 0 "nonimmediate_operand")
4311         (float_truncate:SF
4312           (match_operand:DF 1 "nonimmediate_operand")))]
4313   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4315   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4316     ;
4317   else if (flag_unsafe_math_optimizations)
4318     ;
4319   else
4320     {
4321       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4322       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4323       DONE;
4324     }
4327 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4328    cvtsd2ss:
4329       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4330       cvtpd2ps xmm2,xmm1
4331    We do the conversion post reload to avoid producing of 128bit spills
4332    that might lead to ICE on 32bit target.  The sequence unlikely combine
4333    anyway.  */
4334 (define_split
4335   [(set (match_operand:SF 0 "register_operand")
4336         (float_truncate:SF
4337           (match_operand:DF 1 "nonimmediate_operand")))]
4338   "TARGET_USE_VECTOR_FP_CONVERTS
4339    && optimize_insn_for_speed_p ()
4340    && reload_completed && SSE_REG_P (operands[0])
4341    && (!EXT_REX_SSE_REG_P (operands[0])
4342        || TARGET_AVX512VL)"
4343    [(set (match_dup 2)
4344          (vec_concat:V4SF
4345            (float_truncate:V2SF
4346              (match_dup 4))
4347            (match_dup 3)))]
4349   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4350   operands[3] = CONST0_RTX (V2SFmode);
4351   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4352   /* Use movsd for loading from memory, unpcklpd for registers.
4353      Try to avoid move when unpacking can be done in source, or SSE3
4354      movddup is available.  */
4355   if (REG_P (operands[1]))
4356     {
4357       if (!TARGET_SSE3
4358           && true_regnum (operands[0]) != true_regnum (operands[1])
4359           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4360               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4361         {
4362           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4363           emit_move_insn (tmp, operands[1]);
4364           operands[1] = tmp;
4365         }
4366       else if (!TARGET_SSE3)
4367         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4368       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4369     }
4370   else
4371     emit_insn (gen_sse2_loadlpd (operands[4],
4372                                  CONST0_RTX (V2DFmode), operands[1]));
4375 ;; It's more profitable to split and then extend in the same register.
4376 (define_peephole2
4377   [(set (match_operand:SF 0 "register_operand")
4378         (float_truncate:SF
4379           (match_operand:DF 1 "memory_operand")))]
4380   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4381    && optimize_insn_for_speed_p ()
4382    && SSE_REG_P (operands[0])"
4383   [(set (match_dup 2) (match_dup 1))
4384    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4385   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4387 (define_expand "truncdfsf2_with_temp"
4388   [(parallel [(set (match_operand:SF 0)
4389                    (float_truncate:SF (match_operand:DF 1)))
4390               (clobber (match_operand:SF 2))])])
4392 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4393 ;; because nothing we do there is unsafe.
4394 (define_insn "*truncdfsf_fast_mixed"
4395   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4396         (float_truncate:SF
4397           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4398   "TARGET_SSE2 && TARGET_SSE_MATH"
4400   switch (which_alternative)
4401     {
4402     case 0:
4403       return output_387_reg_move (insn, operands);
4404     case 1:
4405       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4406     default:
4407       gcc_unreachable ();
4408     }
4410   [(set_attr "type" "fmov,ssecvt")
4411    (set_attr "prefix" "orig,maybe_vex")
4412    (set_attr "mode" "SF")
4413    (set (attr "enabled")
4414      (cond [(eq_attr "alternative" "0")
4415               (symbol_ref "TARGET_MIX_SSE_I387
4416                            && flag_unsafe_math_optimizations")
4417            ]
4418            (symbol_ref "true")))])
4420 (define_insn "*truncdfsf_fast_i387"
4421   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4422         (float_truncate:SF
4423           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4424   "TARGET_80387 && flag_unsafe_math_optimizations"
4425   "* return output_387_reg_move (insn, operands);"
4426   [(set_attr "type" "fmov")
4427    (set_attr "mode" "SF")])
4429 (define_insn "*truncdfsf_mixed"
4430   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4431         (float_truncate:SF
4432           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4433    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4434   "TARGET_MIX_SSE_I387"
4436   switch (which_alternative)
4437     {
4438     case 0:
4439       return output_387_reg_move (insn, operands);
4440     case 1:
4441       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4443     default:
4444       return "#";
4445     }
4447   [(set_attr "isa" "*,sse2,*,*,*")
4448    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4449    (set_attr "unit" "*,*,i387,i387,i387")
4450    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4451    (set_attr "mode" "SF")])
4453 (define_insn "*truncdfsf_i387"
4454   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4455         (float_truncate:SF
4456           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4457    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4458   "TARGET_80387"
4460   switch (which_alternative)
4461     {
4462     case 0:
4463       return output_387_reg_move (insn, operands);
4465     default:
4466       return "#";
4467     }
4469   [(set_attr "type" "fmov,multi,multi,multi")
4470    (set_attr "unit" "*,i387,i387,i387")
4471    (set_attr "mode" "SF")])
4473 (define_insn "*truncdfsf2_i387_1"
4474   [(set (match_operand:SF 0 "memory_operand" "=m")
4475         (float_truncate:SF
4476           (match_operand:DF 1 "register_operand" "f")))]
4477   "TARGET_80387
4478    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4479    && !TARGET_MIX_SSE_I387"
4480   "* return output_387_reg_move (insn, operands);"
4481   [(set_attr "type" "fmov")
4482    (set_attr "mode" "SF")])
4484 (define_split
4485   [(set (match_operand:SF 0 "register_operand")
4486         (float_truncate:SF
4487          (match_operand:DF 1 "fp_register_operand")))
4488    (clobber (match_operand 2))]
4489   "reload_completed"
4490   [(set (match_dup 2) (match_dup 1))
4491    (set (match_dup 0) (match_dup 2))]
4492   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4494 ;; Conversion from XFmode to {SF,DF}mode
4496 (define_expand "truncxf<mode>2"
4497   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4498                    (float_truncate:MODEF
4499                      (match_operand:XF 1 "register_operand")))
4500               (clobber (match_dup 2))])]
4501   "TARGET_80387"
4503   if (flag_unsafe_math_optimizations)
4504     {
4505       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4506       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4507       if (reg != operands[0])
4508         emit_move_insn (operands[0], reg);
4509       DONE;
4510     }
4511   else
4512     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4515 (define_insn "*truncxfsf2_mixed"
4516   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4517         (float_truncate:SF
4518           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4519    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4520   "TARGET_80387"
4522   gcc_assert (!which_alternative);
4523   return output_387_reg_move (insn, operands);
4525   [(set_attr "type" "fmov,multi,multi,multi")
4526    (set_attr "unit" "*,i387,i387,i387")
4527    (set_attr "mode" "SF")])
4529 (define_insn "*truncxfdf2_mixed"
4530   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4531         (float_truncate:DF
4532           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4533    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4534   "TARGET_80387"
4536   gcc_assert (!which_alternative);
4537   return output_387_reg_move (insn, operands);
4539   [(set_attr "isa" "*,*,sse2,*")
4540    (set_attr "type" "fmov,multi,multi,multi")
4541    (set_attr "unit" "*,i387,i387,i387")
4542    (set_attr "mode" "DF")])
4544 (define_insn "truncxf<mode>2_i387_noop"
4545   [(set (match_operand:MODEF 0 "register_operand" "=f")
4546         (float_truncate:MODEF
4547           (match_operand:XF 1 "register_operand" "f")))]
4548   "TARGET_80387 && flag_unsafe_math_optimizations"
4549   "* return output_387_reg_move (insn, operands);"
4550   [(set_attr "type" "fmov")
4551    (set_attr "mode" "<MODE>")])
4553 (define_insn "*truncxf<mode>2_i387"
4554   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4555         (float_truncate:MODEF
4556           (match_operand:XF 1 "register_operand" "f")))]
4557   "TARGET_80387"
4558   "* return output_387_reg_move (insn, operands);"
4559   [(set_attr "type" "fmov")
4560    (set_attr "mode" "<MODE>")])
4562 (define_split
4563   [(set (match_operand:MODEF 0 "register_operand")
4564         (float_truncate:MODEF
4565           (match_operand:XF 1 "register_operand")))
4566    (clobber (match_operand:MODEF 2 "memory_operand"))]
4567   "TARGET_80387 && reload_completed"
4568   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4569    (set (match_dup 0) (match_dup 2))])
4571 (define_split
4572   [(set (match_operand:MODEF 0 "memory_operand")
4573         (float_truncate:MODEF
4574           (match_operand:XF 1 "register_operand")))
4575    (clobber (match_operand:MODEF 2 "memory_operand"))]
4576   "TARGET_80387"
4577   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4579 ;; Signed conversion to DImode.
4581 (define_expand "fix_truncxfdi2"
4582   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4583                    (fix:DI (match_operand:XF 1 "register_operand")))
4584               (clobber (reg:CC FLAGS_REG))])]
4585   "TARGET_80387"
4587   if (TARGET_FISTTP)
4588    {
4589      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4590      DONE;
4591    }
4594 (define_expand "fix_trunc<mode>di2"
4595   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4596                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4597               (clobber (reg:CC FLAGS_REG))])]
4598   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4600   if (TARGET_FISTTP
4601       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4602    {
4603      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4604      DONE;
4605    }
4606   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4607    {
4608      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4609      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4610      if (out != operands[0])
4611         emit_move_insn (operands[0], out);
4612      DONE;
4613    }
4616 ;; Signed conversion to SImode.
4618 (define_expand "fix_truncxfsi2"
4619   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4620                    (fix:SI (match_operand:XF 1 "register_operand")))
4621               (clobber (reg:CC FLAGS_REG))])]
4622   "TARGET_80387"
4624   if (TARGET_FISTTP)
4625    {
4626      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4627      DONE;
4628    }
4631 (define_expand "fix_trunc<mode>si2"
4632   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4633                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4634               (clobber (reg:CC FLAGS_REG))])]
4635   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4637   if (TARGET_FISTTP
4638       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4639    {
4640      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4641      DONE;
4642    }
4643   if (SSE_FLOAT_MODE_P (<MODE>mode))
4644    {
4645      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4646      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4647      if (out != operands[0])
4648         emit_move_insn (operands[0], out);
4649      DONE;
4650    }
4653 ;; Signed conversion to HImode.
4655 (define_expand "fix_trunc<mode>hi2"
4656   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4657                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4658               (clobber (reg:CC FLAGS_REG))])]
4659   "TARGET_80387
4660    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4662   if (TARGET_FISTTP)
4663    {
4664      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4665      DONE;
4666    }
4669 ;; Unsigned conversion to SImode.
4671 (define_expand "fixuns_trunc<mode>si2"
4672   [(parallel
4673     [(set (match_operand:SI 0 "register_operand")
4674           (unsigned_fix:SI
4675             (match_operand:MODEF 1 "nonimmediate_operand")))
4676      (use (match_dup 2))
4677      (clobber (match_scratch:<ssevecmode> 3))
4678      (clobber (match_scratch:<ssevecmode> 4))])]
4679   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4681   machine_mode mode = <MODE>mode;
4682   machine_mode vecmode = <ssevecmode>mode;
4683   REAL_VALUE_TYPE TWO31r;
4684   rtx two31;
4686   if (optimize_insn_for_size_p ())
4687     FAIL;
4689   real_ldexp (&TWO31r, &dconst1, 31);
4690   two31 = const_double_from_real_value (TWO31r, mode);
4691   two31 = ix86_build_const_vector (vecmode, true, two31);
4692   operands[2] = force_reg (vecmode, two31);
4695 (define_insn_and_split "*fixuns_trunc<mode>_1"
4696   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4697         (unsigned_fix:SI
4698           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4699    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4700    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4701    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4702   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4703    && optimize_function_for_speed_p (cfun)"
4704   "#"
4705   "&& reload_completed"
4706   [(const_int 0)]
4708   ix86_split_convert_uns_si_sse (operands);
4709   DONE;
4712 ;; Unsigned conversion to HImode.
4713 ;; Without these patterns, we'll try the unsigned SI conversion which
4714 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4716 (define_expand "fixuns_trunc<mode>hi2"
4717   [(set (match_dup 2)
4718         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4719    (set (match_operand:HI 0 "nonimmediate_operand")
4720         (subreg:HI (match_dup 2) 0))]
4721   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4722   "operands[2] = gen_reg_rtx (SImode);")
4724 ;; When SSE is available, it is always faster to use it!
4725 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4726   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4727         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4728   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4729    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4730   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4731   [(set_attr "type" "sseicvt")
4732    (set_attr "prefix" "maybe_vex")
4733    (set (attr "prefix_rex")
4734         (if_then_else
4735           (match_test "<SWI48:MODE>mode == DImode")
4736           (const_string "1")
4737           (const_string "*")))
4738    (set_attr "mode" "<MODEF:MODE>")
4739    (set_attr "athlon_decode" "double,vector")
4740    (set_attr "amdfam10_decode" "double,double")
4741    (set_attr "bdver1_decode" "double,double")])
4743 ;; Avoid vector decoded forms of the instruction.
4744 (define_peephole2
4745   [(match_scratch:MODEF 2 "x")
4746    (set (match_operand:SWI48 0 "register_operand")
4747         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4748   "TARGET_AVOID_VECTOR_DECODE
4749    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4750    && optimize_insn_for_speed_p ()"
4751   [(set (match_dup 2) (match_dup 1))
4752    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4754 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4755   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4756         (fix:SWI248x (match_operand 1 "register_operand")))]
4757   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4758    && TARGET_FISTTP
4759    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4760          && (TARGET_64BIT || <MODE>mode != DImode))
4761         && TARGET_SSE_MATH)
4762    && can_create_pseudo_p ()"
4763   "#"
4764   "&& 1"
4765   [(const_int 0)]
4767   if (memory_operand (operands[0], VOIDmode))
4768     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4769   else
4770     {
4771       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4772       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4773                                                             operands[1],
4774                                                             operands[2]));
4775     }
4776   DONE;
4778   [(set_attr "type" "fisttp")
4779    (set_attr "mode" "<MODE>")])
4781 (define_insn "fix_trunc<mode>_i387_fisttp"
4782   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4783         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4784    (clobber (match_scratch:XF 2 "=&1f"))]
4785   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4786    && TARGET_FISTTP
4787    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4788          && (TARGET_64BIT || <MODE>mode != DImode))
4789         && TARGET_SSE_MATH)"
4790   "* return output_fix_trunc (insn, operands, true);"
4791   [(set_attr "type" "fisttp")
4792    (set_attr "mode" "<MODE>")])
4794 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4795   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4796         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4797    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4798    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4799   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4800    && TARGET_FISTTP
4801    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4802         && (TARGET_64BIT || <MODE>mode != DImode))
4803         && TARGET_SSE_MATH)"
4804   "#"
4805   [(set_attr "type" "fisttp")
4806    (set_attr "mode" "<MODE>")])
4808 (define_split
4809   [(set (match_operand:SWI248x 0 "register_operand")
4810         (fix:SWI248x (match_operand 1 "register_operand")))
4811    (clobber (match_operand:SWI248x 2 "memory_operand"))
4812    (clobber (match_scratch 3))]
4813   "reload_completed"
4814   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4815               (clobber (match_dup 3))])
4816    (set (match_dup 0) (match_dup 2))])
4818 (define_split
4819   [(set (match_operand:SWI248x 0 "memory_operand")
4820         (fix:SWI248x (match_operand 1 "register_operand")))
4821    (clobber (match_operand:SWI248x 2 "memory_operand"))
4822    (clobber (match_scratch 3))]
4823   "reload_completed"
4824   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4825               (clobber (match_dup 3))])])
4827 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4828 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4829 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4830 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4831 ;; function in i386.c.
4832 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4833   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4834         (fix:SWI248x (match_operand 1 "register_operand")))
4835    (clobber (reg:CC FLAGS_REG))]
4836   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4837    && !TARGET_FISTTP
4838    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4839          && (TARGET_64BIT || <MODE>mode != DImode))
4840    && can_create_pseudo_p ()"
4841   "#"
4842   "&& 1"
4843   [(const_int 0)]
4845   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4847   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4848   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4849   if (memory_operand (operands[0], VOIDmode))
4850     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4851                                          operands[2], operands[3]));
4852   else
4853     {
4854       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4855       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4856                                                      operands[2], operands[3],
4857                                                      operands[4]));
4858     }
4859   DONE;
4861   [(set_attr "type" "fistp")
4862    (set_attr "i387_cw" "trunc")
4863    (set_attr "mode" "<MODE>")])
4865 (define_insn "fix_truncdi_i387"
4866   [(set (match_operand:DI 0 "memory_operand" "=m")
4867         (fix:DI (match_operand 1 "register_operand" "f")))
4868    (use (match_operand:HI 2 "memory_operand" "m"))
4869    (use (match_operand:HI 3 "memory_operand" "m"))
4870    (clobber (match_scratch:XF 4 "=&1f"))]
4871   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4872    && !TARGET_FISTTP
4873    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4874   "* return output_fix_trunc (insn, operands, false);"
4875   [(set_attr "type" "fistp")
4876    (set_attr "i387_cw" "trunc")
4877    (set_attr "mode" "DI")])
4879 (define_insn "fix_truncdi_i387_with_temp"
4880   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4881         (fix:DI (match_operand 1 "register_operand" "f,f")))
4882    (use (match_operand:HI 2 "memory_operand" "m,m"))
4883    (use (match_operand:HI 3 "memory_operand" "m,m"))
4884    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4885    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4886   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4887    && !TARGET_FISTTP
4888    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4889   "#"
4890   [(set_attr "type" "fistp")
4891    (set_attr "i387_cw" "trunc")
4892    (set_attr "mode" "DI")])
4894 (define_split
4895   [(set (match_operand:DI 0 "register_operand")
4896         (fix:DI (match_operand 1 "register_operand")))
4897    (use (match_operand:HI 2 "memory_operand"))
4898    (use (match_operand:HI 3 "memory_operand"))
4899    (clobber (match_operand:DI 4 "memory_operand"))
4900    (clobber (match_scratch 5))]
4901   "reload_completed"
4902   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4903               (use (match_dup 2))
4904               (use (match_dup 3))
4905               (clobber (match_dup 5))])
4906    (set (match_dup 0) (match_dup 4))])
4908 (define_split
4909   [(set (match_operand:DI 0 "memory_operand")
4910         (fix:DI (match_operand 1 "register_operand")))
4911    (use (match_operand:HI 2 "memory_operand"))
4912    (use (match_operand:HI 3 "memory_operand"))
4913    (clobber (match_operand:DI 4 "memory_operand"))
4914    (clobber (match_scratch 5))]
4915   "reload_completed"
4916   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4917               (use (match_dup 2))
4918               (use (match_dup 3))
4919               (clobber (match_dup 5))])])
4921 (define_insn "fix_trunc<mode>_i387"
4922   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4923         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4924    (use (match_operand:HI 2 "memory_operand" "m"))
4925    (use (match_operand:HI 3 "memory_operand" "m"))]
4926   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4927    && !TARGET_FISTTP
4928    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4929   "* return output_fix_trunc (insn, operands, false);"
4930   [(set_attr "type" "fistp")
4931    (set_attr "i387_cw" "trunc")
4932    (set_attr "mode" "<MODE>")])
4934 (define_insn "fix_trunc<mode>_i387_with_temp"
4935   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4936         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4937    (use (match_operand:HI 2 "memory_operand" "m,m"))
4938    (use (match_operand:HI 3 "memory_operand" "m,m"))
4939    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4940   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4941    && !TARGET_FISTTP
4942    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4943   "#"
4944   [(set_attr "type" "fistp")
4945    (set_attr "i387_cw" "trunc")
4946    (set_attr "mode" "<MODE>")])
4948 (define_split
4949   [(set (match_operand:SWI24 0 "register_operand")
4950         (fix:SWI24 (match_operand 1 "register_operand")))
4951    (use (match_operand:HI 2 "memory_operand"))
4952    (use (match_operand:HI 3 "memory_operand"))
4953    (clobber (match_operand:SWI24 4 "memory_operand"))]
4954   "reload_completed"
4955   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4956               (use (match_dup 2))
4957               (use (match_dup 3))])
4958    (set (match_dup 0) (match_dup 4))])
4960 (define_split
4961   [(set (match_operand:SWI24 0 "memory_operand")
4962         (fix:SWI24 (match_operand 1 "register_operand")))
4963    (use (match_operand:HI 2 "memory_operand"))
4964    (use (match_operand:HI 3 "memory_operand"))
4965    (clobber (match_operand:SWI24 4 "memory_operand"))]
4966   "reload_completed"
4967   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4968               (use (match_dup 2))
4969               (use (match_dup 3))])])
4971 (define_insn "x86_fnstcw_1"
4972   [(set (match_operand:HI 0 "memory_operand" "=m")
4973         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4974   "TARGET_80387"
4975   "fnstcw\t%0"
4976   [(set (attr "length")
4977         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4978    (set_attr "mode" "HI")
4979    (set_attr "unit" "i387")
4980    (set_attr "bdver1_decode" "vector")])
4982 (define_insn "x86_fldcw_1"
4983   [(set (reg:HI FPCR_REG)
4984         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4985   "TARGET_80387"
4986   "fldcw\t%0"
4987   [(set (attr "length")
4988         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4989    (set_attr "mode" "HI")
4990    (set_attr "unit" "i387")
4991    (set_attr "athlon_decode" "vector")
4992    (set_attr "amdfam10_decode" "vector")
4993    (set_attr "bdver1_decode" "vector")])
4995 ;; Conversion between fixed point and floating point.
4997 ;; Even though we only accept memory inputs, the backend _really_
4998 ;; wants to be able to do this between registers.  Thankfully, LRA
4999 ;; will fix this up for us during register allocation.
5001 (define_insn "floathi<mode>2"
5002   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5003         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5004   "TARGET_80387
5005    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5006        || TARGET_MIX_SSE_I387)"
5007   "fild%Z1\t%1"
5008   [(set_attr "type" "fmov")
5009    (set_attr "mode" "<MODE>")
5010    (set_attr "znver1_decode" "double")
5011    (set_attr "fp_int_src" "true")])
5013 (define_insn "float<SWI48x:mode>xf2"
5014   [(set (match_operand:XF 0 "register_operand" "=f")
5015         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5016   "TARGET_80387"
5017   "fild%Z1\t%1"
5018   [(set_attr "type" "fmov")
5019    (set_attr "mode" "XF")
5020    (set_attr "znver1_decode" "double")
5021    (set_attr "fp_int_src" "true")])
5023 (define_expand "float<SWI48:mode><MODEF:mode>2"
5024   [(set (match_operand:MODEF 0 "register_operand")
5025         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5026   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5028   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5029       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5030     {
5031       rtx reg = gen_reg_rtx (XFmode);
5032       rtx (*insn)(rtx, rtx);
5034       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5036       if (<MODEF:MODE>mode == SFmode)
5037         insn = gen_truncxfsf2;
5038       else if (<MODEF:MODE>mode == DFmode)
5039         insn = gen_truncxfdf2;
5040       else
5041         gcc_unreachable ();
5043       emit_insn (insn (operands[0], reg));
5044       DONE;
5045     }
5048 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5049   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5050         (float:MODEF
5051           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5052   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5053   "@
5054    fild%Z1\t%1
5055    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5056    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5057   [(set_attr "type" "fmov,sseicvt,sseicvt")
5058    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5059    (set_attr "mode" "<MODEF:MODE>")
5060    (set (attr "prefix_rex")
5061      (if_then_else
5062        (and (eq_attr "prefix" "maybe_vex")
5063             (match_test "<SWI48:MODE>mode == DImode"))
5064        (const_string "1")
5065        (const_string "*")))
5066    (set_attr "unit" "i387,*,*")
5067    (set_attr "athlon_decode" "*,double,direct")
5068    (set_attr "amdfam10_decode" "*,vector,double")
5069    (set_attr "bdver1_decode" "*,double,direct")
5070    (set_attr "znver1_decode" "double,*,*")
5071    (set_attr "fp_int_src" "true")
5072    (set (attr "enabled")
5073      (cond [(eq_attr "alternative" "0")
5074               (symbol_ref "TARGET_MIX_SSE_I387
5075                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5076                                                 <SWI48:MODE>mode)")
5077            ]
5078            (symbol_ref "true")))
5079    (set (attr "preferred_for_speed")
5080      (cond [(eq_attr "alternative" "1")
5081               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5082            (symbol_ref "true")))])
5084 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5085   [(set (match_operand:MODEF 0 "register_operand" "=f")
5086         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5087   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5088   "fild%Z1\t%1"
5089   [(set_attr "type" "fmov")
5090    (set_attr "mode" "<MODEF:MODE>")
5091    (set_attr "znver1_decode" "double")
5092    (set_attr "fp_int_src" "true")])
5094 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5095 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5096 ;; alternative in sse2_loadld.
5097 (define_split
5098   [(set (match_operand:MODEF 0 "register_operand")
5099         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5100   "TARGET_SSE2 && TARGET_SSE_MATH
5101    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5102    && reload_completed && SSE_REG_P (operands[0])
5103    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5104    && (!EXT_REX_SSE_REG_P (operands[0])
5105        || TARGET_AVX512VL)"
5106   [(const_int 0)]
5108   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5109                                      <MODE>mode, 0);
5110   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5112   emit_insn (gen_sse2_loadld (operands[4],
5113                               CONST0_RTX (V4SImode), operands[1]));
5115   if (<ssevecmode>mode == V4SFmode)
5116     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5117   else
5118     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5119   DONE;
5122 ;; Avoid partial SSE register dependency stalls
5123 (define_split
5124   [(set (match_operand:MODEF 0 "register_operand")
5125         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5126   "TARGET_SSE2 && TARGET_SSE_MATH
5127    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5128    && optimize_function_for_speed_p (cfun)
5129    && reload_completed && SSE_REG_P (operands[0])
5130    && (!EXT_REX_SSE_REG_P (operands[0])
5131        || TARGET_AVX512VL)"
5132   [(const_int 0)]
5134   const machine_mode vmode = <MODEF:ssevecmode>mode;
5135   const machine_mode mode = <MODEF:MODE>mode;
5136   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5138   emit_move_insn (op0, CONST0_RTX (vmode));
5140   t = gen_rtx_FLOAT (mode, operands[1]);
5141   t = gen_rtx_VEC_DUPLICATE (vmode, t);
5142   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5143   emit_insn (gen_rtx_SET (op0, t));
5144   DONE;
5147 ;; Break partial reg stall for cvtsd2ss.
5149 (define_peephole2
5150   [(set (match_operand:SF 0 "register_operand")
5151         (float_truncate:SF
5152           (match_operand:DF 1 "nonimmediate_operand")))]
5153   "TARGET_SSE2 && TARGET_SSE_MATH
5154    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5155    && optimize_function_for_speed_p (cfun)
5156    && SSE_REG_P (operands[0])
5157    && (!SSE_REG_P (operands[1])
5158        || REGNO (operands[0]) != REGNO (operands[1]))
5159    && (!EXT_REX_SSE_REG_P (operands[0])
5160        || TARGET_AVX512VL)"
5161   [(set (match_dup 0)
5162         (vec_merge:V4SF
5163           (vec_duplicate:V4SF
5164             (float_truncate:V2SF
5165               (match_dup 1)))
5166           (match_dup 0)
5167           (const_int 1)))]
5169   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5170                                      SFmode, 0);
5171   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5172                                      DFmode, 0);
5173   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5176 ;; Break partial reg stall for cvtss2sd.
5178 (define_peephole2
5179   [(set (match_operand:DF 0 "register_operand")
5180         (float_extend:DF
5181           (match_operand:SF 1 "nonimmediate_operand")))]
5182   "TARGET_SSE2 && TARGET_SSE_MATH
5183    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5184    && optimize_function_for_speed_p (cfun)
5185    && SSE_REG_P (operands[0])
5186    && (!SSE_REG_P (operands[1])
5187        || REGNO (operands[0]) != REGNO (operands[1]))
5188    && (!EXT_REX_SSE_REG_P (operands[0])
5189        || TARGET_AVX512VL)"
5190   [(set (match_dup 0)
5191         (vec_merge:V2DF
5192           (float_extend:V2DF
5193             (vec_select:V2SF
5194               (match_dup 1)
5195               (parallel [(const_int 0) (const_int 1)])))
5196           (match_dup 0)
5197           (const_int 1)))]
5199   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5200                                      DFmode, 0);
5201   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5202                                      SFmode, 0);
5203   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5206 ;; Avoid store forwarding (partial memory) stall penalty
5207 ;; by passing DImode value through XMM registers.  */
5209 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5210   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5211         (float:X87MODEF
5212           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5213    (clobber (match_scratch:V4SI 3 "=X,x"))
5214    (clobber (match_scratch:V4SI 4 "=X,x"))
5215    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5216   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5217    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5218    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5219   "#"
5220   [(set_attr "type" "multi")
5221    (set_attr "mode" "<X87MODEF:MODE>")
5222    (set_attr "unit" "i387")
5223    (set_attr "fp_int_src" "true")])
5225 (define_split
5226   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5227         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5228    (clobber (match_scratch:V4SI 3))
5229    (clobber (match_scratch:V4SI 4))
5230    (clobber (match_operand:DI 2 "memory_operand"))]
5231   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5232    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5233    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5234    && reload_completed"
5235   [(set (match_dup 2) (match_dup 3))
5236    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5238   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5239      Assemble the 64-bit DImode value in an xmm register.  */
5240   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5241                               gen_lowpart (SImode, operands[1])));
5242   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5243                               gen_highpart (SImode, operands[1])));
5244   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5245                                          operands[4]));
5247   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5250 (define_split
5251   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5252         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5253    (clobber (match_scratch:V4SI 3))
5254    (clobber (match_scratch:V4SI 4))
5255    (clobber (match_operand:DI 2 "memory_operand"))]
5256   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5258    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5259    && reload_completed"
5260   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5262 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5263   [(set (match_operand:MODEF 0 "register_operand")
5264         (unsigned_float:MODEF
5265           (match_operand:SWI12 1 "nonimmediate_operand")))]
5266   "!TARGET_64BIT
5267    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5269   operands[1] = convert_to_mode (SImode, operands[1], 1);
5270   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5271   DONE;
5274 ;; Avoid store forwarding (partial memory) stall penalty by extending
5275 ;; SImode value to DImode through XMM register instead of pushing two
5276 ;; SImode values to stack. Also note that fild loads from memory only.
5278 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5279   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5280         (unsigned_float:X87MODEF
5281           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5282    (clobber (match_scratch:DI 3 "=x"))
5283    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5284   "!TARGET_64BIT
5285    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5287   "#"
5288   "&& reload_completed"
5289   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5290    (set (match_dup 2) (match_dup 3))
5291    (set (match_dup 0)
5292         (float:X87MODEF (match_dup 2)))]
5293   ""
5294   [(set_attr "type" "multi")
5295    (set_attr "mode" "<MODE>")])
5297 (define_expand "floatunssi<mode>2"
5298   [(parallel
5299      [(set (match_operand:X87MODEF 0 "register_operand")
5300            (unsigned_float:X87MODEF
5301              (match_operand:SI 1 "nonimmediate_operand")))
5302       (clobber (match_scratch:DI 3))
5303       (clobber (match_dup 2))])]
5304   "!TARGET_64BIT
5305    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5306         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5307        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5309   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5310     {
5311       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5312       DONE;
5313     }
5314   else
5315     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5318 (define_expand "floatunsdisf2"
5319   [(use (match_operand:SF 0 "register_operand"))
5320    (use (match_operand:DI 1 "nonimmediate_operand"))]
5321   "TARGET_64BIT && TARGET_SSE_MATH"
5322   "x86_emit_floatuns (operands); DONE;")
5324 (define_expand "floatunsdidf2"
5325   [(use (match_operand:DF 0 "register_operand"))
5326    (use (match_operand:DI 1 "nonimmediate_operand"))]
5327   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5328    && TARGET_SSE2 && TARGET_SSE_MATH"
5330   if (TARGET_64BIT)
5331     x86_emit_floatuns (operands);
5332   else
5333     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5334   DONE;
5337 ;; Load effective address instructions
5339 (define_insn_and_split "*lea<mode>"
5340   [(set (match_operand:SWI48 0 "register_operand" "=r")
5341         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5342   ""
5344   if (SImode_address_operand (operands[1], VOIDmode))
5345     {
5346       gcc_assert (TARGET_64BIT);
5347       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5348     }
5349   else 
5350     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5352   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5353   [(const_int 0)]
5355   machine_mode mode = <MODE>mode;
5356   rtx pat;
5358   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5359      change operands[] array behind our back.  */
5360   pat = PATTERN (curr_insn);
5362   operands[0] = SET_DEST (pat);
5363   operands[1] = SET_SRC (pat);
5365   /* Emit all operations in SImode for zero-extended addresses.  */
5366   if (SImode_address_operand (operands[1], VOIDmode))
5367     mode = SImode;
5369   ix86_split_lea_for_addr (curr_insn, operands, mode);
5371   /* Zero-extend return register to DImode for zero-extended addresses.  */
5372   if (mode != <MODE>mode)
5373     emit_insn (gen_zero_extendsidi2
5374                (operands[0], gen_lowpart (mode, operands[0])));
5376   DONE;
5378   [(set_attr "type" "lea")
5379    (set (attr "mode")
5380      (if_then_else
5381        (match_operand 1 "SImode_address_operand")
5382        (const_string "SI")
5383        (const_string "<MODE>")))])
5385 ;; Add instructions
5387 (define_expand "add<mode>3"
5388   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5389         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5390                     (match_operand:SDWIM 2 "<general_operand>")))]
5391   ""
5392   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5394 (define_insn_and_split "*add<dwi>3_doubleword"
5395   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5396         (plus:<DWI>
5397           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5398           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5399    (clobber (reg:CC FLAGS_REG))]
5400   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5401   "#"
5402   "reload_completed"
5403   [(parallel [(set (reg:CCC FLAGS_REG)
5404                    (compare:CCC
5405                      (plus:DWIH (match_dup 1) (match_dup 2))
5406                      (match_dup 1)))
5407               (set (match_dup 0)
5408                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5409    (parallel [(set (match_dup 3)
5410                    (plus:DWIH
5411                      (plus:DWIH
5412                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5413                        (match_dup 4))
5414                      (match_dup 5)))
5415               (clobber (reg:CC FLAGS_REG))])]
5416   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5418 (define_insn "*add<mode>_1"
5419   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5420         (plus:SWI48
5421           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5422           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5423    (clobber (reg:CC FLAGS_REG))]
5424   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5426   switch (get_attr_type (insn))
5427     {
5428     case TYPE_LEA:
5429       return "#";
5431     case TYPE_INCDEC:
5432       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5433       if (operands[2] == const1_rtx)
5434         return "inc{<imodesuffix>}\t%0";
5435       else
5436         {
5437           gcc_assert (operands[2] == constm1_rtx);
5438           return "dec{<imodesuffix>}\t%0";
5439         }
5441     default:
5442       /* For most processors, ADD is faster than LEA.  This alternative
5443          was added to use ADD as much as possible.  */
5444       if (which_alternative == 2)
5445         std::swap (operands[1], operands[2]);
5446         
5447       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5448       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5449         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5451       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5452     }
5454   [(set (attr "type")
5455      (cond [(eq_attr "alternative" "3")
5456               (const_string "lea")
5457             (match_operand:SWI48 2 "incdec_operand")
5458               (const_string "incdec")
5459            ]
5460            (const_string "alu")))
5461    (set (attr "length_immediate")
5462       (if_then_else
5463         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5464         (const_string "1")
5465         (const_string "*")))
5466    (set_attr "mode" "<MODE>")])
5468 ;; It may seem that nonimmediate operand is proper one for operand 1.
5469 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5470 ;; we take care in ix86_binary_operator_ok to not allow two memory
5471 ;; operands so proper swapping will be done in reload.  This allow
5472 ;; patterns constructed from addsi_1 to match.
5474 (define_insn "addsi_1_zext"
5475   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5476         (zero_extend:DI
5477           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5478                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5479    (clobber (reg:CC FLAGS_REG))]
5480   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482   switch (get_attr_type (insn))
5483     {
5484     case TYPE_LEA:
5485       return "#";
5487     case TYPE_INCDEC:
5488       if (operands[2] == const1_rtx)
5489         return "inc{l}\t%k0";
5490       else
5491         {
5492           gcc_assert (operands[2] == constm1_rtx);
5493           return "dec{l}\t%k0";
5494         }
5496     default:
5497       /* For most processors, ADD is faster than LEA.  This alternative
5498          was added to use ADD as much as possible.  */
5499       if (which_alternative == 1)
5500         std::swap (operands[1], operands[2]);
5502       if (x86_maybe_negate_const_int (&operands[2], SImode))
5503         return "sub{l}\t{%2, %k0|%k0, %2}";
5505       return "add{l}\t{%2, %k0|%k0, %2}";
5506     }
5508   [(set (attr "type")
5509      (cond [(eq_attr "alternative" "2")
5510               (const_string "lea")
5511             (match_operand:SI 2 "incdec_operand")
5512               (const_string "incdec")
5513            ]
5514            (const_string "alu")))
5515    (set (attr "length_immediate")
5516       (if_then_else
5517         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5518         (const_string "1")
5519         (const_string "*")))
5520    (set_attr "mode" "SI")])
5522 (define_insn "*addhi_1"
5523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5524         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5525                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5526    (clobber (reg:CC FLAGS_REG))]
5527   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5529   switch (get_attr_type (insn))
5530     {
5531     case TYPE_LEA:
5532       return "#";
5534     case TYPE_INCDEC:
5535       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5536       if (operands[2] == const1_rtx)
5537         return "inc{w}\t%0";
5538       else
5539         {
5540           gcc_assert (operands[2] == constm1_rtx);
5541           return "dec{w}\t%0";
5542         }
5544     default:
5545       /* For most processors, ADD is faster than LEA.  This alternative
5546          was added to use ADD as much as possible.  */
5547       if (which_alternative == 2)
5548         std::swap (operands[1], operands[2]);
5550       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5551       if (x86_maybe_negate_const_int (&operands[2], HImode))
5552         return "sub{w}\t{%2, %0|%0, %2}";
5554       return "add{w}\t{%2, %0|%0, %2}";
5555     }
5557   [(set (attr "type")
5558      (cond [(eq_attr "alternative" "3")
5559               (const_string "lea")
5560             (match_operand:HI 2 "incdec_operand")
5561               (const_string "incdec")
5562            ]
5563            (const_string "alu")))
5564    (set (attr "length_immediate")
5565       (if_then_else
5566         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5567         (const_string "1")
5568         (const_string "*")))
5569    (set_attr "mode" "HI,HI,HI,SI")])
5571 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5572 (define_insn "*addqi_1"
5573   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5574         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5575                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5576    (clobber (reg:CC FLAGS_REG))]
5577   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5579   bool widen = (which_alternative == 3 || which_alternative == 4);
5581   switch (get_attr_type (insn))
5582     {
5583     case TYPE_LEA:
5584       return "#";
5586     case TYPE_INCDEC:
5587       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5588       if (operands[2] == const1_rtx)
5589         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5590       else
5591         {
5592           gcc_assert (operands[2] == constm1_rtx);
5593           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5594         }
5596     default:
5597       /* For most processors, ADD is faster than LEA.  These alternatives
5598          were added to use ADD as much as possible.  */
5599       if (which_alternative == 2 || which_alternative == 4)
5600         std::swap (operands[1], operands[2]);
5602       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5603       if (x86_maybe_negate_const_int (&operands[2], QImode))
5604         {
5605           if (widen)
5606             return "sub{l}\t{%2, %k0|%k0, %2}";
5607           else
5608             return "sub{b}\t{%2, %0|%0, %2}";
5609         }
5610       if (widen)
5611         return "add{l}\t{%k2, %k0|%k0, %k2}";
5612       else
5613         return "add{b}\t{%2, %0|%0, %2}";
5614     }
5616   [(set (attr "type")
5617      (cond [(eq_attr "alternative" "5")
5618               (const_string "lea")
5619             (match_operand:QI 2 "incdec_operand")
5620               (const_string "incdec")
5621            ]
5622            (const_string "alu")))
5623    (set (attr "length_immediate")
5624       (if_then_else
5625         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5626         (const_string "1")
5627         (const_string "*")))
5628    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5630 (define_insn "*addqi_1_slp"
5631   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5632         (plus:QI (match_dup 0)
5633                  (match_operand:QI 1 "general_operand" "qn,qm")))
5634    (clobber (reg:CC FLAGS_REG))]
5635   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5636    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5638   switch (get_attr_type (insn))
5639     {
5640     case TYPE_INCDEC:
5641       if (operands[1] == const1_rtx)
5642         return "inc{b}\t%0";
5643       else
5644         {
5645           gcc_assert (operands[1] == constm1_rtx);
5646           return "dec{b}\t%0";
5647         }
5649     default:
5650       if (x86_maybe_negate_const_int (&operands[1], QImode))
5651         return "sub{b}\t{%1, %0|%0, %1}";
5653       return "add{b}\t{%1, %0|%0, %1}";
5654     }
5656   [(set (attr "type")
5657      (if_then_else (match_operand:QI 1 "incdec_operand")
5658         (const_string "incdec")
5659         (const_string "alu1")))
5660    (set (attr "memory")
5661      (if_then_else (match_operand 1 "memory_operand")
5662         (const_string "load")
5663         (const_string "none")))
5664    (set_attr "mode" "QI")])
5666 ;; Split non destructive adds if we cannot use lea.
5667 (define_split
5668   [(set (match_operand:SWI48 0 "register_operand")
5669         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5670                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5671    (clobber (reg:CC FLAGS_REG))]
5672   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5673   [(set (match_dup 0) (match_dup 1))
5674    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5675               (clobber (reg:CC FLAGS_REG))])])
5677 ;; Convert add to the lea pattern to avoid flags dependency.
5678 (define_split
5679   [(set (match_operand:SWI 0 "register_operand")
5680         (plus:SWI (match_operand:SWI 1 "register_operand")
5681                   (match_operand:SWI 2 "<nonmemory_operand>")))
5682    (clobber (reg:CC FLAGS_REG))]
5683   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5684   [(const_int 0)]
5686   machine_mode mode = <MODE>mode;
5687   rtx pat;
5689   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5690     { 
5691       mode = SImode; 
5692       operands[0] = gen_lowpart (mode, operands[0]);
5693       operands[1] = gen_lowpart (mode, operands[1]);
5694       operands[2] = gen_lowpart (mode, operands[2]);
5695     }
5697   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5699   emit_insn (gen_rtx_SET (operands[0], pat));
5700   DONE;
5703 ;; Split non destructive adds if we cannot use lea.
5704 (define_split
5705   [(set (match_operand:DI 0 "register_operand")
5706         (zero_extend:DI
5707           (plus:SI (match_operand:SI 1 "register_operand")
5708                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5709    (clobber (reg:CC FLAGS_REG))]
5710   "TARGET_64BIT
5711    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5712   [(set (match_dup 3) (match_dup 1))
5713    (parallel [(set (match_dup 0)
5714                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5715               (clobber (reg:CC FLAGS_REG))])]
5716   "operands[3] = gen_lowpart (SImode, operands[0]);")
5718 ;; Convert add to the lea pattern to avoid flags dependency.
5719 (define_split
5720   [(set (match_operand:DI 0 "register_operand")
5721         (zero_extend:DI
5722           (plus:SI (match_operand:SI 1 "register_operand")
5723                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5724    (clobber (reg:CC FLAGS_REG))]
5725   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5726   [(set (match_dup 0)
5727         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5729 (define_insn "*add<mode>_2"
5730   [(set (reg FLAGS_REG)
5731         (compare
5732           (plus:SWI
5733             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5734             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5735           (const_int 0)))
5736    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5737         (plus:SWI (match_dup 1) (match_dup 2)))]
5738   "ix86_match_ccmode (insn, CCGOCmode)
5739    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5741   switch (get_attr_type (insn))
5742     {
5743     case TYPE_INCDEC:
5744       if (operands[2] == const1_rtx)
5745         return "inc{<imodesuffix>}\t%0";
5746       else
5747         {
5748           gcc_assert (operands[2] == constm1_rtx);
5749           return "dec{<imodesuffix>}\t%0";
5750         }
5752     default:
5753       if (which_alternative == 2)
5754         std::swap (operands[1], operands[2]);
5755         
5756       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5757       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5758         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5760       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5761     }
5763   [(set (attr "type")
5764      (if_then_else (match_operand:SWI 2 "incdec_operand")
5765         (const_string "incdec")
5766         (const_string "alu")))
5767    (set (attr "length_immediate")
5768       (if_then_else
5769         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5770         (const_string "1")
5771         (const_string "*")))
5772    (set_attr "mode" "<MODE>")])
5774 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5775 (define_insn "*addsi_2_zext"
5776   [(set (reg FLAGS_REG)
5777         (compare
5778           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5779                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5780           (const_int 0)))
5781    (set (match_operand:DI 0 "register_operand" "=r,r")
5782         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5783   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5784    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5786   switch (get_attr_type (insn))
5787     {
5788     case TYPE_INCDEC:
5789       if (operands[2] == const1_rtx)
5790         return "inc{l}\t%k0";
5791       else
5792         {
5793           gcc_assert (operands[2] == constm1_rtx);
5794           return "dec{l}\t%k0";
5795         }
5797     default:
5798       if (which_alternative == 1)
5799         std::swap (operands[1], operands[2]);
5801       if (x86_maybe_negate_const_int (&operands[2], SImode))
5802         return "sub{l}\t{%2, %k0|%k0, %2}";
5804       return "add{l}\t{%2, %k0|%k0, %2}";
5805     }
5807   [(set (attr "type")
5808      (if_then_else (match_operand:SI 2 "incdec_operand")
5809         (const_string "incdec")
5810         (const_string "alu")))
5811    (set (attr "length_immediate")
5812       (if_then_else
5813         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5814         (const_string "1")
5815         (const_string "*")))
5816    (set_attr "mode" "SI")])
5818 (define_insn "*add<mode>_3"
5819   [(set (reg FLAGS_REG)
5820         (compare
5821           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5822           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5823    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5824   "ix86_match_ccmode (insn, CCZmode)
5825    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5827   switch (get_attr_type (insn))
5828     {
5829     case TYPE_INCDEC:
5830       if (operands[2] == const1_rtx)
5831         return "inc{<imodesuffix>}\t%0";
5832       else
5833         {
5834           gcc_assert (operands[2] == constm1_rtx);
5835           return "dec{<imodesuffix>}\t%0";
5836         }
5838     default:
5839       if (which_alternative == 1)
5840         std::swap (operands[1], operands[2]);
5842       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5844         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5846       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5847     }
5849   [(set (attr "type")
5850      (if_then_else (match_operand:SWI 2 "incdec_operand")
5851         (const_string "incdec")
5852         (const_string "alu")))
5853    (set (attr "length_immediate")
5854       (if_then_else
5855         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5856         (const_string "1")
5857         (const_string "*")))
5858    (set_attr "mode" "<MODE>")])
5860 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5861 (define_insn "*addsi_3_zext"
5862   [(set (reg FLAGS_REG)
5863         (compare
5864           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5865           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5866    (set (match_operand:DI 0 "register_operand" "=r,r")
5867         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5869    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_INCDEC:
5874       if (operands[2] == const1_rtx)
5875         return "inc{l}\t%k0";
5876       else
5877         {
5878           gcc_assert (operands[2] == constm1_rtx);
5879           return "dec{l}\t%k0";
5880         }
5882     default:
5883       if (which_alternative == 1)
5884         std::swap (operands[1], operands[2]);
5886       if (x86_maybe_negate_const_int (&operands[2], SImode))
5887         return "sub{l}\t{%2, %k0|%k0, %2}";
5889       return "add{l}\t{%2, %k0|%k0, %2}";
5890     }
5892   [(set (attr "type")
5893      (if_then_else (match_operand:SI 2 "incdec_operand")
5894         (const_string "incdec")
5895         (const_string "alu")))
5896    (set (attr "length_immediate")
5897       (if_then_else
5898         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5899         (const_string "1")
5900         (const_string "*")))
5901    (set_attr "mode" "SI")])
5903 ; For comparisons against 1, -1 and 128, we may generate better code
5904 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5905 ; is matched then.  We can't accept general immediate, because for
5906 ; case of overflows,  the result is messed up.
5907 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5908 ; only for comparisons not depending on it.
5910 (define_insn "*adddi_4"
5911   [(set (reg FLAGS_REG)
5912         (compare
5913           (match_operand:DI 1 "nonimmediate_operand" "0")
5914           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5915    (clobber (match_scratch:DI 0 "=rm"))]
5916   "TARGET_64BIT
5917    && ix86_match_ccmode (insn, CCGCmode)"
5919   switch (get_attr_type (insn))
5920     {
5921     case TYPE_INCDEC:
5922       if (operands[2] == constm1_rtx)
5923         return "inc{q}\t%0";
5924       else
5925         {
5926           gcc_assert (operands[2] == const1_rtx);
5927           return "dec{q}\t%0";
5928         }
5930     default:
5931       if (x86_maybe_negate_const_int (&operands[2], DImode))
5932         return "add{q}\t{%2, %0|%0, %2}";
5934       return "sub{q}\t{%2, %0|%0, %2}";
5935     }
5937   [(set (attr "type")
5938      (if_then_else (match_operand:DI 2 "incdec_operand")
5939         (const_string "incdec")
5940         (const_string "alu")))
5941    (set (attr "length_immediate")
5942       (if_then_else
5943         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5944         (const_string "1")
5945         (const_string "*")))
5946    (set_attr "mode" "DI")])
5948 ; For comparisons against 1, -1 and 128, we may generate better code
5949 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5950 ; is matched then.  We can't accept general immediate, because for
5951 ; case of overflows,  the result is messed up.
5952 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5953 ; only for comparisons not depending on it.
5955 (define_insn "*add<mode>_4"
5956   [(set (reg FLAGS_REG)
5957         (compare
5958           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5959           (match_operand:SWI124 2 "const_int_operand" "n")))
5960    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5961   "ix86_match_ccmode (insn, CCGCmode)"
5963   switch (get_attr_type (insn))
5964     {
5965     case TYPE_INCDEC:
5966       if (operands[2] == constm1_rtx)
5967         return "inc{<imodesuffix>}\t%0";
5968       else
5969         {
5970           gcc_assert (operands[2] == const1_rtx);
5971           return "dec{<imodesuffix>}\t%0";
5972         }
5974     default:
5975       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5976         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5978       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5979     }
5981   [(set (attr "type")
5982      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5983         (const_string "incdec")
5984         (const_string "alu")))
5985    (set (attr "length_immediate")
5986       (if_then_else
5987         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5988         (const_string "1")
5989         (const_string "*")))
5990    (set_attr "mode" "<MODE>")])
5992 (define_insn "*add<mode>_5"
5993   [(set (reg FLAGS_REG)
5994         (compare
5995           (plus:SWI
5996             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5997             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5998           (const_int 0)))
5999    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6000   "ix86_match_ccmode (insn, CCGOCmode)
6001    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6003   switch (get_attr_type (insn))
6004     {
6005     case TYPE_INCDEC:
6006       if (operands[2] == const1_rtx)
6007         return "inc{<imodesuffix>}\t%0";
6008       else
6009         {
6010           gcc_assert (operands[2] == constm1_rtx);
6011           return "dec{<imodesuffix>}\t%0";
6012         }
6014     default:
6015       if (which_alternative == 1)
6016         std::swap (operands[1], operands[2]);
6018       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6019       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6020         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6022       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6023     }
6025   [(set (attr "type")
6026      (if_then_else (match_operand:SWI 2 "incdec_operand")
6027         (const_string "incdec")
6028         (const_string "alu")))
6029    (set (attr "length_immediate")
6030       (if_then_else
6031         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6032         (const_string "1")
6033         (const_string "*")))
6034    (set_attr "mode" "<MODE>")])
6036 (define_insn "addqi_ext_1"
6037   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6038                          (const_int 8)
6039                          (const_int 8))
6040         (plus:SI
6041           (zero_extract:SI
6042             (match_operand 1 "ext_register_operand" "0,0")
6043             (const_int 8)
6044             (const_int 8))
6045           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6046    (clobber (reg:CC FLAGS_REG))]
6047   ""
6049   switch (get_attr_type (insn))
6050     {
6051     case TYPE_INCDEC:
6052       if (operands[2] == const1_rtx)
6053         return "inc{b}\t%h0";
6054       else
6055         {
6056           gcc_assert (operands[2] == constm1_rtx);
6057           return "dec{b}\t%h0";
6058         }
6060     default:
6061       return "add{b}\t{%2, %h0|%h0, %2}";
6062     }
6064   [(set_attr "isa" "*,nox64")
6065    (set (attr "type")
6066      (if_then_else (match_operand:QI 2 "incdec_operand")
6067         (const_string "incdec")
6068         (const_string "alu")))
6069    (set_attr "modrm" "1")
6070    (set_attr "mode" "QI")])
6072 (define_insn "*addqi_ext_2"
6073   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6074                          (const_int 8)
6075                          (const_int 8))
6076         (plus:SI
6077           (zero_extract:SI
6078             (match_operand 1 "ext_register_operand" "%0")
6079             (const_int 8)
6080             (const_int 8))
6081           (zero_extract:SI
6082             (match_operand 2 "ext_register_operand" "Q")
6083             (const_int 8)
6084             (const_int 8))))
6085    (clobber (reg:CC FLAGS_REG))]
6086   ""
6087   "add{b}\t{%h2, %h0|%h0, %h2}"
6088   [(set_attr "type" "alu")
6089    (set_attr "mode" "QI")])
6091 ;; Add with jump on overflow.
6092 (define_expand "addv<mode>4"
6093   [(parallel [(set (reg:CCO FLAGS_REG)
6094                    (eq:CCO (plus:<DWI>
6095                               (sign_extend:<DWI>
6096                                  (match_operand:SWI 1 "nonimmediate_operand"))
6097                               (match_dup 4))
6098                            (sign_extend:<DWI>
6099                               (plus:SWI (match_dup 1)
6100                                         (match_operand:SWI 2
6101                                            "<general_operand>")))))
6102               (set (match_operand:SWI 0 "register_operand")
6103                    (plus:SWI (match_dup 1) (match_dup 2)))])
6104    (set (pc) (if_then_else
6105                (eq (reg:CCO FLAGS_REG) (const_int 0))
6106                (label_ref (match_operand 3))
6107                (pc)))]
6108   ""
6110   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6111   if (CONST_INT_P (operands[2]))
6112     operands[4] = operands[2];
6113   else
6114     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6117 (define_insn "*addv<mode>4"
6118   [(set (reg:CCO FLAGS_REG)
6119         (eq:CCO (plus:<DWI>
6120                    (sign_extend:<DWI>
6121                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6122                    (sign_extend:<DWI>
6123                       (match_operand:SWI 2 "<general_sext_operand>"
6124                                            "<r>mWe,<r>We")))
6125                 (sign_extend:<DWI>
6126                    (plus:SWI (match_dup 1) (match_dup 2)))))
6127    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6128         (plus:SWI (match_dup 1) (match_dup 2)))]
6129   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6130   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6131   [(set_attr "type" "alu")
6132    (set_attr "mode" "<MODE>")])
6134 (define_insn "*addv<mode>4_1"
6135   [(set (reg:CCO FLAGS_REG)
6136         (eq:CCO (plus:<DWI>
6137                    (sign_extend:<DWI>
6138                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6139                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6140                 (sign_extend:<DWI>
6141                    (plus:SWI (match_dup 1)
6142                              (match_operand:SWI 2 "x86_64_immediate_operand"
6143                                                   "<i>")))))
6144    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6145         (plus:SWI (match_dup 1) (match_dup 2)))]
6146   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6147    && CONST_INT_P (operands[2])
6148    && INTVAL (operands[2]) == INTVAL (operands[3])"
6149   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6150   [(set_attr "type" "alu")
6151    (set_attr "mode" "<MODE>")
6152    (set (attr "length_immediate")
6153         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6154                   (const_string "1")
6155                (match_test "<MODE_SIZE> == 8")
6156                   (const_string "4")]
6157               (const_string "<MODE_SIZE>")))])
6159 (define_expand "uaddv<mode>4"
6160   [(parallel [(set (reg:CCC FLAGS_REG)
6161                    (compare:CCC
6162                      (plus:SWI
6163                        (match_operand:SWI 1 "nonimmediate_operand")
6164                        (match_operand:SWI 2 "<general_operand>"))
6165                      (match_dup 1)))
6166               (set (match_operand:SWI 0 "register_operand")
6167                    (plus:SWI (match_dup 1) (match_dup 2)))])
6168    (set (pc) (if_then_else
6169                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6170                (label_ref (match_operand 3))
6171                (pc)))]
6172   ""
6173   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6175 ;; The lea patterns for modes less than 32 bits need to be matched by
6176 ;; several insns converted to real lea by splitters.
6178 (define_insn_and_split "*lea_general_1"
6179   [(set (match_operand 0 "register_operand" "=r")
6180         (plus (plus (match_operand 1 "index_register_operand" "l")
6181                     (match_operand 2 "register_operand" "r"))
6182               (match_operand 3 "immediate_operand" "i")))]
6183   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6184    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6185    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6186    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6187    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6188        || GET_MODE (operands[3]) == VOIDmode)"
6189   "#"
6190   "&& reload_completed"
6191   [(const_int 0)]
6193   machine_mode mode = SImode;
6194   rtx pat;
6196   operands[0] = gen_lowpart (mode, operands[0]);
6197   operands[1] = gen_lowpart (mode, operands[1]);
6198   operands[2] = gen_lowpart (mode, operands[2]);
6199   operands[3] = gen_lowpart (mode, operands[3]);
6201   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6202                       operands[3]);
6204   emit_insn (gen_rtx_SET (operands[0], pat));
6205   DONE;
6207   [(set_attr "type" "lea")
6208    (set_attr "mode" "SI")])
6210 (define_insn_and_split "*lea_general_2"
6211   [(set (match_operand 0 "register_operand" "=r")
6212         (plus (mult (match_operand 1 "index_register_operand" "l")
6213                     (match_operand 2 "const248_operand" "n"))
6214               (match_operand 3 "nonmemory_operand" "ri")))]
6215   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6216    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6217    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6218    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6219        || GET_MODE (operands[3]) == VOIDmode)"
6220   "#"
6221   "&& reload_completed"
6222   [(const_int 0)]
6224   machine_mode mode = SImode;
6225   rtx pat;
6227   operands[0] = gen_lowpart (mode, operands[0]);
6228   operands[1] = gen_lowpart (mode, operands[1]);
6229   operands[3] = gen_lowpart (mode, operands[3]);
6231   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6232                       operands[3]);
6234   emit_insn (gen_rtx_SET (operands[0], pat));
6235   DONE;
6237   [(set_attr "type" "lea")
6238    (set_attr "mode" "SI")])
6240 (define_insn_and_split "*lea_general_3"
6241   [(set (match_operand 0 "register_operand" "=r")
6242         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6243                           (match_operand 2 "const248_operand" "n"))
6244                     (match_operand 3 "register_operand" "r"))
6245               (match_operand 4 "immediate_operand" "i")))]
6246   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6247    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6248    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6249    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6250   "#"
6251   "&& reload_completed"
6252   [(const_int 0)]
6254   machine_mode mode = SImode;
6255   rtx pat;
6257   operands[0] = gen_lowpart (mode, operands[0]);
6258   operands[1] = gen_lowpart (mode, operands[1]);
6259   operands[3] = gen_lowpart (mode, operands[3]);
6260   operands[4] = gen_lowpart (mode, operands[4]);
6262   pat = gen_rtx_PLUS (mode,
6263                       gen_rtx_PLUS (mode,
6264                                     gen_rtx_MULT (mode, operands[1],
6265                                                         operands[2]),
6266                                     operands[3]),
6267                       operands[4]);
6269   emit_insn (gen_rtx_SET (operands[0], pat));
6270   DONE;
6272   [(set_attr "type" "lea")
6273    (set_attr "mode" "SI")])
6275 (define_insn_and_split "*lea_general_4"
6276   [(set (match_operand 0 "register_operand" "=r")
6277         (any_or (ashift
6278                   (match_operand 1 "index_register_operand" "l")
6279                   (match_operand 2 "const_int_operand" "n"))
6280                 (match_operand 3 "const_int_operand" "n")))]
6281   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6282       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6283     || GET_MODE (operands[0]) == SImode
6284     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6285    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6286    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6287    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6288        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6289   "#"
6290   "&& reload_completed"
6291   [(const_int 0)]
6293   machine_mode mode = GET_MODE (operands[0]);
6294   rtx pat;
6296   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6297     { 
6298       mode = SImode; 
6299       operands[0] = gen_lowpart (mode, operands[0]);
6300       operands[1] = gen_lowpart (mode, operands[1]);
6301     }
6303   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6305   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6306                        INTVAL (operands[3]));
6308   emit_insn (gen_rtx_SET (operands[0], pat));
6309   DONE;
6311   [(set_attr "type" "lea")
6312    (set (attr "mode")
6313       (if_then_else (match_operand:DI 0)
6314         (const_string "DI")
6315         (const_string "SI")))])
6317 ;; Subtract instructions
6319 (define_expand "sub<mode>3"
6320   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6321         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6322                      (match_operand:SDWIM 2 "<general_operand>")))]
6323   ""
6324   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6326 (define_insn_and_split "*sub<dwi>3_doubleword"
6327   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6328         (minus:<DWI>
6329           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6330           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6331    (clobber (reg:CC FLAGS_REG))]
6332   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6333   "#"
6334   "reload_completed"
6335   [(parallel [(set (reg:CC FLAGS_REG)
6336                    (compare:CC (match_dup 1) (match_dup 2)))
6337               (set (match_dup 0)
6338                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6339    (parallel [(set (match_dup 3)
6340                    (minus:DWIH
6341                      (minus:DWIH
6342                        (match_dup 4)
6343                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6344                      (match_dup 5)))
6345               (clobber (reg:CC FLAGS_REG))])]
6346   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6348 (define_insn "*sub<mode>_1"
6349   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6350         (minus:SWI
6351           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6352           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6353    (clobber (reg:CC FLAGS_REG))]
6354   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6355   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6356   [(set_attr "type" "alu")
6357    (set_attr "mode" "<MODE>")])
6359 (define_insn "*subsi_1_zext"
6360   [(set (match_operand:DI 0 "register_operand" "=r")
6361         (zero_extend:DI
6362           (minus:SI (match_operand:SI 1 "register_operand" "0")
6363                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6364    (clobber (reg:CC FLAGS_REG))]
6365   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6366   "sub{l}\t{%2, %k0|%k0, %2}"
6367   [(set_attr "type" "alu")
6368    (set_attr "mode" "SI")])
6370 (define_insn "*subqi_1_slp"
6371   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6372         (minus:QI (match_dup 0)
6373                   (match_operand:QI 1 "general_operand" "qn,qm")))
6374    (clobber (reg:CC FLAGS_REG))]
6375   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6376    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6377   "sub{b}\t{%1, %0|%0, %1}"
6378   [(set_attr "type" "alu1")
6379    (set_attr "mode" "QI")])
6381 (define_insn "*sub<mode>_2"
6382   [(set (reg FLAGS_REG)
6383         (compare
6384           (minus:SWI
6385             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6386             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6387           (const_int 0)))
6388    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6389         (minus:SWI (match_dup 1) (match_dup 2)))]
6390   "ix86_match_ccmode (insn, CCGOCmode)
6391    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6392   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6393   [(set_attr "type" "alu")
6394    (set_attr "mode" "<MODE>")])
6396 (define_insn "*subsi_2_zext"
6397   [(set (reg FLAGS_REG)
6398         (compare
6399           (minus:SI (match_operand:SI 1 "register_operand" "0")
6400                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6401           (const_int 0)))
6402    (set (match_operand:DI 0 "register_operand" "=r")
6403         (zero_extend:DI
6404           (minus:SI (match_dup 1)
6405                     (match_dup 2))))]
6406   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6407    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6408   "sub{l}\t{%2, %k0|%k0, %2}"
6409   [(set_attr "type" "alu")
6410    (set_attr "mode" "SI")])
6412 ;; Subtract with jump on overflow.
6413 (define_expand "subv<mode>4"
6414   [(parallel [(set (reg:CCO FLAGS_REG)
6415                    (eq:CCO (minus:<DWI>
6416                               (sign_extend:<DWI>
6417                                  (match_operand:SWI 1 "nonimmediate_operand"))
6418                               (match_dup 4))
6419                            (sign_extend:<DWI>
6420                               (minus:SWI (match_dup 1)
6421                                          (match_operand:SWI 2
6422                                             "<general_operand>")))))
6423               (set (match_operand:SWI 0 "register_operand")
6424                    (minus:SWI (match_dup 1) (match_dup 2)))])
6425    (set (pc) (if_then_else
6426                (eq (reg:CCO FLAGS_REG) (const_int 0))
6427                (label_ref (match_operand 3))
6428                (pc)))]
6429   ""
6431   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6432   if (CONST_INT_P (operands[2]))
6433     operands[4] = operands[2];
6434   else
6435     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6438 (define_insn "*subv<mode>4"
6439   [(set (reg:CCO FLAGS_REG)
6440         (eq:CCO (minus:<DWI>
6441                    (sign_extend:<DWI>
6442                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6443                    (sign_extend:<DWI>
6444                       (match_operand:SWI 2 "<general_sext_operand>"
6445                                            "<r>We,<r>m")))
6446                 (sign_extend:<DWI>
6447                    (minus:SWI (match_dup 1) (match_dup 2)))))
6448    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449         (minus:SWI (match_dup 1) (match_dup 2)))]
6450   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452   [(set_attr "type" "alu")
6453    (set_attr "mode" "<MODE>")])
6455 (define_insn "*subv<mode>4_1"
6456   [(set (reg:CCO FLAGS_REG)
6457         (eq:CCO (minus:<DWI>
6458                    (sign_extend:<DWI>
6459                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6460                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6461                 (sign_extend:<DWI>
6462                    (minus:SWI (match_dup 1)
6463                               (match_operand:SWI 2 "x86_64_immediate_operand"
6464                                                    "<i>")))))
6465    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6466         (minus:SWI (match_dup 1) (match_dup 2)))]
6467   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6468    && CONST_INT_P (operands[2])
6469    && INTVAL (operands[2]) == INTVAL (operands[3])"
6470   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6471   [(set_attr "type" "alu")
6472    (set_attr "mode" "<MODE>")
6473    (set (attr "length_immediate")
6474         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6475                   (const_string "1")
6476                (match_test "<MODE_SIZE> == 8")
6477                   (const_string "4")]
6478               (const_string "<MODE_SIZE>")))])
6480 (define_expand "usubv<mode>4"
6481   [(parallel [(set (reg:CC FLAGS_REG)
6482                    (compare:CC
6483                      (match_operand:SWI 1 "nonimmediate_operand")
6484                      (match_operand:SWI 2 "<general_operand>")))
6485               (set (match_operand:SWI 0 "register_operand")
6486                    (minus:SWI (match_dup 1) (match_dup 2)))])
6487    (set (pc) (if_then_else
6488                (ltu (reg:CC FLAGS_REG) (const_int 0))
6489                (label_ref (match_operand 3))
6490                (pc)))]
6491   ""
6492   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6494 (define_insn "*sub<mode>_3"
6495   [(set (reg FLAGS_REG)
6496         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6497                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6498    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499         (minus:SWI (match_dup 1) (match_dup 2)))]
6500   "ix86_match_ccmode (insn, CCmode)
6501    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6502   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6503   [(set_attr "type" "alu")
6504    (set_attr "mode" "<MODE>")])
6506 (define_insn "*subsi_3_zext"
6507   [(set (reg FLAGS_REG)
6508         (compare (match_operand:SI 1 "register_operand" "0")
6509                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6510    (set (match_operand:DI 0 "register_operand" "=r")
6511         (zero_extend:DI
6512           (minus:SI (match_dup 1)
6513                     (match_dup 2))))]
6514   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6515    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sub{l}\t{%2, %1|%1, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "mode" "SI")])
6520 ;; Add with carry and subtract with borrow
6522 (define_insn "add<mode>3_carry"
6523   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6524         (plus:SWI
6525           (plus:SWI
6526             (match_operator:SWI 4 "ix86_carry_flag_operator"
6527              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6528             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6529           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6532   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "use_carry" "1")
6535    (set_attr "pent_pair" "pu")
6536    (set_attr "mode" "<MODE>")])
6538 (define_insn "*addsi3_carry_zext"
6539   [(set (match_operand:DI 0 "register_operand" "=r")
6540         (zero_extend:DI
6541           (plus:SI
6542             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6543                       [(reg FLAGS_REG) (const_int 0)])
6544                      (match_operand:SI 1 "register_operand" "%0"))
6545             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6546    (clobber (reg:CC FLAGS_REG))]
6547   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6548   "adc{l}\t{%2, %k0|%k0, %2}"
6549   [(set_attr "type" "alu")
6550    (set_attr "use_carry" "1")
6551    (set_attr "pent_pair" "pu")
6552    (set_attr "mode" "SI")])
6554 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6556 (define_insn "addcarry<mode>"
6557   [(set (reg:CCC FLAGS_REG)
6558         (compare:CCC
6559           (plus:SWI48
6560             (plus:SWI48
6561               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6562                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6563               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6564             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6565           (match_dup 1)))
6566    (set (match_operand:SWI48 0 "register_operand" "=r")
6567         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6568                                  [(match_dup 3) (const_int 0)])
6569                                 (match_dup 1))
6570                     (match_dup 2)))]
6571   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6572   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6573   [(set_attr "type" "alu")
6574    (set_attr "use_carry" "1")
6575    (set_attr "pent_pair" "pu")
6576    (set_attr "mode" "<MODE>")])
6578 (define_insn "sub<mode>3_carry"
6579   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6580         (minus:SWI
6581           (minus:SWI
6582             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6583             (match_operator:SWI 4 "ix86_carry_flag_operator"
6584              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6585           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6586    (clobber (reg:CC FLAGS_REG))]
6587   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6588   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "alu")
6590    (set_attr "use_carry" "1")
6591    (set_attr "pent_pair" "pu")
6592    (set_attr "mode" "<MODE>")])
6594 (define_insn "*subsi3_carry_zext"
6595   [(set (match_operand:DI 0 "register_operand" "=r")
6596         (zero_extend:DI
6597           (minus:SI
6598             (minus:SI
6599               (match_operand:SI 1 "register_operand" "0")
6600               (match_operator:SI 3 "ix86_carry_flag_operator"
6601                [(reg FLAGS_REG) (const_int 0)]))
6602             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6605   "sbb{l}\t{%2, %k0|%k0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "use_carry" "1")
6608    (set_attr "pent_pair" "pu")
6609    (set_attr "mode" "SI")])
6611 (define_insn "subborrow<mode>"
6612   [(set (reg:CCC FLAGS_REG)
6613         (compare:CCC
6614           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6615           (plus:SWI48
6616             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6617              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6618             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6619    (set (match_operand:SWI48 0 "register_operand" "=r")
6620         (minus:SWI48 (minus:SWI48 (match_dup 1)
6621                                   (match_op_dup 4
6622                                    [(match_dup 3) (const_int 0)]))
6623                      (match_dup 2)))]
6624   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6625   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "use_carry" "1")
6628    (set_attr "pent_pair" "pu")
6629    (set_attr "mode" "<MODE>")])
6631 ;; Overflow setting add instructions
6633 (define_expand "addqi3_cconly_overflow"
6634   [(parallel
6635      [(set (reg:CCC FLAGS_REG)
6636            (compare:CCC
6637              (plus:QI
6638                (match_operand:QI 0 "nonimmediate_operand")
6639                (match_operand:QI 1 "general_operand"))
6640              (match_dup 0)))
6641       (clobber (match_scratch:QI 2))])]
6642   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6644 (define_insn "*add<mode>3_cconly_overflow_1"
6645   [(set (reg:CCC FLAGS_REG)
6646         (compare:CCC
6647           (plus:SWI
6648             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6649             (match_operand:SWI 2 "<general_operand>" "<g>"))
6650           (match_dup 1)))
6651    (clobber (match_scratch:SWI 0 "=<r>"))]
6652   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6653   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "mode" "<MODE>")])
6657 (define_insn "*add<mode>3_cconly_overflow_2"
6658   [(set (reg:CCC FLAGS_REG)
6659         (compare:CCC
6660           (plus:SWI
6661             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6662             (match_operand:SWI 2 "<general_operand>" "<g>"))
6663           (match_dup 2)))
6664    (clobber (match_scratch:SWI 0 "=<r>"))]
6665   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6666   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6667   [(set_attr "type" "alu")
6668    (set_attr "mode" "<MODE>")])
6670 (define_insn "*add<mode>3_cc_overflow_1"
6671   [(set (reg:CCC FLAGS_REG)
6672         (compare:CCC
6673             (plus:SWI
6674                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6675                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6676             (match_dup 1)))
6677    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6678         (plus:SWI (match_dup 1) (match_dup 2)))]
6679   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6680   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6681   [(set_attr "type" "alu")
6682    (set_attr "mode" "<MODE>")])
6684 (define_insn "*add<mode>3_cc_overflow_2"
6685   [(set (reg:CCC FLAGS_REG)
6686         (compare:CCC
6687             (plus:SWI
6688                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6689                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6690             (match_dup 2)))
6691    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6692         (plus:SWI (match_dup 1) (match_dup 2)))]
6693   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6694   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "<MODE>")])
6698 (define_insn "*addsi3_zext_cc_overflow_1"
6699   [(set (reg:CCC FLAGS_REG)
6700         (compare:CCC
6701           (plus:SI
6702             (match_operand:SI 1 "nonimmediate_operand" "%0")
6703             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6704           (match_dup 1)))
6705    (set (match_operand:DI 0 "register_operand" "=r")
6706         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6707   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6708   "add{l}\t{%2, %k0|%k0, %2}"
6709   [(set_attr "type" "alu")
6710    (set_attr "mode" "SI")])
6712 (define_insn "*addsi3_zext_cc_overflow_2"
6713   [(set (reg:CCC FLAGS_REG)
6714         (compare:CCC
6715           (plus:SI
6716             (match_operand:SI 1 "nonimmediate_operand" "%0")
6717             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6718           (match_dup 2)))
6719    (set (match_operand:DI 0 "register_operand" "=r")
6720         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6721   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6722   "add{l}\t{%2, %k0|%k0, %2}"
6723   [(set_attr "type" "alu")
6724    (set_attr "mode" "SI")])
6726 ;; The patterns that match these are at the end of this file.
6728 (define_expand "<plusminus_insn>xf3"
6729   [(set (match_operand:XF 0 "register_operand")
6730         (plusminus:XF
6731           (match_operand:XF 1 "register_operand")
6732           (match_operand:XF 2 "register_operand")))]
6733   "TARGET_80387")
6735 (define_expand "<plusminus_insn><mode>3"
6736   [(set (match_operand:MODEF 0 "register_operand")
6737         (plusminus:MODEF
6738           (match_operand:MODEF 1 "register_operand")
6739           (match_operand:MODEF 2 "nonimmediate_operand")))]
6740   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6741     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6743 ;; Multiply instructions
6745 (define_expand "mul<mode>3"
6746   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6747                    (mult:SWIM248
6748                      (match_operand:SWIM248 1 "register_operand")
6749                      (match_operand:SWIM248 2 "<general_operand>")))
6750               (clobber (reg:CC FLAGS_REG))])])
6752 (define_expand "mulqi3"
6753   [(parallel [(set (match_operand:QI 0 "register_operand")
6754                    (mult:QI
6755                      (match_operand:QI 1 "register_operand")
6756                      (match_operand:QI 2 "nonimmediate_operand")))
6757               (clobber (reg:CC FLAGS_REG))])]
6758   "TARGET_QIMODE_MATH")
6760 ;; On AMDFAM10
6761 ;; IMUL reg32/64, reg32/64, imm8        Direct
6762 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6763 ;; IMUL reg32/64, reg32/64, imm32       Direct
6764 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6765 ;; IMUL reg32/64, reg32/64              Direct
6766 ;; IMUL reg32/64, mem32/64              Direct
6768 ;; On BDVER1, all above IMULs use DirectPath
6770 ;; On AMDFAM10
6771 ;; IMUL reg16, reg16, imm8      VectorPath
6772 ;; IMUL reg16, mem16, imm8      VectorPath
6773 ;; IMUL reg16, reg16, imm16     VectorPath
6774 ;; IMUL reg16, mem16, imm16     VectorPath
6775 ;; IMUL reg16, reg16            Direct
6776 ;; IMUL reg16, mem16            Direct
6778 ;; On BDVER1, all HI MULs use DoublePath
6780 (define_insn "*mul<mode>3_1"
6781   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6782         (mult:SWIM248
6783           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6784           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6785    (clobber (reg:CC FLAGS_REG))]
6786   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787   "@
6788    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6789    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6790    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "imul")
6792    (set_attr "prefix_0f" "0,0,1")
6793    (set (attr "athlon_decode")
6794         (cond [(eq_attr "cpu" "athlon")
6795                   (const_string "vector")
6796                (eq_attr "alternative" "1")
6797                   (const_string "vector")
6798                (and (eq_attr "alternative" "2")
6799                     (ior (match_test "<MODE>mode == HImode")
6800                          (match_operand 1 "memory_operand")))
6801                   (const_string "vector")]
6802               (const_string "direct")))
6803    (set (attr "amdfam10_decode")
6804         (cond [(and (eq_attr "alternative" "0,1")
6805                     (ior (match_test "<MODE>mode == HImode")
6806                          (match_operand 1 "memory_operand")))
6807                   (const_string "vector")]
6808               (const_string "direct")))
6809    (set (attr "bdver1_decode")
6810         (if_then_else
6811           (match_test "<MODE>mode == HImode")
6812             (const_string "double")
6813             (const_string "direct")))
6814    (set_attr "mode" "<MODE>")])
6816 (define_insn "*mulsi3_1_zext"
6817   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6818         (zero_extend:DI
6819           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6820                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6821    (clobber (reg:CC FLAGS_REG))]
6822   "TARGET_64BIT
6823    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824   "@
6825    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6826    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6827    imul{l}\t{%2, %k0|%k0, %2}"
6828   [(set_attr "type" "imul")
6829    (set_attr "prefix_0f" "0,0,1")
6830    (set (attr "athlon_decode")
6831         (cond [(eq_attr "cpu" "athlon")
6832                   (const_string "vector")
6833                (eq_attr "alternative" "1")
6834                   (const_string "vector")
6835                (and (eq_attr "alternative" "2")
6836                     (match_operand 1 "memory_operand"))
6837                   (const_string "vector")]
6838               (const_string "direct")))
6839    (set (attr "amdfam10_decode")
6840         (cond [(and (eq_attr "alternative" "0,1")
6841                     (match_operand 1 "memory_operand"))
6842                   (const_string "vector")]
6843               (const_string "direct")))
6844    (set_attr "bdver1_decode" "direct")
6845    (set_attr "mode" "SI")])
6847 ;;On AMDFAM10 and BDVER1
6848 ;; MUL reg8     Direct
6849 ;; MUL mem8     Direct
6851 (define_insn "*mulqi3_1"
6852   [(set (match_operand:QI 0 "register_operand" "=a")
6853         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6854                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6855    (clobber (reg:CC FLAGS_REG))]
6856   "TARGET_QIMODE_MATH
6857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6858   "mul{b}\t%2"
6859   [(set_attr "type" "imul")
6860    (set_attr "length_immediate" "0")
6861    (set (attr "athlon_decode")
6862      (if_then_else (eq_attr "cpu" "athlon")
6863         (const_string "vector")
6864         (const_string "direct")))
6865    (set_attr "amdfam10_decode" "direct")
6866    (set_attr "bdver1_decode" "direct")
6867    (set_attr "mode" "QI")])
6869 ;; Multiply with jump on overflow.
6870 (define_expand "mulv<mode>4"
6871   [(parallel [(set (reg:CCO FLAGS_REG)
6872                    (eq:CCO (mult:<DWI>
6873                               (sign_extend:<DWI>
6874                                  (match_operand:SWI248 1 "register_operand"))
6875                               (match_dup 4))
6876                            (sign_extend:<DWI>
6877                               (mult:SWI248 (match_dup 1)
6878                                            (match_operand:SWI248 2
6879                                               "<general_operand>")))))
6880               (set (match_operand:SWI248 0 "register_operand")
6881                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6882    (set (pc) (if_then_else
6883                (eq (reg:CCO FLAGS_REG) (const_int 0))
6884                (label_ref (match_operand 3))
6885                (pc)))]
6886   ""
6888   if (CONST_INT_P (operands[2]))
6889     operands[4] = operands[2];
6890   else
6891     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6894 (define_insn "*mulv<mode>4"
6895   [(set (reg:CCO FLAGS_REG)
6896         (eq:CCO (mult:<DWI>
6897                    (sign_extend:<DWI>
6898                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6899                    (sign_extend:<DWI>
6900                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6901                 (sign_extend:<DWI>
6902                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6903    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6904         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6905   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906   "@
6907    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6908    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6909   [(set_attr "type" "imul")
6910    (set_attr "prefix_0f" "0,1")
6911    (set (attr "athlon_decode")
6912         (cond [(eq_attr "cpu" "athlon")
6913                   (const_string "vector")
6914                (eq_attr "alternative" "0")
6915                   (const_string "vector")
6916                (and (eq_attr "alternative" "1")
6917                     (match_operand 1 "memory_operand"))
6918                   (const_string "vector")]
6919               (const_string "direct")))
6920    (set (attr "amdfam10_decode")
6921         (cond [(and (eq_attr "alternative" "1")
6922                     (match_operand 1 "memory_operand"))
6923                   (const_string "vector")]
6924               (const_string "direct")))
6925    (set_attr "bdver1_decode" "direct")
6926    (set_attr "mode" "<MODE>")])
6928 (define_insn "*mulvhi4"
6929   [(set (reg:CCO FLAGS_REG)
6930         (eq:CCO (mult:SI
6931                    (sign_extend:SI
6932                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6933                    (sign_extend:SI
6934                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6935                 (sign_extend:SI
6936                    (mult:HI (match_dup 1) (match_dup 2)))))
6937    (set (match_operand:HI 0 "register_operand" "=r")
6938         (mult:HI (match_dup 1) (match_dup 2)))]
6939   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940   "imul{w}\t{%2, %0|%0, %2}"
6941   [(set_attr "type" "imul")
6942    (set_attr "prefix_0f" "1")
6943    (set_attr "athlon_decode" "vector")
6944    (set_attr "amdfam10_decode" "direct")
6945    (set_attr "bdver1_decode" "double")
6946    (set_attr "mode" "HI")])
6948 (define_insn "*mulv<mode>4_1"
6949   [(set (reg:CCO FLAGS_REG)
6950         (eq:CCO (mult:<DWI>
6951                    (sign_extend:<DWI>
6952                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6953                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6954                 (sign_extend:<DWI>
6955                    (mult:SWI248 (match_dup 1)
6956                                 (match_operand:SWI248 2
6957                                    "<immediate_operand>" "K,<i>")))))
6958    (set (match_operand:SWI248 0 "register_operand" "=r,r")
6959         (mult:SWI248 (match_dup 1) (match_dup 2)))]
6960   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6961    && CONST_INT_P (operands[2])
6962    && INTVAL (operands[2]) == INTVAL (operands[3])"
6963   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6964   [(set_attr "type" "imul")
6965    (set (attr "prefix_0f")
6966         (if_then_else
6967           (match_test "<MODE>mode == HImode")
6968             (const_string "0")
6969             (const_string "*")))
6970    (set (attr "athlon_decode")
6971         (cond [(eq_attr "cpu" "athlon")
6972                   (const_string "vector")
6973                (eq_attr "alternative" "1")
6974                   (const_string "vector")]
6975               (const_string "direct")))
6976    (set (attr "amdfam10_decode")
6977         (cond [(ior (match_test "<MODE>mode == HImode")
6978                     (match_operand 1 "memory_operand"))
6979                   (const_string "vector")]
6980               (const_string "direct")))
6981    (set (attr "bdver1_decode")
6982         (if_then_else
6983           (match_test "<MODE>mode == HImode")
6984             (const_string "double")
6985             (const_string "direct")))
6986    (set_attr "mode" "<MODE>")
6987    (set (attr "length_immediate")
6988         (cond [(eq_attr "alternative" "0")
6989                   (const_string "1")
6990                (match_test "<MODE_SIZE> == 8")
6991                   (const_string "4")]
6992               (const_string "<MODE_SIZE>")))])
6994 (define_expand "umulv<mode>4"
6995   [(parallel [(set (reg:CCO FLAGS_REG)
6996                    (eq:CCO (mult:<DWI>
6997                               (zero_extend:<DWI>
6998                                  (match_operand:SWI248 1
6999                                                       "nonimmediate_operand"))
7000                               (zero_extend:<DWI>
7001                                  (match_operand:SWI248 2
7002                                                       "nonimmediate_operand")))
7003                            (zero_extend:<DWI>
7004                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7005               (set (match_operand:SWI248 0 "register_operand")
7006                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7007               (clobber (match_scratch:SWI248 4))])
7008    (set (pc) (if_then_else
7009                (eq (reg:CCO FLAGS_REG) (const_int 0))
7010                (label_ref (match_operand 3))
7011                (pc)))]
7012   ""
7014   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7015     operands[1] = force_reg (<MODE>mode, operands[1]);
7018 (define_insn "*umulv<mode>4"
7019   [(set (reg:CCO FLAGS_REG)
7020         (eq:CCO (mult:<DWI>
7021                    (zero_extend:<DWI>
7022                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7023                    (zero_extend:<DWI>
7024                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7025                 (zero_extend:<DWI>
7026                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7027    (set (match_operand:SWI248 0 "register_operand" "=a")
7028         (mult:SWI248 (match_dup 1) (match_dup 2)))
7029    (clobber (match_scratch:SWI248 3 "=d"))]
7030   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031   "mul{<imodesuffix>}\t%2"
7032   [(set_attr "type" "imul")
7033    (set_attr "length_immediate" "0")
7034    (set (attr "athlon_decode")
7035      (if_then_else (eq_attr "cpu" "athlon")
7036        (const_string "vector")
7037        (const_string "double")))
7038    (set_attr "amdfam10_decode" "double")
7039    (set_attr "bdver1_decode" "direct")
7040    (set_attr "mode" "<MODE>")])
7042 (define_expand "<u>mulvqi4"
7043   [(parallel [(set (reg:CCO FLAGS_REG)
7044                    (eq:CCO (mult:HI
7045                               (any_extend:HI
7046                                  (match_operand:QI 1 "nonimmediate_operand"))
7047                               (any_extend:HI
7048                                  (match_operand:QI 2 "nonimmediate_operand")))
7049                            (any_extend:HI
7050                               (mult:QI (match_dup 1) (match_dup 2)))))
7051               (set (match_operand:QI 0 "register_operand")
7052                    (mult:QI (match_dup 1) (match_dup 2)))])
7053    (set (pc) (if_then_else
7054                (eq (reg:CCO FLAGS_REG) (const_int 0))
7055                (label_ref (match_operand 3))
7056                (pc)))]
7057   "TARGET_QIMODE_MATH"
7059   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7060     operands[1] = force_reg (QImode, operands[1]);
7063 (define_insn "*<u>mulvqi4"
7064   [(set (reg:CCO FLAGS_REG)
7065         (eq:CCO (mult:HI
7066                    (any_extend:HI
7067                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7068                    (any_extend:HI
7069                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7070                 (any_extend:HI
7071                    (mult:QI (match_dup 1) (match_dup 2)))))
7072    (set (match_operand:QI 0 "register_operand" "=a")
7073         (mult:QI (match_dup 1) (match_dup 2)))]
7074   "TARGET_QIMODE_MATH
7075    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7076   "<sgnprefix>mul{b}\t%2"
7077   [(set_attr "type" "imul")
7078    (set_attr "length_immediate" "0")
7079    (set (attr "athlon_decode")
7080      (if_then_else (eq_attr "cpu" "athlon")
7081         (const_string "vector")
7082         (const_string "direct")))
7083    (set_attr "amdfam10_decode" "direct")
7084    (set_attr "bdver1_decode" "direct")
7085    (set_attr "mode" "QI")])
7087 (define_expand "<u>mul<mode><dwi>3"
7088   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7089                    (mult:<DWI>
7090                      (any_extend:<DWI>
7091                        (match_operand:DWIH 1 "nonimmediate_operand"))
7092                      (any_extend:<DWI>
7093                        (match_operand:DWIH 2 "register_operand"))))
7094               (clobber (reg:CC FLAGS_REG))])])
7096 (define_expand "<u>mulqihi3"
7097   [(parallel [(set (match_operand:HI 0 "register_operand")
7098                    (mult:HI
7099                      (any_extend:HI
7100                        (match_operand:QI 1 "nonimmediate_operand"))
7101                      (any_extend:HI
7102                        (match_operand:QI 2 "register_operand"))))
7103               (clobber (reg:CC FLAGS_REG))])]
7104   "TARGET_QIMODE_MATH")
7106 (define_insn "*bmi2_umul<mode><dwi>3_1"
7107   [(set (match_operand:DWIH 0 "register_operand" "=r")
7108         (mult:DWIH
7109           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7110           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7111    (set (match_operand:DWIH 1 "register_operand" "=r")
7112         (truncate:DWIH
7113           (lshiftrt:<DWI>
7114             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7115                         (zero_extend:<DWI> (match_dup 3)))
7116             (match_operand:QI 4 "const_int_operand" "n"))))]
7117   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7118    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7119   "mulx\t{%3, %0, %1|%1, %0, %3}"
7120   [(set_attr "type" "imulx")
7121    (set_attr "prefix" "vex")
7122    (set_attr "mode" "<MODE>")])
7124 (define_insn "*umul<mode><dwi>3_1"
7125   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7126         (mult:<DWI>
7127           (zero_extend:<DWI>
7128             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7129           (zero_extend:<DWI>
7130             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7131    (clobber (reg:CC FLAGS_REG))]
7132   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7133   "@
7134    #
7135    mul{<imodesuffix>}\t%2"
7136   [(set_attr "isa" "bmi2,*")
7137    (set_attr "type" "imulx,imul")
7138    (set_attr "length_immediate" "*,0")
7139    (set (attr "athlon_decode")
7140         (cond [(eq_attr "alternative" "1")
7141                  (if_then_else (eq_attr "cpu" "athlon")
7142                    (const_string "vector")
7143                    (const_string "double"))]
7144               (const_string "*")))
7145    (set_attr "amdfam10_decode" "*,double")
7146    (set_attr "bdver1_decode" "*,direct")
7147    (set_attr "prefix" "vex,orig")
7148    (set_attr "mode" "<MODE>")])
7150 ;; Convert mul to the mulx pattern to avoid flags dependency.
7151 (define_split
7152  [(set (match_operand:<DWI> 0 "register_operand")
7153        (mult:<DWI>
7154          (zero_extend:<DWI>
7155            (match_operand:DWIH 1 "register_operand"))
7156          (zero_extend:<DWI>
7157            (match_operand:DWIH 2 "nonimmediate_operand"))))
7158   (clobber (reg:CC FLAGS_REG))]
7159  "TARGET_BMI2 && reload_completed
7160   && true_regnum (operands[1]) == DX_REG"
7161   [(parallel [(set (match_dup 3)
7162                    (mult:DWIH (match_dup 1) (match_dup 2)))
7163               (set (match_dup 4)
7164                    (truncate:DWIH
7165                      (lshiftrt:<DWI>
7166                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7167                                    (zero_extend:<DWI> (match_dup 2)))
7168                        (match_dup 5))))])]
7170   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7172   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7175 (define_insn "*mul<mode><dwi>3_1"
7176   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7177         (mult:<DWI>
7178           (sign_extend:<DWI>
7179             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7180           (sign_extend:<DWI>
7181             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7184   "imul{<imodesuffix>}\t%2"
7185   [(set_attr "type" "imul")
7186    (set_attr "length_immediate" "0")
7187    (set (attr "athlon_decode")
7188      (if_then_else (eq_attr "cpu" "athlon")
7189         (const_string "vector")
7190         (const_string "double")))
7191    (set_attr "amdfam10_decode" "double")
7192    (set_attr "bdver1_decode" "direct")
7193    (set_attr "mode" "<MODE>")])
7195 (define_insn "*<u>mulqihi3_1"
7196   [(set (match_operand:HI 0 "register_operand" "=a")
7197         (mult:HI
7198           (any_extend:HI
7199             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7200           (any_extend:HI
7201             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7202    (clobber (reg:CC FLAGS_REG))]
7203   "TARGET_QIMODE_MATH
7204    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7205   "<sgnprefix>mul{b}\t%2"
7206   [(set_attr "type" "imul")
7207    (set_attr "length_immediate" "0")
7208    (set (attr "athlon_decode")
7209      (if_then_else (eq_attr "cpu" "athlon")
7210         (const_string "vector")
7211         (const_string "direct")))
7212    (set_attr "amdfam10_decode" "direct")
7213    (set_attr "bdver1_decode" "direct")
7214    (set_attr "mode" "QI")])
7216 (define_expand "<s>mul<mode>3_highpart"
7217   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7218                    (truncate:SWI48
7219                      (lshiftrt:<DWI>
7220                        (mult:<DWI>
7221                          (any_extend:<DWI>
7222                            (match_operand:SWI48 1 "nonimmediate_operand"))
7223                          (any_extend:<DWI>
7224                            (match_operand:SWI48 2 "register_operand")))
7225                        (match_dup 4))))
7226               (clobber (match_scratch:SWI48 3))
7227               (clobber (reg:CC FLAGS_REG))])]
7228   ""
7229   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7231 (define_insn "*<s>muldi3_highpart_1"
7232   [(set (match_operand:DI 0 "register_operand" "=d")
7233         (truncate:DI
7234           (lshiftrt:TI
7235             (mult:TI
7236               (any_extend:TI
7237                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7238               (any_extend:TI
7239                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7240             (const_int 64))))
7241    (clobber (match_scratch:DI 3 "=1"))
7242    (clobber (reg:CC FLAGS_REG))]
7243   "TARGET_64BIT
7244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7245   "<sgnprefix>mul{q}\t%2"
7246   [(set_attr "type" "imul")
7247    (set_attr "length_immediate" "0")
7248    (set (attr "athlon_decode")
7249      (if_then_else (eq_attr "cpu" "athlon")
7250         (const_string "vector")
7251         (const_string "double")))
7252    (set_attr "amdfam10_decode" "double")
7253    (set_attr "bdver1_decode" "direct")
7254    (set_attr "mode" "DI")])
7256 (define_insn "*<s>mulsi3_highpart_1"
7257   [(set (match_operand:SI 0 "register_operand" "=d")
7258         (truncate:SI
7259           (lshiftrt:DI
7260             (mult:DI
7261               (any_extend:DI
7262                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7263               (any_extend:DI
7264                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7265             (const_int 32))))
7266    (clobber (match_scratch:SI 3 "=1"))
7267    (clobber (reg:CC FLAGS_REG))]
7268   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269   "<sgnprefix>mul{l}\t%2"
7270   [(set_attr "type" "imul")
7271    (set_attr "length_immediate" "0")
7272    (set (attr "athlon_decode")
7273      (if_then_else (eq_attr "cpu" "athlon")
7274         (const_string "vector")
7275         (const_string "double")))
7276    (set_attr "amdfam10_decode" "double")
7277    (set_attr "bdver1_decode" "direct")
7278    (set_attr "mode" "SI")])
7280 (define_insn "*<s>mulsi3_highpart_zext"
7281   [(set (match_operand:DI 0 "register_operand" "=d")
7282         (zero_extend:DI (truncate:SI
7283           (lshiftrt:DI
7284             (mult:DI (any_extend:DI
7285                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7286                      (any_extend:DI
7287                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7288             (const_int 32)))))
7289    (clobber (match_scratch:SI 3 "=1"))
7290    (clobber (reg:CC FLAGS_REG))]
7291   "TARGET_64BIT
7292    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7293   "<sgnprefix>mul{l}\t%2"
7294   [(set_attr "type" "imul")
7295    (set_attr "length_immediate" "0")
7296    (set (attr "athlon_decode")
7297      (if_then_else (eq_attr "cpu" "athlon")
7298         (const_string "vector")
7299         (const_string "double")))
7300    (set_attr "amdfam10_decode" "double")
7301    (set_attr "bdver1_decode" "direct")
7302    (set_attr "mode" "SI")])
7304 ;; The patterns that match these are at the end of this file.
7306 (define_expand "mulxf3"
7307   [(set (match_operand:XF 0 "register_operand")
7308         (mult:XF (match_operand:XF 1 "register_operand")
7309                  (match_operand:XF 2 "register_operand")))]
7310   "TARGET_80387")
7312 (define_expand "mul<mode>3"
7313   [(set (match_operand:MODEF 0 "register_operand")
7314         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7315                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7316   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7317     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7319 ;; Divide instructions
7321 ;; The patterns that match these are at the end of this file.
7323 (define_expand "divxf3"
7324   [(set (match_operand:XF 0 "register_operand")
7325         (div:XF (match_operand:XF 1 "register_operand")
7326                 (match_operand:XF 2 "register_operand")))]
7327   "TARGET_80387")
7329 (define_expand "divdf3"
7330   [(set (match_operand:DF 0 "register_operand")
7331         (div:DF (match_operand:DF 1 "register_operand")
7332                 (match_operand:DF 2 "nonimmediate_operand")))]
7333    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7334     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7336 (define_expand "divsf3"
7337   [(set (match_operand:SF 0 "register_operand")
7338         (div:SF (match_operand:SF 1 "register_operand")
7339                 (match_operand:SF 2 "nonimmediate_operand")))]
7340   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7341     || TARGET_SSE_MATH"
7343   if (TARGET_SSE_MATH
7344       && TARGET_RECIP_DIV
7345       && optimize_insn_for_speed_p ()
7346       && flag_finite_math_only && !flag_trapping_math
7347       && flag_unsafe_math_optimizations)
7348     {
7349       ix86_emit_swdivsf (operands[0], operands[1],
7350                          operands[2], SFmode);
7351       DONE;
7352     }
7355 ;; Divmod instructions.
7357 (define_expand "divmod<mode>4"
7358   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7359                    (div:SWIM248
7360                      (match_operand:SWIM248 1 "register_operand")
7361                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7362               (set (match_operand:SWIM248 3 "register_operand")
7363                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7364               (clobber (reg:CC FLAGS_REG))])])
7366 ;; Split with 8bit unsigned divide:
7367 ;;      if (dividend an divisor are in [0-255])
7368 ;;         use 8bit unsigned integer divide
7369 ;;       else
7370 ;;         use original integer divide
7371 (define_split
7372   [(set (match_operand:SWI48 0 "register_operand")
7373         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7374                     (match_operand:SWI48 3 "nonimmediate_operand")))
7375    (set (match_operand:SWI48 1 "register_operand")
7376         (mod:SWI48 (match_dup 2) (match_dup 3)))
7377    (clobber (reg:CC FLAGS_REG))]
7378   "TARGET_USE_8BIT_IDIV
7379    && TARGET_QIMODE_MATH
7380    && can_create_pseudo_p ()
7381    && !optimize_insn_for_size_p ()"
7382   [(const_int 0)]
7383   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7385 (define_insn_and_split "divmod<mode>4_1"
7386   [(set (match_operand:SWI48 0 "register_operand" "=a")
7387         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7388                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7389    (set (match_operand:SWI48 1 "register_operand" "=&d")
7390         (mod:SWI48 (match_dup 2) (match_dup 3)))
7391    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7392    (clobber (reg:CC FLAGS_REG))]
7393   ""
7394   "#"
7395   "reload_completed"
7396   [(parallel [(set (match_dup 1)
7397                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7398               (clobber (reg:CC FLAGS_REG))])
7399    (parallel [(set (match_dup 0)
7400                    (div:SWI48 (match_dup 2) (match_dup 3)))
7401               (set (match_dup 1)
7402                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7403               (use (match_dup 1))
7404               (clobber (reg:CC FLAGS_REG))])]
7406   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7408   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7409     operands[4] = operands[2];
7410   else
7411     {
7412       /* Avoid use of cltd in favor of a mov+shift.  */
7413       emit_move_insn (operands[1], operands[2]);
7414       operands[4] = operands[1];
7415     }
7417   [(set_attr "type" "multi")
7418    (set_attr "mode" "<MODE>")])
7420 (define_insn_and_split "*divmod<mode>4"
7421   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7422         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7423                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7424    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7425         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7426    (clobber (reg:CC FLAGS_REG))]
7427   ""
7428   "#"
7429   "reload_completed"
7430   [(parallel [(set (match_dup 1)
7431                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7432               (clobber (reg:CC FLAGS_REG))])
7433    (parallel [(set (match_dup 0)
7434                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7435               (set (match_dup 1)
7436                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7437               (use (match_dup 1))
7438               (clobber (reg:CC FLAGS_REG))])]
7440   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7442   if (<MODE>mode != HImode
7443       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7444     operands[4] = operands[2];
7445   else
7446     {
7447       /* Avoid use of cltd in favor of a mov+shift.  */
7448       emit_move_insn (operands[1], operands[2]);
7449       operands[4] = operands[1];
7450     }
7452   [(set_attr "type" "multi")
7453    (set_attr "mode" "<MODE>")])
7455 (define_insn "*divmod<mode>4_noext"
7456   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7457         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7458                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7459    (set (match_operand:SWIM248 1 "register_operand" "=d")
7460         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7461    (use (match_operand:SWIM248 4 "register_operand" "1"))
7462    (clobber (reg:CC FLAGS_REG))]
7463   ""
7464   "idiv{<imodesuffix>}\t%3"
7465   [(set_attr "type" "idiv")
7466    (set_attr "mode" "<MODE>")])
7468 (define_expand "divmodqi4"
7469   [(parallel [(set (match_operand:QI 0 "register_operand")
7470                    (div:QI
7471                      (match_operand:QI 1 "register_operand")
7472                      (match_operand:QI 2 "nonimmediate_operand")))
7473               (set (match_operand:QI 3 "register_operand")
7474                    (mod:QI (match_dup 1) (match_dup 2)))
7475               (clobber (reg:CC FLAGS_REG))])]
7476   "TARGET_QIMODE_MATH"
7478   rtx div, mod;
7479   rtx tmp0, tmp1;
7480   
7481   tmp0 = gen_reg_rtx (HImode);
7482   tmp1 = gen_reg_rtx (HImode);
7484   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7485      in AX.  */
7486   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7487   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7489   /* Extract remainder from AH.  */
7490   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7491   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7493   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7494   set_unique_reg_note (insn, REG_EQUAL, mod);
7496   /* Extract quotient from AL.  */
7497   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7499   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7500   set_unique_reg_note (insn, REG_EQUAL, div);
7502   DONE;
7505 ;; Divide AX by r/m8, with result stored in
7506 ;; AL <- Quotient
7507 ;; AH <- Remainder
7508 ;; Change div/mod to HImode and extend the second argument to HImode
7509 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7510 ;; combine may fail.
7511 (define_insn "divmodhiqi3"
7512   [(set (match_operand:HI 0 "register_operand" "=a")
7513         (ior:HI
7514           (ashift:HI
7515             (zero_extend:HI
7516               (truncate:QI
7517                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7518                         (sign_extend:HI
7519                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7520             (const_int 8))
7521           (zero_extend:HI
7522             (truncate:QI
7523               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7524    (clobber (reg:CC FLAGS_REG))]
7525   "TARGET_QIMODE_MATH"
7526   "idiv{b}\t%2"
7527   [(set_attr "type" "idiv")
7528    (set_attr "mode" "QI")])
7530 (define_expand "udivmod<mode>4"
7531   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7532                    (udiv:SWIM248
7533                      (match_operand:SWIM248 1 "register_operand")
7534                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7535               (set (match_operand:SWIM248 3 "register_operand")
7536                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7537               (clobber (reg:CC FLAGS_REG))])])
7539 ;; Split with 8bit unsigned divide:
7540 ;;      if (dividend an divisor are in [0-255])
7541 ;;         use 8bit unsigned integer divide
7542 ;;       else
7543 ;;         use original integer divide
7544 (define_split
7545   [(set (match_operand:SWI48 0 "register_operand")
7546         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7547                     (match_operand:SWI48 3 "nonimmediate_operand")))
7548    (set (match_operand:SWI48 1 "register_operand")
7549         (umod:SWI48 (match_dup 2) (match_dup 3)))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "TARGET_USE_8BIT_IDIV
7552    && TARGET_QIMODE_MATH
7553    && can_create_pseudo_p ()
7554    && !optimize_insn_for_size_p ()"
7555   [(const_int 0)]
7556   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7558 (define_insn_and_split "udivmod<mode>4_1"
7559   [(set (match_operand:SWI48 0 "register_operand" "=a")
7560         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7561                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7562    (set (match_operand:SWI48 1 "register_operand" "=&d")
7563         (umod:SWI48 (match_dup 2) (match_dup 3)))
7564    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7565    (clobber (reg:CC FLAGS_REG))]
7566   ""
7567   "#"
7568   "reload_completed"
7569   [(set (match_dup 1) (const_int 0))
7570    (parallel [(set (match_dup 0)
7571                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7572               (set (match_dup 1)
7573                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7574               (use (match_dup 1))
7575               (clobber (reg:CC FLAGS_REG))])]
7576   ""
7577   [(set_attr "type" "multi")
7578    (set_attr "mode" "<MODE>")])
7580 (define_insn_and_split "*udivmod<mode>4"
7581   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7582         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7583                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7584    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7585         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7586    (clobber (reg:CC FLAGS_REG))]
7587   ""
7588   "#"
7589   "reload_completed"
7590   [(set (match_dup 1) (const_int 0))
7591    (parallel [(set (match_dup 0)
7592                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7593               (set (match_dup 1)
7594                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7595               (use (match_dup 1))
7596               (clobber (reg:CC FLAGS_REG))])]
7597   ""
7598   [(set_attr "type" "multi")
7599    (set_attr "mode" "<MODE>")])
7601 ;; Optimize division or modulo by constant power of 2, if the constant
7602 ;; materializes only after expansion.
7603 (define_insn_and_split "*udivmod<mode>4_pow2"
7604   [(set (match_operand:SWI48 0 "register_operand" "=r")
7605         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7606                     (match_operand:SWI48 3 "const_int_operand" "n")))
7607    (set (match_operand:SWI48 1 "register_operand" "=r")
7608         (umod:SWI48 (match_dup 2) (match_dup 3)))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7611    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7612   "#"
7613   "&& 1"
7614   [(set (match_dup 1) (match_dup 2))
7615    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7616               (clobber (reg:CC FLAGS_REG))])
7617    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7618               (clobber (reg:CC FLAGS_REG))])]
7620   int v = exact_log2 (UINTVAL (operands[3]));
7621   operands[4] = GEN_INT (v);
7622   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7624   [(set_attr "type" "multi")
7625    (set_attr "mode" "<MODE>")])
7627 (define_insn "*udivmod<mode>4_noext"
7628   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7629         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7630                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7631    (set (match_operand:SWIM248 1 "register_operand" "=d")
7632         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7633    (use (match_operand:SWIM248 4 "register_operand" "1"))
7634    (clobber (reg:CC FLAGS_REG))]
7635   ""
7636   "div{<imodesuffix>}\t%3"
7637   [(set_attr "type" "idiv")
7638    (set_attr "mode" "<MODE>")])
7640 (define_expand "udivmodqi4"
7641   [(parallel [(set (match_operand:QI 0 "register_operand")
7642                    (udiv:QI
7643                      (match_operand:QI 1 "register_operand")
7644                      (match_operand:QI 2 "nonimmediate_operand")))
7645               (set (match_operand:QI 3 "register_operand")
7646                    (umod:QI (match_dup 1) (match_dup 2)))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   "TARGET_QIMODE_MATH"
7650   rtx div, mod;
7651   rtx tmp0, tmp1;
7652   
7653   tmp0 = gen_reg_rtx (HImode);
7654   tmp1 = gen_reg_rtx (HImode);
7656   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7657      in AX.  */
7658   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7659   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7661   /* Extract remainder from AH.  */
7662   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7663   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7664   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7666   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7667   set_unique_reg_note (insn, REG_EQUAL, mod);
7669   /* Extract quotient from AL.  */
7670   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7672   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7673   set_unique_reg_note (insn, REG_EQUAL, div);
7675   DONE;
7678 (define_insn "udivmodhiqi3"
7679   [(set (match_operand:HI 0 "register_operand" "=a")
7680         (ior:HI
7681           (ashift:HI
7682             (zero_extend:HI
7683               (truncate:QI
7684                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7685                         (zero_extend:HI
7686                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7687             (const_int 8))
7688           (zero_extend:HI
7689             (truncate:QI
7690               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7691    (clobber (reg:CC FLAGS_REG))]
7692   "TARGET_QIMODE_MATH"
7693   "div{b}\t%2"
7694   [(set_attr "type" "idiv")
7695    (set_attr "mode" "QI")])
7697 ;; We cannot use div/idiv for double division, because it causes
7698 ;; "division by zero" on the overflow and that's not what we expect
7699 ;; from truncate.  Because true (non truncating) double division is
7700 ;; never generated, we can't create this insn anyway.
7702 ;(define_insn ""
7703 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7704 ;       (truncate:SI
7705 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7706 ;                  (zero_extend:DI
7707 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7708 ;   (set (match_operand:SI 3 "register_operand" "=d")
7709 ;       (truncate:SI
7710 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7711 ;   (clobber (reg:CC FLAGS_REG))]
7712 ;  ""
7713 ;  "div{l}\t{%2, %0|%0, %2}"
7714 ;  [(set_attr "type" "idiv")])
7716 ;;- Logical AND instructions
7718 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7719 ;; Note that this excludes ah.
7721 (define_expand "testsi_ccno_1"
7722   [(set (reg:CCNO FLAGS_REG)
7723         (compare:CCNO
7724           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7725                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7726           (const_int 0)))])
7728 (define_expand "testqi_ccz_1"
7729   [(set (reg:CCZ FLAGS_REG)
7730         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7731                              (match_operand:QI 1 "nonmemory_operand"))
7732                  (const_int 0)))])
7734 (define_expand "testdi_ccno_1"
7735   [(set (reg:CCNO FLAGS_REG)
7736         (compare:CCNO
7737           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7738                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7739           (const_int 0)))]
7740   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7742 (define_insn "*testdi_1"
7743   [(set (reg FLAGS_REG)
7744         (compare
7745          (and:DI
7746           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7747           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7748          (const_int 0)))]
7749   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7750    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7751   "@
7752    test{l}\t{%k1, %k0|%k0, %k1}
7753    test{l}\t{%k1, %k0|%k0, %k1}
7754    test{q}\t{%1, %0|%0, %1}
7755    test{q}\t{%1, %0|%0, %1}
7756    test{q}\t{%1, %0|%0, %1}"
7757   [(set_attr "type" "test")
7758    (set_attr "modrm" "0,1,0,1,1")
7759    (set_attr "mode" "SI,SI,DI,DI,DI")])
7761 (define_insn "*testqi_1_maybe_si"
7762   [(set (reg FLAGS_REG)
7763         (compare
7764           (and:QI
7765             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7766             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7767           (const_int 0)))]
7768    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7769     && ix86_match_ccmode (insn,
7770                          CONST_INT_P (operands[1])
7771                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7773   if (which_alternative == 3)
7774     {
7775       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7776         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7777       return "test{l}\t{%1, %k0|%k0, %1}";
7778     }
7779   return "test{b}\t{%1, %0|%0, %1}";
7781   [(set_attr "type" "test")
7782    (set_attr "modrm" "0,1,1,1")
7783    (set_attr "mode" "QI,QI,QI,SI")
7784    (set_attr "pent_pair" "uv,np,uv,np")])
7786 (define_insn "*test<mode>_1"
7787   [(set (reg FLAGS_REG)
7788         (compare
7789          (and:SWI124
7790           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7791           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7792          (const_int 0)))]
7793   "ix86_match_ccmode (insn, CCNOmode)
7794    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7795   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7796   [(set_attr "type" "test")
7797    (set_attr "modrm" "0,1,1")
7798    (set_attr "mode" "<MODE>")
7799    (set_attr "pent_pair" "uv,np,uv")])
7801 (define_expand "testqi_ext_ccno_0"
7802   [(set (reg:CCNO FLAGS_REG)
7803         (compare:CCNO
7804           (and:SI
7805             (zero_extract:SI
7806               (match_operand 0 "ext_register_operand")
7807               (const_int 8)
7808               (const_int 8))
7809             (match_operand 1 "const_int_operand"))
7810           (const_int 0)))])
7812 (define_insn "*testqi_ext_0"
7813   [(set (reg FLAGS_REG)
7814         (compare
7815           (and:SI
7816             (zero_extract:SI
7817               (match_operand 0 "ext_register_operand" "Q")
7818               (const_int 8)
7819               (const_int 8))
7820             (match_operand 1 "const_int_operand" "n"))
7821           (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)"
7823   "test{b}\t{%1, %h0|%h0, %1}"
7824   [(set_attr "type" "test")
7825    (set_attr "mode" "QI")
7826    (set_attr "length_immediate" "1")
7827    (set_attr "modrm" "1")
7828    (set_attr "pent_pair" "np")])
7830 (define_insn "*testqi_ext_1"
7831   [(set (reg FLAGS_REG)
7832         (compare
7833           (and:SI
7834             (zero_extract:SI
7835               (match_operand 0 "ext_register_operand" "Q,Q")
7836               (const_int 8)
7837               (const_int 8))
7838             (zero_extend:SI
7839               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7840           (const_int 0)))]
7841   "ix86_match_ccmode (insn, CCNOmode)"
7842   "test{b}\t{%1, %h0|%h0, %1}"
7843   [(set_attr "isa" "*,nox64")
7844    (set_attr "type" "test")
7845    (set_attr "mode" "QI")])
7847 (define_insn "*testqi_ext_2"
7848   [(set (reg FLAGS_REG)
7849         (compare
7850           (and:SI
7851             (zero_extract:SI
7852               (match_operand 0 "ext_register_operand" "Q")
7853               (const_int 8)
7854               (const_int 8))
7855             (zero_extract:SI
7856               (match_operand 1 "ext_register_operand" "Q")
7857               (const_int 8)
7858               (const_int 8)))
7859           (const_int 0)))]
7860   "ix86_match_ccmode (insn, CCNOmode)"
7861   "test{b}\t{%h1, %h0|%h0, %h1}"
7862   [(set_attr "type" "test")
7863    (set_attr "mode" "QI")])
7865 ;; Combine likes to form bit extractions for some tests.  Humor it.
7866 (define_insn "*testqi_ext_3"
7867   [(set (reg FLAGS_REG)
7868         (compare (zero_extract:SWI48
7869                    (match_operand 0 "nonimmediate_operand" "rm")
7870                    (match_operand 1 "const_int_operand" "n")
7871                    (match_operand 2 "const_int_operand" "n"))
7872                  (const_int 0)))]
7873   "ix86_match_ccmode (insn, CCNOmode)
7874    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7875        || GET_MODE (operands[0]) == SImode
7876        || GET_MODE (operands[0]) == HImode
7877        || GET_MODE (operands[0]) == QImode)
7878    /* Ensure that resulting mask is zero or sign extended operand.  */
7879    && INTVAL (operands[2]) >= 0
7880    && ((INTVAL (operands[1]) > 0
7881         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7882        || (<MODE>mode == DImode
7883            && INTVAL (operands[1]) > 32
7884            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7885   "#")
7887 (define_split
7888   [(set (match_operand 0 "flags_reg_operand")
7889         (match_operator 1 "compare_operator"
7890           [(zero_extract
7891              (match_operand 2 "nonimmediate_operand")
7892              (match_operand 3 "const_int_operand")
7893              (match_operand 4 "const_int_operand"))
7894            (const_int 0)]))]
7895   "ix86_match_ccmode (insn, CCNOmode)"
7896   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7898   rtx val = operands[2];
7899   HOST_WIDE_INT len = INTVAL (operands[3]);
7900   HOST_WIDE_INT pos = INTVAL (operands[4]);
7901   HOST_WIDE_INT mask;
7902   machine_mode mode, submode;
7904   mode = GET_MODE (val);
7905   if (MEM_P (val))
7906     {
7907       /* ??? Combine likes to put non-volatile mem extractions in QImode
7908          no matter the size of the test.  So find a mode that works.  */
7909       if (! MEM_VOLATILE_P (val))
7910         {
7911           mode = smallest_mode_for_size (pos + len, MODE_INT);
7912           val = adjust_address (val, mode, 0);
7913         }
7914     }
7915   else if (SUBREG_P (val)
7916            && (submode = GET_MODE (SUBREG_REG (val)),
7917                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7918            && pos + len <= GET_MODE_BITSIZE (submode)
7919            && GET_MODE_CLASS (submode) == MODE_INT)
7920     {
7921       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7922       mode = submode;
7923       val = SUBREG_REG (val);
7924     }
7925   else if (mode == HImode && pos + len <= 8)
7926     {
7927       /* Small HImode tests can be converted to QImode.  */
7928       mode = QImode;
7929       val = gen_lowpart (QImode, val);
7930     }
7932   if (len == HOST_BITS_PER_WIDE_INT)
7933     mask = -1;
7934   else
7935     mask = ((HOST_WIDE_INT)1 << len) - 1;
7936   mask <<= pos;
7938   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7941 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7942 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7943 ;; this is relatively important trick.
7944 ;; Do the conversion only post-reload to avoid limiting of the register class
7945 ;; to QI regs.
7946 (define_split
7947   [(set (match_operand 0 "flags_reg_operand")
7948         (match_operator 1 "compare_operator"
7949           [(and (match_operand 2 "QIreg_operand")
7950                 (match_operand 3 "const_int_operand"))
7951            (const_int 0)]))]
7952    "reload_completed
7953     && GET_MODE (operands[2]) != QImode
7954     && ((ix86_match_ccmode (insn, CCZmode)
7955          && !(INTVAL (operands[3]) & ~(255 << 8)))
7956         || (ix86_match_ccmode (insn, CCNOmode)
7957             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7958   [(set (match_dup 0)
7959         (match_op_dup 1
7960           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7961                    (match_dup 3))
7962            (const_int 0)]))]
7964   operands[2] = gen_lowpart (SImode, operands[2]);
7965   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7968 (define_split
7969   [(set (match_operand 0 "flags_reg_operand")
7970         (match_operator 1 "compare_operator"
7971           [(and (match_operand 2 "nonimmediate_operand")
7972                 (match_operand 3 "const_int_operand"))
7973            (const_int 0)]))]
7974    "reload_completed
7975     && GET_MODE (operands[2]) != QImode
7976     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7977     && ((ix86_match_ccmode (insn, CCZmode)
7978          && !(INTVAL (operands[3]) & ~255))
7979         || (ix86_match_ccmode (insn, CCNOmode)
7980             && !(INTVAL (operands[3]) & ~127)))"
7981   [(set (match_dup 0)
7982         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7983                          (const_int 0)]))]
7985   operands[2] = gen_lowpart (QImode, operands[2]);
7986   operands[3] = gen_lowpart (QImode, operands[3]);
7989 (define_split
7990   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7991         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7992                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7993    (clobber (reg:CC FLAGS_REG))]
7994   "TARGET_AVX512F && reload_completed"
7995   [(set (match_dup 0)
7996         (any_logic:SWI1248x (match_dup 1)
7997                             (match_dup 2)))])
7999 (define_mode_iterator SWI1248_AVX512BW
8000   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8002 (define_insn "*k<logic><mode>"
8003   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8004         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8005                                     (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8006   "TARGET_AVX512F"
8007   {
8008     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8009       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8010     else
8011       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8012   }
8013   [(set_attr "mode" "<MODE>")
8014    (set_attr "type" "msklog")
8015    (set_attr "prefix" "vex")])
8017 ;; %%% This used to optimize known byte-wide and operations to memory,
8018 ;; and sometimes to QImode registers.  If this is considered useful,
8019 ;; it should be done with splitters.
8021 (define_expand "and<mode>3"
8022   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8023         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8024                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8025   ""
8027   machine_mode mode = <MODE>mode;
8028   rtx (*insn) (rtx, rtx);
8030   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8031     {
8032       HOST_WIDE_INT ival = INTVAL (operands[2]);
8034       if (ival == (HOST_WIDE_INT) 0xffffffff)
8035         mode = SImode;
8036       else if (ival == 0xffff)
8037         mode = HImode;
8038       else if (ival == 0xff)
8039         mode = QImode;
8040       }
8042   if (mode == <MODE>mode)
8043     {
8044       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8045       DONE;
8046     }
8048   if (<MODE>mode == DImode)
8049     insn = (mode == SImode)
8050            ? gen_zero_extendsidi2
8051            : (mode == HImode)
8052            ? gen_zero_extendhidi2
8053            : gen_zero_extendqidi2;
8054   else if (<MODE>mode == SImode)
8055     insn = (mode == HImode)
8056            ? gen_zero_extendhisi2
8057            : gen_zero_extendqisi2;
8058   else if (<MODE>mode == HImode)
8059     insn = gen_zero_extendqihi2;
8060   else
8061     gcc_unreachable ();
8063   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8064   DONE;
8067 (define_insn "*anddi_1"
8068   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8069         (and:DI
8070          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8071          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8075   switch (get_attr_type (insn))
8076     {
8077     case TYPE_IMOVX:
8078       return "#";
8080     case TYPE_MSKLOG:
8081       return "kandq\t{%2, %1, %0|%0, %1, %2}";
8083     default:
8084       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8085       if (get_attr_mode (insn) == MODE_SI)
8086         return "and{l}\t{%k2, %k0|%k0, %k2}";
8087       else
8088         return "and{q}\t{%2, %0|%0, %2}";
8089     }
8091   [(set_attr "type" "alu,alu,alu,imovx,msklog")
8092    (set_attr "length_immediate" "*,*,*,0,0")
8093    (set (attr "prefix_rex")
8094      (if_then_else
8095        (and (eq_attr "type" "imovx")
8096             (and (match_test "INTVAL (operands[2]) == 0xff")
8097                  (match_operand 1 "ext_QIreg_operand")))
8098        (const_string "1")
8099        (const_string "*")))
8100    (set_attr "mode" "SI,DI,DI,SI,DI")])
8102 (define_insn_and_split "*anddi3_doubleword"
8103   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8104         (and:DI
8105          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8106          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (AND, DImode, operands)"
8109   "#"
8110   "&& reload_completed"
8111   [(parallel [(set (match_dup 0)
8112                    (and:SI (match_dup 1) (match_dup 2)))
8113               (clobber (reg:CC FLAGS_REG))])
8114    (parallel [(set (match_dup 3)
8115                    (and:SI (match_dup 4) (match_dup 5)))
8116               (clobber (reg:CC FLAGS_REG))])]
8117   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8119 (define_insn "*andsi_1"
8120   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8121         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8122                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "ix86_binary_operator_ok (AND, SImode, operands)"
8126   switch (get_attr_type (insn))
8127     {
8128     case TYPE_IMOVX:
8129       return "#";
8131     case TYPE_MSKLOG:
8132       return "kandd\t{%2, %1, %0|%0, %1, %2}";
8134     default:
8135       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8136       return "and{l}\t{%2, %0|%0, %2}";
8137     }
8139   [(set_attr "type" "alu,alu,imovx,msklog")
8140    (set (attr "prefix_rex")
8141      (if_then_else
8142        (and (eq_attr "type" "imovx")
8143             (and (match_test "INTVAL (operands[2]) == 0xff")
8144                  (match_operand 1 "ext_QIreg_operand")))
8145        (const_string "1")
8146        (const_string "*")))
8147    (set_attr "length_immediate" "*,*,0,0")
8148    (set_attr "mode" "SI")])
8150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8151 (define_insn "*andsi_1_zext"
8152   [(set (match_operand:DI 0 "register_operand" "=r")
8153         (zero_extend:DI
8154           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8155                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8158   "and{l}\t{%2, %k0|%k0, %2}"
8159   [(set_attr "type" "alu")
8160    (set_attr "mode" "SI")])
8162 (define_insn "*andhi_1"
8163   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8164         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8165                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "ix86_binary_operator_ok (AND, HImode, operands)"
8169   switch (get_attr_type (insn))
8170     {
8171     case TYPE_IMOVX:
8172       return "#";
8174     case TYPE_MSKLOG:
8175       return "kandw\t{%2, %1, %0|%0, %1, %2}";
8177     default:
8178       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8179       return "and{w}\t{%2, %0|%0, %2}";
8180     }
8182   [(set_attr "type" "alu,alu,imovx,msklog")
8183    (set_attr "length_immediate" "*,*,0,*")
8184    (set (attr "prefix_rex")
8185      (if_then_else
8186        (and (eq_attr "type" "imovx")
8187             (match_operand 1 "ext_QIreg_operand"))
8188        (const_string "1")
8189        (const_string "*")))
8190    (set_attr "mode" "HI,HI,SI,HI")])
8192 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8193 (define_insn "*andqi_1"
8194   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8195         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8196                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "ix86_binary_operator_ok (AND, QImode, operands)"
8200   switch (which_alternative)
8201     {
8202     case 0:
8203     case 1:
8204       return "and{b}\t{%2, %0|%0, %2}";
8205     case 2:
8206       return "and{l}\t{%k2, %k0|%k0, %k2}";
8207     case 3:
8208       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8209                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
8210     default:
8211       gcc_unreachable ();
8212     }
8214   [(set_attr "type" "alu,alu,alu,msklog")
8215    (set_attr "mode" "QI,QI,SI,HI")])
8217 (define_insn "*andqi_1_slp"
8218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8219         (and:QI (match_dup 0)
8220                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8221    (clobber (reg:CC FLAGS_REG))]
8222   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8223    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224   "and{b}\t{%1, %0|%0, %1}"
8225   [(set_attr "type" "alu1")
8226    (set_attr "mode" "QI")])
8228 (define_insn "kandn<mode>"
8229   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8230         (and:SWI12
8231           (not:SWI12
8232             (match_operand:SWI12 1 "register_operand" "r,0,k"))
8233           (match_operand:SWI12 2 "register_operand" "r,r,k")))
8234    (clobber (reg:CC FLAGS_REG))]
8235   "TARGET_AVX512F"
8237   switch (which_alternative)
8238     {
8239     case 0:
8240       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8241     case 1:
8242       return "#";
8243     case 2:
8244       if (TARGET_AVX512DQ && <MODE>mode == QImode)
8245         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8246       else
8247         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8248     default:
8249       gcc_unreachable ();
8250     }
8252   [(set_attr "isa" "bmi,*,avx512f")
8253    (set_attr "type" "bitmanip,*,msklog")
8254    (set_attr "prefix" "*,*,vex")
8255    (set_attr "btver2_decode" "direct,*,*")
8256    (set_attr "mode" "<MODE>")])
8258 (define_split
8259   [(set (match_operand:SWI12 0 "general_reg_operand")
8260         (and:SWI12
8261           (not:SWI12
8262             (match_dup 0))
8263           (match_operand:SWI12 1 "general_reg_operand")))
8264    (clobber (reg:CC FLAGS_REG))]
8265   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8266   [(set (match_dup 0)
8267         (not:HI (match_dup 0)))
8268    (parallel [(set (match_dup 0)
8269                    (and:HI (match_dup 0)
8270                            (match_dup 1)))
8271               (clobber (reg:CC FLAGS_REG))])])
8273 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8274 (define_split
8275   [(set (match_operand:DI 0 "register_operand")
8276         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8277                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "TARGET_64BIT"
8280   [(parallel [(set (match_dup 0)
8281                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8282               (clobber (reg:CC FLAGS_REG))])]
8283   "operands[2] = gen_lowpart (SImode, operands[2]);")
8285 (define_split
8286   [(set (match_operand:SWI248 0 "register_operand")
8287         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8288                     (match_operand:SWI248 2 "const_int_operand")))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "reload_completed
8291    && true_regnum (operands[0]) != true_regnum (operands[1])"
8292   [(const_int 0)]
8294   HOST_WIDE_INT ival = INTVAL (operands[2]);
8295   machine_mode mode;
8296   rtx (*insn) (rtx, rtx);
8298   if (ival == (HOST_WIDE_INT) 0xffffffff)
8299     mode = SImode;
8300   else if (ival == 0xffff)
8301     mode = HImode;
8302   else
8303     {
8304       gcc_assert (ival == 0xff);
8305       mode = QImode;
8306     }
8308   if (<MODE>mode == DImode)
8309     insn = (mode == SImode)
8310            ? gen_zero_extendsidi2
8311            : (mode == HImode)
8312            ? gen_zero_extendhidi2
8313            : gen_zero_extendqidi2;
8314   else
8315     {
8316       if (<MODE>mode != SImode)
8317         /* Zero extend to SImode to avoid partial register stalls.  */
8318         operands[0] = gen_lowpart (SImode, operands[0]);
8320       insn = (mode == HImode)
8321              ? gen_zero_extendhisi2
8322              : gen_zero_extendqisi2;
8323     }
8324   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8325   DONE;
8328 (define_split
8329   [(set (match_operand:SWI48 0 "register_operand")
8330         (and:SWI48 (match_dup 0)
8331                    (const_int -65536)))
8332    (clobber (reg:CC FLAGS_REG))]
8333   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8334     || optimize_function_for_size_p (cfun)"
8335   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8336   "operands[1] = gen_lowpart (HImode, operands[0]);")
8338 (define_split
8339   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8340         (and:SWI248 (match_dup 0)
8341                     (const_int -256)))
8342    (clobber (reg:CC FLAGS_REG))]
8343   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8344    && reload_completed"
8345   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8346   "operands[1] = gen_lowpart (QImode, operands[0]);")
8348 (define_split
8349   [(set (match_operand:SWI248 0 "QIreg_operand")
8350         (and:SWI248 (match_dup 0)
8351                     (const_int -65281)))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354    && reload_completed"
8355   [(parallel [(set (zero_extract:SI (match_dup 0)
8356                                     (const_int 8)
8357                                     (const_int 8))
8358                    (xor:SI
8359                      (zero_extract:SI (match_dup 0)
8360                                       (const_int 8)
8361                                       (const_int 8))
8362                      (zero_extract:SI (match_dup 0)
8363                                       (const_int 8)
8364                                       (const_int 8))))
8365               (clobber (reg:CC FLAGS_REG))])]
8366   "operands[0] = gen_lowpart (SImode, operands[0]);")
8368 (define_insn "*anddi_2"
8369   [(set (reg FLAGS_REG)
8370         (compare
8371          (and:DI
8372           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8373           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8374          (const_int 0)))
8375    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8376         (and:DI (match_dup 1) (match_dup 2)))]
8377   "TARGET_64BIT
8378    && ix86_match_ccmode
8379         (insn,
8380          /* If we are going to emit andl instead of andq, and the operands[2]
8381             constant might have the SImode sign bit set, make sure the sign
8382             flag isn't tested, because the instruction will set the sign flag
8383             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8384             conservatively assume it might have bit 31 set.  */
8385          (satisfies_constraint_Z (operands[2])
8386           && (!CONST_INT_P (operands[2])
8387               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8388          ? CCZmode : CCNOmode)
8389    && ix86_binary_operator_ok (AND, DImode, operands)"
8390   "@
8391    and{l}\t{%k2, %k0|%k0, %k2}
8392    and{q}\t{%2, %0|%0, %2}
8393    and{q}\t{%2, %0|%0, %2}"
8394   [(set_attr "type" "alu")
8395    (set_attr "mode" "SI,DI,DI")])
8397 (define_insn "*andqi_2_maybe_si"
8398   [(set (reg FLAGS_REG)
8399         (compare (and:QI
8400                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8401                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8402                  (const_int 0)))
8403    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8404         (and:QI (match_dup 1) (match_dup 2)))]
8405   "ix86_binary_operator_ok (AND, QImode, operands)
8406    && ix86_match_ccmode (insn,
8407                          CONST_INT_P (operands[2])
8408                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8410   if (which_alternative == 2)
8411     {
8412       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8413         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8414       return "and{l}\t{%2, %k0|%k0, %2}";
8415     }
8416   return "and{b}\t{%2, %0|%0, %2}";
8418   [(set_attr "type" "alu")
8419    (set_attr "mode" "QI,QI,SI")])
8421 (define_insn "*and<mode>_2"
8422   [(set (reg FLAGS_REG)
8423         (compare (and:SWI124
8424                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8425                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8426                  (const_int 0)))
8427    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8428         (and:SWI124 (match_dup 1) (match_dup 2)))]
8429   "ix86_match_ccmode (insn, CCNOmode)
8430    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8431   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "mode" "<MODE>")])
8435 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8436 (define_insn "*andsi_2_zext"
8437   [(set (reg FLAGS_REG)
8438         (compare (and:SI
8439                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8440                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8441                  (const_int 0)))
8442    (set (match_operand:DI 0 "register_operand" "=r")
8443         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8444   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8445    && ix86_binary_operator_ok (AND, SImode, operands)"
8446   "and{l}\t{%2, %k0|%k0, %2}"
8447   [(set_attr "type" "alu")
8448    (set_attr "mode" "SI")])
8450 (define_insn "*andqi_2_slp"
8451   [(set (reg FLAGS_REG)
8452         (compare (and:QI
8453                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8454                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8455                  (const_int 0)))
8456    (set (strict_low_part (match_dup 0))
8457         (and:QI (match_dup 0) (match_dup 1)))]
8458   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8459    && ix86_match_ccmode (insn, CCNOmode)
8460    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8461   "and{b}\t{%1, %0|%0, %1}"
8462   [(set_attr "type" "alu1")
8463    (set_attr "mode" "QI")])
8465 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8466 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8467 ;; for a QImode operand, which of course failed.
8468 (define_insn "andqi_ext_0"
8469   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8470                          (const_int 8)
8471                          (const_int 8))
8472         (and:SI
8473           (zero_extract:SI
8474             (match_operand 1 "ext_register_operand" "0")
8475             (const_int 8)
8476             (const_int 8))
8477           (match_operand 2 "const_int_operand" "n")))
8478    (clobber (reg:CC FLAGS_REG))]
8479   ""
8480   "and{b}\t{%2, %h0|%h0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "length_immediate" "1")
8483    (set_attr "modrm" "1")
8484    (set_attr "mode" "QI")])
8486 ;; Generated by peephole translating test to and.  This shows up
8487 ;; often in fp comparisons.
8488 (define_insn "*andqi_ext_0_cc"
8489   [(set (reg FLAGS_REG)
8490         (compare
8491           (and:SI
8492             (zero_extract:SI
8493               (match_operand 1 "ext_register_operand" "0")
8494               (const_int 8)
8495               (const_int 8))
8496             (match_operand 2 "const_int_operand" "n"))
8497           (const_int 0)))
8498    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8499                          (const_int 8)
8500                          (const_int 8))
8501         (and:SI
8502           (zero_extract:SI
8503             (match_dup 1)
8504             (const_int 8)
8505             (const_int 8))
8506           (match_dup 2)))]
8507   "ix86_match_ccmode (insn, CCNOmode)"
8508   "and{b}\t{%2, %h0|%h0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "length_immediate" "1")
8511    (set_attr "modrm" "1")
8512    (set_attr "mode" "QI")])
8514 (define_insn "*andqi_ext_1"
8515   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8516                          (const_int 8)
8517                          (const_int 8))
8518         (and:SI
8519           (zero_extract:SI
8520             (match_operand 1 "ext_register_operand" "0,0")
8521             (const_int 8)
8522             (const_int 8))
8523           (zero_extend:SI
8524             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "and{b}\t{%2, %h0|%h0, %2}"
8528   [(set_attr "isa" "*,nox64")
8529    (set_attr "type" "alu")
8530    (set_attr "length_immediate" "0")
8531    (set_attr "mode" "QI")])
8533 (define_insn "*andqi_ext_2"
8534   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8535                          (const_int 8)
8536                          (const_int 8))
8537         (and:SI
8538           (zero_extract:SI
8539             (match_operand 1 "ext_register_operand" "%0")
8540             (const_int 8)
8541             (const_int 8))
8542           (zero_extract:SI
8543             (match_operand 2 "ext_register_operand" "Q")
8544             (const_int 8)
8545             (const_int 8))))
8546    (clobber (reg:CC FLAGS_REG))]
8547   ""
8548   "and{b}\t{%h2, %h0|%h0, %h2}"
8549   [(set_attr "type" "alu")
8550    (set_attr "length_immediate" "0")
8551    (set_attr "mode" "QI")])
8553 ;; Convert wide AND instructions with immediate operand to shorter QImode
8554 ;; equivalents when possible.
8555 ;; Don't do the splitting with memory operands, since it introduces risk
8556 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8557 ;; for size, but that can (should?) be handled by generic code instead.
8558 (define_split
8559   [(set (match_operand 0 "QIreg_operand")
8560         (and (match_operand 1 "register_operand")
8561              (match_operand 2 "const_int_operand")))
8562    (clobber (reg:CC FLAGS_REG))]
8563    "reload_completed
8564     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8565     && !(~INTVAL (operands[2]) & ~(255 << 8))
8566     && GET_MODE (operands[0]) != QImode"
8567   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8568                    (and:SI (zero_extract:SI (match_dup 1)
8569                                             (const_int 8) (const_int 8))
8570                            (match_dup 2)))
8571               (clobber (reg:CC FLAGS_REG))])]
8573   operands[0] = gen_lowpart (SImode, operands[0]);
8574   operands[1] = gen_lowpart (SImode, operands[1]);
8575   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8578 ;; Since AND can be encoded with sign extended immediate, this is only
8579 ;; profitable when 7th bit is not set.
8580 (define_split
8581   [(set (match_operand 0 "any_QIreg_operand")
8582         (and (match_operand 1 "general_operand")
8583              (match_operand 2 "const_int_operand")))
8584    (clobber (reg:CC FLAGS_REG))]
8585    "reload_completed
8586     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8587     && !(~INTVAL (operands[2]) & ~255)
8588     && !(INTVAL (operands[2]) & 128)
8589     && GET_MODE (operands[0]) != QImode"
8590   [(parallel [(set (strict_low_part (match_dup 0))
8591                    (and:QI (match_dup 1)
8592                            (match_dup 2)))
8593               (clobber (reg:CC FLAGS_REG))])]
8595   operands[0] = gen_lowpart (QImode, operands[0]);
8596   operands[1] = gen_lowpart (QImode, operands[1]);
8597   operands[2] = gen_lowpart (QImode, operands[2]);
8600 ;; Logical inclusive and exclusive OR instructions
8602 ;; %%% This used to optimize known byte-wide and operations to memory.
8603 ;; If this is considered useful, it should be done with splitters.
8605 (define_expand "<code><mode>3"
8606   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8607         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8608                              (match_operand:SWIM1248x 2 "<general_operand>")))]
8609   ""
8610   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8612 (define_insn "*<code><mode>_1"
8613   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8614         (any_or:SWI48
8615          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8616          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8619   "@
8620    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8621    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8622    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8623   [(set_attr "type" "alu,alu,msklog")
8624    (set_attr "mode" "<MODE>")])
8626 (define_insn_and_split "*<code>di3_doubleword"
8627   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8628         (any_or:DI
8629          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8630          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8631    (clobber (reg:CC FLAGS_REG))]
8632   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8633   "#"
8634   "&& reload_completed"
8635   [(parallel [(set (match_dup 0)
8636                    (any_or:SI (match_dup 1) (match_dup 2)))
8637               (clobber (reg:CC FLAGS_REG))])
8638    (parallel [(set (match_dup 3)
8639                    (any_or:SI (match_dup 4) (match_dup 5)))
8640               (clobber (reg:CC FLAGS_REG))])]
8641   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8643 (define_insn "*<code>hi_1"
8644   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8645         (any_or:HI
8646          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8647          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8648    (clobber (reg:CC FLAGS_REG))]
8649   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8650   "@
8651   <logic>{w}\t{%2, %0|%0, %2}
8652   <logic>{w}\t{%2, %0|%0, %2}
8653   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8654   [(set_attr "type" "alu,alu,msklog")
8655    (set_attr "mode" "HI")])
8657 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8658 (define_insn "*<code>qi_1"
8659   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8660         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8661                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8664   "@
8665    <logic>{b}\t{%2, %0|%0, %2}
8666    <logic>{b}\t{%2, %0|%0, %2}
8667    <logic>{l}\t{%k2, %k0|%k0, %k2}
8668    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8669   [(set_attr "type" "alu,alu,alu,msklog")
8670    (set_attr "mode" "QI,QI,SI,HI")])
8672 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8673 (define_insn "*<code>si_1_zext"
8674   [(set (match_operand:DI 0 "register_operand" "=r")
8675         (zero_extend:DI
8676          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8678    (clobber (reg:CC FLAGS_REG))]
8679   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8680   "<logic>{l}\t{%2, %k0|%k0, %2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "SI")])
8684 (define_insn "*<code>si_1_zext_imm"
8685   [(set (match_operand:DI 0 "register_operand" "=r")
8686         (any_or:DI
8687          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689    (clobber (reg:CC FLAGS_REG))]
8690   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8691   "<logic>{l}\t{%2, %k0|%k0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "SI")])
8695 (define_insn "*<code>qi_1_slp"
8696   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8697         (any_or:QI (match_dup 0)
8698                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8701    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8702   "<logic>{b}\t{%1, %0|%0, %1}"
8703   [(set_attr "type" "alu1")
8704    (set_attr "mode" "QI")])
8706 (define_insn "*<code><mode>_2"
8707   [(set (reg FLAGS_REG)
8708         (compare (any_or:SWI
8709                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8710                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8711                  (const_int 0)))
8712    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8713         (any_or:SWI (match_dup 1) (match_dup 2)))]
8714   "ix86_match_ccmode (insn, CCNOmode)
8715    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8716   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "<MODE>")])
8720 (define_insn "kxnor<mode>"
8721   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8722         (not:SWI12
8723           (xor:SWI12
8724             (match_operand:SWI12 1 "register_operand" "0,k")
8725             (match_operand:SWI12 2 "register_operand" "r,k"))))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "TARGET_AVX512F"
8729   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8730     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8731   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8733   [(set_attr "type" "*,msklog")
8734    (set_attr "prefix" "*,vex")
8735    (set_attr "mode" "<MODE>")])
8737 (define_insn "kxnor<mode>"
8738   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8739         (not:SWI48x
8740           (xor:SWI48x
8741             (match_operand:SWI48x 1 "register_operand" "0,k")
8742             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8743    (clobber (reg:CC FLAGS_REG))]
8744   "TARGET_AVX512BW"
8745   "@
8746    #
8747    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8748   [(set_attr "type" "*,msklog")
8749    (set_attr "prefix" "*,vex")
8750    (set_attr "mode" "<MODE>")])
8752 (define_split
8753   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8754         (not:SWI1248x
8755           (xor:SWI1248x
8756             (match_dup 0)
8757             (match_operand:SWI1248x 1 "general_reg_operand"))))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "TARGET_AVX512F && reload_completed"
8760    [(parallel [(set (match_dup 0)
8761                     (xor:SWI1248x (match_dup 0)
8762                                   (match_dup 1)))
8763                (clobber (reg:CC FLAGS_REG))])
8764     (set (match_dup 0)
8765          (not:SWI1248x (match_dup 0)))])
8767 ;;There are kortrest[bdq] but no intrinsics for them.
8768 ;;We probably don't need to implement them.
8769 (define_insn "kortestzhi"
8770   [(set (reg:CCZ FLAGS_REG)
8771         (compare:CCZ
8772           (ior:HI
8773             (match_operand:HI 0 "register_operand" "k")
8774             (match_operand:HI 1 "register_operand" "k"))
8775           (const_int 0)))]
8776   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8777   "kortestw\t{%1, %0|%0, %1}"
8778   [(set_attr "mode" "HI")
8779    (set_attr "type" "msklog")
8780    (set_attr "prefix" "vex")])
8782 (define_insn "kortestchi"
8783   [(set (reg:CCC FLAGS_REG)
8784         (compare:CCC
8785           (ior:HI
8786             (match_operand:HI 0 "register_operand" "k")
8787             (match_operand:HI 1 "register_operand" "k"))
8788           (const_int -1)))]
8789   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8790   "kortestw\t{%1, %0|%0, %1}"
8791   [(set_attr "mode" "HI")
8792    (set_attr "type" "msklog")
8793    (set_attr "prefix" "vex")])
8795 (define_insn "kunpckhi"
8796   [(set (match_operand:HI 0 "register_operand" "=k")
8797         (ior:HI
8798           (ashift:HI
8799             (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8800             (const_int 8))
8801           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8802   "TARGET_AVX512F"
8803   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8804   [(set_attr "mode" "HI")
8805    (set_attr "type" "msklog")
8806    (set_attr "prefix" "vex")])
8808 (define_insn "kunpcksi"
8809   [(set (match_operand:SI 0 "register_operand" "=k")
8810         (ior:SI
8811           (ashift:SI
8812             (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8813             (const_int 16))
8814           (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8815   "TARGET_AVX512BW"
8816   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8817   [(set_attr "mode" "SI")])
8819 (define_insn "kunpckdi"
8820   [(set (match_operand:DI 0 "register_operand" "=k")
8821         (ior:DI
8822           (ashift:DI
8823             (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8824             (const_int 32))
8825           (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8826   "TARGET_AVX512BW"
8827   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8828   [(set_attr "mode" "DI")])
8830 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8831 ;; ??? Special case for immediate operand is missing - it is tricky.
8832 (define_insn "*<code>si_2_zext"
8833   [(set (reg FLAGS_REG)
8834         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8835                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8836                  (const_int 0)))
8837    (set (match_operand:DI 0 "register_operand" "=r")
8838         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8839   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8840    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8841   "<logic>{l}\t{%2, %k0|%k0, %2}"
8842   [(set_attr "type" "alu")
8843    (set_attr "mode" "SI")])
8845 (define_insn "*<code>si_2_zext_imm"
8846   [(set (reg FLAGS_REG)
8847         (compare (any_or:SI
8848                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8849                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8850                  (const_int 0)))
8851    (set (match_operand:DI 0 "register_operand" "=r")
8852         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8853   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8854    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8855   "<logic>{l}\t{%2, %k0|%k0, %2}"
8856   [(set_attr "type" "alu")
8857    (set_attr "mode" "SI")])
8859 (define_insn "*<code>qi_2_slp"
8860   [(set (reg FLAGS_REG)
8861         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8862                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8863                  (const_int 0)))
8864    (set (strict_low_part (match_dup 0))
8865         (any_or:QI (match_dup 0) (match_dup 1)))]
8866   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8867    && ix86_match_ccmode (insn, CCNOmode)
8868    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8869   "<logic>{b}\t{%1, %0|%0, %1}"
8870   [(set_attr "type" "alu1")
8871    (set_attr "mode" "QI")])
8873 (define_insn "*<code><mode>_3"
8874   [(set (reg FLAGS_REG)
8875         (compare (any_or:SWI
8876                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8877                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8878                  (const_int 0)))
8879    (clobber (match_scratch:SWI 0 "=<r>"))]
8880   "ix86_match_ccmode (insn, CCNOmode)
8881    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8882   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8883   [(set_attr "type" "alu")
8884    (set_attr "mode" "<MODE>")])
8886 (define_insn "*<code>qi_ext_0"
8887   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8888                          (const_int 8)
8889                          (const_int 8))
8890         (any_or:SI
8891           (zero_extract:SI
8892             (match_operand 1 "ext_register_operand" "0")
8893             (const_int 8)
8894             (const_int 8))
8895           (match_operand 2 "const_int_operand" "n")))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8898   "<logic>{b}\t{%2, %h0|%h0, %2}"
8899   [(set_attr "type" "alu")
8900    (set_attr "length_immediate" "1")
8901    (set_attr "modrm" "1")
8902    (set_attr "mode" "QI")])
8904 (define_insn "*<code>qi_ext_1"
8905   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8906                          (const_int 8)
8907                          (const_int 8))
8908         (any_or:SI
8909           (zero_extract:SI
8910             (match_operand 1 "ext_register_operand" "0,0")
8911             (const_int 8)
8912             (const_int 8))
8913           (zero_extend:SI
8914             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8915    (clobber (reg:CC FLAGS_REG))]
8916   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8917   "<logic>{b}\t{%2, %h0|%h0, %2}"
8918   [(set_attr "isa" "*,nox64")
8919    (set_attr "type" "alu")
8920    (set_attr "length_immediate" "0")
8921    (set_attr "mode" "QI")])
8923 (define_insn "*<code>qi_ext_2"
8924   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8925                          (const_int 8)
8926                          (const_int 8))
8927         (any_or:SI
8928           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8929                            (const_int 8)
8930                            (const_int 8))
8931           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8932                            (const_int 8)
8933                            (const_int 8))))
8934    (clobber (reg:CC FLAGS_REG))]
8935   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8936   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8937   [(set_attr "type" "alu")
8938    (set_attr "length_immediate" "0")
8939    (set_attr "mode" "QI")])
8941 (define_split
8942   [(set (match_operand 0 "QIreg_operand")
8943         (any_or (match_operand 1 "register_operand")
8944                 (match_operand 2 "const_int_operand")))
8945    (clobber (reg:CC FLAGS_REG))]
8946    "reload_completed
8947     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8948     && !(INTVAL (operands[2]) & ~(255 << 8))
8949     && GET_MODE (operands[0]) != QImode"
8950   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8951                    (any_or:SI (zero_extract:SI (match_dup 1)
8952                                                (const_int 8) (const_int 8))
8953                               (match_dup 2)))
8954               (clobber (reg:CC FLAGS_REG))])]
8956   operands[0] = gen_lowpart (SImode, operands[0]);
8957   operands[1] = gen_lowpart (SImode, operands[1]);
8958   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8961 ;; Since OR can be encoded with sign extended immediate, this is only
8962 ;; profitable when 7th bit is set.
8963 (define_split
8964   [(set (match_operand 0 "any_QIreg_operand")
8965         (any_or (match_operand 1 "general_operand")
8966                 (match_operand 2 "const_int_operand")))
8967    (clobber (reg:CC FLAGS_REG))]
8968    "reload_completed
8969     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8970     && !(INTVAL (operands[2]) & ~255)
8971     && (INTVAL (operands[2]) & 128)
8972     && GET_MODE (operands[0]) != QImode"
8973   [(parallel [(set (strict_low_part (match_dup 0))
8974                    (any_or:QI (match_dup 1)
8975                               (match_dup 2)))
8976               (clobber (reg:CC FLAGS_REG))])]
8978   operands[0] = gen_lowpart (QImode, operands[0]);
8979   operands[1] = gen_lowpart (QImode, operands[1]);
8980   operands[2] = gen_lowpart (QImode, operands[2]);
8983 (define_expand "xorqi_cc_ext_1"
8984   [(parallel [
8985      (set (reg:CCNO FLAGS_REG)
8986           (compare:CCNO
8987             (xor:SI
8988               (zero_extract:SI
8989                 (match_operand 1 "ext_register_operand")
8990                 (const_int 8)
8991                 (const_int 8))
8992               (match_operand:QI 2 "const_int_operand"))
8993             (const_int 0)))
8994      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8995                            (const_int 8)
8996                            (const_int 8))
8997           (xor:SI
8998             (zero_extract:SI
8999              (match_dup 1)
9000              (const_int 8)
9001              (const_int 8))
9002             (match_dup 2)))])])
9004 (define_insn "*xorqi_cc_ext_1"
9005   [(set (reg FLAGS_REG)
9006         (compare
9007           (xor:SI
9008             (zero_extract:SI
9009               (match_operand 1 "ext_register_operand" "0,0")
9010               (const_int 8)
9011               (const_int 8))
9012             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
9013           (const_int 0)))
9014    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9015                          (const_int 8)
9016                          (const_int 8))
9017         (xor:SI
9018           (zero_extract:SI
9019            (match_dup 1)
9020            (const_int 8)
9021            (const_int 8))
9022           (match_dup 2)))]
9023   "ix86_match_ccmode (insn, CCNOmode)"
9024   "xor{b}\t{%2, %h0|%h0, %2}"
9025   [(set_attr "isa" "*,nox64")
9026    (set_attr "type" "alu")
9027    (set_attr "modrm" "1")
9028    (set_attr "mode" "QI")])
9030 ;; Negation instructions
9032 (define_expand "neg<mode>2"
9033   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9034         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9035   ""
9036   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9038 (define_insn_and_split "*neg<dwi>2_doubleword"
9039   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9040         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9041    (clobber (reg:CC FLAGS_REG))]
9042   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9043   "#"
9044   "reload_completed"
9045   [(parallel
9046     [(set (reg:CCZ FLAGS_REG)
9047           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9048      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9049    (parallel
9050     [(set (match_dup 2)
9051           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9052                                 (match_dup 3))
9053                      (const_int 0)))
9054      (clobber (reg:CC FLAGS_REG))])
9055    (parallel
9056     [(set (match_dup 2)
9057           (neg:DWIH (match_dup 2)))
9058      (clobber (reg:CC FLAGS_REG))])]
9059   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9061 (define_insn "*neg<mode>2_1"
9062   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9063         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9064    (clobber (reg:CC FLAGS_REG))]
9065   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9066   "neg{<imodesuffix>}\t%0"
9067   [(set_attr "type" "negnot")
9068    (set_attr "mode" "<MODE>")])
9070 ;; Combine is quite creative about this pattern.
9071 (define_insn "*negsi2_1_zext"
9072   [(set (match_operand:DI 0 "register_operand" "=r")
9073         (lshiftrt:DI
9074           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9075                              (const_int 32)))
9076         (const_int 32)))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9079   "neg{l}\t%k0"
9080   [(set_attr "type" "negnot")
9081    (set_attr "mode" "SI")])
9083 ;; The problem with neg is that it does not perform (compare x 0),
9084 ;; it really performs (compare 0 x), which leaves us with the zero
9085 ;; flag being the only useful item.
9087 (define_insn "*neg<mode>2_cmpz"
9088   [(set (reg:CCZ FLAGS_REG)
9089         (compare:CCZ
9090           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9091                    (const_int 0)))
9092    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9093         (neg:SWI (match_dup 1)))]
9094   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9095   "neg{<imodesuffix>}\t%0"
9096   [(set_attr "type" "negnot")
9097    (set_attr "mode" "<MODE>")])
9099 (define_insn "*negsi2_cmpz_zext"
9100   [(set (reg:CCZ FLAGS_REG)
9101         (compare:CCZ
9102           (lshiftrt:DI
9103             (neg:DI (ashift:DI
9104                       (match_operand:DI 1 "register_operand" "0")
9105                       (const_int 32)))
9106             (const_int 32))
9107           (const_int 0)))
9108    (set (match_operand:DI 0 "register_operand" "=r")
9109         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9110                                         (const_int 32)))
9111                      (const_int 32)))]
9112   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9113   "neg{l}\t%k0"
9114   [(set_attr "type" "negnot")
9115    (set_attr "mode" "SI")])
9117 ;; Negate with jump on overflow.
9118 (define_expand "negv<mode>3"
9119   [(parallel [(set (reg:CCO FLAGS_REG)
9120                    (ne:CCO (match_operand:SWI 1 "register_operand")
9121                            (match_dup 3)))
9122               (set (match_operand:SWI 0 "register_operand")
9123                    (neg:SWI (match_dup 1)))])
9124    (set (pc) (if_then_else
9125                (eq (reg:CCO FLAGS_REG) (const_int 0))
9126                (label_ref (match_operand 2))
9127                (pc)))]
9128   ""
9130   operands[3]
9131     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9132                     <MODE>mode);
9135 (define_insn "*negv<mode>3"
9136   [(set (reg:CCO FLAGS_REG)
9137         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9138                 (match_operand:SWI 2 "const_int_operand")))
9139    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9140         (neg:SWI (match_dup 1)))]
9141   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9142    && mode_signbit_p (<MODE>mode, operands[2])"
9143   "neg{<imodesuffix>}\t%0"
9144   [(set_attr "type" "negnot")
9145    (set_attr "mode" "<MODE>")])
9147 ;; Changing of sign for FP values is doable using integer unit too.
9149 (define_expand "<code><mode>2"
9150   [(set (match_operand:X87MODEF 0 "register_operand")
9151         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9152   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9153   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9155 (define_insn "*absneg<mode>2_mixed"
9156   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9157         (match_operator:MODEF 3 "absneg_operator"
9158           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9159    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9160    (clobber (reg:CC FLAGS_REG))]
9161   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9162   "#"
9163   [(set (attr "enabled")
9164      (cond [(eq_attr "alternative" "2")
9165               (symbol_ref "TARGET_MIX_SSE_I387")
9166            ]
9167            (symbol_ref "true")))])
9169 (define_insn "*absneg<mode>2_i387"
9170   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9171         (match_operator:X87MODEF 3 "absneg_operator"
9172           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9173    (use (match_operand 2))
9174    (clobber (reg:CC FLAGS_REG))]
9175   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9176   "#")
9178 (define_expand "<code>tf2"
9179   [(set (match_operand:TF 0 "register_operand")
9180         (absneg:TF (match_operand:TF 1 "register_operand")))]
9181   "TARGET_SSE"
9182   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9184 (define_insn "*absnegtf2_sse"
9185   [(set (match_operand:TF 0 "register_operand" "=x,x")
9186         (match_operator:TF 3 "absneg_operator"
9187           [(match_operand:TF 1 "register_operand" "0,x")]))
9188    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9189    (clobber (reg:CC FLAGS_REG))]
9190   "TARGET_SSE"
9191   "#")
9193 ;; Splitters for fp abs and neg.
9195 (define_split
9196   [(set (match_operand 0 "fp_register_operand")
9197         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9198    (use (match_operand 2))
9199    (clobber (reg:CC FLAGS_REG))]
9200   "reload_completed"
9201   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9203 (define_split
9204   [(set (match_operand 0 "register_operand")
9205         (match_operator 3 "absneg_operator"
9206           [(match_operand 1 "register_operand")]))
9207    (use (match_operand 2 "nonimmediate_operand"))
9208    (clobber (reg:CC FLAGS_REG))]
9209   "reload_completed && SSE_REG_P (operands[0])"
9210   [(set (match_dup 0) (match_dup 3))]
9212   machine_mode mode = GET_MODE (operands[0]);
9213   machine_mode vmode = GET_MODE (operands[2]);
9214   rtx tmp;
9216   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9217   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9218   if (operands_match_p (operands[0], operands[2]))
9219     std::swap (operands[1], operands[2]);
9220   if (GET_CODE (operands[3]) == ABS)
9221     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9222   else
9223     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9224   operands[3] = tmp;
9227 (define_split
9228   [(set (match_operand:SF 0 "register_operand")
9229         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9230    (use (match_operand:V4SF 2))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "reload_completed"
9233   [(parallel [(set (match_dup 0) (match_dup 1))
9234               (clobber (reg:CC FLAGS_REG))])]
9236   rtx tmp;
9237   operands[0] = gen_lowpart (SImode, operands[0]);
9238   if (GET_CODE (operands[1]) == ABS)
9239     {
9240       tmp = gen_int_mode (0x7fffffff, SImode);
9241       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9242     }
9243   else
9244     {
9245       tmp = gen_int_mode (0x80000000, SImode);
9246       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9247     }
9248   operands[1] = tmp;
9251 (define_split
9252   [(set (match_operand:DF 0 "register_operand")
9253         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9254    (use (match_operand 2))
9255    (clobber (reg:CC FLAGS_REG))]
9256   "reload_completed"
9257   [(parallel [(set (match_dup 0) (match_dup 1))
9258               (clobber (reg:CC FLAGS_REG))])]
9260   rtx tmp;
9261   if (TARGET_64BIT)
9262     {
9263       tmp = gen_lowpart (DImode, operands[0]);
9264       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9265       operands[0] = tmp;
9267       if (GET_CODE (operands[1]) == ABS)
9268         tmp = const0_rtx;
9269       else
9270         tmp = gen_rtx_NOT (DImode, tmp);
9271     }
9272   else
9273     {
9274       operands[0] = gen_highpart (SImode, operands[0]);
9275       if (GET_CODE (operands[1]) == ABS)
9276         {
9277           tmp = gen_int_mode (0x7fffffff, SImode);
9278           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9279         }
9280       else
9281         {
9282           tmp = gen_int_mode (0x80000000, SImode);
9283           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9284         }
9285     }
9286   operands[1] = tmp;
9289 (define_split
9290   [(set (match_operand:XF 0 "register_operand")
9291         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9292    (use (match_operand 2))
9293    (clobber (reg:CC FLAGS_REG))]
9294   "reload_completed"
9295   [(parallel [(set (match_dup 0) (match_dup 1))
9296               (clobber (reg:CC FLAGS_REG))])]
9298   rtx tmp;
9299   operands[0] = gen_rtx_REG (SImode,
9300                              true_regnum (operands[0])
9301                              + (TARGET_64BIT ? 1 : 2));
9302   if (GET_CODE (operands[1]) == ABS)
9303     {
9304       tmp = GEN_INT (0x7fff);
9305       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9306     }
9307   else
9308     {
9309       tmp = GEN_INT (0x8000);
9310       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9311     }
9312   operands[1] = tmp;
9315 ;; Conditionalize these after reload. If they match before reload, we
9316 ;; lose the clobber and ability to use integer instructions.
9318 (define_insn "*<code><mode>2_1"
9319   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9320         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9321   "TARGET_80387
9322    && (reload_completed
9323        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9324   "f<absneg_mnemonic>"
9325   [(set_attr "type" "fsgn")
9326    (set_attr "mode" "<MODE>")])
9328 (define_insn "*<code>extendsfdf2"
9329   [(set (match_operand:DF 0 "register_operand" "=f")
9330         (absneg:DF (float_extend:DF
9331                      (match_operand:SF 1 "register_operand" "0"))))]
9332   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9333   "f<absneg_mnemonic>"
9334   [(set_attr "type" "fsgn")
9335    (set_attr "mode" "DF")])
9337 (define_insn "*<code>extendsfxf2"
9338   [(set (match_operand:XF 0 "register_operand" "=f")
9339         (absneg:XF (float_extend:XF
9340                      (match_operand:SF 1 "register_operand" "0"))))]
9341   "TARGET_80387"
9342   "f<absneg_mnemonic>"
9343   [(set_attr "type" "fsgn")
9344    (set_attr "mode" "XF")])
9346 (define_insn "*<code>extenddfxf2"
9347   [(set (match_operand:XF 0 "register_operand" "=f")
9348         (absneg:XF (float_extend:XF
9349                      (match_operand:DF 1 "register_operand" "0"))))]
9350   "TARGET_80387"
9351   "f<absneg_mnemonic>"
9352   [(set_attr "type" "fsgn")
9353    (set_attr "mode" "XF")])
9355 ;; Copysign instructions
9357 (define_mode_iterator CSGNMODE [SF DF TF])
9358 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9360 (define_expand "copysign<mode>3"
9361   [(match_operand:CSGNMODE 0 "register_operand")
9362    (match_operand:CSGNMODE 1 "nonmemory_operand")
9363    (match_operand:CSGNMODE 2 "register_operand")]
9364   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9365    || (TARGET_SSE && (<MODE>mode == TFmode))"
9366   "ix86_expand_copysign (operands); DONE;")
9368 (define_insn_and_split "copysign<mode>3_const"
9369   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9370         (unspec:CSGNMODE
9371           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9372            (match_operand:CSGNMODE 2 "register_operand" "0")
9373            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9374           UNSPEC_COPYSIGN))]
9375   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9376    || (TARGET_SSE && (<MODE>mode == TFmode))"
9377   "#"
9378   "&& reload_completed"
9379   [(const_int 0)]
9380   "ix86_split_copysign_const (operands); DONE;")
9382 (define_insn "copysign<mode>3_var"
9383   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9384         (unspec:CSGNMODE
9385           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9386            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9387            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9388            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9389           UNSPEC_COPYSIGN))
9390    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9391   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9392    || (TARGET_SSE && (<MODE>mode == TFmode))"
9393   "#")
9395 (define_split
9396   [(set (match_operand:CSGNMODE 0 "register_operand")
9397         (unspec:CSGNMODE
9398           [(match_operand:CSGNMODE 2 "register_operand")
9399            (match_operand:CSGNMODE 3 "register_operand")
9400            (match_operand:<CSGNVMODE> 4)
9401            (match_operand:<CSGNVMODE> 5)]
9402           UNSPEC_COPYSIGN))
9403    (clobber (match_scratch:<CSGNVMODE> 1))]
9404   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9405     || (TARGET_SSE && (<MODE>mode == TFmode)))
9406    && reload_completed"
9407   [(const_int 0)]
9408   "ix86_split_copysign_var (operands); DONE;")
9410 ;; One complement instructions
9412 (define_expand "one_cmpl<mode>2"
9413   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9414         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9415   ""
9416   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9418 (define_insn "*one_cmpl<mode>2_1"
9419   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9420         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9421   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9422   "@
9423    not{<imodesuffix>}\t%0
9424    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9425   [(set_attr "isa" "*,avx512bw")
9426    (set_attr "type" "negnot,msklog")
9427    (set_attr "prefix" "*,vex")
9428    (set_attr "mode" "<MODE>")])
9430 (define_insn "*one_cmplhi2_1"
9431   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9432         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9433   "ix86_unary_operator_ok (NOT, HImode, operands)"
9434   "@
9435    not{w}\t%0
9436    knotw\t{%1, %0|%0, %1}"
9437   [(set_attr "isa" "*,avx512f")
9438    (set_attr "type" "negnot,msklog")
9439    (set_attr "prefix" "*,vex")
9440    (set_attr "mode" "HI")])
9442 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9443 (define_insn "*one_cmplqi2_1"
9444   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9445         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9446   "ix86_unary_operator_ok (NOT, QImode, operands)"
9448   switch (which_alternative)
9449     {
9450     case 0:
9451       return "not{b}\t%0";
9452     case 1:
9453       return "not{l}\t%k0";
9454     case 2:
9455       if (TARGET_AVX512DQ)
9456         return "knotb\t{%1, %0|%0, %1}";
9457       return "knotw\t{%1, %0|%0, %1}";
9458     default:
9459       gcc_unreachable ();
9460     }
9462   [(set_attr "isa" "*,*,avx512f")
9463    (set_attr "type" "negnot,negnot,msklog")
9464    (set_attr "prefix" "*,*,vex")
9465    (set_attr "mode" "QI,SI,QI")])
9467 ;; ??? Currently never generated - xor is used instead.
9468 (define_insn "*one_cmplsi2_1_zext"
9469   [(set (match_operand:DI 0 "register_operand" "=r")
9470         (zero_extend:DI
9471           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9472   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9473   "not{l}\t%k0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9477 (define_insn "*one_cmpl<mode>2_2"
9478   [(set (reg FLAGS_REG)
9479         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9480                  (const_int 0)))
9481    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9482         (not:SWI (match_dup 1)))]
9483   "ix86_match_ccmode (insn, CCNOmode)
9484    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9485   "#"
9486   [(set_attr "type" "alu1")
9487    (set_attr "mode" "<MODE>")])
9489 (define_split
9490   [(set (match_operand 0 "flags_reg_operand")
9491         (match_operator 2 "compare_operator"
9492           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9493            (const_int 0)]))
9494    (set (match_operand:SWI 1 "nonimmediate_operand")
9495         (not:SWI (match_dup 3)))]
9496   "ix86_match_ccmode (insn, CCNOmode)"
9497   [(parallel [(set (match_dup 0)
9498                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9499                                     (const_int 0)]))
9500               (set (match_dup 1)
9501                    (xor:SWI (match_dup 3) (const_int -1)))])])
9503 ;; ??? Currently never generated - xor is used instead.
9504 (define_insn "*one_cmplsi2_2_zext"
9505   [(set (reg FLAGS_REG)
9506         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9507                  (const_int 0)))
9508    (set (match_operand:DI 0 "register_operand" "=r")
9509         (zero_extend:DI (not:SI (match_dup 1))))]
9510   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9511    && ix86_unary_operator_ok (NOT, SImode, operands)"
9512   "#"
9513   [(set_attr "type" "alu1")
9514    (set_attr "mode" "SI")])
9516 (define_split
9517   [(set (match_operand 0 "flags_reg_operand")
9518         (match_operator 2 "compare_operator"
9519           [(not:SI (match_operand:SI 3 "register_operand"))
9520            (const_int 0)]))
9521    (set (match_operand:DI 1 "register_operand")
9522         (zero_extend:DI (not:SI (match_dup 3))))]
9523   "ix86_match_ccmode (insn, CCNOmode)"
9524   [(parallel [(set (match_dup 0)
9525                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9526                                     (const_int 0)]))
9527               (set (match_dup 1)
9528                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9530 ;; Shift instructions
9532 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9533 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9534 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9535 ;; from the assembler input.
9537 ;; This instruction shifts the target reg/mem as usual, but instead of
9538 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9539 ;; is a left shift double, bits are taken from the high order bits of
9540 ;; reg, else if the insn is a shift right double, bits are taken from the
9541 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9542 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9544 ;; Since sh[lr]d does not change the `reg' operand, that is done
9545 ;; separately, making all shifts emit pairs of shift double and normal
9546 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9547 ;; support a 63 bit shift, each shift where the count is in a reg expands
9548 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9550 ;; If the shift count is a constant, we need never emit more than one
9551 ;; shift pair, instead using moves and sign extension for counts greater
9552 ;; than 31.
9554 (define_insn "*<mshift><mode>3"
9555   [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9556         (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9557                                        (match_operand:QI 2 "immediate_operand" "i")))]
9558   "TARGET_AVX512F"
9559   "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9560   [(set_attr "type" "msklog")
9561    (set_attr "prefix" "vex")])
9563 (define_expand "ashl<mode>3"
9564   [(set (match_operand:SDWIM 0 "<shift_operand>")
9565         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9566                       (match_operand:QI 2 "nonmemory_operand")))]
9567   ""
9568   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9570 (define_insn "*ashl<mode>3_doubleword"
9571   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9572         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9573                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9574    (clobber (reg:CC FLAGS_REG))]
9575   ""
9576   "#"
9577   [(set_attr "type" "multi")])
9579 (define_split
9580   [(set (match_operand:DWI 0 "register_operand")
9581         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9582                     (match_operand:QI 2 "nonmemory_operand")))
9583    (clobber (reg:CC FLAGS_REG))]
9584   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9585   [(const_int 0)]
9586   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9588 ;; By default we don't ask for a scratch register, because when DWImode
9589 ;; values are manipulated, registers are already at a premium.  But if
9590 ;; we have one handy, we won't turn it away.
9592 (define_peephole2
9593   [(match_scratch:DWIH 3 "r")
9594    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9595                    (ashift:<DWI>
9596                      (match_operand:<DWI> 1 "nonmemory_operand")
9597                      (match_operand:QI 2 "nonmemory_operand")))
9598               (clobber (reg:CC FLAGS_REG))])
9599    (match_dup 3)]
9600   "TARGET_CMOVE"
9601   [(const_int 0)]
9602   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9604 (define_insn "x86_64_shld"
9605   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9606         (ior:DI (ashift:DI (match_dup 0)
9607                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9608                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9609                   (minus:QI (const_int 64) (match_dup 2)))))
9610    (clobber (reg:CC FLAGS_REG))]
9611   "TARGET_64BIT"
9612   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9613   [(set_attr "type" "ishift")
9614    (set_attr "prefix_0f" "1")
9615    (set_attr "mode" "DI")
9616    (set_attr "athlon_decode" "vector")
9617    (set_attr "amdfam10_decode" "vector")
9618    (set_attr "bdver1_decode" "vector")])
9620 (define_insn "x86_shld"
9621   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9622         (ior:SI (ashift:SI (match_dup 0)
9623                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9624                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9625                   (minus:QI (const_int 32) (match_dup 2)))))
9626    (clobber (reg:CC FLAGS_REG))]
9627   ""
9628   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9629   [(set_attr "type" "ishift")
9630    (set_attr "prefix_0f" "1")
9631    (set_attr "mode" "SI")
9632    (set_attr "pent_pair" "np")
9633    (set_attr "athlon_decode" "vector")
9634    (set_attr "amdfam10_decode" "vector")
9635    (set_attr "bdver1_decode" "vector")])
9637 (define_expand "x86_shift<mode>_adj_1"
9638   [(set (reg:CCZ FLAGS_REG)
9639         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9640                              (match_dup 4))
9641                      (const_int 0)))
9642    (set (match_operand:SWI48 0 "register_operand")
9643         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9644                             (match_operand:SWI48 1 "register_operand")
9645                             (match_dup 0)))
9646    (set (match_dup 1)
9647         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9648                             (match_operand:SWI48 3 "register_operand")
9649                             (match_dup 1)))]
9650   "TARGET_CMOVE"
9651   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9653 (define_expand "x86_shift<mode>_adj_2"
9654   [(use (match_operand:SWI48 0 "register_operand"))
9655    (use (match_operand:SWI48 1 "register_operand"))
9656    (use (match_operand:QI 2 "register_operand"))]
9657   ""
9659   rtx_code_label *label = gen_label_rtx ();
9660   rtx tmp;
9662   emit_insn (gen_testqi_ccz_1 (operands[2],
9663                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9665   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9666   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9667   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9668                               gen_rtx_LABEL_REF (VOIDmode, label),
9669                               pc_rtx);
9670   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9671   JUMP_LABEL (tmp) = label;
9673   emit_move_insn (operands[0], operands[1]);
9674   ix86_expand_clear (operands[1]);
9676   emit_label (label);
9677   LABEL_NUSES (label) = 1;
9679   DONE;
9682 ;; Avoid useless masking of count operand.
9683 (define_insn "*ashl<mode>3_mask"
9684   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9685         (ashift:SWI48
9686           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9687           (subreg:QI
9688             (and:SI
9689               (match_operand:SI 2 "register_operand" "c")
9690               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9693    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9694       == GET_MODE_BITSIZE (<MODE>mode)-1"
9696   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9698   [(set_attr "type" "ishift")
9699    (set_attr "mode" "<MODE>")])
9701 (define_insn "*bmi2_ashl<mode>3_1"
9702   [(set (match_operand:SWI48 0 "register_operand" "=r")
9703         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9704                       (match_operand:SWI48 2 "register_operand" "r")))]
9705   "TARGET_BMI2"
9706   "shlx\t{%2, %1, %0|%0, %1, %2}"
9707   [(set_attr "type" "ishiftx")
9708    (set_attr "mode" "<MODE>")])
9710 (define_insn "*ashl<mode>3_1"
9711   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9712         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9713                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9714    (clobber (reg:CC FLAGS_REG))]
9715   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9717   switch (get_attr_type (insn))
9718     {
9719     case TYPE_LEA:
9720     case TYPE_ISHIFTX:
9721       return "#";
9723     case TYPE_ALU:
9724       gcc_assert (operands[2] == const1_rtx);
9725       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9726       return "add{<imodesuffix>}\t%0, %0";
9728     default:
9729       if (operands[2] == const1_rtx
9730           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731         return "sal{<imodesuffix>}\t%0";
9732       else
9733         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9734     }
9736   [(set_attr "isa" "*,*,bmi2")
9737    (set (attr "type")
9738      (cond [(eq_attr "alternative" "1")
9739               (const_string "lea")
9740             (eq_attr "alternative" "2")
9741               (const_string "ishiftx")
9742             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9743                       (match_operand 0 "register_operand"))
9744                  (match_operand 2 "const1_operand"))
9745               (const_string "alu")
9746            ]
9747            (const_string "ishift")))
9748    (set (attr "length_immediate")
9749      (if_then_else
9750        (ior (eq_attr "type" "alu")
9751             (and (eq_attr "type" "ishift")
9752                  (and (match_operand 2 "const1_operand")
9753                       (ior (match_test "TARGET_SHIFT1")
9754                            (match_test "optimize_function_for_size_p (cfun)")))))
9755        (const_string "0")
9756        (const_string "*")))
9757    (set_attr "mode" "<MODE>")])
9759 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9760 (define_split
9761   [(set (match_operand:SWI48 0 "register_operand")
9762         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9763                       (match_operand:QI 2 "register_operand")))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "TARGET_BMI2 && reload_completed"
9766   [(set (match_dup 0)
9767         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9768   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9770 (define_insn "*bmi2_ashlsi3_1_zext"
9771   [(set (match_operand:DI 0 "register_operand" "=r")
9772         (zero_extend:DI
9773           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9774                      (match_operand:SI 2 "register_operand" "r"))))]
9775   "TARGET_64BIT && TARGET_BMI2"
9776   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9777   [(set_attr "type" "ishiftx")
9778    (set_attr "mode" "SI")])
9780 (define_insn "*ashlsi3_1_zext"
9781   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9782         (zero_extend:DI
9783           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9784                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9785    (clobber (reg:CC FLAGS_REG))]
9786   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9788   switch (get_attr_type (insn))
9789     {
9790     case TYPE_LEA:
9791     case TYPE_ISHIFTX:
9792       return "#";
9794     case TYPE_ALU:
9795       gcc_assert (operands[2] == const1_rtx);
9796       return "add{l}\t%k0, %k0";
9798     default:
9799       if (operands[2] == const1_rtx
9800           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9801         return "sal{l}\t%k0";
9802       else
9803         return "sal{l}\t{%2, %k0|%k0, %2}";
9804     }
9806   [(set_attr "isa" "*,*,bmi2")
9807    (set (attr "type")
9808      (cond [(eq_attr "alternative" "1")
9809               (const_string "lea")
9810             (eq_attr "alternative" "2")
9811               (const_string "ishiftx")
9812             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9813                  (match_operand 2 "const1_operand"))
9814               (const_string "alu")
9815            ]
9816            (const_string "ishift")))
9817    (set (attr "length_immediate")
9818      (if_then_else
9819        (ior (eq_attr "type" "alu")
9820             (and (eq_attr "type" "ishift")
9821                  (and (match_operand 2 "const1_operand")
9822                       (ior (match_test "TARGET_SHIFT1")
9823                            (match_test "optimize_function_for_size_p (cfun)")))))
9824        (const_string "0")
9825        (const_string "*")))
9826    (set_attr "mode" "SI")])
9828 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9829 (define_split
9830   [(set (match_operand:DI 0 "register_operand")
9831         (zero_extend:DI
9832           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9833                      (match_operand:QI 2 "register_operand"))))
9834    (clobber (reg:CC FLAGS_REG))]
9835   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9836   [(set (match_dup 0)
9837         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9838   "operands[2] = gen_lowpart (SImode, operands[2]);")
9840 (define_insn "*ashlhi3_1"
9841   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9842         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9843                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9847   switch (get_attr_type (insn))
9848     {
9849     case TYPE_LEA:
9850       return "#";
9852     case TYPE_ALU:
9853       gcc_assert (operands[2] == const1_rtx);
9854       return "add{w}\t%0, %0";
9856     default:
9857       if (operands[2] == const1_rtx
9858           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9859         return "sal{w}\t%0";
9860       else
9861         return "sal{w}\t{%2, %0|%0, %2}";
9862     }
9864   [(set (attr "type")
9865      (cond [(eq_attr "alternative" "1")
9866               (const_string "lea")
9867             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9868                       (match_operand 0 "register_operand"))
9869                  (match_operand 2 "const1_operand"))
9870               (const_string "alu")
9871            ]
9872            (const_string "ishift")))
9873    (set (attr "length_immediate")
9874      (if_then_else
9875        (ior (eq_attr "type" "alu")
9876             (and (eq_attr "type" "ishift")
9877                  (and (match_operand 2 "const1_operand")
9878                       (ior (match_test "TARGET_SHIFT1")
9879                            (match_test "optimize_function_for_size_p (cfun)")))))
9880        (const_string "0")
9881        (const_string "*")))
9882    (set_attr "mode" "HI,SI")])
9884 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9885 (define_insn "*ashlqi3_1"
9886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9887         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9888                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9889    (clobber (reg:CC FLAGS_REG))]
9890   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9892   switch (get_attr_type (insn))
9893     {
9894     case TYPE_LEA:
9895       return "#";
9897     case TYPE_ALU:
9898       gcc_assert (operands[2] == const1_rtx);
9899       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9900         return "add{l}\t%k0, %k0";
9901       else
9902         return "add{b}\t%0, %0";
9904     default:
9905       if (operands[2] == const1_rtx
9906           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9907         {
9908           if (get_attr_mode (insn) == MODE_SI)
9909             return "sal{l}\t%k0";
9910           else
9911             return "sal{b}\t%0";
9912         }
9913       else
9914         {
9915           if (get_attr_mode (insn) == MODE_SI)
9916             return "sal{l}\t{%2, %k0|%k0, %2}";
9917           else
9918             return "sal{b}\t{%2, %0|%0, %2}";
9919         }
9920     }
9922   [(set (attr "type")
9923      (cond [(eq_attr "alternative" "2")
9924               (const_string "lea")
9925             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9926                       (match_operand 0 "register_operand"))
9927                  (match_operand 2 "const1_operand"))
9928               (const_string "alu")
9929            ]
9930            (const_string "ishift")))
9931    (set (attr "length_immediate")
9932      (if_then_else
9933        (ior (eq_attr "type" "alu")
9934             (and (eq_attr "type" "ishift")
9935                  (and (match_operand 2 "const1_operand")
9936                       (ior (match_test "TARGET_SHIFT1")
9937                            (match_test "optimize_function_for_size_p (cfun)")))))
9938        (const_string "0")
9939        (const_string "*")))
9940    (set_attr "mode" "QI,SI,SI")])
9942 (define_insn "*ashlqi3_1_slp"
9943   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9944         (ashift:QI (match_dup 0)
9945                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9946    (clobber (reg:CC FLAGS_REG))]
9947   "(optimize_function_for_size_p (cfun)
9948     || !TARGET_PARTIAL_FLAG_REG_STALL
9949     || (operands[1] == const1_rtx
9950         && (TARGET_SHIFT1
9951             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9953   switch (get_attr_type (insn))
9954     {
9955     case TYPE_ALU:
9956       gcc_assert (operands[1] == const1_rtx);
9957       return "add{b}\t%0, %0";
9959     default:
9960       if (operands[1] == const1_rtx
9961           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962         return "sal{b}\t%0";
9963       else
9964         return "sal{b}\t{%1, %0|%0, %1}";
9965     }
9967   [(set (attr "type")
9968      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9969                       (match_operand 0 "register_operand"))
9970                  (match_operand 1 "const1_operand"))
9971               (const_string "alu")
9972            ]
9973            (const_string "ishift1")))
9974    (set (attr "length_immediate")
9975      (if_then_else
9976        (ior (eq_attr "type" "alu")
9977             (and (eq_attr "type" "ishift1")
9978                  (and (match_operand 1 "const1_operand")
9979                       (ior (match_test "TARGET_SHIFT1")
9980                            (match_test "optimize_function_for_size_p (cfun)")))))
9981        (const_string "0")
9982        (const_string "*")))
9983    (set_attr "mode" "QI")])
9985 ;; Convert ashift to the lea pattern to avoid flags dependency.
9986 (define_split
9987   [(set (match_operand 0 "register_operand")
9988         (ashift (match_operand 1 "index_register_operand")
9989                 (match_operand:QI 2 "const_int_operand")))
9990    (clobber (reg:CC FLAGS_REG))]
9991   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9992    && reload_completed
9993    && true_regnum (operands[0]) != true_regnum (operands[1])"
9994   [(const_int 0)]
9996   machine_mode mode = GET_MODE (operands[0]);
9997   rtx pat;
9999   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
10000     { 
10001       mode = SImode; 
10002       operands[0] = gen_lowpart (mode, operands[0]);
10003       operands[1] = gen_lowpart (mode, operands[1]);
10004     }
10006   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
10008   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
10010   emit_insn (gen_rtx_SET (operands[0], pat));
10011   DONE;
10014 ;; Convert ashift to the lea pattern to avoid flags dependency.
10015 (define_split
10016   [(set (match_operand:DI 0 "register_operand")
10017         (zero_extend:DI
10018           (ashift:SI (match_operand:SI 1 "index_register_operand")
10019                      (match_operand:QI 2 "const_int_operand"))))
10020    (clobber (reg:CC FLAGS_REG))]
10021   "TARGET_64BIT && reload_completed
10022    && true_regnum (operands[0]) != true_regnum (operands[1])"
10023   [(set (match_dup 0)
10024         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10026   operands[1] = gen_lowpart (SImode, operands[1]);
10027   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
10030 ;; This pattern can't accept a variable shift count, since shifts by
10031 ;; zero don't affect the flags.  We assume that shifts by constant
10032 ;; zero are optimized away.
10033 (define_insn "*ashl<mode>3_cmp"
10034   [(set (reg FLAGS_REG)
10035         (compare
10036           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10037                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10038           (const_int 0)))
10039    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10040         (ashift:SWI (match_dup 1) (match_dup 2)))]
10041   "(optimize_function_for_size_p (cfun)
10042     || !TARGET_PARTIAL_FLAG_REG_STALL
10043     || (operands[2] == const1_rtx
10044         && (TARGET_SHIFT1
10045             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10046    && ix86_match_ccmode (insn, CCGOCmode)
10047    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10049   switch (get_attr_type (insn))
10050     {
10051     case TYPE_ALU:
10052       gcc_assert (operands[2] == const1_rtx);
10053       return "add{<imodesuffix>}\t%0, %0";
10055     default:
10056       if (operands[2] == const1_rtx
10057           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10058         return "sal{<imodesuffix>}\t%0";
10059       else
10060         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10061     }
10063   [(set (attr "type")
10064      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10065                       (match_operand 0 "register_operand"))
10066                  (match_operand 2 "const1_operand"))
10067               (const_string "alu")
10068            ]
10069            (const_string "ishift")))
10070    (set (attr "length_immediate")
10071      (if_then_else
10072        (ior (eq_attr "type" "alu")
10073             (and (eq_attr "type" "ishift")
10074                  (and (match_operand 2 "const1_operand")
10075                       (ior (match_test "TARGET_SHIFT1")
10076                            (match_test "optimize_function_for_size_p (cfun)")))))
10077        (const_string "0")
10078        (const_string "*")))
10079    (set_attr "mode" "<MODE>")])
10081 (define_insn "*ashlsi3_cmp_zext"
10082   [(set (reg FLAGS_REG)
10083         (compare
10084           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10085                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10086           (const_int 0)))
10087    (set (match_operand:DI 0 "register_operand" "=r")
10088         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10089   "TARGET_64BIT
10090    && (optimize_function_for_size_p (cfun)
10091        || !TARGET_PARTIAL_FLAG_REG_STALL
10092        || (operands[2] == const1_rtx
10093            && (TARGET_SHIFT1
10094                || TARGET_DOUBLE_WITH_ADD)))
10095    && ix86_match_ccmode (insn, CCGOCmode)
10096    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10098   switch (get_attr_type (insn))
10099     {
10100     case TYPE_ALU:
10101       gcc_assert (operands[2] == const1_rtx);
10102       return "add{l}\t%k0, %k0";
10104     default:
10105       if (operands[2] == const1_rtx
10106           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10107         return "sal{l}\t%k0";
10108       else
10109         return "sal{l}\t{%2, %k0|%k0, %2}";
10110     }
10112   [(set (attr "type")
10113      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10114                  (match_operand 2 "const1_operand"))
10115               (const_string "alu")
10116            ]
10117            (const_string "ishift")))
10118    (set (attr "length_immediate")
10119      (if_then_else
10120        (ior (eq_attr "type" "alu")
10121             (and (eq_attr "type" "ishift")
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" "SI")])
10129 (define_insn "*ashl<mode>3_cconly"
10130   [(set (reg FLAGS_REG)
10131         (compare
10132           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10133                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10134           (const_int 0)))
10135    (clobber (match_scratch:SWI 0 "=<r>"))]
10136   "(optimize_function_for_size_p (cfun)
10137     || !TARGET_PARTIAL_FLAG_REG_STALL
10138     || (operands[2] == const1_rtx
10139         && (TARGET_SHIFT1
10140             || TARGET_DOUBLE_WITH_ADD)))
10141    && ix86_match_ccmode (insn, CCGOCmode)"
10143   switch (get_attr_type (insn))
10144     {
10145     case TYPE_ALU:
10146       gcc_assert (operands[2] == const1_rtx);
10147       return "add{<imodesuffix>}\t%0, %0";
10149     default:
10150       if (operands[2] == const1_rtx
10151           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10152         return "sal{<imodesuffix>}\t%0";
10153       else
10154         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10155     }
10157   [(set (attr "type")
10158      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10159                       (match_operand 0 "register_operand"))
10160                  (match_operand 2 "const1_operand"))
10161               (const_string "alu")
10162            ]
10163            (const_string "ishift")))
10164    (set (attr "length_immediate")
10165      (if_then_else
10166        (ior (eq_attr "type" "alu")
10167             (and (eq_attr "type" "ishift")
10168                  (and (match_operand 2 "const1_operand")
10169                       (ior (match_test "TARGET_SHIFT1")
10170                            (match_test "optimize_function_for_size_p (cfun)")))))
10171        (const_string "0")
10172        (const_string "*")))
10173    (set_attr "mode" "<MODE>")])
10175 ;; See comment above `ashl<mode>3' about how this works.
10177 (define_expand "<shift_insn><mode>3"
10178   [(set (match_operand:SDWIM 0 "<shift_operand>")
10179         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10180                            (match_operand:QI 2 "nonmemory_operand")))]
10181   ""
10182   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10184 ;; Avoid useless masking of count operand.
10185 (define_insn "*<shift_insn><mode>3_mask"
10186   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10187         (any_shiftrt:SWI48
10188           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10189           (subreg:QI
10190             (and:SI
10191               (match_operand:SI 2 "register_operand" "c")
10192               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10193    (clobber (reg:CC FLAGS_REG))]
10194   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10195    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10196       == GET_MODE_BITSIZE (<MODE>mode)-1"
10198   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10200   [(set_attr "type" "ishift")
10201    (set_attr "mode" "<MODE>")])
10203 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10204   [(set (match_operand:DWI 0 "register_operand" "=r")
10205         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10206                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10207    (clobber (reg:CC FLAGS_REG))]
10208   ""
10209   "#"
10210   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10211   [(const_int 0)]
10212   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10213   [(set_attr "type" "multi")])
10215 ;; By default we don't ask for a scratch register, because when DWImode
10216 ;; values are manipulated, registers are already at a premium.  But if
10217 ;; we have one handy, we won't turn it away.
10219 (define_peephole2
10220   [(match_scratch:DWIH 3 "r")
10221    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10222                    (any_shiftrt:<DWI>
10223                      (match_operand:<DWI> 1 "register_operand")
10224                      (match_operand:QI 2 "nonmemory_operand")))
10225               (clobber (reg:CC FLAGS_REG))])
10226    (match_dup 3)]
10227   "TARGET_CMOVE"
10228   [(const_int 0)]
10229   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10231 (define_insn "x86_64_shrd"
10232   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10233         (ior:DI (lshiftrt:DI (match_dup 0)
10234                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10235                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10236                   (minus:QI (const_int 64) (match_dup 2)))))
10237    (clobber (reg:CC FLAGS_REG))]
10238   "TARGET_64BIT"
10239   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10240   [(set_attr "type" "ishift")
10241    (set_attr "prefix_0f" "1")
10242    (set_attr "mode" "DI")
10243    (set_attr "athlon_decode" "vector")
10244    (set_attr "amdfam10_decode" "vector")
10245    (set_attr "bdver1_decode" "vector")])
10247 (define_insn "x86_shrd"
10248   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10249         (ior:SI (lshiftrt:SI (match_dup 0)
10250                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10251                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10252                   (minus:QI (const_int 32) (match_dup 2)))))
10253    (clobber (reg:CC FLAGS_REG))]
10254   ""
10255   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10256   [(set_attr "type" "ishift")
10257    (set_attr "prefix_0f" "1")
10258    (set_attr "mode" "SI")
10259    (set_attr "pent_pair" "np")
10260    (set_attr "athlon_decode" "vector")
10261    (set_attr "amdfam10_decode" "vector")
10262    (set_attr "bdver1_decode" "vector")])
10264 (define_insn "ashrdi3_cvt"
10265   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10266         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10267                      (match_operand:QI 2 "const_int_operand")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_64BIT && INTVAL (operands[2]) == 63
10270    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10271    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10272   "@
10273    {cqto|cqo}
10274    sar{q}\t{%2, %0|%0, %2}"
10275   [(set_attr "type" "imovx,ishift")
10276    (set_attr "prefix_0f" "0,*")
10277    (set_attr "length_immediate" "0,*")
10278    (set_attr "modrm" "0,1")
10279    (set_attr "mode" "DI")])
10281 (define_insn "ashrsi3_cvt"
10282   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10283         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10284                      (match_operand:QI 2 "const_int_operand")))
10285    (clobber (reg:CC FLAGS_REG))]
10286   "INTVAL (operands[2]) == 31
10287    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10288    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10289   "@
10290    {cltd|cdq}
10291    sar{l}\t{%2, %0|%0, %2}"
10292   [(set_attr "type" "imovx,ishift")
10293    (set_attr "prefix_0f" "0,*")
10294    (set_attr "length_immediate" "0,*")
10295    (set_attr "modrm" "0,1")
10296    (set_attr "mode" "SI")])
10298 (define_insn "*ashrsi3_cvt_zext"
10299   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10300         (zero_extend:DI
10301           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10302                        (match_operand:QI 2 "const_int_operand"))))
10303    (clobber (reg:CC FLAGS_REG))]
10304   "TARGET_64BIT && INTVAL (operands[2]) == 31
10305    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10306    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10307   "@
10308    {cltd|cdq}
10309    sar{l}\t{%2, %k0|%k0, %2}"
10310   [(set_attr "type" "imovx,ishift")
10311    (set_attr "prefix_0f" "0,*")
10312    (set_attr "length_immediate" "0,*")
10313    (set_attr "modrm" "0,1")
10314    (set_attr "mode" "SI")])
10316 (define_expand "x86_shift<mode>_adj_3"
10317   [(use (match_operand:SWI48 0 "register_operand"))
10318    (use (match_operand:SWI48 1 "register_operand"))
10319    (use (match_operand:QI 2 "register_operand"))]
10320   ""
10322   rtx_code_label *label = gen_label_rtx ();
10323   rtx tmp;
10325   emit_insn (gen_testqi_ccz_1 (operands[2],
10326                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10328   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10329   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10330   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10331                               gen_rtx_LABEL_REF (VOIDmode, label),
10332                               pc_rtx);
10333   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10334   JUMP_LABEL (tmp) = label;
10336   emit_move_insn (operands[0], operands[1]);
10337   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10338                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10339   emit_label (label);
10340   LABEL_NUSES (label) = 1;
10342   DONE;
10345 (define_insn "*bmi2_<shift_insn><mode>3_1"
10346   [(set (match_operand:SWI48 0 "register_operand" "=r")
10347         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10348                            (match_operand:SWI48 2 "register_operand" "r")))]
10349   "TARGET_BMI2"
10350   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10351   [(set_attr "type" "ishiftx")
10352    (set_attr "mode" "<MODE>")])
10354 (define_insn "*<shift_insn><mode>3_1"
10355   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10356         (any_shiftrt:SWI48
10357           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10358           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10362   switch (get_attr_type (insn))
10363     {
10364     case TYPE_ISHIFTX:
10365       return "#";
10367     default:
10368       if (operands[2] == const1_rtx
10369           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370         return "<shift>{<imodesuffix>}\t%0";
10371       else
10372         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10373     }
10375   [(set_attr "isa" "*,bmi2")
10376    (set_attr "type" "ishift,ishiftx")
10377    (set (attr "length_immediate")
10378      (if_then_else
10379        (and (match_operand 2 "const1_operand")
10380             (ior (match_test "TARGET_SHIFT1")
10381                  (match_test "optimize_function_for_size_p (cfun)")))
10382        (const_string "0")
10383        (const_string "*")))
10384    (set_attr "mode" "<MODE>")])
10386 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10387 (define_split
10388   [(set (match_operand:SWI48 0 "register_operand")
10389         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10390                            (match_operand:QI 2 "register_operand")))
10391    (clobber (reg:CC FLAGS_REG))]
10392   "TARGET_BMI2 && reload_completed"
10393   [(set (match_dup 0)
10394         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10395   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10397 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10398   [(set (match_operand:DI 0 "register_operand" "=r")
10399         (zero_extend:DI
10400           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10401                           (match_operand:SI 2 "register_operand" "r"))))]
10402   "TARGET_64BIT && TARGET_BMI2"
10403   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10404   [(set_attr "type" "ishiftx")
10405    (set_attr "mode" "SI")])
10407 (define_insn "*<shift_insn>si3_1_zext"
10408   [(set (match_operand:DI 0 "register_operand" "=r,r")
10409         (zero_extend:DI
10410           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10411                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10412    (clobber (reg:CC FLAGS_REG))]
10413   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10415   switch (get_attr_type (insn))
10416     {
10417     case TYPE_ISHIFTX:
10418       return "#";
10420     default:
10421       if (operands[2] == const1_rtx
10422           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10423         return "<shift>{l}\t%k0";
10424       else
10425         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10426     }
10428   [(set_attr "isa" "*,bmi2")
10429    (set_attr "type" "ishift,ishiftx")
10430    (set (attr "length_immediate")
10431      (if_then_else
10432        (and (match_operand 2 "const1_operand")
10433             (ior (match_test "TARGET_SHIFT1")
10434                  (match_test "optimize_function_for_size_p (cfun)")))
10435        (const_string "0")
10436        (const_string "*")))
10437    (set_attr "mode" "SI")])
10439 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10440 (define_split
10441   [(set (match_operand:DI 0 "register_operand")
10442         (zero_extend:DI
10443           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10444                           (match_operand:QI 2 "register_operand"))))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10447   [(set (match_dup 0)
10448         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10449   "operands[2] = gen_lowpart (SImode, operands[2]);")
10451 (define_insn "*<shift_insn><mode>3_1"
10452   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10453         (any_shiftrt:SWI12
10454           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10455           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10456    (clobber (reg:CC FLAGS_REG))]
10457   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10459   if (operands[2] == const1_rtx
10460       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10461     return "<shift>{<imodesuffix>}\t%0";
10462   else
10463     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10465   [(set_attr "type" "ishift")
10466    (set (attr "length_immediate")
10467      (if_then_else
10468        (and (match_operand 2 "const1_operand")
10469             (ior (match_test "TARGET_SHIFT1")
10470                  (match_test "optimize_function_for_size_p (cfun)")))
10471        (const_string "0")
10472        (const_string "*")))
10473    (set_attr "mode" "<MODE>")])
10475 (define_insn "*<shift_insn>qi3_1_slp"
10476   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10477         (any_shiftrt:QI (match_dup 0)
10478                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10479    (clobber (reg:CC FLAGS_REG))]
10480   "(optimize_function_for_size_p (cfun)
10481     || !TARGET_PARTIAL_REG_STALL
10482     || (operands[1] == const1_rtx
10483         && TARGET_SHIFT1))"
10485   if (operands[1] == const1_rtx
10486       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10487     return "<shift>{b}\t%0";
10488   else
10489     return "<shift>{b}\t{%1, %0|%0, %1}";
10491   [(set_attr "type" "ishift1")
10492    (set (attr "length_immediate")
10493      (if_then_else
10494        (and (match_operand 1 "const1_operand")
10495             (ior (match_test "TARGET_SHIFT1")
10496                  (match_test "optimize_function_for_size_p (cfun)")))
10497        (const_string "0")
10498        (const_string "*")))
10499    (set_attr "mode" "QI")])
10501 ;; This pattern can't accept a variable shift count, since shifts by
10502 ;; zero don't affect the flags.  We assume that shifts by constant
10503 ;; zero are optimized away.
10504 (define_insn "*<shift_insn><mode>3_cmp"
10505   [(set (reg FLAGS_REG)
10506         (compare
10507           (any_shiftrt:SWI
10508             (match_operand:SWI 1 "nonimmediate_operand" "0")
10509             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10510           (const_int 0)))
10511    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10512         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10513   "(optimize_function_for_size_p (cfun)
10514     || !TARGET_PARTIAL_FLAG_REG_STALL
10515     || (operands[2] == const1_rtx
10516         && TARGET_SHIFT1))
10517    && ix86_match_ccmode (insn, CCGOCmode)
10518    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10520   if (operands[2] == const1_rtx
10521       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10522     return "<shift>{<imodesuffix>}\t%0";
10523   else
10524     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10526   [(set_attr "type" "ishift")
10527    (set (attr "length_immediate")
10528      (if_then_else
10529        (and (match_operand 2 "const1_operand")
10530             (ior (match_test "TARGET_SHIFT1")
10531                  (match_test "optimize_function_for_size_p (cfun)")))
10532        (const_string "0")
10533        (const_string "*")))
10534    (set_attr "mode" "<MODE>")])
10536 (define_insn "*<shift_insn>si3_cmp_zext"
10537   [(set (reg FLAGS_REG)
10538         (compare
10539           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10540                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10541           (const_int 0)))
10542    (set (match_operand:DI 0 "register_operand" "=r")
10543         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10544   "TARGET_64BIT
10545    && (optimize_function_for_size_p (cfun)
10546        || !TARGET_PARTIAL_FLAG_REG_STALL
10547        || (operands[2] == const1_rtx
10548            && TARGET_SHIFT1))
10549    && ix86_match_ccmode (insn, CCGOCmode)
10550    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10552   if (operands[2] == const1_rtx
10553       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10554     return "<shift>{l}\t%k0";
10555   else
10556     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10558   [(set_attr "type" "ishift")
10559    (set (attr "length_immediate")
10560      (if_then_else
10561        (and (match_operand 2 "const1_operand")
10562             (ior (match_test "TARGET_SHIFT1")
10563                  (match_test "optimize_function_for_size_p (cfun)")))
10564        (const_string "0")
10565        (const_string "*")))
10566    (set_attr "mode" "SI")])
10568 (define_insn "*<shift_insn><mode>3_cconly"
10569   [(set (reg FLAGS_REG)
10570         (compare
10571           (any_shiftrt:SWI
10572             (match_operand:SWI 1 "register_operand" "0")
10573             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10574           (const_int 0)))
10575    (clobber (match_scratch:SWI 0 "=<r>"))]
10576   "(optimize_function_for_size_p (cfun)
10577     || !TARGET_PARTIAL_FLAG_REG_STALL
10578     || (operands[2] == const1_rtx
10579         && TARGET_SHIFT1))
10580    && ix86_match_ccmode (insn, CCGOCmode)"
10582   if (operands[2] == const1_rtx
10583       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10584     return "<shift>{<imodesuffix>}\t%0";
10585   else
10586     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10588   [(set_attr "type" "ishift")
10589    (set (attr "length_immediate")
10590      (if_then_else
10591        (and (match_operand 2 "const1_operand")
10592             (ior (match_test "TARGET_SHIFT1")
10593                  (match_test "optimize_function_for_size_p (cfun)")))
10594        (const_string "0")
10595        (const_string "*")))
10596    (set_attr "mode" "<MODE>")])
10598 ;; Rotate instructions
10600 (define_expand "<rotate_insn>ti3"
10601   [(set (match_operand:TI 0 "register_operand")
10602         (any_rotate:TI (match_operand:TI 1 "register_operand")
10603                        (match_operand:QI 2 "nonmemory_operand")))]
10604   "TARGET_64BIT"
10606   if (const_1_to_63_operand (operands[2], VOIDmode))
10607     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10608                 (operands[0], operands[1], operands[2]));
10609   else
10610     FAIL;
10612   DONE;
10615 (define_expand "<rotate_insn>di3"
10616   [(set (match_operand:DI 0 "shiftdi_operand")
10617         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10618                        (match_operand:QI 2 "nonmemory_operand")))]
10619  ""
10621   if (TARGET_64BIT)
10622     ix86_expand_binary_operator (<CODE>, DImode, operands);
10623   else if (const_1_to_31_operand (operands[2], VOIDmode))
10624     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10625                 (operands[0], operands[1], operands[2]));
10626   else
10627     FAIL;
10629   DONE;
10632 (define_expand "<rotate_insn><mode>3"
10633   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10634         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10635                             (match_operand:QI 2 "nonmemory_operand")))]
10636   ""
10637   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10639 ;; Avoid useless masking of count operand.
10640 (define_insn "*<rotate_insn><mode>3_mask"
10641   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10642         (any_rotate:SWI48
10643           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10644           (subreg:QI
10645             (and:SI
10646               (match_operand:SI 2 "register_operand" "c")
10647               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10648    (clobber (reg:CC FLAGS_REG))]
10649   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10650    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10651       == GET_MODE_BITSIZE (<MODE>mode)-1"
10653   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10655   [(set_attr "type" "rotate")
10656    (set_attr "mode" "<MODE>")])
10658 ;; Implement rotation using two double-precision
10659 ;; shift instructions and a scratch register.
10661 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10662  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10663        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10664                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10665   (clobber (reg:CC FLAGS_REG))
10666   (clobber (match_scratch:DWIH 3 "=&r"))]
10667  ""
10668  "#"
10669  "reload_completed"
10670  [(set (match_dup 3) (match_dup 4))
10671   (parallel
10672    [(set (match_dup 4)
10673          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10674                    (lshiftrt:DWIH (match_dup 5)
10675                                   (minus:QI (match_dup 6) (match_dup 2)))))
10676     (clobber (reg:CC FLAGS_REG))])
10677   (parallel
10678    [(set (match_dup 5)
10679          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10680                    (lshiftrt:DWIH (match_dup 3)
10681                                   (minus:QI (match_dup 6) (match_dup 2)))))
10682     (clobber (reg:CC FLAGS_REG))])]
10684   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10686   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10689 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10690  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10691        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10692                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10693   (clobber (reg:CC FLAGS_REG))
10694   (clobber (match_scratch:DWIH 3 "=&r"))]
10695  ""
10696  "#"
10697  "reload_completed"
10698  [(set (match_dup 3) (match_dup 4))
10699   (parallel
10700    [(set (match_dup 4)
10701          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10702                    (ashift:DWIH (match_dup 5)
10703                                 (minus:QI (match_dup 6) (match_dup 2)))))
10704     (clobber (reg:CC FLAGS_REG))])
10705   (parallel
10706    [(set (match_dup 5)
10707          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10708                    (ashift:DWIH (match_dup 3)
10709                                 (minus:QI (match_dup 6) (match_dup 2)))))
10710     (clobber (reg:CC FLAGS_REG))])]
10712   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10714   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10717 (define_insn "*bmi2_rorx<mode>3_1"
10718   [(set (match_operand:SWI48 0 "register_operand" "=r")
10719         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10720                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10721   "TARGET_BMI2"
10722   "rorx\t{%2, %1, %0|%0, %1, %2}"
10723   [(set_attr "type" "rotatex")
10724    (set_attr "mode" "<MODE>")])
10726 (define_insn "*<rotate_insn><mode>3_1"
10727   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10728         (any_rotate:SWI48
10729           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10730           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10731    (clobber (reg:CC FLAGS_REG))]
10732   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10734   switch (get_attr_type (insn))
10735     {
10736     case TYPE_ROTATEX:
10737       return "#";
10739     default:
10740       if (operands[2] == const1_rtx
10741           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742         return "<rotate>{<imodesuffix>}\t%0";
10743       else
10744         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10745     }
10747   [(set_attr "isa" "*,bmi2")
10748    (set_attr "type" "rotate,rotatex")
10749    (set (attr "length_immediate")
10750      (if_then_else
10751        (and (eq_attr "type" "rotate")
10752             (and (match_operand 2 "const1_operand")
10753                  (ior (match_test "TARGET_SHIFT1")
10754                       (match_test "optimize_function_for_size_p (cfun)"))))
10755        (const_string "0")
10756        (const_string "*")))
10757    (set_attr "mode" "<MODE>")])
10759 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10760 (define_split
10761   [(set (match_operand:SWI48 0 "register_operand")
10762         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10763                       (match_operand:QI 2 "immediate_operand")))
10764    (clobber (reg:CC FLAGS_REG))]
10765   "TARGET_BMI2 && reload_completed"
10766   [(set (match_dup 0)
10767         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10769   operands[2]
10770     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10773 (define_split
10774   [(set (match_operand:SWI48 0 "register_operand")
10775         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10776                         (match_operand:QI 2 "immediate_operand")))
10777    (clobber (reg:CC FLAGS_REG))]
10778   "TARGET_BMI2 && reload_completed"
10779   [(set (match_dup 0)
10780         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10782 (define_insn "*bmi2_rorxsi3_1_zext"
10783   [(set (match_operand:DI 0 "register_operand" "=r")
10784         (zero_extend:DI
10785           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10786                        (match_operand:QI 2 "immediate_operand" "I"))))]
10787   "TARGET_64BIT && TARGET_BMI2"
10788   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10789   [(set_attr "type" "rotatex")
10790    (set_attr "mode" "SI")])
10792 (define_insn "*<rotate_insn>si3_1_zext"
10793   [(set (match_operand:DI 0 "register_operand" "=r,r")
10794         (zero_extend:DI
10795           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10796                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10797    (clobber (reg:CC FLAGS_REG))]
10798   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10800   switch (get_attr_type (insn))
10801     {
10802     case TYPE_ROTATEX:
10803       return "#";
10805     default:
10806       if (operands[2] == const1_rtx
10807           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10808         return "<rotate>{l}\t%k0";
10809       else
10810         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10811     }
10813   [(set_attr "isa" "*,bmi2")
10814    (set_attr "type" "rotate,rotatex")
10815    (set (attr "length_immediate")
10816      (if_then_else
10817        (and (eq_attr "type" "rotate")
10818             (and (match_operand 2 "const1_operand")
10819                  (ior (match_test "TARGET_SHIFT1")
10820                       (match_test "optimize_function_for_size_p (cfun)"))))
10821        (const_string "0")
10822        (const_string "*")))
10823    (set_attr "mode" "SI")])
10825 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10826 (define_split
10827   [(set (match_operand:DI 0 "register_operand")
10828         (zero_extend:DI
10829           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10830                      (match_operand:QI 2 "immediate_operand"))))
10831    (clobber (reg:CC FLAGS_REG))]
10832   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10833   [(set (match_dup 0)
10834         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10836   operands[2]
10837     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10840 (define_split
10841   [(set (match_operand:DI 0 "register_operand")
10842         (zero_extend:DI
10843           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10844                        (match_operand:QI 2 "immediate_operand"))))
10845    (clobber (reg:CC FLAGS_REG))]
10846   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10847   [(set (match_dup 0)
10848         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10850 (define_insn "*<rotate_insn><mode>3_1"
10851   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10852         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10853                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10854    (clobber (reg:CC FLAGS_REG))]
10855   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10857   if (operands[2] == const1_rtx
10858       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10859     return "<rotate>{<imodesuffix>}\t%0";
10860   else
10861     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10863   [(set_attr "type" "rotate")
10864    (set (attr "length_immediate")
10865      (if_then_else
10866        (and (match_operand 2 "const1_operand")
10867             (ior (match_test "TARGET_SHIFT1")
10868                  (match_test "optimize_function_for_size_p (cfun)")))
10869        (const_string "0")
10870        (const_string "*")))
10871    (set_attr "mode" "<MODE>")])
10873 (define_insn "*<rotate_insn>qi3_1_slp"
10874   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10875         (any_rotate:QI (match_dup 0)
10876                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10877    (clobber (reg:CC FLAGS_REG))]
10878   "(optimize_function_for_size_p (cfun)
10879     || !TARGET_PARTIAL_REG_STALL
10880     || (operands[1] == const1_rtx
10881         && TARGET_SHIFT1))"
10883   if (operands[1] == const1_rtx
10884       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10885     return "<rotate>{b}\t%0";
10886   else
10887     return "<rotate>{b}\t{%1, %0|%0, %1}";
10889   [(set_attr "type" "rotate1")
10890    (set (attr "length_immediate")
10891      (if_then_else
10892        (and (match_operand 1 "const1_operand")
10893             (ior (match_test "TARGET_SHIFT1")
10894                  (match_test "optimize_function_for_size_p (cfun)")))
10895        (const_string "0")
10896        (const_string "*")))
10897    (set_attr "mode" "QI")])
10899 (define_split
10900  [(set (match_operand:HI 0 "register_operand")
10901        (any_rotate:HI (match_dup 0) (const_int 8)))
10902   (clobber (reg:CC FLAGS_REG))]
10903  "reload_completed
10904   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10905  [(parallel [(set (strict_low_part (match_dup 0))
10906                   (bswap:HI (match_dup 0)))
10907              (clobber (reg:CC FLAGS_REG))])])
10909 ;; Bit set / bit test instructions
10911 ;; %%% bts, btr, btc, bt.
10912 ;; In general these instructions are *slow* when applied to memory,
10913 ;; since they enforce atomic operation.  When applied to registers,
10914 ;; it depends on the cpu implementation.  They're never faster than
10915 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10916 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10917 ;; within the instruction itself, so operating on bits in the high
10918 ;; 32-bits of a register becomes easier.
10920 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10921 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10922 ;; negdf respectively, so they can never be disabled entirely.
10924 (define_insn "*btsq"
10925   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10926                          (const_int 1)
10927                          (match_operand 1 "const_0_to_63_operand" "J"))
10928         (const_int 1))
10929    (clobber (reg:CC FLAGS_REG))]
10930   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10931   "bts{q}\t{%1, %0|%0, %1}"
10932   [(set_attr "type" "alu1")
10933    (set_attr "prefix_0f" "1")
10934    (set_attr "znver1_decode" "double")
10935    (set_attr "mode" "DI")])
10937 (define_insn "*btrq"
10938   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10939                          (const_int 1)
10940                          (match_operand 1 "const_0_to_63_operand" "J"))
10941         (const_int 0))
10942    (clobber (reg:CC FLAGS_REG))]
10943   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10944   "btr{q}\t{%1, %0|%0, %1}"
10945   [(set_attr "type" "alu1")
10946    (set_attr "prefix_0f" "1")
10947    (set_attr "znver1_decode" "double")
10948    (set_attr "mode" "DI")])
10950 (define_insn "*btcq"
10951   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10952                          (const_int 1)
10953                          (match_operand 1 "const_0_to_63_operand" "J"))
10954         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10955    (clobber (reg:CC FLAGS_REG))]
10956   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10957   "btc{q}\t{%1, %0|%0, %1}"
10958   [(set_attr "type" "alu1")
10959    (set_attr "prefix_0f" "1")
10960    (set_attr "znver1_decode" "double")
10961    (set_attr "mode" "DI")])
10963 ;; Allow Nocona to avoid these instructions if a register is available.
10965 (define_peephole2
10966   [(match_scratch:DI 2 "r")
10967    (parallel [(set (zero_extract:DI
10968                      (match_operand:DI 0 "register_operand")
10969                      (const_int 1)
10970                      (match_operand 1 "const_0_to_63_operand"))
10971                    (const_int 1))
10972               (clobber (reg:CC FLAGS_REG))])]
10973   "TARGET_64BIT && !TARGET_USE_BT"
10974   [(const_int 0)]
10976   int i = INTVAL (operands[1]);
10978   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10980   if (i >= 31)
10981     {
10982       emit_move_insn (operands[2], op1);
10983       op1 = operands[2];
10984     }
10986   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10987   DONE;
10990 (define_peephole2
10991   [(match_scratch:DI 2 "r")
10992    (parallel [(set (zero_extract:DI
10993                      (match_operand:DI 0 "register_operand")
10994                      (const_int 1)
10995                      (match_operand 1 "const_0_to_63_operand"))
10996                    (const_int 0))
10997               (clobber (reg:CC FLAGS_REG))])]
10998   "TARGET_64BIT && !TARGET_USE_BT"
10999   [(const_int 0)]
11001   int i = INTVAL (operands[1]);
11003   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11005   if (i >= 32)
11006     {
11007       emit_move_insn (operands[2], op1);
11008       op1 = operands[2];
11009     }
11011   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
11012   DONE;
11015 (define_peephole2
11016   [(match_scratch:DI 2 "r")
11017    (parallel [(set (zero_extract:DI
11018                      (match_operand:DI 0 "register_operand")
11019                      (const_int 1)
11020                      (match_operand 1 "const_0_to_63_operand"))
11021               (not:DI (zero_extract:DI
11022                         (match_dup 0) (const_int 1) (match_dup 1))))
11023               (clobber (reg:CC FLAGS_REG))])]
11024   "TARGET_64BIT && !TARGET_USE_BT"
11025   [(const_int 0)]
11027   int i = INTVAL (operands[1]);
11029   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11031   if (i >= 31)
11032     {
11033       emit_move_insn (operands[2], op1);
11034       op1 = operands[2];
11035     }
11037   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
11038   DONE;
11041 (define_insn "*bt<mode>"
11042   [(set (reg:CCC FLAGS_REG)
11043         (compare:CCC
11044           (zero_extract:SWI48
11045             (match_operand:SWI48 0 "register_operand" "r")
11046             (const_int 1)
11047             (match_operand:SI 1 "nonmemory_operand" "rN"))
11048           (const_int 0)))]
11049   ""
11051   switch (get_attr_mode (insn))
11052     {
11053     case MODE_SI:
11054       return "bt{l}\t{%1, %k0|%k0, %1}";
11056     case MODE_DI:
11057       return "bt{q}\t{%q1, %0|%0, %q1}";
11059     default:
11060       gcc_unreachable ();
11061     }
11063   [(set_attr "type" "alu1")
11064    (set_attr "prefix_0f" "1")
11065    (set (attr "mode")
11066         (if_then_else
11067           (and (match_test "CONST_INT_P (operands[1])")
11068                (match_test "INTVAL (operands[1]) < 32"))
11069           (const_string "SI")
11070           (const_string "<MODE>")))])
11072 (define_insn_and_split "*jcc_bt<mode>"
11073   [(set (pc)
11074         (if_then_else (match_operator 0 "bt_comparison_operator"
11075                         [(zero_extract:SWI48
11076                            (match_operand:SWI48 1 "register_operand")
11077                            (const_int 1)
11078                            (match_operand:SI 2 "nonmemory_operand"))
11079                          (const_int 0)])
11080                       (label_ref (match_operand 3))
11081                       (pc)))
11082    (clobber (reg:CC FLAGS_REG))]
11083   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11084    && (CONST_INT_P (operands[2])
11085        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11086           && INTVAL (operands[2])
11087                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11088        : register_operand (operands[2], SImode))
11089    && can_create_pseudo_p ()"
11090   "#"
11091   "&& 1"
11092   [(set (reg:CCC FLAGS_REG)
11093         (compare:CCC
11094           (zero_extract:SWI48
11095             (match_dup 1)
11096             (const_int 1)
11097             (match_dup 2))
11098           (const_int 0)))
11099    (set (pc)
11100         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11101                       (label_ref (match_dup 3))
11102                       (pc)))]
11104   operands[0] = shallow_copy_rtx (operands[0]);
11105   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11108 (define_insn_and_split "*jcc_bt<mode>_1"
11109   [(set (pc)
11110         (if_then_else (match_operator 0 "bt_comparison_operator"
11111                         [(zero_extract:SWI48
11112                            (match_operand:SWI48 1 "register_operand")
11113                            (const_int 1)
11114                            (zero_extend:SI
11115                              (match_operand:QI 2 "register_operand")))
11116                          (const_int 0)])
11117                       (label_ref (match_operand 3))
11118                       (pc)))
11119    (clobber (reg:CC FLAGS_REG))]
11120   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11121    && can_create_pseudo_p ()"
11122   "#"
11123   "&& 1"
11124   [(set (reg:CCC FLAGS_REG)
11125         (compare:CCC
11126           (zero_extract:SWI48
11127             (match_dup 1)
11128             (const_int 1)
11129             (match_dup 2))
11130           (const_int 0)))
11131    (set (pc)
11132         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11133                       (label_ref (match_dup 3))
11134                       (pc)))]
11136   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11137   operands[0] = shallow_copy_rtx (operands[0]);
11138   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11141 ;; Avoid useless masking of bit offset operand.
11142 (define_insn_and_split "*jcc_bt<mode>_mask"
11143   [(set (pc)
11144         (if_then_else (match_operator 0 "bt_comparison_operator"
11145                         [(zero_extract:SWI48
11146                            (match_operand:SWI48 1 "register_operand")
11147                            (const_int 1)
11148                            (and:SI
11149                              (match_operand:SI 2 "register_operand")
11150                              (match_operand 3 "const_int_operand")))])
11151                       (label_ref (match_operand 4))
11152                       (pc)))
11153    (clobber (reg:CC FLAGS_REG))]
11154   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11155    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11156       == GET_MODE_BITSIZE (<MODE>mode)-1
11157    && can_create_pseudo_p ()"
11158   "#"
11159   "&& 1"
11160   [(set (reg:CCC FLAGS_REG)
11161         (compare:CCC
11162           (zero_extract:SWI48
11163             (match_dup 1)
11164             (const_int 1)
11165             (match_dup 2))
11166           (const_int 0)))
11167    (set (pc)
11168         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11169                       (label_ref (match_dup 4))
11170                       (pc)))]
11172   operands[0] = shallow_copy_rtx (operands[0]);
11173   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11176 ;; Store-flag instructions.
11178 ;; For all sCOND expanders, also expand the compare or test insn that
11179 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11181 (define_insn_and_split "*setcc_di_1"
11182   [(set (match_operand:DI 0 "register_operand" "=q")
11183         (match_operator:DI 1 "ix86_comparison_operator"
11184           [(reg FLAGS_REG) (const_int 0)]))]
11185   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11186   "#"
11187   "&& reload_completed"
11188   [(set (match_dup 2) (match_dup 1))
11189    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11191   operands[1] = shallow_copy_rtx (operands[1]);
11192   PUT_MODE (operands[1], QImode);
11193   operands[2] = gen_lowpart (QImode, operands[0]);
11196 (define_insn_and_split "*setcc_si_1_and"
11197   [(set (match_operand:SI 0 "register_operand" "=q")
11198         (match_operator:SI 1 "ix86_comparison_operator"
11199           [(reg FLAGS_REG) (const_int 0)]))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "!TARGET_PARTIAL_REG_STALL
11202    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11203   "#"
11204   "&& reload_completed"
11205   [(set (match_dup 2) (match_dup 1))
11206    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11207               (clobber (reg:CC FLAGS_REG))])]
11209   operands[1] = shallow_copy_rtx (operands[1]);
11210   PUT_MODE (operands[1], QImode);
11211   operands[2] = gen_lowpart (QImode, operands[0]);
11214 (define_insn_and_split "*setcc_si_1_movzbl"
11215   [(set (match_operand:SI 0 "register_operand" "=q")
11216         (match_operator:SI 1 "ix86_comparison_operator"
11217           [(reg FLAGS_REG) (const_int 0)]))]
11218   "!TARGET_PARTIAL_REG_STALL
11219    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11220   "#"
11221   "&& reload_completed"
11222   [(set (match_dup 2) (match_dup 1))
11223    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11225   operands[1] = shallow_copy_rtx (operands[1]);
11226   PUT_MODE (operands[1], QImode);
11227   operands[2] = gen_lowpart (QImode, operands[0]);
11230 (define_insn "*setcc_qi"
11231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11232         (match_operator:QI 1 "ix86_comparison_operator"
11233           [(reg FLAGS_REG) (const_int 0)]))]
11234   ""
11235   "set%C1\t%0"
11236   [(set_attr "type" "setcc")
11237    (set_attr "mode" "QI")])
11239 (define_insn "*setcc_qi_slp"
11240   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11241         (match_operator:QI 1 "ix86_comparison_operator"
11242           [(reg FLAGS_REG) (const_int 0)]))]
11243   ""
11244   "set%C1\t%0"
11245   [(set_attr "type" "setcc")
11246    (set_attr "mode" "QI")])
11248 ;; In general it is not safe to assume too much about CCmode registers,
11249 ;; so simplify-rtx stops when it sees a second one.  Under certain
11250 ;; conditions this is safe on x86, so help combine not create
11252 ;;      seta    %al
11253 ;;      testb   %al, %al
11254 ;;      sete    %al
11256 (define_split
11257   [(set (match_operand:QI 0 "nonimmediate_operand")
11258         (ne:QI (match_operator 1 "ix86_comparison_operator"
11259                  [(reg FLAGS_REG) (const_int 0)])
11260             (const_int 0)))]
11261   ""
11262   [(set (match_dup 0) (match_dup 1))]
11264   operands[1] = shallow_copy_rtx (operands[1]);
11265   PUT_MODE (operands[1], QImode);
11268 (define_split
11269   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11270         (ne:QI (match_operator 1 "ix86_comparison_operator"
11271                  [(reg FLAGS_REG) (const_int 0)])
11272             (const_int 0)))]
11273   ""
11274   [(set (match_dup 0) (match_dup 1))]
11276   operands[1] = shallow_copy_rtx (operands[1]);
11277   PUT_MODE (operands[1], QImode);
11280 (define_split
11281   [(set (match_operand:QI 0 "nonimmediate_operand")
11282         (eq:QI (match_operator 1 "ix86_comparison_operator"
11283                  [(reg FLAGS_REG) (const_int 0)])
11284             (const_int 0)))]
11285   ""
11286   [(set (match_dup 0) (match_dup 1))]
11288   operands[1] = shallow_copy_rtx (operands[1]);
11289   PUT_MODE (operands[1], QImode);
11290   PUT_CODE (operands[1],
11291             ix86_reverse_condition (GET_CODE (operands[1]),
11292                                     GET_MODE (XEXP (operands[1], 0))));
11294   /* Make sure that (a) the CCmode we have for the flags is strong
11295      enough for the reversed compare or (b) we have a valid FP compare.  */
11296   if (! ix86_comparison_operator (operands[1], VOIDmode))
11297     FAIL;
11300 (define_split
11301   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11302         (eq:QI (match_operator 1 "ix86_comparison_operator"
11303                  [(reg FLAGS_REG) (const_int 0)])
11304             (const_int 0)))]
11305   ""
11306   [(set (match_dup 0) (match_dup 1))]
11308   operands[1] = shallow_copy_rtx (operands[1]);
11309   PUT_MODE (operands[1], QImode);
11310   PUT_CODE (operands[1],
11311             ix86_reverse_condition (GET_CODE (operands[1]),
11312                                     GET_MODE (XEXP (operands[1], 0))));
11314   /* Make sure that (a) the CCmode we have for the flags is strong
11315      enough for the reversed compare or (b) we have a valid FP compare.  */
11316   if (! ix86_comparison_operator (operands[1], VOIDmode))
11317     FAIL;
11320 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11321 ;; subsequent logical operations are used to imitate conditional moves.
11322 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11323 ;; it directly.
11325 (define_insn "setcc_<mode>_sse"
11326   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11327         (match_operator:MODEF 3 "sse_comparison_operator"
11328           [(match_operand:MODEF 1 "register_operand" "0,x")
11329            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11330   "SSE_FLOAT_MODE_P (<MODE>mode)"
11331   "@
11332    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11333    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11334   [(set_attr "isa" "noavx,avx")
11335    (set_attr "type" "ssecmp")
11336    (set_attr "length_immediate" "1")
11337    (set_attr "prefix" "orig,vex")
11338    (set_attr "mode" "<MODE>")])
11340 ;; Basic conditional jump instructions.
11341 ;; We ignore the overflow flag for signed branch instructions.
11343 (define_insn "*jcc_1"
11344   [(set (pc)
11345         (if_then_else (match_operator 1 "ix86_comparison_operator"
11346                                       [(reg FLAGS_REG) (const_int 0)])
11347                       (label_ref (match_operand 0))
11348                       (pc)))]
11349   ""
11350   "%!%+j%C1\t%l0"
11351   [(set_attr "type" "ibr")
11352    (set_attr "modrm" "0")
11353    (set (attr "length")
11354         (if_then_else
11355           (and (ge (minus (match_dup 0) (pc))
11356                    (const_int -126))
11357                (lt (minus (match_dup 0) (pc))
11358                    (const_int 128)))
11359           (const_int 2)
11360           (const_int 6)))
11361    (set_attr "maybe_prefix_bnd" "1")])
11363 (define_insn "*jcc_2"
11364   [(set (pc)
11365         (if_then_else (match_operator 1 "ix86_comparison_operator"
11366                                       [(reg FLAGS_REG) (const_int 0)])
11367                       (pc)
11368                       (label_ref (match_operand 0))))]
11369   ""
11370   "%!%+j%c1\t%l0"
11371   [(set_attr "type" "ibr")
11372    (set_attr "modrm" "0")
11373    (set (attr "length")
11374         (if_then_else
11375           (and (ge (minus (match_dup 0) (pc))
11376                    (const_int -126))
11377                (lt (minus (match_dup 0) (pc))
11378                    (const_int 128)))
11379           (const_int 2)
11380           (const_int 6)))
11381    (set_attr "maybe_prefix_bnd" "1")])
11383 ;; In general it is not safe to assume too much about CCmode registers,
11384 ;; so simplify-rtx stops when it sees a second one.  Under certain
11385 ;; conditions this is safe on x86, so help combine not create
11387 ;;      seta    %al
11388 ;;      testb   %al, %al
11389 ;;      je      Lfoo
11391 (define_split
11392   [(set (pc)
11393         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11394                                       [(reg FLAGS_REG) (const_int 0)])
11395                           (const_int 0))
11396                       (label_ref (match_operand 1))
11397                       (pc)))]
11398   ""
11399   [(set (pc)
11400         (if_then_else (match_dup 0)
11401                       (label_ref (match_dup 1))
11402                       (pc)))]
11404   operands[0] = shallow_copy_rtx (operands[0]);
11405   PUT_MODE (operands[0], VOIDmode);
11408 (define_split
11409   [(set (pc)
11410         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11411                                       [(reg FLAGS_REG) (const_int 0)])
11412                           (const_int 0))
11413                       (label_ref (match_operand 1))
11414                       (pc)))]
11415   ""
11416   [(set (pc)
11417         (if_then_else (match_dup 0)
11418                       (label_ref (match_dup 1))
11419                       (pc)))]
11421   operands[0] = shallow_copy_rtx (operands[0]);
11422   PUT_MODE (operands[0], VOIDmode);
11423   PUT_CODE (operands[0],
11424             ix86_reverse_condition (GET_CODE (operands[0]),
11425                                     GET_MODE (XEXP (operands[0], 0))));
11427   /* Make sure that (a) the CCmode we have for the flags is strong
11428      enough for the reversed compare or (b) we have a valid FP compare.  */
11429   if (! ix86_comparison_operator (operands[0], VOIDmode))
11430     FAIL;
11433 ;; Define combination compare-and-branch fp compare instructions to help
11434 ;; combine.
11436 (define_insn "*jcc<mode>_0_i387"
11437   [(set (pc)
11438         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11439                         [(match_operand:X87MODEF 1 "register_operand" "f")
11440                          (match_operand:X87MODEF 2 "const0_operand")])
11441           (label_ref (match_operand 3))
11442           (pc)))
11443    (clobber (reg:CCFP FPSR_REG))
11444    (clobber (reg:CCFP FLAGS_REG))
11445    (clobber (match_scratch:HI 4 "=a"))]
11446   "TARGET_80387 && !TARGET_CMOVE"
11447   "#")
11449 (define_insn "*jcc<mode>_0_r_i387"
11450   [(set (pc)
11451         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11452                         [(match_operand:X87MODEF 1 "register_operand" "f")
11453                          (match_operand:X87MODEF 2 "const0_operand")])
11454           (pc)
11455           (label_ref (match_operand 3))))
11456    (clobber (reg:CCFP FPSR_REG))
11457    (clobber (reg:CCFP FLAGS_REG))
11458    (clobber (match_scratch:HI 4 "=a"))]
11459   "TARGET_80387 && !TARGET_CMOVE"
11460   "#")
11462 (define_insn "*jccxf_i387"
11463   [(set (pc)
11464         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11465                         [(match_operand:XF 1 "register_operand" "f")
11466                          (match_operand:XF 2 "register_operand" "f")])
11467           (label_ref (match_operand 3))
11468           (pc)))
11469    (clobber (reg:CCFP FPSR_REG))
11470    (clobber (reg:CCFP FLAGS_REG))
11471    (clobber (match_scratch:HI 4 "=a"))]
11472   "TARGET_80387 && !TARGET_CMOVE"
11473   "#")
11475 (define_insn "*jccxf_r_i387"
11476   [(set (pc)
11477         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11478                         [(match_operand:XF 1 "register_operand" "f")
11479                          (match_operand:XF 2 "register_operand" "f")])
11480           (pc)
11481           (label_ref (match_operand 3))))
11482    (clobber (reg:CCFP FPSR_REG))
11483    (clobber (reg:CCFP FLAGS_REG))
11484    (clobber (match_scratch:HI 4 "=a"))]
11485   "TARGET_80387 && !TARGET_CMOVE"
11486   "#")
11488 (define_insn "*jcc<mode>_i387"
11489   [(set (pc)
11490         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11491                         [(match_operand:MODEF 1 "register_operand" "f")
11492                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11493           (label_ref (match_operand 3))
11494           (pc)))
11495    (clobber (reg:CCFP FPSR_REG))
11496    (clobber (reg:CCFP FLAGS_REG))
11497    (clobber (match_scratch:HI 4 "=a"))]
11498   "TARGET_80387 && !TARGET_CMOVE"
11499   "#")
11501 (define_insn "*jcc<mode>_r_i387"
11502   [(set (pc)
11503         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11504                         [(match_operand:MODEF 1 "register_operand" "f")
11505                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11506           (pc)
11507           (label_ref (match_operand 3))))
11508    (clobber (reg:CCFP FPSR_REG))
11509    (clobber (reg:CCFP FLAGS_REG))
11510    (clobber (match_scratch:HI 4 "=a"))]
11511   "TARGET_80387 && !TARGET_CMOVE"
11512   "#")
11514 (define_insn "*jccu<mode>_i387"
11515   [(set (pc)
11516         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11517                         [(match_operand:X87MODEF 1 "register_operand" "f")
11518                          (match_operand:X87MODEF 2 "register_operand" "f")])
11519           (label_ref (match_operand 3))
11520           (pc)))
11521    (clobber (reg:CCFP FPSR_REG))
11522    (clobber (reg:CCFP FLAGS_REG))
11523    (clobber (match_scratch:HI 4 "=a"))]
11524   "TARGET_80387 && !TARGET_CMOVE"
11525   "#")
11527 (define_insn "*jccu<mode>_r_i387"
11528   [(set (pc)
11529         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11530                         [(match_operand:X87MODEF 1 "register_operand" "f")
11531                          (match_operand:X87MODEF 2 "register_operand" "f")])
11532           (pc)
11533           (label_ref (match_operand 3))))
11534    (clobber (reg:CCFP FPSR_REG))
11535    (clobber (reg:CCFP FLAGS_REG))
11536    (clobber (match_scratch:HI 4 "=a"))]
11537   "TARGET_80387 && !TARGET_CMOVE"
11538   "#")
11540 (define_split
11541   [(set (pc)
11542         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11543                         [(match_operand:X87MODEF 1 "register_operand")
11544                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11545           (match_operand 3)
11546           (match_operand 4)))
11547    (clobber (reg:CCFP FPSR_REG))
11548    (clobber (reg:CCFP FLAGS_REG))]
11549   "TARGET_80387 && !TARGET_CMOVE
11550    && reload_completed"
11551   [(const_int 0)]
11553   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11554                         operands[3], operands[4], NULL_RTX);
11555   DONE;
11558 (define_split
11559   [(set (pc)
11560         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11561                         [(match_operand:X87MODEF 1 "register_operand")
11562                          (match_operand:X87MODEF 2 "general_operand")])
11563           (match_operand 3)
11564           (match_operand 4)))
11565    (clobber (reg:CCFP FPSR_REG))
11566    (clobber (reg:CCFP FLAGS_REG))
11567    (clobber (match_scratch:HI 5))]
11568   "TARGET_80387 && !TARGET_CMOVE
11569    && reload_completed"
11570   [(const_int 0)]
11572   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11573                         operands[3], operands[4], operands[5]);
11574   DONE;
11577 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11578 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11579 ;; with a precedence over other operators and is always put in the first
11580 ;; place. Swap condition and operands to match ficom instruction.
11582 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11583   [(set (pc)
11584         (if_then_else
11585           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11586             [(match_operator:X87MODEF 1 "float_operator"
11587               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11588              (match_operand:X87MODEF 3 "register_operand" "f")])
11589           (label_ref (match_operand 4))
11590           (pc)))
11591    (clobber (reg:CCFP FPSR_REG))
11592    (clobber (reg:CCFP FLAGS_REG))
11593    (clobber (match_scratch:HI 5 "=a"))]
11594   "TARGET_80387 && !TARGET_CMOVE
11595    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11596        || optimize_function_for_size_p (cfun))"
11597   "#")
11599 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11600   [(set (pc)
11601         (if_then_else
11602           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11603             [(match_operator:X87MODEF 1 "float_operator"
11604               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11605              (match_operand:X87MODEF 3 "register_operand" "f")])
11606           (pc)
11607           (label_ref (match_operand 4))))
11608    (clobber (reg:CCFP FPSR_REG))
11609    (clobber (reg:CCFP FLAGS_REG))
11610    (clobber (match_scratch:HI 5 "=a"))]
11611   "TARGET_80387 && !TARGET_CMOVE
11612    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11613        || optimize_function_for_size_p (cfun))"
11614   "#")
11616 (define_split
11617   [(set (pc)
11618         (if_then_else
11619           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11620             [(match_operator:X87MODEF 1 "float_operator"
11621               [(match_operand:SWI24 2 "memory_operand")])
11622              (match_operand:X87MODEF 3 "register_operand")])
11623           (match_operand 4)
11624           (match_operand 5)))
11625    (clobber (reg:CCFP FPSR_REG))
11626    (clobber (reg:CCFP FLAGS_REG))
11627    (clobber (match_scratch:HI 6))]
11628   "TARGET_80387 && !TARGET_CMOVE
11629    && reload_completed"
11630   [(const_int 0)]
11632   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11633                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11634                         operands[4], operands[5], operands[6]);
11635   DONE;
11638 ;; Unconditional and other jump instructions
11640 (define_insn "jump"
11641   [(set (pc)
11642         (label_ref (match_operand 0)))]
11643   ""
11644   "%!jmp\t%l0"
11645   [(set_attr "type" "ibr")
11646    (set_attr "modrm" "0")
11647    (set (attr "length")
11648         (if_then_else
11649           (and (ge (minus (match_dup 0) (pc))
11650                    (const_int -126))
11651                (lt (minus (match_dup 0) (pc))
11652                    (const_int 128)))
11653           (const_int 2)
11654           (const_int 5)))
11655    (set_attr "maybe_prefix_bnd" "1")])
11657 (define_expand "indirect_jump"
11658   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11659   ""
11661   if (TARGET_X32)
11662     operands[0] = convert_memory_address (word_mode, operands[0]);
11665 (define_insn "*indirect_jump"
11666   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11667   ""
11668   "%!jmp\t%A0"
11669   [(set_attr "type" "ibr")
11670    (set_attr "length_immediate" "0")
11671    (set_attr "maybe_prefix_bnd" "1")])
11673 (define_expand "tablejump"
11674   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11675               (use (label_ref (match_operand 1)))])]
11676   ""
11678   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11679      relative.  Convert the relative address to an absolute address.  */
11680   if (flag_pic)
11681     {
11682       rtx op0, op1;
11683       enum rtx_code code;
11685       /* We can't use @GOTOFF for text labels on VxWorks;
11686          see gotoff_operand.  */
11687       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11688         {
11689           code = PLUS;
11690           op0 = operands[0];
11691           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11692         }
11693       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11694         {
11695           code = PLUS;
11696           op0 = operands[0];
11697           op1 = pic_offset_table_rtx;
11698         }
11699       else
11700         {
11701           code = MINUS;
11702           op0 = pic_offset_table_rtx;
11703           op1 = operands[0];
11704         }
11706       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11707                                          OPTAB_DIRECT);
11708     }
11710   if (TARGET_X32)
11711     operands[0] = convert_memory_address (word_mode, operands[0]);
11714 (define_insn "*tablejump_1"
11715   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11716    (use (label_ref (match_operand 1)))]
11717   ""
11718   "%!jmp\t%A0"
11719   [(set_attr "type" "ibr")
11720    (set_attr "length_immediate" "0")
11721    (set_attr "maybe_prefix_bnd" "1")])
11723 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11725 (define_peephole2
11726   [(set (reg FLAGS_REG) (match_operand 0))
11727    (set (match_operand:QI 1 "register_operand")
11728         (match_operator:QI 2 "ix86_comparison_operator"
11729           [(reg FLAGS_REG) (const_int 0)]))
11730    (set (match_operand 3 "any_QIreg_operand")
11731         (zero_extend (match_dup 1)))]
11732   "(peep2_reg_dead_p (3, operands[1])
11733     || operands_match_p (operands[1], operands[3]))
11734    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11735   [(set (match_dup 4) (match_dup 0))
11736    (set (strict_low_part (match_dup 5))
11737         (match_dup 2))]
11739   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11740   operands[5] = gen_lowpart (QImode, operands[3]);
11741   ix86_expand_clear (operands[3]);
11744 (define_peephole2
11745   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11746               (match_operand 4)])
11747    (set (match_operand:QI 1 "register_operand")
11748         (match_operator:QI 2 "ix86_comparison_operator"
11749           [(reg FLAGS_REG) (const_int 0)]))
11750    (set (match_operand 3 "any_QIreg_operand")
11751         (zero_extend (match_dup 1)))]
11752   "(peep2_reg_dead_p (3, operands[1])
11753     || operands_match_p (operands[1], operands[3]))
11754    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11755    && ! (GET_CODE (operands[4]) == CLOBBER
11756          && reg_mentioned_p (operands[3], operands[4]))"
11757   [(parallel [(set (match_dup 5) (match_dup 0))
11758               (match_dup 4)])
11759    (set (strict_low_part (match_dup 6))
11760         (match_dup 2))]
11762   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11763   operands[6] = gen_lowpart (QImode, operands[3]);
11764   ix86_expand_clear (operands[3]);
11767 ;; Similar, but match zero extend with andsi3.
11769 (define_peephole2
11770   [(set (reg FLAGS_REG) (match_operand 0))
11771    (set (match_operand:QI 1 "register_operand")
11772         (match_operator:QI 2 "ix86_comparison_operator"
11773           [(reg FLAGS_REG) (const_int 0)]))
11774    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11775                    (and:SI (match_dup 3) (const_int 255)))
11776               (clobber (reg:CC FLAGS_REG))])]
11777   "REGNO (operands[1]) == REGNO (operands[3])
11778    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11779   [(set (match_dup 4) (match_dup 0))
11780    (set (strict_low_part (match_dup 5))
11781         (match_dup 2))]
11783   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11784   operands[5] = gen_lowpart (QImode, operands[3]);
11785   ix86_expand_clear (operands[3]);
11788 (define_peephole2
11789   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11790               (match_operand 4)])
11791    (set (match_operand:QI 1 "register_operand")
11792         (match_operator:QI 2 "ix86_comparison_operator"
11793           [(reg FLAGS_REG) (const_int 0)]))
11794    (parallel [(set (match_operand 3 "any_QIreg_operand")
11795                    (zero_extend (match_dup 1)))
11796               (clobber (reg:CC FLAGS_REG))])]
11797   "(peep2_reg_dead_p (3, operands[1])
11798     || operands_match_p (operands[1], operands[3]))
11799    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11800    && ! (GET_CODE (operands[4]) == CLOBBER
11801          && reg_mentioned_p (operands[3], operands[4]))"
11802   [(parallel [(set (match_dup 5) (match_dup 0))
11803               (match_dup 4)])
11804    (set (strict_low_part (match_dup 6))
11805         (match_dup 2))]
11807   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11808   operands[6] = gen_lowpart (QImode, operands[3]);
11809   ix86_expand_clear (operands[3]);
11812 ;; Call instructions.
11814 ;; The predicates normally associated with named expanders are not properly
11815 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11816 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11818 ;; P6 processors will jump to the address after the decrement when %esp
11819 ;; is used as a call operand, so they will execute return address as a code.
11820 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11822 ;; Register constraint for call instruction.
11823 (define_mode_attr c [(SI "l") (DI "r")])
11825 ;; Call subroutine returning no value.
11827 (define_expand "call"
11828   [(call (match_operand:QI 0)
11829          (match_operand 1))
11830    (use (match_operand 2))]
11831   ""
11833   ix86_expand_call (NULL, operands[0], operands[1],
11834                     operands[2], NULL, false);
11835   DONE;
11838 (define_expand "sibcall"
11839   [(call (match_operand:QI 0)
11840          (match_operand 1))
11841    (use (match_operand 2))]
11842   ""
11844   ix86_expand_call (NULL, operands[0], operands[1],
11845                     operands[2], NULL, true);
11846   DONE;
11849 (define_insn "*call"
11850   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11851          (match_operand 1))]
11852   "!SIBLING_CALL_P (insn)"
11853   "* return ix86_output_call_insn (insn, operands[0]);"
11854   [(set_attr "type" "call")])
11856 ;; This covers both call and sibcall since only GOT slot is allowed.
11857 (define_insn "*call_got_x32"
11858   [(call (mem:QI (zero_extend:DI
11859                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11860          (match_operand 1))]
11861   "TARGET_X32"
11862   "* return ix86_output_call_insn (insn, operands[0]);"
11863   [(set_attr "type" "call")])
11865 (define_insn "*sibcall"
11866   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11867          (match_operand 1))]
11868   "SIBLING_CALL_P (insn)"
11869   "* return ix86_output_call_insn (insn, operands[0]);"
11870   [(set_attr "type" "call")])
11872 (define_insn "*sibcall_memory"
11873   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11874          (match_operand 1))
11875    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11876   "!TARGET_X32"
11877   "* return ix86_output_call_insn (insn, operands[0]);"
11878   [(set_attr "type" "call")])
11880 (define_peephole2
11881   [(set (match_operand:W 0 "register_operand")
11882         (match_operand:W 1 "memory_operand"))
11883    (call (mem:QI (match_dup 0))
11884          (match_operand 3))]
11885   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11886    && !reg_mentioned_p (operands[0],
11887                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11888   [(parallel [(call (mem:QI (match_dup 1))
11889                     (match_dup 3))
11890               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11892 (define_peephole2
11893   [(set (match_operand:W 0 "register_operand")
11894         (match_operand:W 1 "memory_operand"))
11895    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11896    (call (mem:QI (match_dup 0))
11897          (match_operand 3))]
11898   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11899    && !reg_mentioned_p (operands[0],
11900                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11901   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11902    (parallel [(call (mem:QI (match_dup 1))
11903                     (match_dup 3))
11904               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11906 (define_expand "call_pop"
11907   [(parallel [(call (match_operand:QI 0)
11908                     (match_operand:SI 1))
11909               (set (reg:SI SP_REG)
11910                    (plus:SI (reg:SI SP_REG)
11911                             (match_operand:SI 3)))])]
11912   "!TARGET_64BIT"
11914   ix86_expand_call (NULL, operands[0], operands[1],
11915                     operands[2], operands[3], false);
11916   DONE;
11919 (define_insn "*call_pop"
11920   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11921          (match_operand 1))
11922    (set (reg:SI SP_REG)
11923         (plus:SI (reg:SI SP_REG)
11924                  (match_operand:SI 2 "immediate_operand" "i")))]
11925   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11926   "* return ix86_output_call_insn (insn, operands[0]);"
11927   [(set_attr "type" "call")])
11929 (define_insn "*sibcall_pop"
11930   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11931          (match_operand 1))
11932    (set (reg:SI SP_REG)
11933         (plus:SI (reg:SI SP_REG)
11934                  (match_operand:SI 2 "immediate_operand" "i")))]
11935   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11936   "* return ix86_output_call_insn (insn, operands[0]);"
11937   [(set_attr "type" "call")])
11939 (define_insn "*sibcall_pop_memory"
11940   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11941          (match_operand 1))
11942    (set (reg:SI SP_REG)
11943         (plus:SI (reg:SI SP_REG)
11944                  (match_operand:SI 2 "immediate_operand" "i")))
11945    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11946   "!TARGET_64BIT"
11947   "* return ix86_output_call_insn (insn, operands[0]);"
11948   [(set_attr "type" "call")])
11950 (define_peephole2
11951   [(set (match_operand:SI 0 "register_operand")
11952         (match_operand:SI 1 "memory_operand"))
11953    (parallel [(call (mem:QI (match_dup 0))
11954                     (match_operand 3))
11955               (set (reg:SI SP_REG)
11956                    (plus:SI (reg:SI SP_REG)
11957                             (match_operand:SI 4 "immediate_operand")))])]
11958   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11959    && !reg_mentioned_p (operands[0],
11960                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11961   [(parallel [(call (mem:QI (match_dup 1))
11962                     (match_dup 3))
11963               (set (reg:SI SP_REG)
11964                    (plus:SI (reg:SI SP_REG)
11965                             (match_dup 4)))
11966               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11968 (define_peephole2
11969   [(set (match_operand:SI 0 "register_operand")
11970         (match_operand:SI 1 "memory_operand"))
11971    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11972    (parallel [(call (mem:QI (match_dup 0))
11973                     (match_operand 3))
11974               (set (reg:SI SP_REG)
11975                    (plus:SI (reg:SI SP_REG)
11976                             (match_operand:SI 4 "immediate_operand")))])]
11977   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11978    && !reg_mentioned_p (operands[0],
11979                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11980   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11981    (parallel [(call (mem:QI (match_dup 1))
11982                     (match_dup 3))
11983               (set (reg:SI SP_REG)
11984                    (plus:SI (reg:SI SP_REG)
11985                             (match_dup 4)))
11986               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11988 ;; Combining simple memory jump instruction
11990 (define_peephole2
11991   [(set (match_operand:W 0 "register_operand")
11992         (match_operand:W 1 "memory_operand"))
11993    (set (pc) (match_dup 0))]
11994   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11995   [(set (pc) (match_dup 1))])
11997 ;; Call subroutine, returning value in operand 0
11999 (define_expand "call_value"
12000   [(set (match_operand 0)
12001         (call (match_operand:QI 1)
12002               (match_operand 2)))
12003    (use (match_operand 3))]
12004   ""
12006   ix86_expand_call (operands[0], operands[1], operands[2],
12007                     operands[3], NULL, false);
12008   DONE;
12011 (define_expand "sibcall_value"
12012   [(set (match_operand 0)
12013         (call (match_operand:QI 1)
12014               (match_operand 2)))
12015    (use (match_operand 3))]
12016   ""
12018   ix86_expand_call (operands[0], operands[1], operands[2],
12019                     operands[3], NULL, true);
12020   DONE;
12023 (define_insn "*call_value"
12024   [(set (match_operand 0)
12025         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12026               (match_operand 2)))]
12027   "!SIBLING_CALL_P (insn)"
12028   "* return ix86_output_call_insn (insn, operands[1]);"
12029   [(set_attr "type" "callv")])
12031 ;; This covers both call and sibcall since only GOT slot is allowed.
12032 (define_insn "*call_value_got_x32"
12033   [(set (match_operand 0)
12034         (call (mem:QI
12035                 (zero_extend:DI
12036                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12037               (match_operand 2)))]
12038   "TARGET_X32"
12039   "* return ix86_output_call_insn (insn, operands[1]);"
12040   [(set_attr "type" "callv")])
12042 (define_insn "*sibcall_value"
12043   [(set (match_operand 0)
12044         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12045               (match_operand 2)))]
12046   "SIBLING_CALL_P (insn)"
12047   "* return ix86_output_call_insn (insn, operands[1]);"
12048   [(set_attr "type" "callv")])
12050 (define_insn "*sibcall_value_memory"
12051   [(set (match_operand 0)
12052         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12053               (match_operand 2)))
12054    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12055   "!TARGET_X32"
12056   "* return ix86_output_call_insn (insn, operands[1]);"
12057   [(set_attr "type" "callv")])
12059 (define_peephole2
12060   [(set (match_operand:W 0 "register_operand")
12061         (match_operand:W 1 "memory_operand"))
12062    (set (match_operand 2)
12063    (call (mem:QI (match_dup 0))
12064                  (match_operand 3)))]
12065   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12066    && !reg_mentioned_p (operands[0],
12067                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12068   [(parallel [(set (match_dup 2)
12069                    (call (mem:QI (match_dup 1))
12070                          (match_dup 3)))
12071               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12073 (define_peephole2
12074   [(set (match_operand:W 0 "register_operand")
12075         (match_operand:W 1 "memory_operand"))
12076    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12077    (set (match_operand 2)
12078         (call (mem:QI (match_dup 0))
12079               (match_operand 3)))]
12080   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12081    && !reg_mentioned_p (operands[0],
12082                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12083   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12084    (parallel [(set (match_dup 2)
12085                    (call (mem:QI (match_dup 1))
12086                          (match_dup 3)))
12087               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12089 (define_expand "call_value_pop"
12090   [(parallel [(set (match_operand 0)
12091                    (call (match_operand:QI 1)
12092                          (match_operand:SI 2)))
12093               (set (reg:SI SP_REG)
12094                    (plus:SI (reg:SI SP_REG)
12095                             (match_operand:SI 4)))])]
12096   "!TARGET_64BIT"
12098   ix86_expand_call (operands[0], operands[1], operands[2],
12099                     operands[3], operands[4], false);
12100   DONE;
12103 (define_insn "*call_value_pop"
12104   [(set (match_operand 0)
12105         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12106               (match_operand 2)))
12107    (set (reg:SI SP_REG)
12108         (plus:SI (reg:SI SP_REG)
12109                  (match_operand:SI 3 "immediate_operand" "i")))]
12110   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12111   "* return ix86_output_call_insn (insn, operands[1]);"
12112   [(set_attr "type" "callv")])
12114 (define_insn "*sibcall_value_pop"
12115   [(set (match_operand 0)
12116         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12117               (match_operand 2)))
12118    (set (reg:SI SP_REG)
12119         (plus:SI (reg:SI SP_REG)
12120                  (match_operand:SI 3 "immediate_operand" "i")))]
12121   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12122   "* return ix86_output_call_insn (insn, operands[1]);"
12123   [(set_attr "type" "callv")])
12125 (define_insn "*sibcall_value_pop_memory"
12126   [(set (match_operand 0)
12127         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12128               (match_operand 2)))
12129    (set (reg:SI SP_REG)
12130         (plus:SI (reg:SI SP_REG)
12131                  (match_operand:SI 3 "immediate_operand" "i")))
12132    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12133   "!TARGET_64BIT"
12134   "* return ix86_output_call_insn (insn, operands[1]);"
12135   [(set_attr "type" "callv")])
12137 (define_peephole2
12138   [(set (match_operand:SI 0 "register_operand")
12139         (match_operand:SI 1 "memory_operand"))
12140    (parallel [(set (match_operand 2)
12141                    (call (mem:QI (match_dup 0))
12142                          (match_operand 3)))
12143               (set (reg:SI SP_REG)
12144                    (plus:SI (reg:SI SP_REG)
12145                             (match_operand:SI 4 "immediate_operand")))])]
12146   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12147    && !reg_mentioned_p (operands[0],
12148                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12149   [(parallel [(set (match_dup 2)
12150                    (call (mem:QI (match_dup 1))
12151                          (match_dup 3)))
12152               (set (reg:SI SP_REG)
12153                    (plus:SI (reg:SI SP_REG)
12154                             (match_dup 4)))
12155               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12157 (define_peephole2
12158   [(set (match_operand:SI 0 "register_operand")
12159         (match_operand:SI 1 "memory_operand"))
12160    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12161    (parallel [(set (match_operand 2)
12162                    (call (mem:QI (match_dup 0))
12163                          (match_operand 3)))
12164               (set (reg:SI SP_REG)
12165                    (plus:SI (reg:SI SP_REG)
12166                             (match_operand:SI 4 "immediate_operand")))])]
12167   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12168    && !reg_mentioned_p (operands[0],
12169                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12170   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12171    (parallel [(set (match_dup 2)
12172                    (call (mem:QI (match_dup 1))
12173                          (match_dup 3)))
12174               (set (reg:SI SP_REG)
12175                    (plus:SI (reg:SI SP_REG)
12176                             (match_dup 4)))
12177               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12179 ;; Call subroutine returning any type.
12181 (define_expand "untyped_call"
12182   [(parallel [(call (match_operand 0)
12183                     (const_int 0))
12184               (match_operand 1)
12185               (match_operand 2)])]
12186   ""
12188   int i;
12190   /* In order to give reg-stack an easier job in validating two
12191      coprocessor registers as containing a possible return value,
12192      simply pretend the untyped call returns a complex long double
12193      value. 
12195      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12196      and should have the default ABI.  */
12198   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12199                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12200                     operands[0], const0_rtx,
12201                     GEN_INT ((TARGET_64BIT
12202                               ? (ix86_abi == SYSV_ABI
12203                                  ? X86_64_SSE_REGPARM_MAX
12204                                  : X86_64_MS_SSE_REGPARM_MAX)
12205                               : X86_32_SSE_REGPARM_MAX)
12206                              - 1),
12207                     NULL, false);
12209   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12210     {
12211       rtx set = XVECEXP (operands[2], 0, i);
12212       emit_move_insn (SET_DEST (set), SET_SRC (set));
12213     }
12215   /* The optimizer does not know that the call sets the function value
12216      registers we stored in the result block.  We avoid problems by
12217      claiming that all hard registers are used and clobbered at this
12218      point.  */
12219   emit_insn (gen_blockage ());
12221   DONE;
12224 ;; Prologue and epilogue instructions
12226 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12227 ;; all of memory.  This blocks insns from being moved across this point.
12229 (define_insn "blockage"
12230   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12231   ""
12232   ""
12233   [(set_attr "length" "0")])
12235 ;; Do not schedule instructions accessing memory across this point.
12237 (define_expand "memory_blockage"
12238   [(set (match_dup 0)
12239         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12240   ""
12242   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12243   MEM_VOLATILE_P (operands[0]) = 1;
12246 (define_insn "*memory_blockage"
12247   [(set (match_operand:BLK 0)
12248         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12249   ""
12250   ""
12251   [(set_attr "length" "0")])
12253 ;; As USE insns aren't meaningful after reload, this is used instead
12254 ;; to prevent deleting instructions setting registers for PIC code
12255 (define_insn "prologue_use"
12256   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12257   ""
12258   ""
12259   [(set_attr "length" "0")])
12261 ;; Insn emitted into the body of a function to return from a function.
12262 ;; This is only done if the function's epilogue is known to be simple.
12263 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12265 (define_expand "return"
12266   [(simple_return)]
12267   "ix86_can_use_return_insn_p ()"
12269   if (crtl->args.pops_args)
12270     {
12271       rtx popc = GEN_INT (crtl->args.pops_args);
12272       emit_jump_insn (gen_simple_return_pop_internal (popc));
12273       DONE;
12274     }
12277 ;; We need to disable this for TARGET_SEH, as otherwise
12278 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12279 ;; the maximum size of prologue in unwind information.
12280 ;; Also disallow shrink-wrapping if using stack slot to pass the
12281 ;; static chain pointer - the first instruction has to be pushl %esi
12282 ;; and it can't be moved around, as we use alternate entry points
12283 ;; in that case.
12285 (define_expand "simple_return"
12286   [(simple_return)]
12287   "!TARGET_SEH && !ix86_static_chain_on_stack"
12289   if (crtl->args.pops_args)
12290     {
12291       rtx popc = GEN_INT (crtl->args.pops_args);
12292       emit_jump_insn (gen_simple_return_pop_internal (popc));
12293       DONE;
12294     }
12297 (define_insn "simple_return_internal"
12298   [(simple_return)]
12299   "reload_completed"
12300   "%!ret"
12301   [(set_attr "length" "1")
12302    (set_attr "atom_unit" "jeu")
12303    (set_attr "length_immediate" "0")
12304    (set_attr "modrm" "0")
12305    (set_attr "maybe_prefix_bnd" "1")])
12307 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12308 ;; instruction Athlon and K8 have.
12310 (define_insn "simple_return_internal_long"
12311   [(simple_return)
12312    (unspec [(const_int 0)] UNSPEC_REP)]
12313   "reload_completed"
12315   if (ix86_bnd_prefixed_insn_p (insn))
12316     return "%!ret";
12318   return "rep%; ret";
12320   [(set_attr "length" "2")
12321    (set_attr "atom_unit" "jeu")
12322    (set_attr "length_immediate" "0")
12323    (set_attr "prefix_rep" "1")
12324    (set_attr "modrm" "0")])
12326 (define_insn "simple_return_pop_internal"
12327   [(simple_return)
12328    (use (match_operand:SI 0 "const_int_operand"))]
12329   "reload_completed"
12330   "%!ret\t%0"
12331   [(set_attr "length" "3")
12332    (set_attr "atom_unit" "jeu")
12333    (set_attr "length_immediate" "2")
12334    (set_attr "modrm" "0")
12335    (set_attr "maybe_prefix_bnd" "1")])
12337 (define_insn "simple_return_indirect_internal"
12338   [(simple_return)
12339    (use (match_operand:SI 0 "register_operand" "r"))]
12340   "reload_completed"
12341   "%!jmp\t%A0"
12342   [(set_attr "type" "ibr")
12343    (set_attr "length_immediate" "0")
12344    (set_attr "maybe_prefix_bnd" "1")])
12346 (define_insn "nop"
12347   [(const_int 0)]
12348   ""
12349   "nop"
12350   [(set_attr "length" "1")
12351    (set_attr "length_immediate" "0")
12352    (set_attr "modrm" "0")])
12354 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12355 (define_insn "nops"
12356   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12357                     UNSPECV_NOPS)]
12358   "reload_completed"
12360   int num = INTVAL (operands[0]);
12362   gcc_assert (IN_RANGE (num, 1, 8));
12364   while (num--)
12365     fputs ("\tnop\n", asm_out_file);
12367   return "";
12369   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12370    (set_attr "length_immediate" "0")
12371    (set_attr "modrm" "0")])
12373 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12374 ;; branch prediction penalty for the third jump in a 16-byte
12375 ;; block on K8.
12377 (define_insn "pad"
12378   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12379   ""
12381 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12382   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12383 #else
12384   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12385      The align insn is used to avoid 3 jump instructions in the row to improve
12386      branch prediction and the benefits hardly outweigh the cost of extra 8
12387      nops on the average inserted by full alignment pseudo operation.  */
12388 #endif
12389   return "";
12391   [(set_attr "length" "16")])
12393 (define_expand "prologue"
12394   [(const_int 0)]
12395   ""
12396   "ix86_expand_prologue (); DONE;")
12398 (define_insn "set_got"
12399   [(set (match_operand:SI 0 "register_operand" "=r")
12400         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12401    (clobber (reg:CC FLAGS_REG))]
12402   "!TARGET_64BIT"
12403   "* return output_set_got (operands[0], NULL_RTX);"
12404   [(set_attr "type" "multi")
12405    (set_attr "length" "12")])
12407 (define_insn "set_got_labelled"
12408   [(set (match_operand:SI 0 "register_operand" "=r")
12409         (unspec:SI [(label_ref (match_operand 1))]
12410          UNSPEC_SET_GOT))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "!TARGET_64BIT"
12413   "* return output_set_got (operands[0], operands[1]);"
12414   [(set_attr "type" "multi")
12415    (set_attr "length" "12")])
12417 (define_insn "set_got_rex64"
12418   [(set (match_operand:DI 0 "register_operand" "=r")
12419         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12420   "TARGET_64BIT"
12421   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12422   [(set_attr "type" "lea")
12423    (set_attr "length_address" "4")
12424    (set_attr "mode" "DI")])
12426 (define_insn "set_rip_rex64"
12427   [(set (match_operand:DI 0 "register_operand" "=r")
12428         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12429   "TARGET_64BIT"
12430   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12431   [(set_attr "type" "lea")
12432    (set_attr "length_address" "4")
12433    (set_attr "mode" "DI")])
12435 (define_insn "set_got_offset_rex64"
12436   [(set (match_operand:DI 0 "register_operand" "=r")
12437         (unspec:DI
12438           [(label_ref (match_operand 1))]
12439           UNSPEC_SET_GOT_OFFSET))]
12440   "TARGET_LP64"
12441   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12442   [(set_attr "type" "imov")
12443    (set_attr "length_immediate" "0")
12444    (set_attr "length_address" "8")
12445    (set_attr "mode" "DI")])
12447 (define_expand "epilogue"
12448   [(const_int 0)]
12449   ""
12450   "ix86_expand_epilogue (1); DONE;")
12452 (define_expand "sibcall_epilogue"
12453   [(const_int 0)]
12454   ""
12455   "ix86_expand_epilogue (0); DONE;")
12457 (define_expand "eh_return"
12458   [(use (match_operand 0 "register_operand"))]
12459   ""
12461   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12463   /* Tricky bit: we write the address of the handler to which we will
12464      be returning into someone else's stack frame, one word below the
12465      stack address we wish to restore.  */
12466   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12467   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12468   tmp = gen_rtx_MEM (Pmode, tmp);
12469   emit_move_insn (tmp, ra);
12471   emit_jump_insn (gen_eh_return_internal ());
12472   emit_barrier ();
12473   DONE;
12476 (define_insn_and_split "eh_return_internal"
12477   [(eh_return)]
12478   ""
12479   "#"
12480   "epilogue_completed"
12481   [(const_int 0)]
12482   "ix86_expand_epilogue (2); DONE;")
12484 (define_insn "leave"
12485   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12486    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12487    (clobber (mem:BLK (scratch)))]
12488   "!TARGET_64BIT"
12489   "leave"
12490   [(set_attr "type" "leave")])
12492 (define_insn "leave_rex64"
12493   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12494    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12495    (clobber (mem:BLK (scratch)))]
12496   "TARGET_64BIT"
12497   "leave"
12498   [(set_attr "type" "leave")])
12500 ;; Handle -fsplit-stack.
12502 (define_expand "split_stack_prologue"
12503   [(const_int 0)]
12504   ""
12506   ix86_expand_split_stack_prologue ();
12507   DONE;
12510 ;; In order to support the call/return predictor, we use a return
12511 ;; instruction which the middle-end doesn't see.
12512 (define_insn "split_stack_return"
12513   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12514                      UNSPECV_SPLIT_STACK_RETURN)]
12515   ""
12517   if (operands[0] == const0_rtx)
12518     return "ret";
12519   else
12520     return "ret\t%0";
12522   [(set_attr "atom_unit" "jeu")
12523    (set_attr "modrm" "0")
12524    (set (attr "length")
12525         (if_then_else (match_operand:SI 0 "const0_operand")
12526                       (const_int 1)
12527                       (const_int 3)))
12528    (set (attr "length_immediate")
12529         (if_then_else (match_operand:SI 0 "const0_operand")
12530                       (const_int 0)
12531                       (const_int 2)))])
12533 ;; If there are operand 0 bytes available on the stack, jump to
12534 ;; operand 1.
12536 (define_expand "split_stack_space_check"
12537   [(set (pc) (if_then_else
12538               (ltu (minus (reg SP_REG)
12539                           (match_operand 0 "register_operand"))
12540                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12541               (label_ref (match_operand 1))
12542               (pc)))]
12543   ""
12545   rtx reg, size, limit;
12547   reg = gen_reg_rtx (Pmode);
12548   size = force_reg (Pmode, operands[0]);
12549   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12550   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12551                           UNSPEC_STACK_CHECK);
12552   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12553   ix86_expand_branch (GEU, reg, limit, operands[1]);
12555   DONE;
12558 ;; Bit manipulation instructions.
12560 (define_expand "ffs<mode>2"
12561   [(set (match_dup 2) (const_int -1))
12562    (parallel [(set (match_dup 3) (match_dup 4))
12563               (set (match_operand:SWI48 0 "register_operand")
12564                    (ctz:SWI48
12565                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12566    (set (match_dup 0) (if_then_else:SWI48
12567                         (eq (match_dup 3) (const_int 0))
12568                         (match_dup 2)
12569                         (match_dup 0)))
12570    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12571               (clobber (reg:CC FLAGS_REG))])]
12572   ""
12574   machine_mode flags_mode;
12576   if (<MODE>mode == SImode && !TARGET_CMOVE)
12577     {
12578       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12579       DONE;
12580     }
12582   flags_mode
12583     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12585   operands[2] = gen_reg_rtx (<MODE>mode);
12586   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12587   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12590 (define_insn_and_split "ffssi2_no_cmove"
12591   [(set (match_operand:SI 0 "register_operand" "=r")
12592         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12593    (clobber (match_scratch:SI 2 "=&q"))
12594    (clobber (reg:CC FLAGS_REG))]
12595   "!TARGET_CMOVE"
12596   "#"
12597   "&& reload_completed"
12598   [(parallel [(set (match_dup 4) (match_dup 5))
12599               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12600    (set (strict_low_part (match_dup 3))
12601         (eq:QI (match_dup 4) (const_int 0)))
12602    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12603               (clobber (reg:CC FLAGS_REG))])
12604    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12605               (clobber (reg:CC FLAGS_REG))])
12606    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12607               (clobber (reg:CC FLAGS_REG))])]
12609   machine_mode flags_mode
12610     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12612   operands[3] = gen_lowpart (QImode, operands[2]);
12613   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12614   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12616   ix86_expand_clear (operands[2]);
12619 (define_insn "*tzcnt<mode>_1"
12620   [(set (reg:CCC FLAGS_REG)
12621         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12622                      (const_int 0)))
12623    (set (match_operand:SWI48 0 "register_operand" "=r")
12624         (ctz:SWI48 (match_dup 1)))]
12625   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12626   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12627   [(set_attr "type" "alu1")
12628    (set_attr "prefix_0f" "1")
12629    (set_attr "prefix_rep" "1")
12630    (set_attr "btver2_decode" "double")
12631    (set_attr "mode" "<MODE>")])
12633 (define_insn "*bsf<mode>_1"
12634   [(set (reg:CCZ FLAGS_REG)
12635         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12636                      (const_int 0)))
12637    (set (match_operand:SWI48 0 "register_operand" "=r")
12638         (ctz:SWI48 (match_dup 1)))]
12639   ""
12640   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12641   [(set_attr "type" "alu1")
12642    (set_attr "prefix_0f" "1")
12643    (set_attr "btver2_decode" "double")
12644    (set_attr "znver1_decode" "vector")
12645    (set_attr "mode" "<MODE>")])
12647 (define_expand "ctz<mode>2"
12648   [(parallel
12649     [(set (match_operand:SWI248 0 "register_operand")
12650           (ctz:SWI248
12651             (match_operand:SWI248 1 "nonimmediate_operand")))
12652      (clobber (reg:CC FLAGS_REG))])])
12654 ; False dependency happens when destination is only updated by tzcnt,
12655 ; lzcnt or popcnt.  There is no false dependency when destination is
12656 ; also used in source.
12657 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12658   [(set (match_operand:SWI48 0 "register_operand" "=r")
12659         (ctz:SWI48
12660           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "(TARGET_BMI || TARGET_GENERIC)
12663    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12664   "#"
12665   "&& reload_completed"
12666   [(parallel
12667     [(set (match_dup 0)
12668           (ctz:SWI48 (match_dup 1)))
12669      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12670      (clobber (reg:CC FLAGS_REG))])]
12672   if (!reg_mentioned_p (operands[0], operands[1]))
12673     ix86_expand_clear (operands[0]);
12676 (define_insn "*ctz<mode>2_falsedep"
12677   [(set (match_operand:SWI48 0 "register_operand" "=r")
12678         (ctz:SWI48
12679           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12680    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12681            UNSPEC_INSN_FALSE_DEP)
12682    (clobber (reg:CC FLAGS_REG))]
12683   ""
12685   if (TARGET_BMI)
12686     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12687   else if (TARGET_GENERIC)
12688     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12689     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12690   else
12691     gcc_unreachable ();
12693   [(set_attr "type" "alu1")
12694    (set_attr "prefix_0f" "1")
12695    (set_attr "prefix_rep" "1")
12696    (set_attr "mode" "<MODE>")])
12698 (define_insn "*ctz<mode>2"
12699   [(set (match_operand:SWI248 0 "register_operand" "=r")
12700         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12701    (clobber (reg:CC FLAGS_REG))]
12702   ""
12704   if (TARGET_BMI)
12705     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12706   else if (optimize_function_for_size_p (cfun))
12707     ;
12708   else if (TARGET_GENERIC)
12709     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12710     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12712   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12714   [(set_attr "type" "alu1")
12715    (set_attr "prefix_0f" "1")
12716    (set (attr "prefix_rep")
12717      (if_then_else
12718        (ior (match_test "TARGET_BMI")
12719             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12720                  (match_test "TARGET_GENERIC")))
12721        (const_string "1")
12722        (const_string "0")))
12723    (set_attr "mode" "<MODE>")])
12725 (define_expand "clz<mode>2"
12726   [(parallel
12727      [(set (match_operand:SWI248 0 "register_operand")
12728            (minus:SWI248
12729              (match_dup 2)
12730              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12731       (clobber (reg:CC FLAGS_REG))])
12732    (parallel
12733      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12734       (clobber (reg:CC FLAGS_REG))])]
12735   ""
12737   if (TARGET_LZCNT)
12738     {
12739       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12740       DONE;
12741     }
12742   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12745 (define_expand "clz<mode>2_lzcnt"
12746   [(parallel
12747     [(set (match_operand:SWI248 0 "register_operand")
12748           (clz:SWI248
12749             (match_operand:SWI248 1 "nonimmediate_operand")))
12750      (clobber (reg:CC FLAGS_REG))])]
12751   "TARGET_LZCNT")
12753 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12754   [(set (match_operand:SWI48 0 "register_operand" "=r")
12755         (clz:SWI48
12756           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12757    (clobber (reg:CC FLAGS_REG))]
12758   "TARGET_LZCNT
12759    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12760   "#"
12761   "&& reload_completed"
12762   [(parallel
12763     [(set (match_dup 0)
12764           (clz:SWI48 (match_dup 1)))
12765      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12766      (clobber (reg:CC FLAGS_REG))])]
12768   if (!reg_mentioned_p (operands[0], operands[1]))
12769     ix86_expand_clear (operands[0]);
12772 (define_insn "*clz<mode>2_lzcnt_falsedep"
12773   [(set (match_operand:SWI48 0 "register_operand" "=r")
12774         (clz:SWI48
12775           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12776    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12777            UNSPEC_INSN_FALSE_DEP)
12778    (clobber (reg:CC FLAGS_REG))]
12779   "TARGET_LZCNT"
12780   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12781   [(set_attr "prefix_rep" "1")
12782    (set_attr "type" "bitmanip")
12783    (set_attr "mode" "<MODE>")])
12785 (define_insn "*clz<mode>2_lzcnt"
12786   [(set (match_operand:SWI248 0 "register_operand" "=r")
12787         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12788    (clobber (reg:CC FLAGS_REG))]
12789   "TARGET_LZCNT"
12790   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12791   [(set_attr "prefix_rep" "1")
12792    (set_attr "type" "bitmanip")
12793    (set_attr "mode" "<MODE>")])
12795 ;; BMI instructions.
12796 (define_insn "*bmi_andn_<mode>"
12797   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12798         (and:SWI48
12799           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12800           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12801    (clobber (reg:CC FLAGS_REG))]
12802   "TARGET_BMI"
12803   "andn\t{%2, %1, %0|%0, %1, %2}"
12804   [(set_attr "type" "bitmanip")
12805    (set_attr "btver2_decode" "direct, double")
12806    (set_attr "mode" "<MODE>")])
12808 (define_insn "*bmi_andn_<mode>_ccno"
12809   [(set (reg FLAGS_REG)
12810         (compare
12811           (and:SWI48
12812             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12813             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12814           (const_int 0)))
12815    (clobber (match_scratch:SWI48 0 "=r,r"))]
12816   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12817   "andn\t{%2, %1, %0|%0, %1, %2}"
12818   [(set_attr "type" "bitmanip")
12819    (set_attr "btver2_decode" "direct, double")
12820    (set_attr "mode" "<MODE>")])
12822 (define_insn "bmi_bextr_<mode>"
12823   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12824         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12825                        (match_operand:SWI48 2 "register_operand" "r,r")]
12826                       UNSPEC_BEXTR))
12827    (clobber (reg:CC FLAGS_REG))]
12828   "TARGET_BMI"
12829   "bextr\t{%2, %1, %0|%0, %1, %2}"
12830   [(set_attr "type" "bitmanip")
12831    (set_attr "btver2_decode" "direct, double")
12832    (set_attr "mode" "<MODE>")])
12834 (define_insn "*bmi_bextr_<mode>_ccz"
12835   [(set (reg:CCZ FLAGS_REG)
12836         (compare:CCZ
12837           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12838                          (match_operand:SWI48 2 "register_operand" "r,r")]
12839                         UNSPEC_BEXTR)
12840           (const_int 0)))
12841    (clobber (match_scratch:SWI48 0 "=r,r"))]
12842   "TARGET_BMI"
12843   "bextr\t{%2, %1, %0|%0, %1, %2}"
12844   [(set_attr "type" "bitmanip")
12845    (set_attr "btver2_decode" "direct, double")
12846    (set_attr "mode" "<MODE>")])
12848 (define_insn "*bmi_blsi_<mode>"
12849   [(set (match_operand:SWI48 0 "register_operand" "=r")
12850         (and:SWI48
12851           (neg:SWI48
12852             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12853           (match_dup 1)))
12854    (clobber (reg:CC FLAGS_REG))]
12855   "TARGET_BMI"
12856   "blsi\t{%1, %0|%0, %1}"
12857   [(set_attr "type" "bitmanip")
12858    (set_attr "btver2_decode" "double")
12859    (set_attr "mode" "<MODE>")])
12861 (define_insn "*bmi_blsmsk_<mode>"
12862   [(set (match_operand:SWI48 0 "register_operand" "=r")
12863         (xor:SWI48
12864           (plus:SWI48
12865             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12866             (const_int -1))
12867           (match_dup 1)))
12868    (clobber (reg:CC FLAGS_REG))]
12869   "TARGET_BMI"
12870   "blsmsk\t{%1, %0|%0, %1}"
12871   [(set_attr "type" "bitmanip")
12872    (set_attr "btver2_decode" "double")
12873    (set_attr "mode" "<MODE>")])
12875 (define_insn "*bmi_blsr_<mode>"
12876   [(set (match_operand:SWI48 0 "register_operand" "=r")
12877         (and:SWI48
12878           (plus:SWI48
12879             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12880             (const_int -1))
12881           (match_dup 1)))
12882    (clobber (reg:CC FLAGS_REG))]
12883    "TARGET_BMI"
12884    "blsr\t{%1, %0|%0, %1}"
12885   [(set_attr "type" "bitmanip")
12886    (set_attr "btver2_decode" "double")
12887    (set_attr "mode" "<MODE>")])
12889 ;; BMI2 instructions.
12890 (define_expand "bmi2_bzhi_<mode>3"
12891   [(parallel
12892     [(set (match_operand:SWI48 0 "register_operand")
12893           (zero_extract:SWI48
12894             (match_operand:SWI48 1 "nonimmediate_operand")
12895             (umin:SWI48
12896               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12897                          (const_int 255))
12898               (match_dup 3))
12899             (const_int 0)))
12900      (clobber (reg:CC FLAGS_REG))])]
12901   "TARGET_BMI2"
12902   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12904 (define_insn "*bmi2_bzhi_<mode>3"
12905   [(set (match_operand:SWI48 0 "register_operand" "=r")
12906         (zero_extract:SWI48
12907           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12908           (umin:SWI48
12909             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12910                        (const_int 255))
12911             (match_operand:SWI48 3 "const_int_operand" "n"))
12912           (const_int 0)))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12915   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12916   [(set_attr "type" "bitmanip")
12917    (set_attr "prefix" "vex")
12918    (set_attr "mode" "<MODE>")])
12920 (define_mode_attr k [(SI "k") (DI "q")])
12922 (define_insn "*bmi2_bzhi_<mode>3_1"
12923   [(set (match_operand:SWI48 0 "register_operand" "=r")
12924         (zero_extract:SWI48
12925           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12926           (umin:SWI48
12927             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12928             (match_operand:SWI48 3 "const_int_operand" "n"))
12929           (const_int 0)))
12930    (clobber (reg:CC FLAGS_REG))]
12931   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12932   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12933   [(set_attr "type" "bitmanip")
12934    (set_attr "prefix" "vex")
12935    (set_attr "mode" "<MODE>")])
12937 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12938   [(set (reg:CCZ FLAGS_REG)
12939         (compare:CCZ
12940           (zero_extract:SWI48
12941             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12942             (umin:SWI48
12943               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12944               (match_operand:SWI48 3 "const_int_operand" "n"))
12945             (const_int 0))
12946         (const_int 0)))
12947    (clobber (match_scratch:SWI48 0 "=r"))]
12948   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12949   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12950   [(set_attr "type" "bitmanip")
12951    (set_attr "prefix" "vex")
12952    (set_attr "mode" "<MODE>")])
12954 (define_insn "bmi2_pdep_<mode>3"
12955   [(set (match_operand:SWI48 0 "register_operand" "=r")
12956         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12957                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12958                        UNSPEC_PDEP))]
12959   "TARGET_BMI2"
12960   "pdep\t{%2, %1, %0|%0, %1, %2}"
12961   [(set_attr "type" "bitmanip")
12962    (set_attr "prefix" "vex")
12963    (set_attr "mode" "<MODE>")])
12965 (define_insn "bmi2_pext_<mode>3"
12966   [(set (match_operand:SWI48 0 "register_operand" "=r")
12967         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12968                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12969                        UNSPEC_PEXT))]
12970   "TARGET_BMI2"
12971   "pext\t{%2, %1, %0|%0, %1, %2}"
12972   [(set_attr "type" "bitmanip")
12973    (set_attr "prefix" "vex")
12974    (set_attr "mode" "<MODE>")])
12976 ;; TBM instructions.
12977 (define_insn "tbm_bextri_<mode>"
12978   [(set (match_operand:SWI48 0 "register_operand" "=r")
12979         (zero_extract:SWI48
12980           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12981           (match_operand 2 "const_0_to_255_operand" "N")
12982           (match_operand 3 "const_0_to_255_operand" "N")))
12983    (clobber (reg:CC FLAGS_REG))]
12984    "TARGET_TBM"
12986   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12987   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12989   [(set_attr "type" "bitmanip")
12990    (set_attr "mode" "<MODE>")])
12992 (define_insn "*tbm_blcfill_<mode>"
12993   [(set (match_operand:SWI48 0 "register_operand" "=r")
12994         (and:SWI48
12995           (plus:SWI48
12996             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12997             (const_int 1))
12998           (match_dup 1)))
12999    (clobber (reg:CC FLAGS_REG))]
13000    "TARGET_TBM"
13001    "blcfill\t{%1, %0|%0, %1}"
13002   [(set_attr "type" "bitmanip")
13003    (set_attr "mode" "<MODE>")])
13005 (define_insn "*tbm_blci_<mode>"
13006   [(set (match_operand:SWI48 0 "register_operand" "=r")
13007         (ior:SWI48
13008           (not:SWI48
13009             (plus:SWI48
13010               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13011               (const_int 1)))
13012           (match_dup 1)))
13013    (clobber (reg:CC FLAGS_REG))]
13014    "TARGET_TBM"
13015    "blci\t{%1, %0|%0, %1}"
13016   [(set_attr "type" "bitmanip")
13017    (set_attr "mode" "<MODE>")])
13019 (define_insn "*tbm_blcic_<mode>"
13020   [(set (match_operand:SWI48 0 "register_operand" "=r")
13021         (and:SWI48
13022           (plus:SWI48
13023             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13024             (const_int 1))
13025           (not:SWI48
13026             (match_dup 1))))
13027    (clobber (reg:CC FLAGS_REG))]
13028    "TARGET_TBM"
13029    "blcic\t{%1, %0|%0, %1}"
13030   [(set_attr "type" "bitmanip")
13031    (set_attr "mode" "<MODE>")])
13033 (define_insn "*tbm_blcmsk_<mode>"
13034   [(set (match_operand:SWI48 0 "register_operand" "=r")
13035         (xor:SWI48
13036           (plus:SWI48
13037             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13038             (const_int 1))
13039           (match_dup 1)))
13040    (clobber (reg:CC FLAGS_REG))]
13041    "TARGET_TBM"
13042    "blcmsk\t{%1, %0|%0, %1}"
13043   [(set_attr "type" "bitmanip")
13044    (set_attr "mode" "<MODE>")])
13046 (define_insn "*tbm_blcs_<mode>"
13047   [(set (match_operand:SWI48 0 "register_operand" "=r")
13048         (ior:SWI48
13049           (plus:SWI48
13050             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13051             (const_int 1))
13052           (match_dup 1)))
13053    (clobber (reg:CC FLAGS_REG))]
13054    "TARGET_TBM"
13055    "blcs\t{%1, %0|%0, %1}"
13056   [(set_attr "type" "bitmanip")
13057    (set_attr "mode" "<MODE>")])
13059 (define_insn "*tbm_blsfill_<mode>"
13060   [(set (match_operand:SWI48 0 "register_operand" "=r")
13061         (ior:SWI48
13062           (plus:SWI48
13063             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13064             (const_int -1))
13065           (match_dup 1)))
13066    (clobber (reg:CC FLAGS_REG))]
13067    "TARGET_TBM"
13068    "blsfill\t{%1, %0|%0, %1}"
13069   [(set_attr "type" "bitmanip")
13070    (set_attr "mode" "<MODE>")])
13072 (define_insn "*tbm_blsic_<mode>"
13073   [(set (match_operand:SWI48 0 "register_operand" "=r")
13074         (ior:SWI48
13075           (plus:SWI48
13076             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13077             (const_int -1))
13078           (not:SWI48
13079             (match_dup 1))))
13080    (clobber (reg:CC FLAGS_REG))]
13081    "TARGET_TBM"
13082    "blsic\t{%1, %0|%0, %1}"
13083   [(set_attr "type" "bitmanip")
13084    (set_attr "mode" "<MODE>")])
13086 (define_insn "*tbm_t1mskc_<mode>"
13087   [(set (match_operand:SWI48 0 "register_operand" "=r")
13088         (ior:SWI48
13089           (plus:SWI48
13090             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13091             (const_int 1))
13092           (not:SWI48
13093             (match_dup 1))))
13094    (clobber (reg:CC FLAGS_REG))]
13095    "TARGET_TBM"
13096    "t1mskc\t{%1, %0|%0, %1}"
13097   [(set_attr "type" "bitmanip")
13098    (set_attr "mode" "<MODE>")])
13100 (define_insn "*tbm_tzmsk_<mode>"
13101   [(set (match_operand:SWI48 0 "register_operand" "=r")
13102         (and:SWI48
13103           (plus:SWI48
13104             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13105             (const_int -1))
13106           (not:SWI48
13107             (match_dup 1))))
13108    (clobber (reg:CC FLAGS_REG))]
13109    "TARGET_TBM"
13110    "tzmsk\t{%1, %0|%0, %1}"
13111   [(set_attr "type" "bitmanip")
13112    (set_attr "mode" "<MODE>")])
13114 (define_insn "bsr_rex64"
13115   [(set (match_operand:DI 0 "register_operand" "=r")
13116         (minus:DI (const_int 63)
13117                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13118    (clobber (reg:CC FLAGS_REG))]
13119   "TARGET_64BIT"
13120   "bsr{q}\t{%1, %0|%0, %1}"
13121   [(set_attr "type" "alu1")
13122    (set_attr "prefix_0f" "1")
13123    (set_attr "znver1_decode" "vector")
13124    (set_attr "mode" "DI")])
13126 (define_insn "bsr"
13127   [(set (match_operand:SI 0 "register_operand" "=r")
13128         (minus:SI (const_int 31)
13129                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13130    (clobber (reg:CC FLAGS_REG))]
13131   ""
13132   "bsr{l}\t{%1, %0|%0, %1}"
13133   [(set_attr "type" "alu1")
13134    (set_attr "prefix_0f" "1")
13135    (set_attr "znver1_decode" "vector")
13136    (set_attr "mode" "SI")])
13138 (define_insn "*bsrhi"
13139   [(set (match_operand:HI 0 "register_operand" "=r")
13140         (minus:HI (const_int 15)
13141                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13142    (clobber (reg:CC FLAGS_REG))]
13143   ""
13144   "bsr{w}\t{%1, %0|%0, %1}"
13145   [(set_attr "type" "alu1")
13146    (set_attr "prefix_0f" "1")
13147    (set_attr "znver1_decode" "vector")
13148    (set_attr "mode" "HI")])
13150 (define_expand "popcount<mode>2"
13151   [(parallel
13152     [(set (match_operand:SWI248 0 "register_operand")
13153           (popcount:SWI248
13154             (match_operand:SWI248 1 "nonimmediate_operand")))
13155      (clobber (reg:CC FLAGS_REG))])]
13156   "TARGET_POPCNT")
13158 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13159   [(set (match_operand:SWI48 0 "register_operand" "=r")
13160         (popcount:SWI48
13161           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13162    (clobber (reg:CC FLAGS_REG))]
13163   "TARGET_POPCNT
13164    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13165   "#"
13166   "&& reload_completed"
13167   [(parallel
13168     [(set (match_dup 0)
13169           (popcount:SWI48 (match_dup 1)))
13170      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13171      (clobber (reg:CC FLAGS_REG))])]
13173   if (!reg_mentioned_p (operands[0], operands[1]))
13174     ix86_expand_clear (operands[0]);
13177 (define_insn "*popcount<mode>2_falsedep"
13178   [(set (match_operand:SWI48 0 "register_operand" "=r")
13179         (popcount:SWI48
13180           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13181    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13182            UNSPEC_INSN_FALSE_DEP)
13183    (clobber (reg:CC FLAGS_REG))]
13184   "TARGET_POPCNT"
13186 #if TARGET_MACHO
13187   return "popcnt\t{%1, %0|%0, %1}";
13188 #else
13189   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13190 #endif
13192   [(set_attr "prefix_rep" "1")
13193    (set_attr "type" "bitmanip")
13194    (set_attr "mode" "<MODE>")])
13196 (define_insn "*popcount<mode>2"
13197   [(set (match_operand:SWI248 0 "register_operand" "=r")
13198         (popcount:SWI248
13199           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13200    (clobber (reg:CC FLAGS_REG))]
13201   "TARGET_POPCNT"
13203 #if TARGET_MACHO
13204   return "popcnt\t{%1, %0|%0, %1}";
13205 #else
13206   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13207 #endif
13209   [(set_attr "prefix_rep" "1")
13210    (set_attr "type" "bitmanip")
13211    (set_attr "mode" "<MODE>")])
13213 (define_expand "bswapdi2"
13214   [(set (match_operand:DI 0 "register_operand")
13215         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13216   "TARGET_64BIT"
13218   if (!TARGET_MOVBE)
13219     operands[1] = force_reg (DImode, operands[1]);
13222 (define_expand "bswapsi2"
13223   [(set (match_operand:SI 0 "register_operand")
13224         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13225   ""
13227   if (TARGET_MOVBE)
13228     ;
13229   else if (TARGET_BSWAP)
13230     operands[1] = force_reg (SImode, operands[1]);
13231   else
13232     {
13233       rtx x = operands[0];
13235       emit_move_insn (x, operands[1]);
13236       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13237       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13238       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13239       DONE;
13240     }
13243 (define_insn "*bswap<mode>2_movbe"
13244   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13245         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13246   "TARGET_MOVBE
13247    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13248   "@
13249     bswap\t%0
13250     movbe\t{%1, %0|%0, %1}
13251     movbe\t{%1, %0|%0, %1}"
13252   [(set_attr "type" "bitmanip,imov,imov")
13253    (set_attr "modrm" "0,1,1")
13254    (set_attr "prefix_0f" "*,1,1")
13255    (set_attr "prefix_extra" "*,1,1")
13256    (set_attr "mode" "<MODE>")])
13258 (define_insn "*bswap<mode>2"
13259   [(set (match_operand:SWI48 0 "register_operand" "=r")
13260         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13261   "TARGET_BSWAP"
13262   "bswap\t%0"
13263   [(set_attr "type" "bitmanip")
13264    (set_attr "modrm" "0")
13265    (set_attr "mode" "<MODE>")])
13267 (define_insn "*bswaphi_lowpart_1"
13268   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13269         (bswap:HI (match_dup 0)))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13272   "@
13273     xchg{b}\t{%h0, %b0|%b0, %h0}
13274     rol{w}\t{$8, %0|%0, 8}"
13275   [(set_attr "length" "2,4")
13276    (set_attr "mode" "QI,HI")])
13278 (define_insn "bswaphi_lowpart"
13279   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13280         (bswap:HI (match_dup 0)))
13281    (clobber (reg:CC FLAGS_REG))]
13282   ""
13283   "rol{w}\t{$8, %0|%0, 8}"
13284   [(set_attr "length" "4")
13285    (set_attr "mode" "HI")])
13287 (define_expand "paritydi2"
13288   [(set (match_operand:DI 0 "register_operand")
13289         (parity:DI (match_operand:DI 1 "register_operand")))]
13290   "! TARGET_POPCNT"
13292   rtx scratch = gen_reg_rtx (QImode);
13293   rtx cond;
13295   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13296                                 NULL_RTX, operands[1]));
13298   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13299                          gen_rtx_REG (CCmode, FLAGS_REG),
13300                          const0_rtx);
13301   emit_insn (gen_rtx_SET (scratch, cond));
13303   if (TARGET_64BIT)
13304     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13305   else
13306     {
13307       rtx tmp = gen_reg_rtx (SImode);
13309       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13310       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13311     }
13312   DONE;
13315 (define_expand "paritysi2"
13316   [(set (match_operand:SI 0 "register_operand")
13317         (parity:SI (match_operand:SI 1 "register_operand")))]
13318   "! TARGET_POPCNT"
13320   rtx scratch = gen_reg_rtx (QImode);
13321   rtx cond;
13323   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13325   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13326                          gen_rtx_REG (CCmode, FLAGS_REG),
13327                          const0_rtx);
13328   emit_insn (gen_rtx_SET (scratch, cond));
13330   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13331   DONE;
13334 (define_insn_and_split "paritydi2_cmp"
13335   [(set (reg:CC FLAGS_REG)
13336         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13337                    UNSPEC_PARITY))
13338    (clobber (match_scratch:DI 0 "=r"))
13339    (clobber (match_scratch:SI 1 "=&r"))
13340    (clobber (match_scratch:HI 2 "=Q"))]
13341   "! TARGET_POPCNT"
13342   "#"
13343   "&& reload_completed"
13344   [(parallel
13345      [(set (match_dup 1)
13346            (xor:SI (match_dup 1) (match_dup 4)))
13347       (clobber (reg:CC FLAGS_REG))])
13348    (parallel
13349      [(set (reg:CC FLAGS_REG)
13350            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13351       (clobber (match_dup 1))
13352       (clobber (match_dup 2))])]
13354   operands[4] = gen_lowpart (SImode, operands[3]);
13356   if (TARGET_64BIT)
13357     {
13358       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13359       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13360     }
13361   else
13362     operands[1] = gen_highpart (SImode, operands[3]);
13365 (define_insn_and_split "paritysi2_cmp"
13366   [(set (reg:CC FLAGS_REG)
13367         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13368                    UNSPEC_PARITY))
13369    (clobber (match_scratch:SI 0 "=r"))
13370    (clobber (match_scratch:HI 1 "=&Q"))]
13371   "! TARGET_POPCNT"
13372   "#"
13373   "&& reload_completed"
13374   [(parallel
13375      [(set (match_dup 1)
13376            (xor:HI (match_dup 1) (match_dup 3)))
13377       (clobber (reg:CC FLAGS_REG))])
13378    (parallel
13379      [(set (reg:CC FLAGS_REG)
13380            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13381       (clobber (match_dup 1))])]
13383   operands[3] = gen_lowpart (HImode, operands[2]);
13385   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13386   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13389 (define_insn "*parityhi2_cmp"
13390   [(set (reg:CC FLAGS_REG)
13391         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13392                    UNSPEC_PARITY))
13393    (clobber (match_scratch:HI 0 "=Q"))]
13394   "! TARGET_POPCNT"
13395   "xor{b}\t{%h0, %b0|%b0, %h0}"
13396   [(set_attr "length" "2")
13397    (set_attr "mode" "HI")])
13400 ;; Thread-local storage patterns for ELF.
13402 ;; Note that these code sequences must appear exactly as shown
13403 ;; in order to allow linker relaxation.
13405 (define_insn "*tls_global_dynamic_32_gnu"
13406   [(set (match_operand:SI 0 "register_operand" "=a")
13407         (unspec:SI
13408          [(match_operand:SI 1 "register_operand" "b")
13409           (match_operand 2 "tls_symbolic_operand")
13410           (match_operand 3 "constant_call_address_operand" "Bz")
13411           (reg:SI SP_REG)]
13412          UNSPEC_TLS_GD))
13413    (clobber (match_scratch:SI 4 "=d"))
13414    (clobber (match_scratch:SI 5 "=c"))
13415    (clobber (reg:CC FLAGS_REG))]
13416   "!TARGET_64BIT && TARGET_GNU_TLS"
13418   output_asm_insn
13419     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13420   if (TARGET_SUN_TLS)
13421 #ifdef HAVE_AS_IX86_TLSGDPLT
13422     return "call\t%a2@tlsgdplt";
13423 #else
13424     return "call\t%p3@plt";
13425 #endif
13426   return "call\t%P3";
13428   [(set_attr "type" "multi")
13429    (set_attr "length" "12")])
13431 (define_expand "tls_global_dynamic_32"
13432   [(parallel
13433     [(set (match_operand:SI 0 "register_operand")
13434           (unspec:SI [(match_operand:SI 2 "register_operand")
13435                       (match_operand 1 "tls_symbolic_operand")
13436                       (match_operand 3 "constant_call_address_operand")
13437                       (reg:SI SP_REG)]
13438                      UNSPEC_TLS_GD))
13439      (clobber (match_scratch:SI 4))
13440      (clobber (match_scratch:SI 5))
13441      (clobber (reg:CC FLAGS_REG))])]
13442   ""
13443   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13445 (define_insn "*tls_global_dynamic_64_<mode>"
13446   [(set (match_operand:P 0 "register_operand" "=a")
13447         (call:P
13448          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13449          (match_operand 3)))
13450    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13451               (reg:P SP_REG)]
13452              UNSPEC_TLS_GD)]
13453   "TARGET_64BIT"
13455   if (!TARGET_X32)
13456     fputs (ASM_BYTE "0x66\n", asm_out_file);
13457   output_asm_insn
13458     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13459   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13460   fputs ("\trex64\n", asm_out_file);
13461   if (TARGET_SUN_TLS)
13462     return "call\t%p2@plt";
13463   return "call\t%P2";
13465   [(set_attr "type" "multi")
13466    (set (attr "length")
13467         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13469 (define_insn "*tls_global_dynamic_64_largepic"
13470   [(set (match_operand:DI 0 "register_operand" "=a")
13471         (call:DI
13472          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13473                           (match_operand:DI 3 "immediate_operand" "i")))
13474          (match_operand 4)))
13475    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13476                (reg:DI SP_REG)]
13477               UNSPEC_TLS_GD)]
13478   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13479    && GET_CODE (operands[3]) == CONST
13480    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13481    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13483   output_asm_insn
13484     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13485   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13486   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13487   return "call\t{*%%rax|rax}";
13489   [(set_attr "type" "multi")
13490    (set_attr "length" "22")])
13492 (define_expand "tls_global_dynamic_64_<mode>"
13493   [(parallel
13494     [(set (match_operand:P 0 "register_operand")
13495           (call:P
13496            (mem:QI (match_operand 2))
13497            (const_int 0)))
13498      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13499                 (reg:P SP_REG)]
13500                UNSPEC_TLS_GD)])]
13501   "TARGET_64BIT"
13502   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13504 (define_insn "*tls_local_dynamic_base_32_gnu"
13505   [(set (match_operand:SI 0 "register_operand" "=a")
13506         (unspec:SI
13507          [(match_operand:SI 1 "register_operand" "b")
13508           (match_operand 2 "constant_call_address_operand" "Bz")
13509           (reg:SI SP_REG)]
13510          UNSPEC_TLS_LD_BASE))
13511    (clobber (match_scratch:SI 3 "=d"))
13512    (clobber (match_scratch:SI 4 "=c"))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "!TARGET_64BIT && TARGET_GNU_TLS"
13516   output_asm_insn
13517     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13518   if (TARGET_SUN_TLS)
13519     {
13520       if (HAVE_AS_IX86_TLSLDMPLT)
13521         return "call\t%&@tlsldmplt";
13522       else
13523         return "call\t%p2@plt";
13524     }
13525   return "call\t%P2";
13527   [(set_attr "type" "multi")
13528    (set_attr "length" "11")])
13530 (define_expand "tls_local_dynamic_base_32"
13531   [(parallel
13532      [(set (match_operand:SI 0 "register_operand")
13533            (unspec:SI
13534             [(match_operand:SI 1 "register_operand")
13535              (match_operand 2 "constant_call_address_operand")
13536              (reg:SI SP_REG)]
13537             UNSPEC_TLS_LD_BASE))
13538       (clobber (match_scratch:SI 3))
13539       (clobber (match_scratch:SI 4))
13540       (clobber (reg:CC FLAGS_REG))])]
13541   ""
13542   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13544 (define_insn "*tls_local_dynamic_base_64_<mode>"
13545   [(set (match_operand:P 0 "register_operand" "=a")
13546         (call:P
13547          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13548          (match_operand 2)))
13549    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13550   "TARGET_64BIT"
13552   output_asm_insn
13553     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13554   if (TARGET_SUN_TLS)
13555     return "call\t%p1@plt";
13556   return "call\t%P1";
13558   [(set_attr "type" "multi")
13559    (set_attr "length" "12")])
13561 (define_insn "*tls_local_dynamic_base_64_largepic"
13562   [(set (match_operand:DI 0 "register_operand" "=a")
13563         (call:DI
13564          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13565                           (match_operand:DI 2 "immediate_operand" "i")))
13566          (match_operand 3)))
13567    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13568   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13569    && GET_CODE (operands[2]) == CONST
13570    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13571    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13573   output_asm_insn
13574     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13575   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13576   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13577   return "call\t{*%%rax|rax}";
13579   [(set_attr "type" "multi")
13580    (set_attr "length" "22")])
13582 (define_expand "tls_local_dynamic_base_64_<mode>"
13583   [(parallel
13584      [(set (match_operand:P 0 "register_operand")
13585            (call:P
13586             (mem:QI (match_operand 1))
13587             (const_int 0)))
13588       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13589   "TARGET_64BIT"
13590   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13592 ;; Local dynamic of a single variable is a lose.  Show combine how
13593 ;; to convert that back to global dynamic.
13595 (define_insn_and_split "*tls_local_dynamic_32_once"
13596   [(set (match_operand:SI 0 "register_operand" "=a")
13597         (plus:SI
13598          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13599                      (match_operand 2 "constant_call_address_operand" "Bz")
13600                      (reg:SI SP_REG)]
13601                     UNSPEC_TLS_LD_BASE)
13602          (const:SI (unspec:SI
13603                     [(match_operand 3 "tls_symbolic_operand")]
13604                     UNSPEC_DTPOFF))))
13605    (clobber (match_scratch:SI 4 "=d"))
13606    (clobber (match_scratch:SI 5 "=c"))
13607    (clobber (reg:CC FLAGS_REG))]
13608   ""
13609   "#"
13610   ""
13611   [(parallel
13612      [(set (match_dup 0)
13613            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13614                        (reg:SI SP_REG)]
13615                       UNSPEC_TLS_GD))
13616       (clobber (match_dup 4))
13617       (clobber (match_dup 5))
13618       (clobber (reg:CC FLAGS_REG))])])
13620 ;; Segment register for the thread base ptr load
13621 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13623 ;; Load and add the thread base pointer from %<tp_seg>:0.
13624 (define_insn "*load_tp_x32"
13625   [(set (match_operand:SI 0 "register_operand" "=r")
13626         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13627   "TARGET_X32"
13628   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13629   [(set_attr "type" "imov")
13630    (set_attr "modrm" "0")
13631    (set_attr "length" "7")
13632    (set_attr "memory" "load")
13633    (set_attr "imm_disp" "false")])
13635 (define_insn "*load_tp_x32_zext"
13636   [(set (match_operand:DI 0 "register_operand" "=r")
13637         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13638   "TARGET_X32"
13639   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13640   [(set_attr "type" "imov")
13641    (set_attr "modrm" "0")
13642    (set_attr "length" "7")
13643    (set_attr "memory" "load")
13644    (set_attr "imm_disp" "false")])
13646 (define_insn "*load_tp_<mode>"
13647   [(set (match_operand:P 0 "register_operand" "=r")
13648         (unspec:P [(const_int 0)] UNSPEC_TP))]
13649   "!TARGET_X32"
13650   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13651   [(set_attr "type" "imov")
13652    (set_attr "modrm" "0")
13653    (set_attr "length" "7")
13654    (set_attr "memory" "load")
13655    (set_attr "imm_disp" "false")])
13657 (define_insn "*add_tp_x32"
13658   [(set (match_operand:SI 0 "register_operand" "=r")
13659         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13660                  (match_operand:SI 1 "register_operand" "0")))
13661    (clobber (reg:CC FLAGS_REG))]
13662   "TARGET_X32"
13663   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13664   [(set_attr "type" "alu")
13665    (set_attr "modrm" "0")
13666    (set_attr "length" "7")
13667    (set_attr "memory" "load")
13668    (set_attr "imm_disp" "false")])
13670 (define_insn "*add_tp_x32_zext"
13671   [(set (match_operand:DI 0 "register_operand" "=r")
13672         (zero_extend:DI
13673           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13674                    (match_operand:SI 1 "register_operand" "0"))))
13675    (clobber (reg:CC FLAGS_REG))]
13676   "TARGET_X32"
13677   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13678   [(set_attr "type" "alu")
13679    (set_attr "modrm" "0")
13680    (set_attr "length" "7")
13681    (set_attr "memory" "load")
13682    (set_attr "imm_disp" "false")])
13684 (define_insn "*add_tp_<mode>"
13685   [(set (match_operand:P 0 "register_operand" "=r")
13686         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13687                 (match_operand:P 1 "register_operand" "0")))
13688    (clobber (reg:CC FLAGS_REG))]
13689   "!TARGET_X32"
13690   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13691   [(set_attr "type" "alu")
13692    (set_attr "modrm" "0")
13693    (set_attr "length" "7")
13694    (set_attr "memory" "load")
13695    (set_attr "imm_disp" "false")])
13697 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13698 ;; %rax as destination of the initial executable code sequence.
13699 (define_insn "tls_initial_exec_64_sun"
13700   [(set (match_operand:DI 0 "register_operand" "=a")
13701         (unspec:DI
13702          [(match_operand 1 "tls_symbolic_operand")]
13703          UNSPEC_TLS_IE_SUN))
13704    (clobber (reg:CC FLAGS_REG))]
13705   "TARGET_64BIT && TARGET_SUN_TLS"
13707   output_asm_insn
13708     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13709   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13711   [(set_attr "type" "multi")])
13713 ;; GNU2 TLS patterns can be split.
13715 (define_expand "tls_dynamic_gnu2_32"
13716   [(set (match_dup 3)
13717         (plus:SI (match_operand:SI 2 "register_operand")
13718                  (const:SI
13719                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13720                              UNSPEC_TLSDESC))))
13721    (parallel
13722     [(set (match_operand:SI 0 "register_operand")
13723           (unspec:SI [(match_dup 1) (match_dup 3)
13724                       (match_dup 2) (reg:SI SP_REG)]
13725                       UNSPEC_TLSDESC))
13726      (clobber (reg:CC FLAGS_REG))])]
13727   "!TARGET_64BIT && TARGET_GNU2_TLS"
13729   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13730   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13733 (define_insn "*tls_dynamic_gnu2_lea_32"
13734   [(set (match_operand:SI 0 "register_operand" "=r")
13735         (plus:SI (match_operand:SI 1 "register_operand" "b")
13736                  (const:SI
13737                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13738                               UNSPEC_TLSDESC))))]
13739   "!TARGET_64BIT && TARGET_GNU2_TLS"
13740   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13741   [(set_attr "type" "lea")
13742    (set_attr "mode" "SI")
13743    (set_attr "length" "6")
13744    (set_attr "length_address" "4")])
13746 (define_insn "*tls_dynamic_gnu2_call_32"
13747   [(set (match_operand:SI 0 "register_operand" "=a")
13748         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13749                     (match_operand:SI 2 "register_operand" "0")
13750                     ;; we have to make sure %ebx still points to the GOT
13751                     (match_operand:SI 3 "register_operand" "b")
13752                     (reg:SI SP_REG)]
13753                    UNSPEC_TLSDESC))
13754    (clobber (reg:CC FLAGS_REG))]
13755   "!TARGET_64BIT && TARGET_GNU2_TLS"
13756   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13757   [(set_attr "type" "call")
13758    (set_attr "length" "2")
13759    (set_attr "length_address" "0")])
13761 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13762   [(set (match_operand:SI 0 "register_operand" "=&a")
13763         (plus:SI
13764          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13765                      (match_operand:SI 4)
13766                      (match_operand:SI 2 "register_operand" "b")
13767                      (reg:SI SP_REG)]
13768                     UNSPEC_TLSDESC)
13769          (const:SI (unspec:SI
13770                     [(match_operand 1 "tls_symbolic_operand")]
13771                     UNSPEC_DTPOFF))))
13772    (clobber (reg:CC FLAGS_REG))]
13773   "!TARGET_64BIT && TARGET_GNU2_TLS"
13774   "#"
13775   ""
13776   [(set (match_dup 0) (match_dup 5))]
13778   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13779   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13782 (define_expand "tls_dynamic_gnu2_64"
13783   [(set (match_dup 2)
13784         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13785                    UNSPEC_TLSDESC))
13786    (parallel
13787     [(set (match_operand:DI 0 "register_operand")
13788           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13789                      UNSPEC_TLSDESC))
13790      (clobber (reg:CC FLAGS_REG))])]
13791   "TARGET_64BIT && TARGET_GNU2_TLS"
13793   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13794   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13797 (define_insn "*tls_dynamic_gnu2_lea_64"
13798   [(set (match_operand:DI 0 "register_operand" "=r")
13799         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13800                    UNSPEC_TLSDESC))]
13801   "TARGET_64BIT && TARGET_GNU2_TLS"
13802   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13803   [(set_attr "type" "lea")
13804    (set_attr "mode" "DI")
13805    (set_attr "length" "7")
13806    (set_attr "length_address" "4")])
13808 (define_insn "*tls_dynamic_gnu2_call_64"
13809   [(set (match_operand:DI 0 "register_operand" "=a")
13810         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13811                     (match_operand:DI 2 "register_operand" "0")
13812                     (reg:DI SP_REG)]
13813                    UNSPEC_TLSDESC))
13814    (clobber (reg:CC FLAGS_REG))]
13815   "TARGET_64BIT && TARGET_GNU2_TLS"
13816   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13817   [(set_attr "type" "call")
13818    (set_attr "length" "2")
13819    (set_attr "length_address" "0")])
13821 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13822   [(set (match_operand:DI 0 "register_operand" "=&a")
13823         (plus:DI
13824          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13825                      (match_operand:DI 3)
13826                      (reg:DI SP_REG)]
13827                     UNSPEC_TLSDESC)
13828          (const:DI (unspec:DI
13829                     [(match_operand 1 "tls_symbolic_operand")]
13830                     UNSPEC_DTPOFF))))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "TARGET_64BIT && TARGET_GNU2_TLS"
13833   "#"
13834   ""
13835   [(set (match_dup 0) (match_dup 4))]
13837   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13838   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13841 ;; These patterns match the binary 387 instructions for addM3, subM3,
13842 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13843 ;; SFmode.  The first is the normal insn, the second the same insn but
13844 ;; with one operand a conversion, and the third the same insn but with
13845 ;; the other operand a conversion.  The conversion may be SFmode or
13846 ;; SImode if the target mode DFmode, but only SImode if the target mode
13847 ;; is SFmode.
13849 ;; Gcc is slightly more smart about handling normal two address instructions
13850 ;; so use special patterns for add and mull.
13852 (define_insn "*fop_<mode>_comm_mixed"
13853   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13854         (match_operator:MODEF 3 "binary_fp_operator"
13855           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13856            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13857   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13858    && COMMUTATIVE_ARITH_P (operands[3])
13859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13860   "* return output_387_binary_op (insn, operands);"
13861   [(set (attr "type")
13862         (if_then_else (eq_attr "alternative" "1,2")
13863            (if_then_else (match_operand:MODEF 3 "mult_operator")
13864               (const_string "ssemul")
13865               (const_string "sseadd"))
13866            (if_then_else (match_operand:MODEF 3 "mult_operator")
13867               (const_string "fmul")
13868               (const_string "fop"))))
13869    (set_attr "isa" "*,noavx,avx")
13870    (set_attr "prefix" "orig,orig,vex")
13871    (set_attr "mode" "<MODE>")
13872    (set (attr "enabled")
13873      (cond [(eq_attr "alternative" "0")
13874               (symbol_ref "TARGET_MIX_SSE_I387")
13875            ]
13876            (const_string "*")))])
13878 (define_insn "*fop_<mode>_comm_i387"
13879   [(set (match_operand:MODEF 0 "register_operand" "=f")
13880         (match_operator:MODEF 3 "binary_fp_operator"
13881           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13882            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13883   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13884    && COMMUTATIVE_ARITH_P (operands[3])
13885    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13886   "* return output_387_binary_op (insn, operands);"
13887   [(set (attr "type")
13888         (if_then_else (match_operand:MODEF 3 "mult_operator")
13889            (const_string "fmul")
13890            (const_string "fop")))
13891    (set_attr "mode" "<MODE>")])
13893 (define_insn "*rcpsf2_sse"
13894   [(set (match_operand:SF 0 "register_operand" "=x")
13895         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13896                    UNSPEC_RCP))]
13897   "TARGET_SSE_MATH"
13898   "%vrcpss\t{%1, %d0|%d0, %1}"
13899   [(set_attr "type" "sse")
13900    (set_attr "atom_sse_attr" "rcp")
13901    (set_attr "btver2_sse_attr" "rcp")
13902    (set_attr "prefix" "maybe_vex")
13903    (set_attr "mode" "SF")])
13905 (define_insn "*fop_<mode>_1_mixed"
13906   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13907         (match_operator:MODEF 3 "binary_fp_operator"
13908           [(match_operand:MODEF 1
13909              "register_mixssei387nonimm_operand" "0,fm,0,v")
13910            (match_operand:MODEF 2
13911              "nonimmediate_operand"              "fm,0,xm,vm")]))]
13912   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13913    && !COMMUTATIVE_ARITH_P (operands[3])
13914    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13915   "* return output_387_binary_op (insn, operands);"
13916   [(set (attr "type")
13917         (cond [(and (eq_attr "alternative" "2,3")
13918                     (match_operand:MODEF 3 "mult_operator"))
13919                  (const_string "ssemul")
13920                (and (eq_attr "alternative" "2,3")
13921                     (match_operand:MODEF 3 "div_operator"))
13922                  (const_string "ssediv")
13923                (eq_attr "alternative" "2,3")
13924                  (const_string "sseadd")
13925                (match_operand:MODEF 3 "mult_operator")
13926                  (const_string "fmul")
13927                (match_operand:MODEF 3 "div_operator")
13928                  (const_string "fdiv")
13929               ]
13930               (const_string "fop")))
13931    (set_attr "isa" "*,*,noavx,avx")
13932    (set_attr "prefix" "orig,orig,orig,vex")
13933    (set_attr "mode" "<MODE>")
13934    (set (attr "enabled")
13935      (cond [(eq_attr "alternative" "0,1")
13936               (symbol_ref "TARGET_MIX_SSE_I387")
13937            ]
13938            (const_string "*")))])
13940 ;; This pattern is not fully shadowed by the pattern above.
13941 (define_insn "*fop_<mode>_1_i387"
13942   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13943         (match_operator:MODEF 3 "binary_fp_operator"
13944           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13945            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13946   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13947    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13948    && !COMMUTATIVE_ARITH_P (operands[3])
13949    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13950   "* return output_387_binary_op (insn, operands);"
13951   [(set (attr "type")
13952         (cond [(match_operand:MODEF 3 "mult_operator")
13953                  (const_string "fmul")
13954                (match_operand:MODEF 3 "div_operator")
13955                  (const_string "fdiv")
13956               ]
13957               (const_string "fop")))
13958    (set_attr "mode" "<MODE>")])
13960 ;; ??? Add SSE splitters for these!
13961 (define_insn "*fop_<MODEF:mode>_2_i387"
13962   [(set (match_operand:MODEF 0 "register_operand" "=f")
13963         (match_operator:MODEF 3 "binary_fp_operator"
13964           [(float:MODEF
13965              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13966            (match_operand:MODEF 2 "register_operand" "0")]))]
13967   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13968    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13969    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13970        || optimize_function_for_size_p (cfun))"
13971   { return output_387_binary_op (insn, operands); }
13972   [(set (attr "type")
13973         (cond [(match_operand:MODEF 3 "mult_operator")
13974                  (const_string "fmul")
13975                (match_operand:MODEF 3 "div_operator")
13976                  (const_string "fdiv")
13977               ]
13978               (const_string "fop")))
13979    (set_attr "fp_int_src" "true")
13980    (set_attr "mode" "<SWI24:MODE>")])
13982 (define_insn "*fop_<MODEF:mode>_3_i387"
13983   [(set (match_operand:MODEF 0 "register_operand" "=f")
13984         (match_operator:MODEF 3 "binary_fp_operator"
13985           [(match_operand:MODEF 1 "register_operand" "0")
13986            (float:MODEF
13987              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13988   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13989    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13990    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13991        || optimize_function_for_size_p (cfun))"
13992   { return output_387_binary_op (insn, operands); }
13993   [(set (attr "type")
13994         (cond [(match_operand:MODEF 3 "mult_operator")
13995                  (const_string "fmul")
13996                (match_operand:MODEF 3 "div_operator")
13997                  (const_string "fdiv")
13998               ]
13999               (const_string "fop")))
14000    (set_attr "fp_int_src" "true")
14001    (set_attr "mode" "<MODE>")])
14003 (define_insn "*fop_df_4_i387"
14004   [(set (match_operand:DF 0 "register_operand" "=f,f")
14005         (match_operator:DF 3 "binary_fp_operator"
14006            [(float_extend:DF
14007              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14008             (match_operand:DF 2 "register_operand" "0,f")]))]
14009   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14010    && !(TARGET_SSE2 && TARGET_SSE_MATH)
14011    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14012   "* return output_387_binary_op (insn, operands);"
14013   [(set (attr "type")
14014         (cond [(match_operand:DF 3 "mult_operator")
14015                  (const_string "fmul")
14016                (match_operand:DF 3 "div_operator")
14017                  (const_string "fdiv")
14018               ]
14019               (const_string "fop")))
14020    (set_attr "mode" "SF")])
14022 (define_insn "*fop_df_5_i387"
14023   [(set (match_operand:DF 0 "register_operand" "=f,f")
14024         (match_operator:DF 3 "binary_fp_operator"
14025           [(match_operand:DF 1 "register_operand" "0,f")
14026            (float_extend:DF
14027             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14028   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14029    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14030   "* return output_387_binary_op (insn, operands);"
14031   [(set (attr "type")
14032         (cond [(match_operand:DF 3 "mult_operator")
14033                  (const_string "fmul")
14034                (match_operand:DF 3 "div_operator")
14035                  (const_string "fdiv")
14036               ]
14037               (const_string "fop")))
14038    (set_attr "mode" "SF")])
14040 (define_insn "*fop_df_6_i387"
14041   [(set (match_operand:DF 0 "register_operand" "=f,f")
14042         (match_operator:DF 3 "binary_fp_operator"
14043           [(float_extend:DF
14044             (match_operand:SF 1 "register_operand" "0,f"))
14045            (float_extend:DF
14046             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14047   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14048    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14049   "* return output_387_binary_op (insn, operands);"
14050   [(set (attr "type")
14051         (cond [(match_operand:DF 3 "mult_operator")
14052                  (const_string "fmul")
14053                (match_operand:DF 3 "div_operator")
14054                  (const_string "fdiv")
14055               ]
14056               (const_string "fop")))
14057    (set_attr "mode" "SF")])
14059 (define_insn "*fop_xf_comm_i387"
14060   [(set (match_operand:XF 0 "register_operand" "=f")
14061         (match_operator:XF 3 "binary_fp_operator"
14062                         [(match_operand:XF 1 "register_operand" "%0")
14063                          (match_operand:XF 2 "register_operand" "f")]))]
14064   "TARGET_80387
14065    && COMMUTATIVE_ARITH_P (operands[3])"
14066   "* return output_387_binary_op (insn, operands);"
14067   [(set (attr "type")
14068         (if_then_else (match_operand:XF 3 "mult_operator")
14069            (const_string "fmul")
14070            (const_string "fop")))
14071    (set_attr "mode" "XF")])
14073 (define_insn "*fop_xf_1_i387"
14074   [(set (match_operand:XF 0 "register_operand" "=f,f")
14075         (match_operator:XF 3 "binary_fp_operator"
14076                         [(match_operand:XF 1 "register_operand" "0,f")
14077                          (match_operand:XF 2 "register_operand" "f,0")]))]
14078   "TARGET_80387
14079    && !COMMUTATIVE_ARITH_P (operands[3])"
14080   "* return output_387_binary_op (insn, operands);"
14081   [(set (attr "type")
14082         (cond [(match_operand:XF 3 "mult_operator")
14083                  (const_string "fmul")
14084                (match_operand:XF 3 "div_operator")
14085                  (const_string "fdiv")
14086               ]
14087               (const_string "fop")))
14088    (set_attr "mode" "XF")])
14090 (define_insn "*fop_xf_2_i387"
14091   [(set (match_operand:XF 0 "register_operand" "=f")
14092         (match_operator:XF 3 "binary_fp_operator"
14093           [(float:XF
14094              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14095            (match_operand:XF 2 "register_operand" "0")]))]
14096   "TARGET_80387
14097    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14098   { return output_387_binary_op (insn, operands); }
14099   [(set (attr "type")
14100         (cond [(match_operand:XF 3 "mult_operator")
14101                  (const_string "fmul")
14102                (match_operand:XF 3 "div_operator")
14103                  (const_string "fdiv")
14104               ]
14105               (const_string "fop")))
14106    (set_attr "fp_int_src" "true")
14107    (set_attr "mode" "<MODE>")])
14109 (define_insn "*fop_xf_3_i387"
14110   [(set (match_operand:XF 0 "register_operand" "=f")
14111         (match_operator:XF 3 "binary_fp_operator"
14112           [(match_operand:XF 1 "register_operand" "0")
14113            (float:XF
14114              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14115   "TARGET_80387
14116    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14117   { return output_387_binary_op (insn, operands); }
14118   [(set (attr "type")
14119         (cond [(match_operand:XF 3 "mult_operator")
14120                  (const_string "fmul")
14121                (match_operand:XF 3 "div_operator")
14122                  (const_string "fdiv")
14123               ]
14124               (const_string "fop")))
14125    (set_attr "fp_int_src" "true")
14126    (set_attr "mode" "<MODE>")])
14128 (define_insn "*fop_xf_4_i387"
14129   [(set (match_operand:XF 0 "register_operand" "=f,f")
14130         (match_operator:XF 3 "binary_fp_operator"
14131            [(float_extend:XF
14132               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14133             (match_operand:XF 2 "register_operand" "0,f")]))]
14134   "TARGET_80387"
14135   "* return output_387_binary_op (insn, operands);"
14136   [(set (attr "type")
14137         (cond [(match_operand:XF 3 "mult_operator")
14138                  (const_string "fmul")
14139                (match_operand:XF 3 "div_operator")
14140                  (const_string "fdiv")
14141               ]
14142               (const_string "fop")))
14143    (set_attr "mode" "<MODE>")])
14145 (define_insn "*fop_xf_5_i387"
14146   [(set (match_operand:XF 0 "register_operand" "=f,f")
14147         (match_operator:XF 3 "binary_fp_operator"
14148           [(match_operand:XF 1 "register_operand" "0,f")
14149            (float_extend:XF
14150              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14151   "TARGET_80387"
14152   "* return output_387_binary_op (insn, operands);"
14153   [(set (attr "type")
14154         (cond [(match_operand:XF 3 "mult_operator")
14155                  (const_string "fmul")
14156                (match_operand:XF 3 "div_operator")
14157                  (const_string "fdiv")
14158               ]
14159               (const_string "fop")))
14160    (set_attr "mode" "<MODE>")])
14162 (define_insn "*fop_xf_6_i387"
14163   [(set (match_operand:XF 0 "register_operand" "=f,f")
14164         (match_operator:XF 3 "binary_fp_operator"
14165           [(float_extend:XF
14166              (match_operand:MODEF 1 "register_operand" "0,f"))
14167            (float_extend:XF
14168              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14169   "TARGET_80387"
14170   "* return output_387_binary_op (insn, operands);"
14171   [(set (attr "type")
14172         (cond [(match_operand:XF 3 "mult_operator")
14173                  (const_string "fmul")
14174                (match_operand:XF 3 "div_operator")
14175                  (const_string "fdiv")
14176               ]
14177               (const_string "fop")))
14178    (set_attr "mode" "<MODE>")])
14180 ;; FPU special functions.
14182 ;; This pattern implements a no-op XFmode truncation for
14183 ;; all fancy i386 XFmode math functions.
14185 (define_insn "truncxf<mode>2_i387_noop_unspec"
14186   [(set (match_operand:MODEF 0 "register_operand" "=f")
14187         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14188         UNSPEC_TRUNC_NOOP))]
14189   "TARGET_USE_FANCY_MATH_387"
14190   "* return output_387_reg_move (insn, operands);"
14191   [(set_attr "type" "fmov")
14192    (set_attr "mode" "<MODE>")])
14194 (define_insn "sqrtxf2"
14195   [(set (match_operand:XF 0 "register_operand" "=f")
14196         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14197   "TARGET_USE_FANCY_MATH_387"
14198   "fsqrt"
14199   [(set_attr "type" "fpspc")
14200    (set_attr "mode" "XF")
14201    (set_attr "athlon_decode" "direct")
14202    (set_attr "amdfam10_decode" "direct")
14203    (set_attr "bdver1_decode" "direct")])
14205 (define_insn "sqrt_extend<mode>xf2_i387"
14206   [(set (match_operand:XF 0 "register_operand" "=f")
14207         (sqrt:XF
14208           (float_extend:XF
14209             (match_operand:MODEF 1 "register_operand" "0"))))]
14210   "TARGET_USE_FANCY_MATH_387"
14211   "fsqrt"
14212   [(set_attr "type" "fpspc")
14213    (set_attr "mode" "XF")
14214    (set_attr "athlon_decode" "direct")
14215    (set_attr "amdfam10_decode" "direct")
14216    (set_attr "bdver1_decode" "direct")])
14218 (define_insn "*rsqrtsf2_sse"
14219   [(set (match_operand:SF 0 "register_operand" "=x")
14220         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14221                    UNSPEC_RSQRT))]
14222   "TARGET_SSE_MATH"
14223   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14224   [(set_attr "type" "sse")
14225    (set_attr "atom_sse_attr" "rcp")
14226    (set_attr "btver2_sse_attr" "rcp")
14227    (set_attr "prefix" "maybe_vex")
14228    (set_attr "mode" "SF")])
14230 (define_expand "rsqrtsf2"
14231   [(set (match_operand:SF 0 "register_operand")
14232         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14233                    UNSPEC_RSQRT))]
14234   "TARGET_SSE_MATH"
14236   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14237   DONE;
14240 (define_insn "*sqrt<mode>2_sse"
14241   [(set (match_operand:MODEF 0 "register_operand" "=v")
14242         (sqrt:MODEF
14243           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14244   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14245   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14246   [(set_attr "type" "sse")
14247    (set_attr "atom_sse_attr" "sqrt")
14248    (set_attr "btver2_sse_attr" "sqrt")
14249    (set_attr "prefix" "maybe_vex")
14250    (set_attr "mode" "<MODE>")
14251    (set_attr "athlon_decode" "*")
14252    (set_attr "amdfam10_decode" "*")
14253    (set_attr "bdver1_decode" "*")])
14255 (define_expand "sqrt<mode>2"
14256   [(set (match_operand:MODEF 0 "register_operand")
14257         (sqrt:MODEF
14258           (match_operand:MODEF 1 "nonimmediate_operand")))]
14259   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14260    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14262   if (<MODE>mode == SFmode
14263       && TARGET_SSE_MATH
14264       && TARGET_RECIP_SQRT
14265       && !optimize_function_for_size_p (cfun)
14266       && flag_finite_math_only && !flag_trapping_math
14267       && flag_unsafe_math_optimizations)
14268     {
14269       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14270       DONE;
14271     }
14273   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14274     {
14275       rtx op0 = gen_reg_rtx (XFmode);
14276       rtx op1 = force_reg (<MODE>mode, operands[1]);
14278       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14279       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14280       DONE;
14281    }
14284 (define_insn "fpremxf4_i387"
14285   [(set (match_operand:XF 0 "register_operand" "=f")
14286         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14287                     (match_operand:XF 3 "register_operand" "1")]
14288                    UNSPEC_FPREM_F))
14289    (set (match_operand:XF 1 "register_operand" "=u")
14290         (unspec:XF [(match_dup 2) (match_dup 3)]
14291                    UNSPEC_FPREM_U))
14292    (set (reg:CCFP FPSR_REG)
14293         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14294                      UNSPEC_C2_FLAG))]
14295   "TARGET_USE_FANCY_MATH_387
14296    && flag_finite_math_only"
14297   "fprem"
14298   [(set_attr "type" "fpspc")
14299    (set_attr "znver1_decode" "vector")
14300    (set_attr "mode" "XF")])
14302 (define_expand "fmodxf3"
14303   [(use (match_operand:XF 0 "register_operand"))
14304    (use (match_operand:XF 1 "general_operand"))
14305    (use (match_operand:XF 2 "general_operand"))]
14306   "TARGET_USE_FANCY_MATH_387
14307    && flag_finite_math_only"
14309   rtx_code_label *label = gen_label_rtx ();
14311   rtx op1 = gen_reg_rtx (XFmode);
14312   rtx op2 = gen_reg_rtx (XFmode);
14314   emit_move_insn (op2, operands[2]);
14315   emit_move_insn (op1, operands[1]);
14317   emit_label (label);
14318   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14319   ix86_emit_fp_unordered_jump (label);
14320   LABEL_NUSES (label) = 1;
14322   emit_move_insn (operands[0], op1);
14323   DONE;
14326 (define_expand "fmod<mode>3"
14327   [(use (match_operand:MODEF 0 "register_operand"))
14328    (use (match_operand:MODEF 1 "general_operand"))
14329    (use (match_operand:MODEF 2 "general_operand"))]
14330   "TARGET_USE_FANCY_MATH_387
14331    && flag_finite_math_only"
14333   rtx (*gen_truncxf) (rtx, rtx);
14335   rtx_code_label *label = gen_label_rtx ();
14337   rtx op1 = gen_reg_rtx (XFmode);
14338   rtx op2 = gen_reg_rtx (XFmode);
14340   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14341   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14343   emit_label (label);
14344   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14345   ix86_emit_fp_unordered_jump (label);
14346   LABEL_NUSES (label) = 1;
14348   /* Truncate the result properly for strict SSE math.  */
14349   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14350       && !TARGET_MIX_SSE_I387)
14351     gen_truncxf = gen_truncxf<mode>2;
14352   else
14353     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14355   emit_insn (gen_truncxf (operands[0], op1));
14356   DONE;
14359 (define_insn "fprem1xf4_i387"
14360   [(set (match_operand:XF 0 "register_operand" "=f")
14361         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14362                     (match_operand:XF 3 "register_operand" "1")]
14363                    UNSPEC_FPREM1_F))
14364    (set (match_operand:XF 1 "register_operand" "=u")
14365         (unspec:XF [(match_dup 2) (match_dup 3)]
14366                    UNSPEC_FPREM1_U))
14367    (set (reg:CCFP FPSR_REG)
14368         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14369                      UNSPEC_C2_FLAG))]
14370   "TARGET_USE_FANCY_MATH_387
14371    && flag_finite_math_only"
14372   "fprem1"
14373   [(set_attr "type" "fpspc")
14374    (set_attr "znver1_decode" "vector")
14375    (set_attr "mode" "XF")])
14377 (define_expand "remainderxf3"
14378   [(use (match_operand:XF 0 "register_operand"))
14379    (use (match_operand:XF 1 "general_operand"))
14380    (use (match_operand:XF 2 "general_operand"))]
14381   "TARGET_USE_FANCY_MATH_387
14382    && flag_finite_math_only"
14384   rtx_code_label *label = gen_label_rtx ();
14386   rtx op1 = gen_reg_rtx (XFmode);
14387   rtx op2 = gen_reg_rtx (XFmode);
14389   emit_move_insn (op2, operands[2]);
14390   emit_move_insn (op1, operands[1]);
14392   emit_label (label);
14393   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14394   ix86_emit_fp_unordered_jump (label);
14395   LABEL_NUSES (label) = 1;
14397   emit_move_insn (operands[0], op1);
14398   DONE;
14401 (define_expand "remainder<mode>3"
14402   [(use (match_operand:MODEF 0 "register_operand"))
14403    (use (match_operand:MODEF 1 "general_operand"))
14404    (use (match_operand:MODEF 2 "general_operand"))]
14405   "TARGET_USE_FANCY_MATH_387
14406    && flag_finite_math_only"
14408   rtx (*gen_truncxf) (rtx, rtx);
14410   rtx_code_label *label = gen_label_rtx ();
14412   rtx op1 = gen_reg_rtx (XFmode);
14413   rtx op2 = gen_reg_rtx (XFmode);
14415   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14416   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418   emit_label (label);
14420   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14421   ix86_emit_fp_unordered_jump (label);
14422   LABEL_NUSES (label) = 1;
14424   /* Truncate the result properly for strict SSE math.  */
14425   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14426       && !TARGET_MIX_SSE_I387)
14427     gen_truncxf = gen_truncxf<mode>2;
14428   else
14429     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14431   emit_insn (gen_truncxf (operands[0], op1));
14432   DONE;
14435 (define_int_iterator SINCOS
14436         [UNSPEC_SIN
14437          UNSPEC_COS])
14439 (define_int_attr sincos
14440         [(UNSPEC_SIN "sin")
14441          (UNSPEC_COS "cos")])
14443 (define_insn "*<sincos>xf2_i387"
14444   [(set (match_operand:XF 0 "register_operand" "=f")
14445         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14446                    SINCOS))]
14447   "TARGET_USE_FANCY_MATH_387
14448    && flag_unsafe_math_optimizations"
14449   "f<sincos>"
14450   [(set_attr "type" "fpspc")
14451    (set_attr "znver1_decode" "vector")
14452    (set_attr "mode" "XF")])
14454 (define_insn "*<sincos>_extend<mode>xf2_i387"
14455   [(set (match_operand:XF 0 "register_operand" "=f")
14456         (unspec:XF [(float_extend:XF
14457                       (match_operand:MODEF 1 "register_operand" "0"))]
14458                    SINCOS))]
14459   "TARGET_USE_FANCY_MATH_387
14460    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14461        || TARGET_MIX_SSE_I387)
14462    && flag_unsafe_math_optimizations"
14463   "f<sincos>"
14464   [(set_attr "type" "fpspc")
14465    (set_attr "znver1_decode" "vector")
14466    (set_attr "mode" "XF")])
14468 ;; When sincos pattern is defined, sin and cos builtin functions will be
14469 ;; expanded to sincos pattern with one of its outputs left unused.
14470 ;; CSE pass will figure out if two sincos patterns can be combined,
14471 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14472 ;; depending on the unused output.
14474 (define_insn "sincosxf3"
14475   [(set (match_operand:XF 0 "register_operand" "=f")
14476         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14477                    UNSPEC_SINCOS_COS))
14478    (set (match_operand:XF 1 "register_operand" "=u")
14479         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14480   "TARGET_USE_FANCY_MATH_387
14481    && flag_unsafe_math_optimizations"
14482   "fsincos"
14483   [(set_attr "type" "fpspc")
14484    (set_attr "znver1_decode" "vector")
14485    (set_attr "mode" "XF")])
14487 (define_split
14488   [(set (match_operand:XF 0 "register_operand")
14489         (unspec:XF [(match_operand:XF 2 "register_operand")]
14490                    UNSPEC_SINCOS_COS))
14491    (set (match_operand:XF 1 "register_operand")
14492         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14493   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14494    && can_create_pseudo_p ()"
14495   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14497 (define_split
14498   [(set (match_operand:XF 0 "register_operand")
14499         (unspec:XF [(match_operand:XF 2 "register_operand")]
14500                    UNSPEC_SINCOS_COS))
14501    (set (match_operand:XF 1 "register_operand")
14502         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14503   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14504    && can_create_pseudo_p ()"
14505   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14507 (define_insn "sincos_extend<mode>xf3_i387"
14508   [(set (match_operand:XF 0 "register_operand" "=f")
14509         (unspec:XF [(float_extend:XF
14510                       (match_operand:MODEF 2 "register_operand" "0"))]
14511                    UNSPEC_SINCOS_COS))
14512    (set (match_operand:XF 1 "register_operand" "=u")
14513         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14514   "TARGET_USE_FANCY_MATH_387
14515    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14516        || TARGET_MIX_SSE_I387)
14517    && flag_unsafe_math_optimizations"
14518   "fsincos"
14519   [(set_attr "type" "fpspc")
14520    (set_attr "znver1_decode" "vector")
14521    (set_attr "mode" "XF")])
14523 (define_split
14524   [(set (match_operand:XF 0 "register_operand")
14525         (unspec:XF [(float_extend:XF
14526                       (match_operand:MODEF 2 "register_operand"))]
14527                    UNSPEC_SINCOS_COS))
14528    (set (match_operand:XF 1 "register_operand")
14529         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14530   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14531    && can_create_pseudo_p ()"
14532   [(set (match_dup 1)
14533         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14535 (define_split
14536   [(set (match_operand:XF 0 "register_operand")
14537         (unspec:XF [(float_extend:XF
14538                       (match_operand:MODEF 2 "register_operand"))]
14539                    UNSPEC_SINCOS_COS))
14540    (set (match_operand:XF 1 "register_operand")
14541         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14542   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14543    && can_create_pseudo_p ()"
14544   [(set (match_dup 0)
14545         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14547 (define_expand "sincos<mode>3"
14548   [(use (match_operand:MODEF 0 "register_operand"))
14549    (use (match_operand:MODEF 1 "register_operand"))
14550    (use (match_operand:MODEF 2 "register_operand"))]
14551   "TARGET_USE_FANCY_MATH_387
14552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553        || TARGET_MIX_SSE_I387)
14554    && flag_unsafe_math_optimizations"
14556   rtx op0 = gen_reg_rtx (XFmode);
14557   rtx op1 = gen_reg_rtx (XFmode);
14559   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14560   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14561   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14562   DONE;
14565 (define_insn "fptanxf4_i387"
14566   [(set (match_operand:XF 0 "register_operand" "=f")
14567         (match_operand:XF 3 "const_double_operand" "F"))
14568    (set (match_operand:XF 1 "register_operand" "=u")
14569         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14570                    UNSPEC_TAN))]
14571   "TARGET_USE_FANCY_MATH_387
14572    && flag_unsafe_math_optimizations
14573    && standard_80387_constant_p (operands[3]) == 2"
14574   "fptan"
14575   [(set_attr "type" "fpspc")
14576    (set_attr "znver1_decode" "vector")
14577    (set_attr "mode" "XF")])
14579 (define_insn "fptan_extend<mode>xf4_i387"
14580   [(set (match_operand:MODEF 0 "register_operand" "=f")
14581         (match_operand:MODEF 3 "const_double_operand" "F"))
14582    (set (match_operand:XF 1 "register_operand" "=u")
14583         (unspec:XF [(float_extend:XF
14584                       (match_operand:MODEF 2 "register_operand" "0"))]
14585                    UNSPEC_TAN))]
14586   "TARGET_USE_FANCY_MATH_387
14587    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14588        || TARGET_MIX_SSE_I387)
14589    && flag_unsafe_math_optimizations
14590    && standard_80387_constant_p (operands[3]) == 2"
14591   "fptan"
14592   [(set_attr "type" "fpspc")
14593    (set_attr "znver1_decode" "vector")
14594    (set_attr "mode" "XF")])
14596 (define_expand "tanxf2"
14597   [(use (match_operand:XF 0 "register_operand"))
14598    (use (match_operand:XF 1 "register_operand"))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && flag_unsafe_math_optimizations"
14602   rtx one = gen_reg_rtx (XFmode);
14603   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14605   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14606   DONE;
14609 (define_expand "tan<mode>2"
14610   [(use (match_operand:MODEF 0 "register_operand"))
14611    (use (match_operand:MODEF 1 "register_operand"))]
14612   "TARGET_USE_FANCY_MATH_387
14613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614        || TARGET_MIX_SSE_I387)
14615    && flag_unsafe_math_optimizations"
14617   rtx op0 = gen_reg_rtx (XFmode);
14619   rtx one = gen_reg_rtx (<MODE>mode);
14620   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14622   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14623                                              operands[1], op2));
14624   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14625   DONE;
14628 (define_insn "*fpatanxf3_i387"
14629   [(set (match_operand:XF 0 "register_operand" "=f")
14630         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14631                     (match_operand:XF 2 "register_operand" "u")]
14632                    UNSPEC_FPATAN))
14633    (clobber (match_scratch:XF 3 "=2"))]
14634   "TARGET_USE_FANCY_MATH_387
14635    && flag_unsafe_math_optimizations"
14636   "fpatan"
14637   [(set_attr "type" "fpspc")
14638    (set_attr "znver1_decode" "vector")
14639    (set_attr "mode" "XF")])
14641 (define_insn "fpatan_extend<mode>xf3_i387"
14642   [(set (match_operand:XF 0 "register_operand" "=f")
14643         (unspec:XF [(float_extend:XF
14644                       (match_operand:MODEF 1 "register_operand" "0"))
14645                     (float_extend:XF
14646                       (match_operand:MODEF 2 "register_operand" "u"))]
14647                    UNSPEC_FPATAN))
14648    (clobber (match_scratch:XF 3 "=2"))]
14649   "TARGET_USE_FANCY_MATH_387
14650    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14651        || TARGET_MIX_SSE_I387)
14652    && flag_unsafe_math_optimizations"
14653   "fpatan"
14654   [(set_attr "type" "fpspc")
14655    (set_attr "znver1_decode" "vector")
14656    (set_attr "mode" "XF")])
14658 (define_expand "atan2xf3"
14659   [(parallel [(set (match_operand:XF 0 "register_operand")
14660                    (unspec:XF [(match_operand:XF 2 "register_operand")
14661                                (match_operand:XF 1 "register_operand")]
14662                               UNSPEC_FPATAN))
14663               (clobber (match_scratch:XF 3))])]
14664   "TARGET_USE_FANCY_MATH_387
14665    && flag_unsafe_math_optimizations")
14667 (define_expand "atan2<mode>3"
14668   [(use (match_operand:MODEF 0 "register_operand"))
14669    (use (match_operand:MODEF 1 "register_operand"))
14670    (use (match_operand:MODEF 2 "register_operand"))]
14671   "TARGET_USE_FANCY_MATH_387
14672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673        || TARGET_MIX_SSE_I387)
14674    && flag_unsafe_math_optimizations"
14676   rtx op0 = gen_reg_rtx (XFmode);
14678   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14679   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14680   DONE;
14683 (define_expand "atanxf2"
14684   [(parallel [(set (match_operand:XF 0 "register_operand")
14685                    (unspec:XF [(match_dup 2)
14686                                (match_operand:XF 1 "register_operand")]
14687                               UNSPEC_FPATAN))
14688               (clobber (match_scratch:XF 3))])]
14689   "TARGET_USE_FANCY_MATH_387
14690    && flag_unsafe_math_optimizations"
14692   operands[2] = gen_reg_rtx (XFmode);
14693   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14696 (define_expand "atan<mode>2"
14697   [(use (match_operand:MODEF 0 "register_operand"))
14698    (use (match_operand:MODEF 1 "register_operand"))]
14699   "TARGET_USE_FANCY_MATH_387
14700    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14701        || TARGET_MIX_SSE_I387)
14702    && flag_unsafe_math_optimizations"
14704   rtx op0 = gen_reg_rtx (XFmode);
14706   rtx op2 = gen_reg_rtx (<MODE>mode);
14707   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14709   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14710   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14711   DONE;
14714 (define_expand "asinxf2"
14715   [(set (match_dup 2)
14716         (mult:XF (match_operand:XF 1 "register_operand")
14717                  (match_dup 1)))
14718    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14719    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14720    (parallel [(set (match_operand:XF 0 "register_operand")
14721                    (unspec:XF [(match_dup 5) (match_dup 1)]
14722                               UNSPEC_FPATAN))
14723               (clobber (match_scratch:XF 6))])]
14724   "TARGET_USE_FANCY_MATH_387
14725    && flag_unsafe_math_optimizations"
14727   int i;
14729   if (optimize_insn_for_size_p ())
14730     FAIL;
14732   for (i = 2; i < 6; i++)
14733     operands[i] = gen_reg_rtx (XFmode);
14735   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14738 (define_expand "asin<mode>2"
14739   [(use (match_operand:MODEF 0 "register_operand"))
14740    (use (match_operand:MODEF 1 "general_operand"))]
14741  "TARGET_USE_FANCY_MATH_387
14742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14743        || TARGET_MIX_SSE_I387)
14744    && flag_unsafe_math_optimizations"
14746   rtx op0 = gen_reg_rtx (XFmode);
14747   rtx op1 = gen_reg_rtx (XFmode);
14749   if (optimize_insn_for_size_p ())
14750     FAIL;
14752   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14753   emit_insn (gen_asinxf2 (op0, op1));
14754   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14755   DONE;
14758 (define_expand "acosxf2"
14759   [(set (match_dup 2)
14760         (mult:XF (match_operand:XF 1 "register_operand")
14761                  (match_dup 1)))
14762    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14763    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14764    (parallel [(set (match_operand:XF 0 "register_operand")
14765                    (unspec:XF [(match_dup 1) (match_dup 5)]
14766                               UNSPEC_FPATAN))
14767               (clobber (match_scratch:XF 6))])]
14768   "TARGET_USE_FANCY_MATH_387
14769    && flag_unsafe_math_optimizations"
14771   int i;
14773   if (optimize_insn_for_size_p ())
14774     FAIL;
14776   for (i = 2; i < 6; i++)
14777     operands[i] = gen_reg_rtx (XFmode);
14779   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14782 (define_expand "acos<mode>2"
14783   [(use (match_operand:MODEF 0 "register_operand"))
14784    (use (match_operand:MODEF 1 "general_operand"))]
14785  "TARGET_USE_FANCY_MATH_387
14786    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14787        || TARGET_MIX_SSE_I387)
14788    && flag_unsafe_math_optimizations"
14790   rtx op0 = gen_reg_rtx (XFmode);
14791   rtx op1 = gen_reg_rtx (XFmode);
14793   if (optimize_insn_for_size_p ())
14794     FAIL;
14796   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14797   emit_insn (gen_acosxf2 (op0, op1));
14798   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14799   DONE;
14802 (define_insn "fyl2xxf3_i387"
14803   [(set (match_operand:XF 0 "register_operand" "=f")
14804         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14805                     (match_operand:XF 2 "register_operand" "u")]
14806                    UNSPEC_FYL2X))
14807    (clobber (match_scratch:XF 3 "=2"))]
14808   "TARGET_USE_FANCY_MATH_387
14809    && flag_unsafe_math_optimizations"
14810   "fyl2x"
14811   [(set_attr "type" "fpspc")
14812    (set_attr "znver1_decode" "vector")
14813    (set_attr "mode" "XF")])
14815 (define_insn "fyl2x_extend<mode>xf3_i387"
14816   [(set (match_operand:XF 0 "register_operand" "=f")
14817         (unspec:XF [(float_extend:XF
14818                       (match_operand:MODEF 1 "register_operand" "0"))
14819                     (match_operand:XF 2 "register_operand" "u")]
14820                    UNSPEC_FYL2X))
14821    (clobber (match_scratch:XF 3 "=2"))]
14822   "TARGET_USE_FANCY_MATH_387
14823    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824        || TARGET_MIX_SSE_I387)
14825    && flag_unsafe_math_optimizations"
14826   "fyl2x"
14827   [(set_attr "type" "fpspc")
14828    (set_attr "znver1_decode" "vector")
14829    (set_attr "mode" "XF")])
14831 (define_expand "logxf2"
14832   [(parallel [(set (match_operand:XF 0 "register_operand")
14833                    (unspec:XF [(match_operand:XF 1 "register_operand")
14834                                (match_dup 2)] UNSPEC_FYL2X))
14835               (clobber (match_scratch:XF 3))])]
14836   "TARGET_USE_FANCY_MATH_387
14837    && flag_unsafe_math_optimizations"
14839   operands[2] = gen_reg_rtx (XFmode);
14840   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14843 (define_expand "log<mode>2"
14844   [(use (match_operand:MODEF 0 "register_operand"))
14845    (use (match_operand:MODEF 1 "register_operand"))]
14846   "TARGET_USE_FANCY_MATH_387
14847    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14848        || TARGET_MIX_SSE_I387)
14849    && flag_unsafe_math_optimizations"
14851   rtx op0 = gen_reg_rtx (XFmode);
14853   rtx op2 = gen_reg_rtx (XFmode);
14854   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14856   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14857   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14858   DONE;
14861 (define_expand "log10xf2"
14862   [(parallel [(set (match_operand:XF 0 "register_operand")
14863                    (unspec:XF [(match_operand:XF 1 "register_operand")
14864                                (match_dup 2)] UNSPEC_FYL2X))
14865               (clobber (match_scratch:XF 3))])]
14866   "TARGET_USE_FANCY_MATH_387
14867    && flag_unsafe_math_optimizations"
14869   operands[2] = gen_reg_rtx (XFmode);
14870   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14873 (define_expand "log10<mode>2"
14874   [(use (match_operand:MODEF 0 "register_operand"))
14875    (use (match_operand:MODEF 1 "register_operand"))]
14876   "TARGET_USE_FANCY_MATH_387
14877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878        || TARGET_MIX_SSE_I387)
14879    && flag_unsafe_math_optimizations"
14881   rtx op0 = gen_reg_rtx (XFmode);
14883   rtx op2 = gen_reg_rtx (XFmode);
14884   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14886   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14888   DONE;
14891 (define_expand "log2xf2"
14892   [(parallel [(set (match_operand:XF 0 "register_operand")
14893                    (unspec:XF [(match_operand:XF 1 "register_operand")
14894                                (match_dup 2)] UNSPEC_FYL2X))
14895               (clobber (match_scratch:XF 3))])]
14896   "TARGET_USE_FANCY_MATH_387
14897    && flag_unsafe_math_optimizations"
14899   operands[2] = gen_reg_rtx (XFmode);
14900   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14903 (define_expand "log2<mode>2"
14904   [(use (match_operand:MODEF 0 "register_operand"))
14905    (use (match_operand:MODEF 1 "register_operand"))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14908        || TARGET_MIX_SSE_I387)
14909    && flag_unsafe_math_optimizations"
14911   rtx op0 = gen_reg_rtx (XFmode);
14913   rtx op2 = gen_reg_rtx (XFmode);
14914   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14916   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14917   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14918   DONE;
14921 (define_insn "fyl2xp1xf3_i387"
14922   [(set (match_operand:XF 0 "register_operand" "=f")
14923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14924                     (match_operand:XF 2 "register_operand" "u")]
14925                    UNSPEC_FYL2XP1))
14926    (clobber (match_scratch:XF 3 "=2"))]
14927   "TARGET_USE_FANCY_MATH_387
14928    && flag_unsafe_math_optimizations"
14929   "fyl2xp1"
14930   [(set_attr "type" "fpspc")
14931    (set_attr "znver1_decode" "vector")
14932    (set_attr "mode" "XF")])
14934 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14935   [(set (match_operand:XF 0 "register_operand" "=f")
14936         (unspec:XF [(float_extend:XF
14937                       (match_operand:MODEF 1 "register_operand" "0"))
14938                     (match_operand:XF 2 "register_operand" "u")]
14939                    UNSPEC_FYL2XP1))
14940    (clobber (match_scratch:XF 3 "=2"))]
14941   "TARGET_USE_FANCY_MATH_387
14942    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14943        || TARGET_MIX_SSE_I387)
14944    && flag_unsafe_math_optimizations"
14945   "fyl2xp1"
14946   [(set_attr "type" "fpspc")
14947    (set_attr "znver1_decode" "vector")
14948    (set_attr "mode" "XF")])
14950 (define_expand "log1pxf2"
14951   [(use (match_operand:XF 0 "register_operand"))
14952    (use (match_operand:XF 1 "register_operand"))]
14953   "TARGET_USE_FANCY_MATH_387
14954    && flag_unsafe_math_optimizations"
14956   if (optimize_insn_for_size_p ())
14957     FAIL;
14959   ix86_emit_i387_log1p (operands[0], operands[1]);
14960   DONE;
14963 (define_expand "log1p<mode>2"
14964   [(use (match_operand:MODEF 0 "register_operand"))
14965    (use (match_operand:MODEF 1 "register_operand"))]
14966   "TARGET_USE_FANCY_MATH_387
14967    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14968        || TARGET_MIX_SSE_I387)
14969    && flag_unsafe_math_optimizations"
14971   rtx op0;
14973   if (optimize_insn_for_size_p ())
14974     FAIL;
14976   op0 = gen_reg_rtx (XFmode);
14978   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14980   ix86_emit_i387_log1p (op0, operands[1]);
14981   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14982   DONE;
14985 (define_insn "fxtractxf3_i387"
14986   [(set (match_operand:XF 0 "register_operand" "=f")
14987         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14988                    UNSPEC_XTRACT_FRACT))
14989    (set (match_operand:XF 1 "register_operand" "=u")
14990         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14991   "TARGET_USE_FANCY_MATH_387
14992    && flag_unsafe_math_optimizations"
14993   "fxtract"
14994   [(set_attr "type" "fpspc")
14995    (set_attr "znver1_decode" "vector")
14996    (set_attr "mode" "XF")])
14998 (define_insn "fxtract_extend<mode>xf3_i387"
14999   [(set (match_operand:XF 0 "register_operand" "=f")
15000         (unspec:XF [(float_extend:XF
15001                       (match_operand:MODEF 2 "register_operand" "0"))]
15002                    UNSPEC_XTRACT_FRACT))
15003    (set (match_operand:XF 1 "register_operand" "=u")
15004         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15005   "TARGET_USE_FANCY_MATH_387
15006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15007        || TARGET_MIX_SSE_I387)
15008    && flag_unsafe_math_optimizations"
15009   "fxtract"
15010   [(set_attr "type" "fpspc")
15011    (set_attr "znver1_decode" "vector")
15012    (set_attr "mode" "XF")])
15014 (define_expand "logbxf2"
15015   [(parallel [(set (match_dup 2)
15016                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15017                               UNSPEC_XTRACT_FRACT))
15018               (set (match_operand:XF 0 "register_operand")
15019                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15020   "TARGET_USE_FANCY_MATH_387
15021    && flag_unsafe_math_optimizations"
15022   "operands[2] = gen_reg_rtx (XFmode);")
15024 (define_expand "logb<mode>2"
15025   [(use (match_operand:MODEF 0 "register_operand"))
15026    (use (match_operand:MODEF 1 "register_operand"))]
15027   "TARGET_USE_FANCY_MATH_387
15028    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15029        || TARGET_MIX_SSE_I387)
15030    && flag_unsafe_math_optimizations"
15032   rtx op0 = gen_reg_rtx (XFmode);
15033   rtx op1 = gen_reg_rtx (XFmode);
15035   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15036   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15037   DONE;
15040 (define_expand "ilogbxf2"
15041   [(use (match_operand:SI 0 "register_operand"))
15042    (use (match_operand:XF 1 "register_operand"))]
15043   "TARGET_USE_FANCY_MATH_387
15044    && flag_unsafe_math_optimizations"
15046   rtx op0, op1;
15048   if (optimize_insn_for_size_p ())
15049     FAIL;
15051   op0 = gen_reg_rtx (XFmode);
15052   op1 = gen_reg_rtx (XFmode);
15054   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15055   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15056   DONE;
15059 (define_expand "ilogb<mode>2"
15060   [(use (match_operand:SI 0 "register_operand"))
15061    (use (match_operand:MODEF 1 "register_operand"))]
15062   "TARGET_USE_FANCY_MATH_387
15063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15064        || TARGET_MIX_SSE_I387)
15065    && flag_unsafe_math_optimizations"
15067   rtx op0, op1;
15069   if (optimize_insn_for_size_p ())
15070     FAIL;
15072   op0 = gen_reg_rtx (XFmode);
15073   op1 = gen_reg_rtx (XFmode);
15075   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15076   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15077   DONE;
15080 (define_insn "*f2xm1xf2_i387"
15081   [(set (match_operand:XF 0 "register_operand" "=f")
15082         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15083                    UNSPEC_F2XM1))]
15084   "TARGET_USE_FANCY_MATH_387
15085    && flag_unsafe_math_optimizations"
15086   "f2xm1"
15087   [(set_attr "type" "fpspc")
15088    (set_attr "znver1_decode" "vector")
15089    (set_attr "mode" "XF")])
15091 (define_insn "fscalexf4_i387"
15092   [(set (match_operand:XF 0 "register_operand" "=f")
15093         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15094                     (match_operand:XF 3 "register_operand" "1")]
15095                    UNSPEC_FSCALE_FRACT))
15096    (set (match_operand:XF 1 "register_operand" "=u")
15097         (unspec:XF [(match_dup 2) (match_dup 3)]
15098                    UNSPEC_FSCALE_EXP))]
15099   "TARGET_USE_FANCY_MATH_387
15100    && flag_unsafe_math_optimizations"
15101   "fscale"
15102   [(set_attr "type" "fpspc")
15103    (set_attr "znver1_decode" "vector")
15104    (set_attr "mode" "XF")])
15106 (define_expand "expNcorexf3"
15107   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15108                                (match_operand:XF 2 "register_operand")))
15109    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15110    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15111    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15112    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15113    (parallel [(set (match_operand:XF 0 "register_operand")
15114                    (unspec:XF [(match_dup 8) (match_dup 4)]
15115                               UNSPEC_FSCALE_FRACT))
15116               (set (match_dup 9)
15117                    (unspec:XF [(match_dup 8) (match_dup 4)]
15118                               UNSPEC_FSCALE_EXP))])]
15119   "TARGET_USE_FANCY_MATH_387
15120    && flag_unsafe_math_optimizations"
15122   int i;
15124   if (optimize_insn_for_size_p ())
15125     FAIL;
15127   for (i = 3; i < 10; i++)
15128     operands[i] = gen_reg_rtx (XFmode);
15130   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15133 (define_expand "expxf2"
15134   [(use (match_operand:XF 0 "register_operand"))
15135    (use (match_operand:XF 1 "register_operand"))]
15136   "TARGET_USE_FANCY_MATH_387
15137    && flag_unsafe_math_optimizations"
15139   rtx op2;
15141   if (optimize_insn_for_size_p ())
15142     FAIL;
15144   op2 = gen_reg_rtx (XFmode);
15145   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15147   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15148   DONE;
15151 (define_expand "exp<mode>2"
15152   [(use (match_operand:MODEF 0 "register_operand"))
15153    (use (match_operand:MODEF 1 "general_operand"))]
15154  "TARGET_USE_FANCY_MATH_387
15155    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156        || TARGET_MIX_SSE_I387)
15157    && flag_unsafe_math_optimizations"
15159   rtx op0, op1;
15161   if (optimize_insn_for_size_p ())
15162     FAIL;
15164   op0 = gen_reg_rtx (XFmode);
15165   op1 = gen_reg_rtx (XFmode);
15167   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15168   emit_insn (gen_expxf2 (op0, op1));
15169   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15170   DONE;
15173 (define_expand "exp10xf2"
15174   [(use (match_operand:XF 0 "register_operand"))
15175    (use (match_operand:XF 1 "register_operand"))]
15176   "TARGET_USE_FANCY_MATH_387
15177    && flag_unsafe_math_optimizations"
15179   rtx op2;
15181   if (optimize_insn_for_size_p ())
15182     FAIL;
15184   op2 = gen_reg_rtx (XFmode);
15185   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15187   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15188   DONE;
15191 (define_expand "exp10<mode>2"
15192   [(use (match_operand:MODEF 0 "register_operand"))
15193    (use (match_operand:MODEF 1 "general_operand"))]
15194  "TARGET_USE_FANCY_MATH_387
15195    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15196        || TARGET_MIX_SSE_I387)
15197    && flag_unsafe_math_optimizations"
15199   rtx op0, op1;
15201   if (optimize_insn_for_size_p ())
15202     FAIL;
15204   op0 = gen_reg_rtx (XFmode);
15205   op1 = gen_reg_rtx (XFmode);
15207   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15208   emit_insn (gen_exp10xf2 (op0, op1));
15209   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15210   DONE;
15213 (define_expand "exp2xf2"
15214   [(use (match_operand:XF 0 "register_operand"))
15215    (use (match_operand:XF 1 "register_operand"))]
15216   "TARGET_USE_FANCY_MATH_387
15217    && flag_unsafe_math_optimizations"
15219   rtx op2;
15221   if (optimize_insn_for_size_p ())
15222     FAIL;
15224   op2 = gen_reg_rtx (XFmode);
15225   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15227   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15228   DONE;
15231 (define_expand "exp2<mode>2"
15232   [(use (match_operand:MODEF 0 "register_operand"))
15233    (use (match_operand:MODEF 1 "general_operand"))]
15234  "TARGET_USE_FANCY_MATH_387
15235    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15236        || TARGET_MIX_SSE_I387)
15237    && flag_unsafe_math_optimizations"
15239   rtx op0, op1;
15241   if (optimize_insn_for_size_p ())
15242     FAIL;
15244   op0 = gen_reg_rtx (XFmode);
15245   op1 = gen_reg_rtx (XFmode);
15247   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15248   emit_insn (gen_exp2xf2 (op0, op1));
15249   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15250   DONE;
15253 (define_expand "expm1xf2"
15254   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15255                                (match_dup 2)))
15256    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15257    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15258    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15259    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15260    (parallel [(set (match_dup 7)
15261                    (unspec:XF [(match_dup 6) (match_dup 4)]
15262                               UNSPEC_FSCALE_FRACT))
15263               (set (match_dup 8)
15264                    (unspec:XF [(match_dup 6) (match_dup 4)]
15265                               UNSPEC_FSCALE_EXP))])
15266    (parallel [(set (match_dup 10)
15267                    (unspec:XF [(match_dup 9) (match_dup 8)]
15268                               UNSPEC_FSCALE_FRACT))
15269               (set (match_dup 11)
15270                    (unspec:XF [(match_dup 9) (match_dup 8)]
15271                               UNSPEC_FSCALE_EXP))])
15272    (set (match_dup 12) (minus:XF (match_dup 10)
15273                                  (float_extend:XF (match_dup 13))))
15274    (set (match_operand:XF 0 "register_operand")
15275         (plus:XF (match_dup 12) (match_dup 7)))]
15276   "TARGET_USE_FANCY_MATH_387
15277    && flag_unsafe_math_optimizations"
15279   int i;
15281   if (optimize_insn_for_size_p ())
15282     FAIL;
15284   for (i = 2; i < 13; i++)
15285     operands[i] = gen_reg_rtx (XFmode);
15287   operands[13]
15288     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15290   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15293 (define_expand "expm1<mode>2"
15294   [(use (match_operand:MODEF 0 "register_operand"))
15295    (use (match_operand:MODEF 1 "general_operand"))]
15296  "TARGET_USE_FANCY_MATH_387
15297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15298        || TARGET_MIX_SSE_I387)
15299    && flag_unsafe_math_optimizations"
15301   rtx op0, op1;
15303   if (optimize_insn_for_size_p ())
15304     FAIL;
15306   op0 = gen_reg_rtx (XFmode);
15307   op1 = gen_reg_rtx (XFmode);
15309   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15310   emit_insn (gen_expm1xf2 (op0, op1));
15311   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15312   DONE;
15315 (define_expand "ldexpxf3"
15316   [(match_operand:XF 0 "register_operand")
15317    (match_operand:XF 1 "register_operand")
15318    (match_operand:SI 2 "register_operand")]
15319   "TARGET_USE_FANCY_MATH_387
15320    && flag_unsafe_math_optimizations"
15322   rtx tmp1, tmp2;
15323   if (optimize_insn_for_size_p ())
15324     FAIL;
15326   tmp1 = gen_reg_rtx (XFmode);
15327   tmp2 = gen_reg_rtx (XFmode);
15329   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15330   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15331                                  operands[1], tmp1));
15332   DONE;
15335 (define_expand "ldexp<mode>3"
15336   [(use (match_operand:MODEF 0 "register_operand"))
15337    (use (match_operand:MODEF 1 "general_operand"))
15338    (use (match_operand:SI 2 "register_operand"))]
15339  "TARGET_USE_FANCY_MATH_387
15340    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15341        || TARGET_MIX_SSE_I387)
15342    && flag_unsafe_math_optimizations"
15344   rtx op0, op1;
15346   if (optimize_insn_for_size_p ())
15347     FAIL;
15349   op0 = gen_reg_rtx (XFmode);
15350   op1 = gen_reg_rtx (XFmode);
15352   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15353   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15354   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15355   DONE;
15358 (define_expand "scalbxf3"
15359   [(parallel [(set (match_operand:XF 0 " register_operand")
15360                    (unspec:XF [(match_operand:XF 1 "register_operand")
15361                                (match_operand:XF 2 "register_operand")]
15362                               UNSPEC_FSCALE_FRACT))
15363               (set (match_dup 3)
15364                    (unspec:XF [(match_dup 1) (match_dup 2)]
15365                               UNSPEC_FSCALE_EXP))])]
15366   "TARGET_USE_FANCY_MATH_387
15367    && flag_unsafe_math_optimizations"
15369   if (optimize_insn_for_size_p ())
15370     FAIL;
15372   operands[3] = gen_reg_rtx (XFmode);
15375 (define_expand "scalb<mode>3"
15376   [(use (match_operand:MODEF 0 "register_operand"))
15377    (use (match_operand:MODEF 1 "general_operand"))
15378    (use (match_operand:MODEF 2 "general_operand"))]
15379  "TARGET_USE_FANCY_MATH_387
15380    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15381        || TARGET_MIX_SSE_I387)
15382    && flag_unsafe_math_optimizations"
15384   rtx op0, op1, op2;
15386   if (optimize_insn_for_size_p ())
15387     FAIL;
15389   op0 = gen_reg_rtx (XFmode);
15390   op1 = gen_reg_rtx (XFmode);
15391   op2 = gen_reg_rtx (XFmode);
15393   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15394   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15395   emit_insn (gen_scalbxf3 (op0, op1, op2));
15396   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15397   DONE;
15400 (define_expand "significandxf2"
15401   [(parallel [(set (match_operand:XF 0 "register_operand")
15402                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15403                               UNSPEC_XTRACT_FRACT))
15404               (set (match_dup 2)
15405                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15406   "TARGET_USE_FANCY_MATH_387
15407    && flag_unsafe_math_optimizations"
15408   "operands[2] = gen_reg_rtx (XFmode);")
15410 (define_expand "significand<mode>2"
15411   [(use (match_operand:MODEF 0 "register_operand"))
15412    (use (match_operand:MODEF 1 "register_operand"))]
15413   "TARGET_USE_FANCY_MATH_387
15414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15415        || TARGET_MIX_SSE_I387)
15416    && flag_unsafe_math_optimizations"
15418   rtx op0 = gen_reg_rtx (XFmode);
15419   rtx op1 = gen_reg_rtx (XFmode);
15421   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15422   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15423   DONE;
15427 (define_insn "sse4_1_round<mode>2"
15428   [(set (match_operand:MODEF 0 "register_operand" "=x")
15429         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15430                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15431                       UNSPEC_ROUND))]
15432   "TARGET_ROUND"
15433   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15434   [(set_attr "type" "ssecvt")
15435    (set_attr "prefix_extra" "1")
15436    (set_attr "prefix" "maybe_vex")
15437    (set_attr "mode" "<MODE>")])
15439 (define_insn "rintxf2"
15440   [(set (match_operand:XF 0 "register_operand" "=f")
15441         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15442                    UNSPEC_FRNDINT))]
15443   "TARGET_USE_FANCY_MATH_387
15444    && flag_unsafe_math_optimizations"
15445   "frndint"
15446   [(set_attr "type" "fpspc")
15447    (set_attr "znver1_decode" "vector")
15448    (set_attr "mode" "XF")])
15450 (define_expand "rint<mode>2"
15451   [(use (match_operand:MODEF 0 "register_operand"))
15452    (use (match_operand:MODEF 1 "register_operand"))]
15453   "(TARGET_USE_FANCY_MATH_387
15454     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15455         || TARGET_MIX_SSE_I387)
15456     && flag_unsafe_math_optimizations)
15457    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15458        && !flag_trapping_math)"
15460   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15461       && !flag_trapping_math)
15462     {
15463       if (TARGET_ROUND)
15464         emit_insn (gen_sse4_1_round<mode>2
15465                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15466       else if (optimize_insn_for_size_p ())
15467         FAIL;
15468       else
15469         ix86_expand_rint (operands[0], operands[1]);
15470     }
15471   else
15472     {
15473       rtx op0 = gen_reg_rtx (XFmode);
15474       rtx op1 = gen_reg_rtx (XFmode);
15476       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15477       emit_insn (gen_rintxf2 (op0, op1));
15479       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15480     }
15481   DONE;
15484 (define_expand "round<mode>2"
15485   [(match_operand:X87MODEF 0 "register_operand")
15486    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15487   "(TARGET_USE_FANCY_MATH_387
15488     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15489         || TARGET_MIX_SSE_I387)
15490     && flag_unsafe_math_optimizations)
15491    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15492        && !flag_trapping_math && !flag_rounding_math)"
15494   if (optimize_insn_for_size_p ())
15495     FAIL;
15497   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15498       && !flag_trapping_math && !flag_rounding_math)
15499     {
15500       if (TARGET_ROUND)
15501         {
15502           operands[1] = force_reg (<MODE>mode, operands[1]);
15503           ix86_expand_round_sse4 (operands[0], operands[1]);
15504         }
15505       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15506         ix86_expand_round (operands[0], operands[1]);
15507       else
15508         ix86_expand_rounddf_32 (operands[0], operands[1]);
15509     }
15510   else
15511     {
15512       operands[1] = force_reg (<MODE>mode, operands[1]);
15513       ix86_emit_i387_round (operands[0], operands[1]);
15514     }
15515   DONE;
15518 (define_insn_and_split "*fistdi2_1"
15519   [(set (match_operand:DI 0 "nonimmediate_operand")
15520         (unspec:DI [(match_operand:XF 1 "register_operand")]
15521                    UNSPEC_FIST))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && can_create_pseudo_p ()"
15524   "#"
15525   "&& 1"
15526   [(const_int 0)]
15528   if (memory_operand (operands[0], VOIDmode))
15529     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15530   else
15531     {
15532       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15533       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15534                                          operands[2]));
15535     }
15536   DONE;
15538   [(set_attr "type" "fpspc")
15539    (set_attr "mode" "DI")])
15541 (define_insn "fistdi2"
15542   [(set (match_operand:DI 0 "memory_operand" "=m")
15543         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15544                    UNSPEC_FIST))
15545    (clobber (match_scratch:XF 2 "=&1f"))]
15546   "TARGET_USE_FANCY_MATH_387"
15547   "* return output_fix_trunc (insn, operands, false);"
15548   [(set_attr "type" "fpspc")
15549    (set_attr "mode" "DI")])
15551 (define_insn "fistdi2_with_temp"
15552   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15553         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15554                    UNSPEC_FIST))
15555    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15556    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15557   "TARGET_USE_FANCY_MATH_387"
15558   "#"
15559   [(set_attr "type" "fpspc")
15560    (set_attr "mode" "DI")])
15562 (define_split
15563   [(set (match_operand:DI 0 "register_operand")
15564         (unspec:DI [(match_operand:XF 1 "register_operand")]
15565                    UNSPEC_FIST))
15566    (clobber (match_operand:DI 2 "memory_operand"))
15567    (clobber (match_scratch 3))]
15568   "reload_completed"
15569   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15570               (clobber (match_dup 3))])
15571    (set (match_dup 0) (match_dup 2))])
15573 (define_split
15574   [(set (match_operand:DI 0 "memory_operand")
15575         (unspec:DI [(match_operand:XF 1 "register_operand")]
15576                    UNSPEC_FIST))
15577    (clobber (match_operand:DI 2 "memory_operand"))
15578    (clobber (match_scratch 3))]
15579   "reload_completed"
15580   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15581               (clobber (match_dup 3))])])
15583 (define_insn_and_split "*fist<mode>2_1"
15584   [(set (match_operand:SWI24 0 "register_operand")
15585         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15586                       UNSPEC_FIST))]
15587   "TARGET_USE_FANCY_MATH_387
15588    && can_create_pseudo_p ()"
15589   "#"
15590   "&& 1"
15591   [(const_int 0)]
15593   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15594   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15595                                         operands[2]));
15596   DONE;
15598   [(set_attr "type" "fpspc")
15599    (set_attr "mode" "<MODE>")])
15601 (define_insn "fist<mode>2"
15602   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15603         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15604                       UNSPEC_FIST))]
15605   "TARGET_USE_FANCY_MATH_387"
15606   "* return output_fix_trunc (insn, operands, false);"
15607   [(set_attr "type" "fpspc")
15608    (set_attr "mode" "<MODE>")])
15610 (define_insn "fist<mode>2_with_temp"
15611   [(set (match_operand:SWI24 0 "register_operand" "=r")
15612         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15613                       UNSPEC_FIST))
15614    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15615   "TARGET_USE_FANCY_MATH_387"
15616   "#"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "<MODE>")])
15620 (define_split
15621   [(set (match_operand:SWI24 0 "register_operand")
15622         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15623                       UNSPEC_FIST))
15624    (clobber (match_operand:SWI24 2 "memory_operand"))]
15625   "reload_completed"
15626   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15627    (set (match_dup 0) (match_dup 2))])
15629 (define_split
15630   [(set (match_operand:SWI24 0 "memory_operand")
15631         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15632                       UNSPEC_FIST))
15633    (clobber (match_operand:SWI24 2 "memory_operand"))]
15634   "reload_completed"
15635   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15637 (define_expand "lrintxf<mode>2"
15638   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15639      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15640                      UNSPEC_FIST))]
15641   "TARGET_USE_FANCY_MATH_387")
15643 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15644   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15645      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15646                    UNSPEC_FIX_NOTRUNC))]
15647   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15649 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15650   [(match_operand:SWI248x 0 "nonimmediate_operand")
15651    (match_operand:X87MODEF 1 "register_operand")]
15652   "(TARGET_USE_FANCY_MATH_387
15653     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15654         || TARGET_MIX_SSE_I387)
15655     && flag_unsafe_math_optimizations)
15656    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15657        && <SWI248x:MODE>mode != HImode 
15658        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15659        && !flag_trapping_math && !flag_rounding_math)"
15661   if (optimize_insn_for_size_p ())
15662     FAIL;
15664   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15665       && <SWI248x:MODE>mode != HImode
15666       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15667       && !flag_trapping_math && !flag_rounding_math)
15668     ix86_expand_lround (operands[0], operands[1]);
15669   else
15670     ix86_emit_i387_round (operands[0], operands[1]);
15671   DONE;
15674 (define_int_iterator FRNDINT_ROUNDING
15675         [UNSPEC_FRNDINT_FLOOR
15676          UNSPEC_FRNDINT_CEIL
15677          UNSPEC_FRNDINT_TRUNC])
15679 (define_int_iterator FIST_ROUNDING
15680         [UNSPEC_FIST_FLOOR
15681          UNSPEC_FIST_CEIL])
15683 ;; Base name for define_insn
15684 (define_int_attr rounding_insn
15685         [(UNSPEC_FRNDINT_FLOOR "floor")
15686          (UNSPEC_FRNDINT_CEIL "ceil")
15687          (UNSPEC_FRNDINT_TRUNC "btrunc")
15688          (UNSPEC_FIST_FLOOR "floor")
15689          (UNSPEC_FIST_CEIL "ceil")])
15691 (define_int_attr rounding
15692         [(UNSPEC_FRNDINT_FLOOR "floor")
15693          (UNSPEC_FRNDINT_CEIL "ceil")
15694          (UNSPEC_FRNDINT_TRUNC "trunc")
15695          (UNSPEC_FIST_FLOOR "floor")
15696          (UNSPEC_FIST_CEIL "ceil")])
15698 (define_int_attr ROUNDING
15699         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15700          (UNSPEC_FRNDINT_CEIL "CEIL")
15701          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15702          (UNSPEC_FIST_FLOOR "FLOOR")
15703          (UNSPEC_FIST_CEIL "CEIL")])
15705 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15706 (define_insn_and_split "frndintxf2_<rounding>"
15707   [(set (match_operand:XF 0 "register_operand")
15708         (unspec:XF [(match_operand:XF 1 "register_operand")]
15709                    FRNDINT_ROUNDING))
15710    (clobber (reg:CC FLAGS_REG))]
15711   "TARGET_USE_FANCY_MATH_387
15712    && flag_unsafe_math_optimizations
15713    && can_create_pseudo_p ()"
15714   "#"
15715   "&& 1"
15716   [(const_int 0)]
15718   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15720   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15721   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15723   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15724                                              operands[2], operands[3]));
15725   DONE;
15727   [(set_attr "type" "frndint")
15728    (set_attr "i387_cw" "<rounding>")
15729    (set_attr "mode" "XF")])
15731 (define_insn "frndintxf2_<rounding>_i387"
15732   [(set (match_operand:XF 0 "register_operand" "=f")
15733         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15734                    FRNDINT_ROUNDING))
15735    (use (match_operand:HI 2 "memory_operand" "m"))
15736    (use (match_operand:HI 3 "memory_operand" "m"))]
15737   "TARGET_USE_FANCY_MATH_387
15738    && flag_unsafe_math_optimizations"
15739   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15740   [(set_attr "type" "frndint")
15741    (set_attr "i387_cw" "<rounding>")
15742    (set_attr "mode" "XF")])
15744 (define_expand "<rounding_insn>xf2"
15745   [(parallel [(set (match_operand:XF 0 "register_operand")
15746                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15747                               FRNDINT_ROUNDING))
15748               (clobber (reg:CC FLAGS_REG))])]
15749   "TARGET_USE_FANCY_MATH_387
15750    && flag_unsafe_math_optimizations
15751    && !optimize_insn_for_size_p ()")
15753 (define_expand "<rounding_insn><mode>2"
15754   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15755                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15756                                  FRNDINT_ROUNDING))
15757               (clobber (reg:CC FLAGS_REG))])]
15758   "(TARGET_USE_FANCY_MATH_387
15759     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15760         || TARGET_MIX_SSE_I387)
15761     && flag_unsafe_math_optimizations)
15762    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15763        && !flag_trapping_math)"
15765   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15766       && !flag_trapping_math)
15767     {
15768       if (TARGET_ROUND)
15769         emit_insn (gen_sse4_1_round<mode>2
15770                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15771       else if (optimize_insn_for_size_p ())
15772         FAIL;
15773       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15774         {
15775           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15776             ix86_expand_floorceil (operands[0], operands[1], true);
15777           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15778             ix86_expand_floorceil (operands[0], operands[1], false);
15779           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15780             ix86_expand_trunc (operands[0], operands[1]);
15781           else
15782             gcc_unreachable ();
15783         }
15784       else
15785         {
15786           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15787             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15788           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15789             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15790           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15791             ix86_expand_truncdf_32 (operands[0], operands[1]);
15792           else
15793             gcc_unreachable ();
15794         }
15795     }
15796   else
15797     {
15798       rtx op0, op1;
15800       if (optimize_insn_for_size_p ())
15801         FAIL;
15803       op0 = gen_reg_rtx (XFmode);
15804       op1 = gen_reg_rtx (XFmode);
15805       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15806       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15808       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15809     }
15810   DONE;
15813 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15814 (define_insn_and_split "frndintxf2_mask_pm"
15815   [(set (match_operand:XF 0 "register_operand")
15816         (unspec:XF [(match_operand:XF 1 "register_operand")]
15817                    UNSPEC_FRNDINT_MASK_PM))
15818    (clobber (reg:CC FLAGS_REG))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && flag_unsafe_math_optimizations
15821    && can_create_pseudo_p ()"
15822   "#"
15823   "&& 1"
15824   [(const_int 0)]
15826   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15828   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15829   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15831   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15832                                           operands[2], operands[3]));
15833   DONE;
15835   [(set_attr "type" "frndint")
15836    (set_attr "i387_cw" "mask_pm")
15837    (set_attr "mode" "XF")])
15839 (define_insn "frndintxf2_mask_pm_i387"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15842                    UNSPEC_FRNDINT_MASK_PM))
15843    (use (match_operand:HI 2 "memory_operand" "m"))
15844    (use (match_operand:HI 3 "memory_operand" "m"))]
15845   "TARGET_USE_FANCY_MATH_387
15846    && flag_unsafe_math_optimizations"
15847   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15848   [(set_attr "type" "frndint")
15849    (set_attr "i387_cw" "mask_pm")
15850    (set_attr "mode" "XF")])
15852 (define_expand "nearbyintxf2"
15853   [(parallel [(set (match_operand:XF 0 "register_operand")
15854                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15855                               UNSPEC_FRNDINT_MASK_PM))
15856               (clobber (reg:CC FLAGS_REG))])]
15857   "TARGET_USE_FANCY_MATH_387
15858    && flag_unsafe_math_optimizations")
15860 (define_expand "nearbyint<mode>2"
15861   [(use (match_operand:MODEF 0 "register_operand"))
15862    (use (match_operand:MODEF 1 "register_operand"))]
15863   "TARGET_USE_FANCY_MATH_387
15864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15865        || TARGET_MIX_SSE_I387)
15866    && flag_unsafe_math_optimizations"
15868   rtx op0 = gen_reg_rtx (XFmode);
15869   rtx op1 = gen_reg_rtx (XFmode);
15871   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15872   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15874   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15875   DONE;
15878 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15879 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15880   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15881         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15882                         FIST_ROUNDING))
15883    (clobber (reg:CC FLAGS_REG))]
15884   "TARGET_USE_FANCY_MATH_387
15885    && flag_unsafe_math_optimizations
15886    && can_create_pseudo_p ()"
15887   "#"
15888   "&& 1"
15889   [(const_int 0)]
15891   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15893   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15894   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15895   if (memory_operand (operands[0], VOIDmode))
15896     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15897                                            operands[2], operands[3]));
15898   else
15899     {
15900       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15901       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15902                   (operands[0], operands[1], operands[2],
15903                    operands[3], operands[4]));
15904     }
15905   DONE;
15907   [(set_attr "type" "fistp")
15908    (set_attr "i387_cw" "<rounding>")
15909    (set_attr "mode" "<MODE>")])
15911 (define_insn "fistdi2_<rounding>"
15912   [(set (match_operand:DI 0 "memory_operand" "=m")
15913         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15914                    FIST_ROUNDING))
15915    (use (match_operand:HI 2 "memory_operand" "m"))
15916    (use (match_operand:HI 3 "memory_operand" "m"))
15917    (clobber (match_scratch:XF 4 "=&1f"))]
15918   "TARGET_USE_FANCY_MATH_387
15919    && flag_unsafe_math_optimizations"
15920   "* return output_fix_trunc (insn, operands, false);"
15921   [(set_attr "type" "fistp")
15922    (set_attr "i387_cw" "<rounding>")
15923    (set_attr "mode" "DI")])
15925 (define_insn "fistdi2_<rounding>_with_temp"
15926   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15927         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15928                    FIST_ROUNDING))
15929    (use (match_operand:HI 2 "memory_operand" "m,m"))
15930    (use (match_operand:HI 3 "memory_operand" "m,m"))
15931    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15932    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15933   "TARGET_USE_FANCY_MATH_387
15934    && flag_unsafe_math_optimizations"
15935   "#"
15936   [(set_attr "type" "fistp")
15937    (set_attr "i387_cw" "<rounding>")
15938    (set_attr "mode" "DI")])
15940 (define_split
15941   [(set (match_operand:DI 0 "register_operand")
15942         (unspec:DI [(match_operand:XF 1 "register_operand")]
15943                    FIST_ROUNDING))
15944    (use (match_operand:HI 2 "memory_operand"))
15945    (use (match_operand:HI 3 "memory_operand"))
15946    (clobber (match_operand:DI 4 "memory_operand"))
15947    (clobber (match_scratch 5))]
15948   "reload_completed"
15949   [(parallel [(set (match_dup 4)
15950                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15951               (use (match_dup 2))
15952               (use (match_dup 3))
15953               (clobber (match_dup 5))])
15954    (set (match_dup 0) (match_dup 4))])
15956 (define_split
15957   [(set (match_operand:DI 0 "memory_operand")
15958         (unspec:DI [(match_operand:XF 1 "register_operand")]
15959                    FIST_ROUNDING))
15960    (use (match_operand:HI 2 "memory_operand"))
15961    (use (match_operand:HI 3 "memory_operand"))
15962    (clobber (match_operand:DI 4 "memory_operand"))
15963    (clobber (match_scratch 5))]
15964   "reload_completed"
15965   [(parallel [(set (match_dup 0)
15966                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15967               (use (match_dup 2))
15968               (use (match_dup 3))
15969               (clobber (match_dup 5))])])
15971 (define_insn "fist<mode>2_<rounding>"
15972   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15973         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15974                       FIST_ROUNDING))
15975    (use (match_operand:HI 2 "memory_operand" "m"))
15976    (use (match_operand:HI 3 "memory_operand" "m"))]
15977   "TARGET_USE_FANCY_MATH_387
15978    && flag_unsafe_math_optimizations"
15979   "* return output_fix_trunc (insn, operands, false);"
15980   [(set_attr "type" "fistp")
15981    (set_attr "i387_cw" "<rounding>")
15982    (set_attr "mode" "<MODE>")])
15984 (define_insn "fist<mode>2_<rounding>_with_temp"
15985   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15986         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15987                       FIST_ROUNDING))
15988    (use (match_operand:HI 2 "memory_operand" "m,m"))
15989    (use (match_operand:HI 3 "memory_operand" "m,m"))
15990    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15991   "TARGET_USE_FANCY_MATH_387
15992    && flag_unsafe_math_optimizations"
15993   "#"
15994   [(set_attr "type" "fistp")
15995    (set_attr "i387_cw" "<rounding>")
15996    (set_attr "mode" "<MODE>")])
15998 (define_split
15999   [(set (match_operand:SWI24 0 "register_operand")
16000         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16001                       FIST_ROUNDING))
16002    (use (match_operand:HI 2 "memory_operand"))
16003    (use (match_operand:HI 3 "memory_operand"))
16004    (clobber (match_operand:SWI24 4 "memory_operand"))]
16005   "reload_completed"
16006   [(parallel [(set (match_dup 4)
16007                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16008               (use (match_dup 2))
16009               (use (match_dup 3))])
16010    (set (match_dup 0) (match_dup 4))])
16012 (define_split
16013   [(set (match_operand:SWI24 0 "memory_operand")
16014         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16015                       FIST_ROUNDING))
16016    (use (match_operand:HI 2 "memory_operand"))
16017    (use (match_operand:HI 3 "memory_operand"))
16018    (clobber (match_operand:SWI24 4 "memory_operand"))]
16019   "reload_completed"
16020   [(parallel [(set (match_dup 0)
16021                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16022               (use (match_dup 2))
16023               (use (match_dup 3))])])
16025 (define_expand "l<rounding_insn>xf<mode>2"
16026   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16027                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16028                                    FIST_ROUNDING))
16029               (clobber (reg:CC FLAGS_REG))])]
16030   "TARGET_USE_FANCY_MATH_387
16031    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16032    && flag_unsafe_math_optimizations")
16034 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16035   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16036                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16037                                  FIST_ROUNDING))
16038               (clobber (reg:CC FLAGS_REG))])]
16039   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16040    && !flag_trapping_math"
16042   if (TARGET_64BIT && optimize_insn_for_size_p ())
16043     FAIL;
16045   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16046     ix86_expand_lfloorceil (operands[0], operands[1], true);
16047   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16048     ix86_expand_lfloorceil (operands[0], operands[1], false);
16049   else
16050     gcc_unreachable ();
16052   DONE;
16055 (define_insn "fxam<mode>2_i387"
16056   [(set (match_operand:HI 0 "register_operand" "=a")
16057         (unspec:HI
16058           [(match_operand:X87MODEF 1 "register_operand" "f")]
16059           UNSPEC_FXAM))]
16060   "TARGET_USE_FANCY_MATH_387"
16061   "fxam\n\tfnstsw\t%0"
16062   [(set_attr "type" "multi")
16063    (set_attr "length" "4")
16064    (set_attr "unit" "i387")
16065    (set_attr "mode" "<MODE>")])
16067 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16068   [(set (match_operand:HI 0 "register_operand")
16069         (unspec:HI
16070           [(match_operand:MODEF 1 "memory_operand")]
16071           UNSPEC_FXAM_MEM))]
16072   "TARGET_USE_FANCY_MATH_387
16073    && can_create_pseudo_p ()"
16074   "#"
16075   "&& 1"
16076   [(set (match_dup 2)(match_dup 1))
16077    (set (match_dup 0)
16078         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16080   operands[2] = gen_reg_rtx (<MODE>mode);
16082   MEM_VOLATILE_P (operands[1]) = 1;
16084   [(set_attr "type" "multi")
16085    (set_attr "unit" "i387")
16086    (set_attr "mode" "<MODE>")])
16088 (define_expand "isinfxf2"
16089   [(use (match_operand:SI 0 "register_operand"))
16090    (use (match_operand:XF 1 "register_operand"))]
16091   "TARGET_USE_FANCY_MATH_387
16092    && ix86_libc_has_function (function_c99_misc)"
16094   rtx mask = GEN_INT (0x45);
16095   rtx val = GEN_INT (0x05);
16097   rtx cond;
16099   rtx scratch = gen_reg_rtx (HImode);
16100   rtx res = gen_reg_rtx (QImode);
16102   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16104   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16105   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16106   cond = gen_rtx_fmt_ee (EQ, QImode,
16107                          gen_rtx_REG (CCmode, FLAGS_REG),
16108                          const0_rtx);
16109   emit_insn (gen_rtx_SET (res, cond));
16110   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16111   DONE;
16114 (define_expand "isinf<mode>2"
16115   [(use (match_operand:SI 0 "register_operand"))
16116    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16117   "TARGET_USE_FANCY_MATH_387
16118    && ix86_libc_has_function (function_c99_misc)
16119    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16121   rtx mask = GEN_INT (0x45);
16122   rtx val = GEN_INT (0x05);
16124   rtx cond;
16126   rtx scratch = gen_reg_rtx (HImode);
16127   rtx res = gen_reg_rtx (QImode);
16129   /* Remove excess precision by forcing value through memory. */
16130   if (memory_operand (operands[1], VOIDmode))
16131     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16132   else
16133     {
16134       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16136       emit_move_insn (temp, operands[1]);
16137       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16138     }
16140   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16141   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16142   cond = gen_rtx_fmt_ee (EQ, QImode,
16143                          gen_rtx_REG (CCmode, FLAGS_REG),
16144                          const0_rtx);
16145   emit_insn (gen_rtx_SET (res, cond));
16146   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16147   DONE;
16150 (define_expand "signbitxf2"
16151   [(use (match_operand:SI 0 "register_operand"))
16152    (use (match_operand:XF 1 "register_operand"))]
16153   "TARGET_USE_FANCY_MATH_387"
16155   rtx scratch = gen_reg_rtx (HImode);
16157   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16158   emit_insn (gen_andsi3 (operands[0],
16159              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16160   DONE;
16163 (define_insn "movmsk_df"
16164   [(set (match_operand:SI 0 "register_operand" "=r")
16165         (unspec:SI
16166           [(match_operand:DF 1 "register_operand" "x")]
16167           UNSPEC_MOVMSK))]
16168   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16169   "%vmovmskpd\t{%1, %0|%0, %1}"
16170   [(set_attr "type" "ssemov")
16171    (set_attr "prefix" "maybe_vex")
16172    (set_attr "mode" "DF")])
16174 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16175 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16176 (define_expand "signbitdf2"
16177   [(use (match_operand:SI 0 "register_operand"))
16178    (use (match_operand:DF 1 "register_operand"))]
16179   "TARGET_USE_FANCY_MATH_387
16180    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16182   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16183     {
16184       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16185       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16186     }
16187   else
16188     {
16189       rtx scratch = gen_reg_rtx (HImode);
16191       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16192       emit_insn (gen_andsi3 (operands[0],
16193                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16194     }
16195   DONE;
16198 (define_expand "signbitsf2"
16199   [(use (match_operand:SI 0 "register_operand"))
16200    (use (match_operand:SF 1 "register_operand"))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16204   rtx scratch = gen_reg_rtx (HImode);
16206   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16207   emit_insn (gen_andsi3 (operands[0],
16208              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16209   DONE;
16212 ;; Block operation instructions
16214 (define_insn "cld"
16215   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16216   ""
16217   "cld"
16218   [(set_attr "length" "1")
16219    (set_attr "length_immediate" "0")
16220    (set_attr "modrm" "0")])
16222 (define_expand "movmem<mode>"
16223   [(use (match_operand:BLK 0 "memory_operand"))
16224    (use (match_operand:BLK 1 "memory_operand"))
16225    (use (match_operand:SWI48 2 "nonmemory_operand"))
16226    (use (match_operand:SWI48 3 "const_int_operand"))
16227    (use (match_operand:SI 4 "const_int_operand"))
16228    (use (match_operand:SI 5 "const_int_operand"))
16229    (use (match_operand:SI 6 ""))
16230    (use (match_operand:SI 7 ""))
16231    (use (match_operand:SI 8 ""))]
16232   ""
16234  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16235                                 operands[2], NULL, operands[3],
16236                                 operands[4], operands[5],
16237                                 operands[6], operands[7],
16238                                 operands[8], false))
16239    DONE;
16240  else
16241    FAIL;
16244 ;; Most CPUs don't like single string operations
16245 ;; Handle this case here to simplify previous expander.
16247 (define_expand "strmov"
16248   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16249    (set (match_operand 1 "memory_operand") (match_dup 4))
16250    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16251               (clobber (reg:CC FLAGS_REG))])
16252    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16253               (clobber (reg:CC FLAGS_REG))])]
16254   ""
16256   /* Can't use this for non-default address spaces.  */
16257   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16258     FAIL;
16260   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16262   /* If .md ever supports :P for Pmode, these can be directly
16263      in the pattern above.  */
16264   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16265   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16267   /* Can't use this if the user has appropriated esi or edi.  */
16268   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16269       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16270     {
16271       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16272                                       operands[2], operands[3],
16273                                       operands[5], operands[6]));
16274       DONE;
16275     }
16277   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16280 (define_expand "strmov_singleop"
16281   [(parallel [(set (match_operand 1 "memory_operand")
16282                    (match_operand 3 "memory_operand"))
16283               (set (match_operand 0 "register_operand")
16284                    (match_operand 4))
16285               (set (match_operand 2 "register_operand")
16286                    (match_operand 5))])]
16287   ""
16288   "ix86_current_function_needs_cld = 1;")
16290 (define_insn "*strmovdi_rex_1"
16291   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16292         (mem:DI (match_operand:P 3 "register_operand" "1")))
16293    (set (match_operand:P 0 "register_operand" "=D")
16294         (plus:P (match_dup 2)
16295                 (const_int 8)))
16296    (set (match_operand:P 1 "register_operand" "=S")
16297         (plus:P (match_dup 3)
16298                 (const_int 8)))]
16299   "TARGET_64BIT
16300    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16301    && ix86_check_no_addr_space (insn)"
16302   "%^movsq"
16303   [(set_attr "type" "str")
16304    (set_attr "memory" "both")
16305    (set_attr "mode" "DI")])
16307 (define_insn "*strmovsi_1"
16308   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16309         (mem:SI (match_operand:P 3 "register_operand" "1")))
16310    (set (match_operand:P 0 "register_operand" "=D")
16311         (plus:P (match_dup 2)
16312                 (const_int 4)))
16313    (set (match_operand:P 1 "register_operand" "=S")
16314         (plus:P (match_dup 3)
16315                 (const_int 4)))]
16316   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16317    && ix86_check_no_addr_space (insn)"
16318   "%^movs{l|d}"
16319   [(set_attr "type" "str")
16320    (set_attr "memory" "both")
16321    (set_attr "mode" "SI")])
16323 (define_insn "*strmovhi_1"
16324   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16325         (mem:HI (match_operand:P 3 "register_operand" "1")))
16326    (set (match_operand:P 0 "register_operand" "=D")
16327         (plus:P (match_dup 2)
16328                 (const_int 2)))
16329    (set (match_operand:P 1 "register_operand" "=S")
16330         (plus:P (match_dup 3)
16331                 (const_int 2)))]
16332   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16333    && ix86_check_no_addr_space (insn)"
16334   "%^movsw"
16335   [(set_attr "type" "str")
16336    (set_attr "memory" "both")
16337    (set_attr "mode" "HI")])
16339 (define_insn "*strmovqi_1"
16340   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16341         (mem:QI (match_operand:P 3 "register_operand" "1")))
16342    (set (match_operand:P 0 "register_operand" "=D")
16343         (plus:P (match_dup 2)
16344                 (const_int 1)))
16345    (set (match_operand:P 1 "register_operand" "=S")
16346         (plus:P (match_dup 3)
16347                 (const_int 1)))]
16348   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16349    && ix86_check_no_addr_space (insn)"
16350   "%^movsb"
16351   [(set_attr "type" "str")
16352    (set_attr "memory" "both")
16353    (set (attr "prefix_rex")
16354         (if_then_else
16355           (match_test "<P:MODE>mode == DImode")
16356           (const_string "0")
16357           (const_string "*")))
16358    (set_attr "mode" "QI")])
16360 (define_expand "rep_mov"
16361   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16362               (set (match_operand 0 "register_operand")
16363                    (match_operand 5))
16364               (set (match_operand 2 "register_operand")
16365                    (match_operand 6))
16366               (set (match_operand 1 "memory_operand")
16367                    (match_operand 3 "memory_operand"))
16368               (use (match_dup 4))])]
16369   ""
16370   "ix86_current_function_needs_cld = 1;")
16372 (define_insn "*rep_movdi_rex64"
16373   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16374    (set (match_operand:P 0 "register_operand" "=D")
16375         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16376                           (const_int 3))
16377                 (match_operand:P 3 "register_operand" "0")))
16378    (set (match_operand:P 1 "register_operand" "=S")
16379         (plus:P (ashift:P (match_dup 5) (const_int 3))
16380                 (match_operand:P 4 "register_operand" "1")))
16381    (set (mem:BLK (match_dup 3))
16382         (mem:BLK (match_dup 4)))
16383    (use (match_dup 5))]
16384   "TARGET_64BIT
16385    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16386    && ix86_check_no_addr_space (insn)"
16387   "%^rep{%;} movsq"
16388   [(set_attr "type" "str")
16389    (set_attr "prefix_rep" "1")
16390    (set_attr "memory" "both")
16391    (set_attr "mode" "DI")])
16393 (define_insn "*rep_movsi"
16394   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16395    (set (match_operand:P 0 "register_operand" "=D")
16396         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16397                           (const_int 2))
16398                  (match_operand:P 3 "register_operand" "0")))
16399    (set (match_operand:P 1 "register_operand" "=S")
16400         (plus:P (ashift:P (match_dup 5) (const_int 2))
16401                 (match_operand:P 4 "register_operand" "1")))
16402    (set (mem:BLK (match_dup 3))
16403         (mem:BLK (match_dup 4)))
16404    (use (match_dup 5))]
16405   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16406    && ix86_check_no_addr_space (insn)"
16407   "%^rep{%;} movs{l|d}"
16408   [(set_attr "type" "str")
16409    (set_attr "prefix_rep" "1")
16410    (set_attr "memory" "both")
16411    (set_attr "mode" "SI")])
16413 (define_insn "*rep_movqi"
16414   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16415    (set (match_operand:P 0 "register_operand" "=D")
16416         (plus:P (match_operand:P 3 "register_operand" "0")
16417                 (match_operand:P 5 "register_operand" "2")))
16418    (set (match_operand:P 1 "register_operand" "=S")
16419         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16420    (set (mem:BLK (match_dup 3))
16421         (mem:BLK (match_dup 4)))
16422    (use (match_dup 5))]
16423   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16424    && ix86_check_no_addr_space (insn)"
16425   "%^rep{%;} movsb"
16426   [(set_attr "type" "str")
16427    (set_attr "prefix_rep" "1")
16428    (set_attr "memory" "both")
16429    (set_attr "mode" "QI")])
16431 (define_expand "setmem<mode>"
16432    [(use (match_operand:BLK 0 "memory_operand"))
16433     (use (match_operand:SWI48 1 "nonmemory_operand"))
16434     (use (match_operand:QI 2 "nonmemory_operand"))
16435     (use (match_operand 3 "const_int_operand"))
16436     (use (match_operand:SI 4 "const_int_operand"))
16437     (use (match_operand:SI 5 "const_int_operand"))
16438     (use (match_operand:SI 6 ""))
16439     (use (match_operand:SI 7 ""))
16440     (use (match_operand:SI 8 ""))]
16441   ""
16443  if (ix86_expand_set_or_movmem (operands[0], NULL,
16444                                 operands[1], operands[2],
16445                                 operands[3], operands[4],
16446                                 operands[5], operands[6],
16447                                 operands[7], operands[8], true))
16448    DONE;
16449  else
16450    FAIL;
16453 ;; Most CPUs don't like single string operations
16454 ;; Handle this case here to simplify previous expander.
16456 (define_expand "strset"
16457   [(set (match_operand 1 "memory_operand")
16458         (match_operand 2 "register_operand"))
16459    (parallel [(set (match_operand 0 "register_operand")
16460                    (match_dup 3))
16461               (clobber (reg:CC FLAGS_REG))])]
16462   ""
16464   /* Can't use this for non-default address spaces.  */
16465   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16466     FAIL;
16468   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16469     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16471   /* If .md ever supports :P for Pmode, this can be directly
16472      in the pattern above.  */
16473   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16474                               GEN_INT (GET_MODE_SIZE (GET_MODE
16475                                                       (operands[2]))));
16476   /* Can't use this if the user has appropriated eax or edi.  */
16477   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16478       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16479     {
16480       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16481                                       operands[3]));
16482       DONE;
16483     }
16486 (define_expand "strset_singleop"
16487   [(parallel [(set (match_operand 1 "memory_operand")
16488                    (match_operand 2 "register_operand"))
16489               (set (match_operand 0 "register_operand")
16490                    (match_operand 3))
16491               (unspec [(const_int 0)] UNSPEC_STOS)])]
16492   ""
16493   "ix86_current_function_needs_cld = 1;")
16495 (define_insn "*strsetdi_rex_1"
16496   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16497         (match_operand:DI 2 "register_operand" "a"))
16498    (set (match_operand:P 0 "register_operand" "=D")
16499         (plus:P (match_dup 1)
16500                 (const_int 8)))
16501    (unspec [(const_int 0)] UNSPEC_STOS)]
16502   "TARGET_64BIT
16503    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16504    && ix86_check_no_addr_space (insn)"
16505   "%^stosq"
16506   [(set_attr "type" "str")
16507    (set_attr "memory" "store")
16508    (set_attr "mode" "DI")])
16510 (define_insn "*strsetsi_1"
16511   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16512         (match_operand:SI 2 "register_operand" "a"))
16513    (set (match_operand:P 0 "register_operand" "=D")
16514         (plus:P (match_dup 1)
16515                 (const_int 4)))
16516    (unspec [(const_int 0)] UNSPEC_STOS)]
16517   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16518    && ix86_check_no_addr_space (insn)"
16519   "%^stos{l|d}"
16520   [(set_attr "type" "str")
16521    (set_attr "memory" "store")
16522    (set_attr "mode" "SI")])
16524 (define_insn "*strsethi_1"
16525   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16526         (match_operand:HI 2 "register_operand" "a"))
16527    (set (match_operand:P 0 "register_operand" "=D")
16528         (plus:P (match_dup 1)
16529                 (const_int 2)))
16530    (unspec [(const_int 0)] UNSPEC_STOS)]
16531   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16532    && ix86_check_no_addr_space (insn)"
16533   "%^stosw"
16534   [(set_attr "type" "str")
16535    (set_attr "memory" "store")
16536    (set_attr "mode" "HI")])
16538 (define_insn "*strsetqi_1"
16539   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16540         (match_operand:QI 2 "register_operand" "a"))
16541    (set (match_operand:P 0 "register_operand" "=D")
16542         (plus:P (match_dup 1)
16543                 (const_int 1)))
16544    (unspec [(const_int 0)] UNSPEC_STOS)]
16545   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16546    && ix86_check_no_addr_space (insn)"
16547   "%^stosb"
16548   [(set_attr "type" "str")
16549    (set_attr "memory" "store")
16550    (set (attr "prefix_rex")
16551         (if_then_else
16552           (match_test "<P:MODE>mode == DImode")
16553           (const_string "0")
16554           (const_string "*")))
16555    (set_attr "mode" "QI")])
16557 (define_expand "rep_stos"
16558   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16559               (set (match_operand 0 "register_operand")
16560                    (match_operand 4))
16561               (set (match_operand 2 "memory_operand") (const_int 0))
16562               (use (match_operand 3 "register_operand"))
16563               (use (match_dup 1))])]
16564   ""
16565   "ix86_current_function_needs_cld = 1;")
16567 (define_insn "*rep_stosdi_rex64"
16568   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16569    (set (match_operand:P 0 "register_operand" "=D")
16570         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16571                           (const_int 3))
16572                  (match_operand:P 3 "register_operand" "0")))
16573    (set (mem:BLK (match_dup 3))
16574         (const_int 0))
16575    (use (match_operand:DI 2 "register_operand" "a"))
16576    (use (match_dup 4))]
16577   "TARGET_64BIT
16578    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16579    && ix86_check_no_addr_space (insn)"
16580   "%^rep{%;} stosq"
16581   [(set_attr "type" "str")
16582    (set_attr "prefix_rep" "1")
16583    (set_attr "memory" "store")
16584    (set_attr "mode" "DI")])
16586 (define_insn "*rep_stossi"
16587   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16588    (set (match_operand:P 0 "register_operand" "=D")
16589         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16590                           (const_int 2))
16591                  (match_operand:P 3 "register_operand" "0")))
16592    (set (mem:BLK (match_dup 3))
16593         (const_int 0))
16594    (use (match_operand:SI 2 "register_operand" "a"))
16595    (use (match_dup 4))]
16596   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16597    && ix86_check_no_addr_space (insn)"
16598   "%^rep{%;} stos{l|d}"
16599   [(set_attr "type" "str")
16600    (set_attr "prefix_rep" "1")
16601    (set_attr "memory" "store")
16602    (set_attr "mode" "SI")])
16604 (define_insn "*rep_stosqi"
16605   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16606    (set (match_operand:P 0 "register_operand" "=D")
16607         (plus:P (match_operand:P 3 "register_operand" "0")
16608                 (match_operand:P 4 "register_operand" "1")))
16609    (set (mem:BLK (match_dup 3))
16610         (const_int 0))
16611    (use (match_operand:QI 2 "register_operand" "a"))
16612    (use (match_dup 4))]
16613   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16614    && ix86_check_no_addr_space (insn)"
16615   "%^rep{%;} stosb"
16616   [(set_attr "type" "str")
16617    (set_attr "prefix_rep" "1")
16618    (set_attr "memory" "store")
16619    (set (attr "prefix_rex")
16620         (if_then_else
16621           (match_test "<P:MODE>mode == DImode")
16622           (const_string "0")
16623           (const_string "*")))
16624    (set_attr "mode" "QI")])
16626 (define_expand "cmpstrnsi"
16627   [(set (match_operand:SI 0 "register_operand")
16628         (compare:SI (match_operand:BLK 1 "general_operand")
16629                     (match_operand:BLK 2 "general_operand")))
16630    (use (match_operand 3 "general_operand"))
16631    (use (match_operand 4 "immediate_operand"))]
16632   ""
16634   rtx addr1, addr2, out, outlow, count, countreg, align;
16636   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16637     FAIL;
16639   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16640   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16641     FAIL;
16643   out = operands[0];
16644   if (!REG_P (out))
16645     out = gen_reg_rtx (SImode);
16647   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16648   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16649   if (addr1 != XEXP (operands[1], 0))
16650     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16651   if (addr2 != XEXP (operands[2], 0))
16652     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16654   count = operands[3];
16655   countreg = ix86_zero_extend_to_Pmode (count);
16657   /* %%% Iff we are testing strict equality, we can use known alignment
16658      to good advantage.  This may be possible with combine, particularly
16659      once cc0 is dead.  */
16660   align = operands[4];
16662   if (CONST_INT_P (count))
16663     {
16664       if (INTVAL (count) == 0)
16665         {
16666           emit_move_insn (operands[0], const0_rtx);
16667           DONE;
16668         }
16669       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16670                                      operands[1], operands[2]));
16671     }
16672   else
16673     {
16674       rtx (*gen_cmp) (rtx, rtx);
16676       gen_cmp = (TARGET_64BIT
16677                  ? gen_cmpdi_1 : gen_cmpsi_1);
16679       emit_insn (gen_cmp (countreg, countreg));
16680       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16681                                   operands[1], operands[2]));
16682     }
16684   outlow = gen_lowpart (QImode, out);
16685   emit_insn (gen_cmpintqi (outlow));
16686   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16688   if (operands[0] != out)
16689     emit_move_insn (operands[0], out);
16691   DONE;
16694 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16696 (define_expand "cmpintqi"
16697   [(set (match_dup 1)
16698         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16699    (set (match_dup 2)
16700         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16701    (parallel [(set (match_operand:QI 0 "register_operand")
16702                    (minus:QI (match_dup 1)
16703                              (match_dup 2)))
16704               (clobber (reg:CC FLAGS_REG))])]
16705   ""
16707   operands[1] = gen_reg_rtx (QImode);
16708   operands[2] = gen_reg_rtx (QImode);
16711 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16712 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16714 (define_expand "cmpstrnqi_nz_1"
16715   [(parallel [(set (reg:CC FLAGS_REG)
16716                    (compare:CC (match_operand 4 "memory_operand")
16717                                (match_operand 5 "memory_operand")))
16718               (use (match_operand 2 "register_operand"))
16719               (use (match_operand:SI 3 "immediate_operand"))
16720               (clobber (match_operand 0 "register_operand"))
16721               (clobber (match_operand 1 "register_operand"))
16722               (clobber (match_dup 2))])]
16723   ""
16724   "ix86_current_function_needs_cld = 1;")
16726 (define_insn "*cmpstrnqi_nz_1"
16727   [(set (reg:CC FLAGS_REG)
16728         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16729                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16730    (use (match_operand:P 6 "register_operand" "2"))
16731    (use (match_operand:SI 3 "immediate_operand" "i"))
16732    (clobber (match_operand:P 0 "register_operand" "=S"))
16733    (clobber (match_operand:P 1 "register_operand" "=D"))
16734    (clobber (match_operand:P 2 "register_operand" "=c"))]
16735   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16736    && ix86_check_no_addr_space (insn)"
16737   "%^repz{%;} cmpsb"
16738   [(set_attr "type" "str")
16739    (set_attr "mode" "QI")
16740    (set (attr "prefix_rex")
16741         (if_then_else
16742           (match_test "<P:MODE>mode == DImode")
16743           (const_string "0")
16744           (const_string "*")))
16745    (set_attr "prefix_rep" "1")])
16747 ;; The same, but the count is not known to not be zero.
16749 (define_expand "cmpstrnqi_1"
16750   [(parallel [(set (reg:CC FLAGS_REG)
16751                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16752                                      (const_int 0))
16753                   (compare:CC (match_operand 4 "memory_operand")
16754                               (match_operand 5 "memory_operand"))
16755                   (const_int 0)))
16756               (use (match_operand:SI 3 "immediate_operand"))
16757               (use (reg:CC FLAGS_REG))
16758               (clobber (match_operand 0 "register_operand"))
16759               (clobber (match_operand 1 "register_operand"))
16760               (clobber (match_dup 2))])]
16761   ""
16762   "ix86_current_function_needs_cld = 1;")
16764 (define_insn "*cmpstrnqi_1"
16765   [(set (reg:CC FLAGS_REG)
16766         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16767                              (const_int 0))
16768           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16769                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16770           (const_int 0)))
16771    (use (match_operand:SI 3 "immediate_operand" "i"))
16772    (use (reg:CC FLAGS_REG))
16773    (clobber (match_operand:P 0 "register_operand" "=S"))
16774    (clobber (match_operand:P 1 "register_operand" "=D"))
16775    (clobber (match_operand:P 2 "register_operand" "=c"))]
16776   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16777    && ix86_check_no_addr_space (insn)"
16778   "%^repz{%;} cmpsb"
16779   [(set_attr "type" "str")
16780    (set_attr "mode" "QI")
16781    (set (attr "prefix_rex")
16782         (if_then_else
16783           (match_test "<P:MODE>mode == DImode")
16784           (const_string "0")
16785           (const_string "*")))
16786    (set_attr "prefix_rep" "1")])
16788 (define_expand "strlen<mode>"
16789   [(set (match_operand:P 0 "register_operand")
16790         (unspec:P [(match_operand:BLK 1 "general_operand")
16791                    (match_operand:QI 2 "immediate_operand")
16792                    (match_operand 3 "immediate_operand")]
16793                   UNSPEC_SCAS))]
16794   ""
16796  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16797    DONE;
16798  else
16799    FAIL;
16802 (define_expand "strlenqi_1"
16803   [(parallel [(set (match_operand 0 "register_operand")
16804                    (match_operand 2))
16805               (clobber (match_operand 1 "register_operand"))
16806               (clobber (reg:CC FLAGS_REG))])]
16807   ""
16808   "ix86_current_function_needs_cld = 1;")
16810 (define_insn "*strlenqi_1"
16811   [(set (match_operand:P 0 "register_operand" "=&c")
16812         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16813                    (match_operand:QI 2 "register_operand" "a")
16814                    (match_operand:P 3 "immediate_operand" "i")
16815                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16816    (clobber (match_operand:P 1 "register_operand" "=D"))
16817    (clobber (reg:CC FLAGS_REG))]
16818   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16819    && ix86_check_no_addr_space (insn)"
16820   "%^repnz{%;} scasb"
16821   [(set_attr "type" "str")
16822    (set_attr "mode" "QI")
16823    (set (attr "prefix_rex")
16824         (if_then_else
16825           (match_test "<P:MODE>mode == DImode")
16826           (const_string "0")
16827           (const_string "*")))
16828    (set_attr "prefix_rep" "1")])
16830 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16831 ;; handled in combine, but it is not currently up to the task.
16832 ;; When used for their truth value, the cmpstrn* expanders generate
16833 ;; code like this:
16835 ;;   repz cmpsb
16836 ;;   seta       %al
16837 ;;   setb       %dl
16838 ;;   cmpb       %al, %dl
16839 ;;   jcc        label
16841 ;; The intermediate three instructions are unnecessary.
16843 ;; This one handles cmpstrn*_nz_1...
16844 (define_peephole2
16845   [(parallel[
16846      (set (reg:CC FLAGS_REG)
16847           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16848                       (mem:BLK (match_operand 5 "register_operand"))))
16849      (use (match_operand 6 "register_operand"))
16850      (use (match_operand:SI 3 "immediate_operand"))
16851      (clobber (match_operand 0 "register_operand"))
16852      (clobber (match_operand 1 "register_operand"))
16853      (clobber (match_operand 2 "register_operand"))])
16854    (set (match_operand:QI 7 "register_operand")
16855         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16856    (set (match_operand:QI 8 "register_operand")
16857         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16858    (set (reg FLAGS_REG)
16859         (compare (match_dup 7) (match_dup 8)))
16860   ]
16861   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16862   [(parallel[
16863      (set (reg:CC FLAGS_REG)
16864           (compare:CC (mem:BLK (match_dup 4))
16865                       (mem:BLK (match_dup 5))))
16866      (use (match_dup 6))
16867      (use (match_dup 3))
16868      (clobber (match_dup 0))
16869      (clobber (match_dup 1))
16870      (clobber (match_dup 2))])])
16872 ;; ...and this one handles cmpstrn*_1.
16873 (define_peephole2
16874   [(parallel[
16875      (set (reg:CC FLAGS_REG)
16876           (if_then_else:CC (ne (match_operand 6 "register_operand")
16877                                (const_int 0))
16878             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16879                         (mem:BLK (match_operand 5 "register_operand")))
16880             (const_int 0)))
16881      (use (match_operand:SI 3 "immediate_operand"))
16882      (use (reg:CC FLAGS_REG))
16883      (clobber (match_operand 0 "register_operand"))
16884      (clobber (match_operand 1 "register_operand"))
16885      (clobber (match_operand 2 "register_operand"))])
16886    (set (match_operand:QI 7 "register_operand")
16887         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16888    (set (match_operand:QI 8 "register_operand")
16889         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16890    (set (reg FLAGS_REG)
16891         (compare (match_dup 7) (match_dup 8)))
16892   ]
16893   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16894   [(parallel[
16895      (set (reg:CC FLAGS_REG)
16896           (if_then_else:CC (ne (match_dup 6)
16897                                (const_int 0))
16898             (compare:CC (mem:BLK (match_dup 4))
16899                         (mem:BLK (match_dup 5)))
16900             (const_int 0)))
16901      (use (match_dup 3))
16902      (use (reg:CC FLAGS_REG))
16903      (clobber (match_dup 0))
16904      (clobber (match_dup 1))
16905      (clobber (match_dup 2))])])
16907 ;; Conditional move instructions.
16909 (define_expand "mov<mode>cc"
16910   [(set (match_operand:SWIM 0 "register_operand")
16911         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16912                            (match_operand:SWIM 2 "<general_operand>")
16913                            (match_operand:SWIM 3 "<general_operand>")))]
16914   ""
16915   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16917 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16918 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16919 ;; So just document what we're doing explicitly.
16921 (define_expand "x86_mov<mode>cc_0_m1"
16922   [(parallel
16923     [(set (match_operand:SWI48 0 "register_operand")
16924           (if_then_else:SWI48
16925             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16926              [(match_operand 1 "flags_reg_operand")
16927               (const_int 0)])
16928             (const_int -1)
16929             (const_int 0)))
16930      (clobber (reg:CC FLAGS_REG))])])
16932 (define_insn "*x86_mov<mode>cc_0_m1"
16933   [(set (match_operand:SWI48 0 "register_operand" "=r")
16934         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16935                              [(reg FLAGS_REG) (const_int 0)])
16936           (const_int -1)
16937           (const_int 0)))
16938    (clobber (reg:CC FLAGS_REG))]
16939   ""
16940   "sbb{<imodesuffix>}\t%0, %0"
16941   ; Since we don't have the proper number of operands for an alu insn,
16942   ; fill in all the blanks.
16943   [(set_attr "type" "alu")
16944    (set_attr "modrm_class" "op0")
16945    (set_attr "use_carry" "1")
16946    (set_attr "pent_pair" "pu")
16947    (set_attr "memory" "none")
16948    (set_attr "imm_disp" "false")
16949    (set_attr "mode" "<MODE>")
16950    (set_attr "length_immediate" "0")])
16952 (define_insn "*x86_mov<mode>cc_0_m1_se"
16953   [(set (match_operand:SWI48 0 "register_operand" "=r")
16954         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16955                              [(reg FLAGS_REG) (const_int 0)])
16956                             (const_int 1)
16957                             (const_int 0)))
16958    (clobber (reg:CC FLAGS_REG))]
16959   ""
16960   "sbb{<imodesuffix>}\t%0, %0"
16961   [(set_attr "type" "alu")
16962    (set_attr "modrm_class" "op0")
16963    (set_attr "use_carry" "1")
16964    (set_attr "pent_pair" "pu")
16965    (set_attr "memory" "none")
16966    (set_attr "imm_disp" "false")
16967    (set_attr "mode" "<MODE>")
16968    (set_attr "length_immediate" "0")])
16970 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16971   [(set (match_operand:SWI48 0 "register_operand" "=r")
16972         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16973                     [(reg FLAGS_REG) (const_int 0)])))
16974    (clobber (reg:CC FLAGS_REG))]
16975   ""
16976   "sbb{<imodesuffix>}\t%0, %0"
16977   [(set_attr "type" "alu")
16978    (set_attr "modrm_class" "op0")
16979    (set_attr "use_carry" "1")
16980    (set_attr "pent_pair" "pu")
16981    (set_attr "memory" "none")
16982    (set_attr "imm_disp" "false")
16983    (set_attr "mode" "<MODE>")
16984    (set_attr "length_immediate" "0")])
16986 (define_insn "*mov<mode>cc_noc"
16987   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16988         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16989                                [(reg FLAGS_REG) (const_int 0)])
16990           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16991           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16992   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16993   "@
16994    cmov%O2%C1\t{%2, %0|%0, %2}
16995    cmov%O2%c1\t{%3, %0|%0, %3}"
16996   [(set_attr "type" "icmov")
16997    (set_attr "mode" "<MODE>")])
16999 (define_insn "*movsicc_noc_zext"
17000   [(set (match_operand:DI 0 "register_operand" "=r,r")
17001         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17002                            [(reg FLAGS_REG) (const_int 0)])
17003           (zero_extend:DI
17004             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17005           (zero_extend:DI
17006             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17007   "TARGET_64BIT
17008    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17009   "@
17010    cmov%O2%C1\t{%2, %k0|%k0, %2}
17011    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17012   [(set_attr "type" "icmov")
17013    (set_attr "mode" "SI")])
17015 ;; Don't do conditional moves with memory inputs.  This splitter helps
17016 ;; register starved x86_32 by forcing inputs into registers before reload.
17017 (define_split
17018   [(set (match_operand:SWI248 0 "register_operand")
17019         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17020                                [(reg FLAGS_REG) (const_int 0)])
17021           (match_operand:SWI248 2 "nonimmediate_operand")
17022           (match_operand:SWI248 3 "nonimmediate_operand")))]
17023   "!TARGET_64BIT && TARGET_CMOVE
17024    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17025    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17026    && can_create_pseudo_p ()
17027    && optimize_insn_for_speed_p ()"
17028   [(set (match_dup 0)
17029         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17031   if (MEM_P (operands[2]))
17032     operands[2] = force_reg (<MODE>mode, operands[2]);
17033   if (MEM_P (operands[3]))
17034     operands[3] = force_reg (<MODE>mode, operands[3]);
17037 (define_insn "*movqicc_noc"
17038   [(set (match_operand:QI 0 "register_operand" "=r,r")
17039         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17040                            [(reg FLAGS_REG) (const_int 0)])
17041                       (match_operand:QI 2 "register_operand" "r,0")
17042                       (match_operand:QI 3 "register_operand" "0,r")))]
17043   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17044   "#"
17045   [(set_attr "type" "icmov")
17046    (set_attr "mode" "QI")])
17048 (define_split
17049   [(set (match_operand:SWI12 0 "register_operand")
17050         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17051                               [(reg FLAGS_REG) (const_int 0)])
17052                       (match_operand:SWI12 2 "register_operand")
17053                       (match_operand:SWI12 3 "register_operand")))]
17054   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17055    && reload_completed"
17056   [(set (match_dup 0)
17057         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17059   operands[0] = gen_lowpart (SImode, operands[0]);
17060   operands[2] = gen_lowpart (SImode, operands[2]);
17061   operands[3] = gen_lowpart (SImode, operands[3]);
17064 ;; Don't do conditional moves with memory inputs
17065 (define_peephole2
17066   [(match_scratch:SWI248 4 "r")
17067    (set (match_operand:SWI248 0 "register_operand")
17068         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17069                                [(reg FLAGS_REG) (const_int 0)])
17070           (match_operand:SWI248 2 "nonimmediate_operand")
17071           (match_operand:SWI248 3 "nonimmediate_operand")))]
17072   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17073    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17074    && optimize_insn_for_speed_p ()"
17075   [(set (match_dup 4) (match_dup 5))
17076    (set (match_dup 0)
17077         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17079   if (MEM_P (operands[2]))
17080     {
17081       operands[5] = operands[2];
17082       operands[2] = operands[4];
17083     }
17084   else if (MEM_P (operands[3]))
17085     {
17086       operands[5] = operands[3];
17087       operands[3] = operands[4];
17088     }
17089   else
17090     gcc_unreachable ();
17093 (define_peephole2
17094   [(match_scratch:SI 4 "r")
17095    (set (match_operand:DI 0 "register_operand")
17096         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17097                            [(reg FLAGS_REG) (const_int 0)])
17098           (zero_extend:DI
17099             (match_operand:SI 2 "nonimmediate_operand"))
17100           (zero_extend:DI
17101             (match_operand:SI 3 "nonimmediate_operand"))))]
17102   "TARGET_64BIT
17103    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17104    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17105    && optimize_insn_for_speed_p ()"
17106   [(set (match_dup 4) (match_dup 5))
17107    (set (match_dup 0)
17108         (if_then_else:DI (match_dup 1)
17109           (zero_extend:DI (match_dup 2))
17110           (zero_extend:DI (match_dup 3))))]
17112   if (MEM_P (operands[2]))
17113     {
17114       operands[5] = operands[2];
17115       operands[2] = operands[4];
17116     }
17117   else if (MEM_P (operands[3]))
17118     {
17119       operands[5] = operands[3];
17120       operands[3] = operands[4];
17121     }
17122   else
17123     gcc_unreachable ();
17126 (define_expand "mov<mode>cc"
17127   [(set (match_operand:X87MODEF 0 "register_operand")
17128         (if_then_else:X87MODEF
17129           (match_operand 1 "comparison_operator")
17130           (match_operand:X87MODEF 2 "register_operand")
17131           (match_operand:X87MODEF 3 "register_operand")))]
17132   "(TARGET_80387 && TARGET_CMOVE)
17133    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17134   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17136 (define_insn "*movxfcc_1"
17137   [(set (match_operand:XF 0 "register_operand" "=f,f")
17138         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17139                                 [(reg FLAGS_REG) (const_int 0)])
17140                       (match_operand:XF 2 "register_operand" "f,0")
17141                       (match_operand:XF 3 "register_operand" "0,f")))]
17142   "TARGET_80387 && TARGET_CMOVE"
17143   "@
17144    fcmov%F1\t{%2, %0|%0, %2}
17145    fcmov%f1\t{%3, %0|%0, %3}"
17146   [(set_attr "type" "fcmov")
17147    (set_attr "mode" "XF")])
17149 (define_insn "*movdfcc_1"
17150   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17151         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17152                                 [(reg FLAGS_REG) (const_int 0)])
17153                       (match_operand:DF 2 "nonimmediate_operand"
17154                                                "f ,0,rm,0 ,rm,0")
17155                       (match_operand:DF 3 "nonimmediate_operand"
17156                                                "0 ,f,0 ,rm,0, rm")))]
17157   "TARGET_80387 && TARGET_CMOVE
17158    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17159   "@
17160    fcmov%F1\t{%2, %0|%0, %2}
17161    fcmov%f1\t{%3, %0|%0, %3}
17162    #
17163    #
17164    cmov%O2%C1\t{%2, %0|%0, %2}
17165    cmov%O2%c1\t{%3, %0|%0, %3}"
17166   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17167    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17168    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17170 (define_split
17171   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
17172         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17173                                 [(reg FLAGS_REG) (const_int 0)])
17174                       (match_operand:DF 2 "nonimmediate_operand")
17175                       (match_operand:DF 3 "nonimmediate_operand")))]
17176   "!TARGET_64BIT && reload_completed"
17177   [(set (match_dup 2)
17178         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17179    (set (match_dup 3)
17180         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17182   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17183   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17186 (define_insn "*movsfcc_1_387"
17187   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17188         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17189                                 [(reg FLAGS_REG) (const_int 0)])
17190                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17191                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17192   "TARGET_80387 && TARGET_CMOVE
17193    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17194   "@
17195    fcmov%F1\t{%2, %0|%0, %2}
17196    fcmov%f1\t{%3, %0|%0, %3}
17197    cmov%O2%C1\t{%2, %0|%0, %2}
17198    cmov%O2%c1\t{%3, %0|%0, %3}"
17199   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17200    (set_attr "mode" "SF,SF,SI,SI")])
17202 ;; Don't do conditional moves with memory inputs.  This splitter helps
17203 ;; register starved x86_32 by forcing inputs into registers before reload.
17204 (define_split
17205   [(set (match_operand:MODEF 0 "register_operand")
17206         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17207                               [(reg FLAGS_REG) (const_int 0)])
17208           (match_operand:MODEF 2 "nonimmediate_operand")
17209           (match_operand:MODEF 3 "nonimmediate_operand")))]
17210   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17211    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17212    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17213    && can_create_pseudo_p ()
17214    && optimize_insn_for_speed_p ()"
17215   [(set (match_dup 0)
17216         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17218   if (MEM_P (operands[2]))
17219     operands[2] = force_reg (<MODE>mode, operands[2]);
17220   if (MEM_P (operands[3]))
17221     operands[3] = force_reg (<MODE>mode, operands[3]);
17224 ;; Don't do conditional moves with memory inputs
17225 (define_peephole2
17226   [(match_scratch:MODEF 4 "r")
17227    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
17228         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17229                               [(reg FLAGS_REG) (const_int 0)])
17230           (match_operand:MODEF 2 "nonimmediate_operand")
17231           (match_operand:MODEF 3 "nonimmediate_operand")))]
17232   "(<MODE>mode != DFmode || TARGET_64BIT)
17233    && TARGET_80387 && TARGET_CMOVE
17234    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17235    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17236    && optimize_insn_for_speed_p ()"
17237   [(set (match_dup 4) (match_dup 5))
17238    (set (match_dup 0)
17239         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17241   if (MEM_P (operands[2]))
17242     {
17243       operands[5] = operands[2];
17244       operands[2] = operands[4];
17245     }
17246   else if (MEM_P (operands[3]))
17247     {
17248       operands[5] = operands[3];
17249       operands[3] = operands[4];
17250     }
17251   else
17252     gcc_unreachable ();
17255 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17256 ;; the scalar versions to have only XMM registers as operands.
17258 ;; XOP conditional move
17259 (define_insn "*xop_pcmov_<mode>"
17260   [(set (match_operand:MODEF 0 "register_operand" "=x")
17261         (if_then_else:MODEF
17262           (match_operand:MODEF 1 "register_operand" "x")
17263           (match_operand:MODEF 2 "register_operand" "x")
17264           (match_operand:MODEF 3 "register_operand" "x")))]
17265   "TARGET_XOP"
17266   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17267   [(set_attr "type" "sse4arg")])
17269 ;; These versions of the min/max patterns are intentionally ignorant of
17270 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17271 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17272 ;; are undefined in this condition, we're certain this is correct.
17274 (define_insn "<code><mode>3"
17275   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17276         (smaxmin:MODEF
17277           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17278           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17279   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17280   "@
17281    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17282    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17283   [(set_attr "isa" "noavx,avx")
17284    (set_attr "prefix" "orig,vex")
17285    (set_attr "type" "sseadd")
17286    (set_attr "mode" "<MODE>")])
17288 ;; These versions of the min/max patterns implement exactly the operations
17289 ;;   min = (op1 < op2 ? op1 : op2)
17290 ;;   max = (!(op1 < op2) ? op1 : op2)
17291 ;; Their operands are not commutative, and thus they may be used in the
17292 ;; presence of -0.0 and NaN.
17294 (define_int_iterator IEEE_MAXMIN
17295         [UNSPEC_IEEE_MAX
17296          UNSPEC_IEEE_MIN])
17298 (define_int_attr ieee_maxmin
17299         [(UNSPEC_IEEE_MAX "max")
17300          (UNSPEC_IEEE_MIN "min")])
17302 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17303   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17304         (unspec:MODEF
17305           [(match_operand:MODEF 1 "register_operand" "0,v")
17306            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17307           IEEE_MAXMIN))]
17308   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17309   "@
17310    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17311    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17312   [(set_attr "isa" "noavx,avx")
17313    (set_attr "prefix" "orig,maybe_evex")
17314    (set_attr "type" "sseadd")
17315    (set_attr "mode" "<MODE>")])
17317 ;; Make two stack loads independent:
17318 ;;   fld aa              fld aa
17319 ;;   fld %st(0)     ->   fld bb
17320 ;;   fmul bb             fmul %st(1), %st
17322 ;; Actually we only match the last two instructions for simplicity.
17323 (define_peephole2
17324   [(set (match_operand 0 "fp_register_operand")
17325         (match_operand 1 "fp_register_operand"))
17326    (set (match_dup 0)
17327         (match_operator 2 "binary_fp_operator"
17328            [(match_dup 0)
17329             (match_operand 3 "memory_operand")]))]
17330   "REGNO (operands[0]) != REGNO (operands[1])"
17331   [(set (match_dup 0) (match_dup 3))
17332    (set (match_dup 0) (match_dup 4))]
17334   ;; The % modifier is not operational anymore in peephole2's, so we have to
17335   ;; swap the operands manually in the case of addition and multiplication.
17337   rtx op0, op1;
17339   if (COMMUTATIVE_ARITH_P (operands[2]))
17340     op0 = operands[0], op1 = operands[1];
17341   else
17342     op0 = operands[1], op1 = operands[0];
17344   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17345                                 GET_MODE (operands[2]),
17346                                 op0, op1);
17349 ;; Conditional addition patterns
17350 (define_expand "add<mode>cc"
17351   [(match_operand:SWI 0 "register_operand")
17352    (match_operand 1 "ordered_comparison_operator")
17353    (match_operand:SWI 2 "register_operand")
17354    (match_operand:SWI 3 "const_int_operand")]
17355   ""
17356   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17358 ;; Misc patterns (?)
17360 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17361 ;; Otherwise there will be nothing to keep
17363 ;; [(set (reg ebp) (reg esp))]
17364 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17365 ;;  (clobber (eflags)]
17366 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17368 ;; in proper program order.
17370 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17371   [(set (match_operand:P 0 "register_operand" "=r,r")
17372         (plus:P (match_operand:P 1 "register_operand" "0,r")
17373                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17374    (clobber (reg:CC FLAGS_REG))
17375    (clobber (mem:BLK (scratch)))]
17376   ""
17378   switch (get_attr_type (insn))
17379     {
17380     case TYPE_IMOV:
17381       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17383     case TYPE_ALU:
17384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17385       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17386         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17388       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17390     default:
17391       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17392       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17393     }
17395   [(set (attr "type")
17396         (cond [(and (eq_attr "alternative" "0")
17397                     (not (match_test "TARGET_OPT_AGU")))
17398                  (const_string "alu")
17399                (match_operand:<MODE> 2 "const0_operand")
17400                  (const_string "imov")
17401               ]
17402               (const_string "lea")))
17403    (set (attr "length_immediate")
17404         (cond [(eq_attr "type" "imov")
17405                  (const_string "0")
17406                (and (eq_attr "type" "alu")
17407                     (match_operand 2 "const128_operand"))
17408                  (const_string "1")
17409               ]
17410               (const_string "*")))
17411    (set_attr "mode" "<MODE>")])
17413 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17414   [(set (match_operand:P 0 "register_operand" "=r")
17415         (minus:P (match_operand:P 1 "register_operand" "0")
17416                  (match_operand:P 2 "register_operand" "r")))
17417    (clobber (reg:CC FLAGS_REG))
17418    (clobber (mem:BLK (scratch)))]
17419   ""
17420   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17421   [(set_attr "type" "alu")
17422    (set_attr "mode" "<MODE>")])
17424 (define_insn "allocate_stack_worker_probe_<mode>"
17425   [(set (match_operand:P 0 "register_operand" "=a")
17426         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17427                             UNSPECV_STACK_PROBE))
17428    (clobber (reg:CC FLAGS_REG))]
17429   "ix86_target_stack_probe ()"
17430   "call\t___chkstk_ms"
17431   [(set_attr "type" "multi")
17432    (set_attr "length" "5")])
17434 (define_expand "allocate_stack"
17435   [(match_operand 0 "register_operand")
17436    (match_operand 1 "general_operand")]
17437   "ix86_target_stack_probe ()"
17439   rtx x;
17441 #ifndef CHECK_STACK_LIMIT
17442 #define CHECK_STACK_LIMIT 0
17443 #endif
17445   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17446       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17447     x = operands[1];
17448   else
17449     {
17450       rtx (*insn) (rtx, rtx);
17452       x = copy_to_mode_reg (Pmode, operands[1]);
17454       insn = (TARGET_64BIT
17455               ? gen_allocate_stack_worker_probe_di
17456               : gen_allocate_stack_worker_probe_si);
17458       emit_insn (insn (x, x));
17459     }
17461   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17462                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17464   if (x != stack_pointer_rtx)
17465     emit_move_insn (stack_pointer_rtx, x);
17467   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17468   DONE;
17471 ;; Use IOR for stack probes, this is shorter.
17472 (define_expand "probe_stack"
17473   [(match_operand 0 "memory_operand")]
17474   ""
17476   rtx (*gen_ior3) (rtx, rtx, rtx);
17478   gen_ior3 = (GET_MODE (operands[0]) == DImode
17479               ? gen_iordi3 : gen_iorsi3);
17481   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17482   DONE;
17485 (define_insn "adjust_stack_and_probe<mode>"
17486   [(set (match_operand:P 0 "register_operand" "=r")
17487         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17488                             UNSPECV_PROBE_STACK_RANGE))
17489    (set (reg:P SP_REG)
17490         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17491    (clobber (reg:CC FLAGS_REG))
17492    (clobber (mem:BLK (scratch)))]
17493   ""
17494   "* return output_adjust_stack_and_probe (operands[0]);"
17495   [(set_attr "type" "multi")])
17497 (define_insn "probe_stack_range<mode>"
17498   [(set (match_operand:P 0 "register_operand" "=r")
17499         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17500                             (match_operand:P 2 "const_int_operand" "n")]
17501                             UNSPECV_PROBE_STACK_RANGE))
17502    (clobber (reg:CC FLAGS_REG))]
17503   ""
17504   "* return output_probe_stack_range (operands[0], operands[2]);"
17505   [(set_attr "type" "multi")])
17507 (define_expand "builtin_setjmp_receiver"
17508   [(label_ref (match_operand 0))]
17509   "!TARGET_64BIT && flag_pic"
17511 #if TARGET_MACHO
17512   if (TARGET_MACHO)
17513     {
17514       rtx xops[3];
17515       rtx_code_label *label_rtx = gen_label_rtx ();
17516       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17517       xops[0] = xops[1] = pic_offset_table_rtx;
17518       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17519       ix86_expand_binary_operator (MINUS, SImode, xops);
17520     }
17521   else
17522 #endif
17523     emit_insn (gen_set_got (pic_offset_table_rtx));
17524   DONE;
17527 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17528 ;; Do not split instructions with mask registers.
17529 (define_split
17530   [(set (match_operand 0 "general_reg_operand")
17531         (match_operator 3 "promotable_binary_operator"
17532            [(match_operand 1 "general_reg_operand")
17533             (match_operand 2 "aligned_operand")]))
17534    (clobber (reg:CC FLAGS_REG))]
17535   "! TARGET_PARTIAL_REG_STALL && reload_completed
17536    && ((GET_MODE (operands[0]) == HImode
17537         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17538             /* ??? next two lines just !satisfies_constraint_K (...) */
17539             || !CONST_INT_P (operands[2])
17540             || satisfies_constraint_K (operands[2])))
17541        || (GET_MODE (operands[0]) == QImode
17542            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17543   [(parallel [(set (match_dup 0)
17544                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17545               (clobber (reg:CC FLAGS_REG))])]
17547   operands[0] = gen_lowpart (SImode, operands[0]);
17548   operands[1] = gen_lowpart (SImode, operands[1]);
17549   if (GET_CODE (operands[3]) != ASHIFT)
17550     operands[2] = gen_lowpart (SImode, operands[2]);
17551   operands[3] = shallow_copy_rtx (operands[3]);
17552   PUT_MODE (operands[3], SImode);
17555 ; Promote the QImode tests, as i386 has encoding of the AND
17556 ; instruction with 32-bit sign-extended immediate and thus the
17557 ; instruction size is unchanged, except in the %eax case for
17558 ; which it is increased by one byte, hence the ! optimize_size.
17559 (define_split
17560   [(set (match_operand 0 "flags_reg_operand")
17561         (match_operator 2 "compare_operator"
17562           [(and (match_operand 3 "aligned_operand")
17563                 (match_operand 4 "const_int_operand"))
17564            (const_int 0)]))
17565    (set (match_operand 1 "register_operand")
17566         (and (match_dup 3) (match_dup 4)))]
17567   "! TARGET_PARTIAL_REG_STALL && reload_completed
17568    && optimize_insn_for_speed_p ()
17569    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17570        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17571    /* Ensure that the operand will remain sign-extended immediate.  */
17572    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17573   [(parallel [(set (match_dup 0)
17574                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17575                                     (const_int 0)]))
17576               (set (match_dup 1)
17577                    (and:SI (match_dup 3) (match_dup 4)))])]
17579   operands[4]
17580     = gen_int_mode (INTVAL (operands[4])
17581                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17582   operands[1] = gen_lowpart (SImode, operands[1]);
17583   operands[3] = gen_lowpart (SImode, operands[3]);
17586 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17587 ; the TEST instruction with 32-bit sign-extended immediate and thus
17588 ; the instruction size would at least double, which is not what we
17589 ; want even with ! optimize_size.
17590 (define_split
17591   [(set (match_operand 0 "flags_reg_operand")
17592         (match_operator 1 "compare_operator"
17593           [(and (match_operand:HI 2 "aligned_operand")
17594                 (match_operand:HI 3 "const_int_operand"))
17595            (const_int 0)]))]
17596   "! TARGET_PARTIAL_REG_STALL && reload_completed
17597    && ! TARGET_FAST_PREFIX
17598    && optimize_insn_for_speed_p ()
17599    /* Ensure that the operand will remain sign-extended immediate.  */
17600    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17601   [(set (match_dup 0)
17602         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17603                          (const_int 0)]))]
17605   operands[3]
17606     = gen_int_mode (INTVAL (operands[3])
17607                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17608   operands[2] = gen_lowpart (SImode, operands[2]);
17611 (define_split
17612   [(set (match_operand 0 "register_operand")
17613         (neg (match_operand 1 "register_operand")))
17614    (clobber (reg:CC FLAGS_REG))]
17615   "! TARGET_PARTIAL_REG_STALL && reload_completed
17616    && (GET_MODE (operands[0]) == HImode
17617        || (GET_MODE (operands[0]) == QImode
17618            && (TARGET_PROMOTE_QImode
17619                || optimize_insn_for_size_p ())))"
17620   [(parallel [(set (match_dup 0)
17621                    (neg:SI (match_dup 1)))
17622               (clobber (reg:CC FLAGS_REG))])]
17624   operands[0] = gen_lowpart (SImode, operands[0]);
17625   operands[1] = gen_lowpart (SImode, operands[1]);
17628 ;; Do not split instructions with mask regs.
17629 (define_split
17630   [(set (match_operand 0 "general_reg_operand")
17631         (not (match_operand 1 "general_reg_operand")))]
17632   "! TARGET_PARTIAL_REG_STALL && reload_completed
17633    && (GET_MODE (operands[0]) == HImode
17634        || (GET_MODE (operands[0]) == QImode
17635            && (TARGET_PROMOTE_QImode
17636                || optimize_insn_for_size_p ())))"
17637   [(set (match_dup 0)
17638         (not:SI (match_dup 1)))]
17640   operands[0] = gen_lowpart (SImode, operands[0]);
17641   operands[1] = gen_lowpart (SImode, operands[1]);
17644 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17645 ;; transform a complex memory operation into two memory to register operations.
17647 ;; Don't push memory operands
17648 (define_peephole2
17649   [(set (match_operand:SWI 0 "push_operand")
17650         (match_operand:SWI 1 "memory_operand"))
17651    (match_scratch:SWI 2 "<r>")]
17652   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17653    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17654   [(set (match_dup 2) (match_dup 1))
17655    (set (match_dup 0) (match_dup 2))])
17657 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17658 ;; SImode pushes.
17659 (define_peephole2
17660   [(set (match_operand:SF 0 "push_operand")
17661         (match_operand:SF 1 "memory_operand"))
17662    (match_scratch:SF 2 "r")]
17663   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17664    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17665   [(set (match_dup 2) (match_dup 1))
17666    (set (match_dup 0) (match_dup 2))])
17668 ;; Don't move an immediate directly to memory when the instruction
17669 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17670 (define_peephole2
17671   [(match_scratch:SWI124 1 "<r>")
17672    (set (match_operand:SWI124 0 "memory_operand")
17673         (const_int 0))]
17674   "optimize_insn_for_speed_p ()
17675    && ((<MODE>mode == HImode
17676        && TARGET_LCP_STALL)
17677        || (!TARGET_USE_MOV0
17678           && TARGET_SPLIT_LONG_MOVES
17679           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17680    && peep2_regno_dead_p (0, FLAGS_REG)"
17681   [(parallel [(set (match_dup 2) (const_int 0))
17682               (clobber (reg:CC FLAGS_REG))])
17683    (set (match_dup 0) (match_dup 1))]
17684   "operands[2] = gen_lowpart (SImode, operands[1]);")
17686 (define_peephole2
17687   [(match_scratch:SWI124 2 "<r>")
17688    (set (match_operand:SWI124 0 "memory_operand")
17689         (match_operand:SWI124 1 "immediate_operand"))]
17690   "optimize_insn_for_speed_p ()
17691    && ((<MODE>mode == HImode
17692        && TARGET_LCP_STALL)
17693        || (TARGET_SPLIT_LONG_MOVES
17694           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17695   [(set (match_dup 2) (match_dup 1))
17696    (set (match_dup 0) (match_dup 2))])
17698 ;; Don't compare memory with zero, load and use a test instead.
17699 (define_peephole2
17700   [(set (match_operand 0 "flags_reg_operand")
17701         (match_operator 1 "compare_operator"
17702           [(match_operand:SI 2 "memory_operand")
17703            (const_int 0)]))
17704    (match_scratch:SI 3 "r")]
17705   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17706   [(set (match_dup 3) (match_dup 2))
17707    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17709 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17710 ;; Don't split NOTs with a displacement operand, because resulting XOR
17711 ;; will not be pairable anyway.
17713 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17714 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17715 ;; so this split helps here as well.
17717 ;; Note: Can't do this as a regular split because we can't get proper
17718 ;; lifetime information then.
17720 (define_peephole2
17721   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17722         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17723   "optimize_insn_for_speed_p ()
17724    && ((TARGET_NOT_UNPAIRABLE
17725         && (!MEM_P (operands[0])
17726             || !memory_displacement_operand (operands[0], <MODE>mode)))
17727        || (TARGET_NOT_VECTORMODE
17728            && long_memory_operand (operands[0], <MODE>mode)))
17729    && peep2_regno_dead_p (0, FLAGS_REG)"
17730   [(parallel [(set (match_dup 0)
17731                    (xor:SWI124 (match_dup 1) (const_int -1)))
17732               (clobber (reg:CC FLAGS_REG))])])
17734 ;; Non pairable "test imm, reg" instructions can be translated to
17735 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17736 ;; byte opcode instead of two, have a short form for byte operands),
17737 ;; so do it for other CPUs as well.  Given that the value was dead,
17738 ;; this should not create any new dependencies.  Pass on the sub-word
17739 ;; versions if we're concerned about partial register stalls.
17741 (define_peephole2
17742   [(set (match_operand 0 "flags_reg_operand")
17743         (match_operator 1 "compare_operator"
17744           [(and:SI (match_operand:SI 2 "register_operand")
17745                    (match_operand:SI 3 "immediate_operand"))
17746            (const_int 0)]))]
17747   "ix86_match_ccmode (insn, CCNOmode)
17748    && (true_regnum (operands[2]) != AX_REG
17749        || satisfies_constraint_K (operands[3]))
17750    && peep2_reg_dead_p (1, operands[2])"
17751   [(parallel
17752      [(set (match_dup 0)
17753            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17754                             (const_int 0)]))
17755       (set (match_dup 2)
17756            (and:SI (match_dup 2) (match_dup 3)))])])
17758 ;; We don't need to handle HImode case, because it will be promoted to SImode
17759 ;; on ! TARGET_PARTIAL_REG_STALL
17761 (define_peephole2
17762   [(set (match_operand 0 "flags_reg_operand")
17763         (match_operator 1 "compare_operator"
17764           [(and:QI (match_operand:QI 2 "register_operand")
17765                    (match_operand:QI 3 "immediate_operand"))
17766            (const_int 0)]))]
17767   "! TARGET_PARTIAL_REG_STALL
17768    && ix86_match_ccmode (insn, CCNOmode)
17769    && true_regnum (operands[2]) != AX_REG
17770    && peep2_reg_dead_p (1, operands[2])"
17771   [(parallel
17772      [(set (match_dup 0)
17773            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17774                             (const_int 0)]))
17775       (set (match_dup 2)
17776            (and:QI (match_dup 2) (match_dup 3)))])])
17778 (define_peephole2
17779   [(set (match_operand 0 "flags_reg_operand")
17780         (match_operator 1 "compare_operator"
17781           [(and:SI
17782              (zero_extract:SI
17783                (match_operand 2 "QIreg_operand")
17784                (const_int 8)
17785                (const_int 8))
17786              (match_operand 3 "const_int_operand"))
17787            (const_int 0)]))]
17788   "! TARGET_PARTIAL_REG_STALL
17789    && ix86_match_ccmode (insn, CCNOmode)
17790    && true_regnum (operands[2]) != AX_REG
17791    && peep2_reg_dead_p (1, operands[2])"
17792   [(parallel [(set (match_dup 0)
17793                    (match_op_dup 1
17794                      [(and:SI
17795                         (zero_extract:SI
17796                           (match_dup 2)
17797                           (const_int 8)
17798                           (const_int 8))
17799                         (match_dup 3))
17800                       (const_int 0)]))
17801               (set (zero_extract:SI (match_dup 2)
17802                                     (const_int 8)
17803                                     (const_int 8))
17804                    (and:SI
17805                      (zero_extract:SI
17806                        (match_dup 2)
17807                        (const_int 8)
17808                        (const_int 8))
17809                      (match_dup 3)))])])
17811 ;; Don't do logical operations with memory inputs.
17812 (define_peephole2
17813   [(match_scratch:SI 2 "r")
17814    (parallel [(set (match_operand:SI 0 "register_operand")
17815                    (match_operator:SI 3 "arith_or_logical_operator"
17816                      [(match_dup 0)
17817                       (match_operand:SI 1 "memory_operand")]))
17818               (clobber (reg:CC FLAGS_REG))])]
17819   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17820   [(set (match_dup 2) (match_dup 1))
17821    (parallel [(set (match_dup 0)
17822                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17823               (clobber (reg:CC FLAGS_REG))])])
17825 (define_peephole2
17826   [(match_scratch:SI 2 "r")
17827    (parallel [(set (match_operand:SI 0 "register_operand")
17828                    (match_operator:SI 3 "arith_or_logical_operator"
17829                      [(match_operand:SI 1 "memory_operand")
17830                       (match_dup 0)]))
17831               (clobber (reg:CC FLAGS_REG))])]
17832   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17833   [(set (match_dup 2) (match_dup 1))
17834    (parallel [(set (match_dup 0)
17835                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17836               (clobber (reg:CC FLAGS_REG))])])
17838 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17839 ;; refers to the destination of the load!
17841 (define_peephole2
17842   [(set (match_operand:SI 0 "register_operand")
17843         (match_operand:SI 1 "register_operand"))
17844    (parallel [(set (match_dup 0)
17845                    (match_operator:SI 3 "commutative_operator"
17846                      [(match_dup 0)
17847                       (match_operand:SI 2 "memory_operand")]))
17848               (clobber (reg:CC FLAGS_REG))])]
17849   "REGNO (operands[0]) != REGNO (operands[1])
17850    && GENERAL_REGNO_P (REGNO (operands[0]))
17851    && GENERAL_REGNO_P (REGNO (operands[1]))"
17852   [(set (match_dup 0) (match_dup 4))
17853    (parallel [(set (match_dup 0)
17854                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17855               (clobber (reg:CC FLAGS_REG))])]
17856   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17858 (define_peephole2
17859   [(set (match_operand 0 "register_operand")
17860         (match_operand 1 "register_operand"))
17861    (set (match_dup 0)
17862                    (match_operator 3 "commutative_operator"
17863                      [(match_dup 0)
17864                       (match_operand 2 "memory_operand")]))]
17865   "REGNO (operands[0]) != REGNO (operands[1])
17866    && ((MMX_REGNO_P (REGNO (operands[0]))
17867         && MMX_REGNO_P (REGNO (operands[1]))) 
17868        || (SSE_REGNO_P (REGNO (operands[0]))
17869            && SSE_REGNO_P (REGNO (operands[1]))))"
17870   [(set (match_dup 0) (match_dup 2))
17871    (set (match_dup 0)
17872         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17874 ; Don't do logical operations with memory outputs
17876 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17877 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17878 ; the same decoder scheduling characteristics as the original.
17880 (define_peephole2
17881   [(match_scratch:SI 2 "r")
17882    (parallel [(set (match_operand:SI 0 "memory_operand")
17883                    (match_operator:SI 3 "arith_or_logical_operator"
17884                      [(match_dup 0)
17885                       (match_operand:SI 1 "nonmemory_operand")]))
17886               (clobber (reg:CC FLAGS_REG))])]
17887   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17888    /* Do not split stack checking probes.  */
17889    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17890   [(set (match_dup 2) (match_dup 0))
17891    (parallel [(set (match_dup 2)
17892                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17893               (clobber (reg:CC FLAGS_REG))])
17894    (set (match_dup 0) (match_dup 2))])
17896 (define_peephole2
17897   [(match_scratch:SI 2 "r")
17898    (parallel [(set (match_operand:SI 0 "memory_operand")
17899                    (match_operator:SI 3 "arith_or_logical_operator"
17900                      [(match_operand:SI 1 "nonmemory_operand")
17901                       (match_dup 0)]))
17902               (clobber (reg:CC FLAGS_REG))])]
17903   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17904    /* Do not split stack checking probes.  */
17905    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17906   [(set (match_dup 2) (match_dup 0))
17907    (parallel [(set (match_dup 2)
17908                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17909               (clobber (reg:CC FLAGS_REG))])
17910    (set (match_dup 0) (match_dup 2))])
17912 ;; Attempt to use arith or logical operations with memory outputs with
17913 ;; setting of flags.
17914 (define_peephole2
17915   [(set (match_operand:SWI 0 "register_operand")
17916         (match_operand:SWI 1 "memory_operand"))
17917    (parallel [(set (match_dup 0)
17918                    (match_operator:SWI 3 "plusminuslogic_operator"
17919                      [(match_dup 0)
17920                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17921               (clobber (reg:CC FLAGS_REG))])
17922    (set (match_dup 1) (match_dup 0))
17923    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17924   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17925    && peep2_reg_dead_p (4, operands[0])
17926    && !reg_overlap_mentioned_p (operands[0], operands[1])
17927    && !reg_overlap_mentioned_p (operands[0], operands[2])
17928    && (<MODE>mode != QImode
17929        || immediate_operand (operands[2], QImode)
17930        || any_QIreg_operand (operands[2], QImode))
17931    && ix86_match_ccmode (peep2_next_insn (3),
17932                          (GET_CODE (operands[3]) == PLUS
17933                           || GET_CODE (operands[3]) == MINUS)
17934                          ? CCGOCmode : CCNOmode)"
17935   [(parallel [(set (match_dup 4) (match_dup 5))
17936               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17937                                                   (match_dup 2)]))])]
17939   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17940   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17941                                 copy_rtx (operands[1]),
17942                                 copy_rtx (operands[2]));
17943   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17944                                  operands[5], const0_rtx);
17947 (define_peephole2
17948   [(parallel [(set (match_operand:SWI 0 "register_operand")
17949                    (match_operator:SWI 2 "plusminuslogic_operator"
17950                      [(match_dup 0)
17951                       (match_operand:SWI 1 "memory_operand")]))
17952               (clobber (reg:CC FLAGS_REG))])
17953    (set (match_dup 1) (match_dup 0))
17954    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17955   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17956    && GET_CODE (operands[2]) != MINUS
17957    && peep2_reg_dead_p (3, operands[0])
17958    && !reg_overlap_mentioned_p (operands[0], operands[1])
17959    && ix86_match_ccmode (peep2_next_insn (2),
17960                          GET_CODE (operands[2]) == PLUS
17961                          ? CCGOCmode : CCNOmode)"
17962   [(parallel [(set (match_dup 3) (match_dup 4))
17963               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17964                                                   (match_dup 0)]))])]
17966   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17967   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17968                                 copy_rtx (operands[1]),
17969                                 copy_rtx (operands[0]));
17970   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17971                                  operands[4], const0_rtx);
17974 (define_peephole2
17975   [(set (match_operand:SWI12 0 "register_operand")
17976         (match_operand:SWI12 1 "memory_operand"))
17977    (parallel [(set (match_operand:SI 4 "register_operand")
17978                    (match_operator:SI 3 "plusminuslogic_operator"
17979                      [(match_dup 4)
17980                       (match_operand:SI 2 "nonmemory_operand")]))
17981               (clobber (reg:CC FLAGS_REG))])
17982    (set (match_dup 1) (match_dup 0))
17983    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17984   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17985    && REG_P (operands[0]) && REG_P (operands[4])
17986    && REGNO (operands[0]) == REGNO (operands[4])
17987    && peep2_reg_dead_p (4, operands[0])
17988    && (<MODE>mode != QImode
17989        || immediate_operand (operands[2], SImode)
17990        || any_QIreg_operand (operands[2], SImode))
17991    && !reg_overlap_mentioned_p (operands[0], operands[1])
17992    && !reg_overlap_mentioned_p (operands[0], operands[2])
17993    && ix86_match_ccmode (peep2_next_insn (3),
17994                          (GET_CODE (operands[3]) == PLUS
17995                           || GET_CODE (operands[3]) == MINUS)
17996                          ? CCGOCmode : CCNOmode)"
17997   [(parallel [(set (match_dup 4) (match_dup 5))
17998               (set (match_dup 1) (match_dup 6))])]
18000   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
18001   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18002   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18003                                 copy_rtx (operands[1]), operands[2]);
18004   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
18005                                  operands[5], const0_rtx);
18006   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18007                                 copy_rtx (operands[1]),
18008                                 copy_rtx (operands[2]));
18011 ;; Attempt to always use XOR for zeroing registers.
18012 (define_peephole2
18013   [(set (match_operand 0 "register_operand")
18014         (match_operand 1 "const0_operand"))]
18015   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18016    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18017    && GENERAL_REGNO_P (REGNO (operands[0]))
18018    && peep2_regno_dead_p (0, FLAGS_REG)"
18019   [(parallel [(set (match_dup 0) (const_int 0))
18020               (clobber (reg:CC FLAGS_REG))])]
18021   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18023 (define_peephole2
18024   [(set (strict_low_part (match_operand 0 "register_operand"))
18025         (const_int 0))]
18026   "(GET_MODE (operands[0]) == QImode
18027     || GET_MODE (operands[0]) == HImode)
18028    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18029    && peep2_regno_dead_p (0, FLAGS_REG)"
18030   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18031               (clobber (reg:CC FLAGS_REG))])])
18033 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18034 (define_peephole2
18035   [(set (match_operand:SWI248 0 "register_operand")
18036         (const_int -1))]
18037   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
18038    && GENERAL_REGNO_P (REGNO (operands[0]))
18039    && peep2_regno_dead_p (0, FLAGS_REG)"
18040   [(parallel [(set (match_dup 0) (const_int -1))
18041               (clobber (reg:CC FLAGS_REG))])]
18043   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18044     operands[0] = gen_lowpart (SImode, operands[0]);
18047 ;; Attempt to convert simple lea to add/shift.
18048 ;; These can be created by move expanders.
18049 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18050 ;; relevant lea instructions were already split.
18052 (define_peephole2
18053   [(set (match_operand:SWI48 0 "register_operand")
18054         (plus:SWI48 (match_dup 0)
18055                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18056   "!TARGET_OPT_AGU
18057    && peep2_regno_dead_p (0, FLAGS_REG)"
18058   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18059               (clobber (reg:CC FLAGS_REG))])])
18061 (define_peephole2
18062   [(set (match_operand:SWI48 0 "register_operand")
18063         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18064                     (match_dup 0)))]
18065   "!TARGET_OPT_AGU
18066    && peep2_regno_dead_p (0, FLAGS_REG)"
18067   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18068               (clobber (reg:CC FLAGS_REG))])])
18070 (define_peephole2
18071   [(set (match_operand:DI 0 "register_operand")
18072         (zero_extend:DI
18073           (plus:SI (match_operand:SI 1 "register_operand")
18074                    (match_operand:SI 2 "nonmemory_operand"))))]
18075   "TARGET_64BIT && !TARGET_OPT_AGU
18076    && REGNO (operands[0]) == REGNO (operands[1])
18077    && peep2_regno_dead_p (0, FLAGS_REG)"
18078   [(parallel [(set (match_dup 0)
18079                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18080               (clobber (reg:CC FLAGS_REG))])])
18082 (define_peephole2
18083   [(set (match_operand:DI 0 "register_operand")
18084         (zero_extend:DI
18085           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18086                    (match_operand:SI 2 "register_operand"))))]
18087   "TARGET_64BIT && !TARGET_OPT_AGU
18088    && REGNO (operands[0]) == REGNO (operands[2])
18089    && peep2_regno_dead_p (0, FLAGS_REG)"
18090   [(parallel [(set (match_dup 0)
18091                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18092               (clobber (reg:CC FLAGS_REG))])])
18094 (define_peephole2
18095   [(set (match_operand:SWI48 0 "register_operand")
18096         (mult:SWI48 (match_dup 0)
18097                     (match_operand:SWI48 1 "const_int_operand")))]
18098   "exact_log2 (INTVAL (operands[1])) >= 0
18099    && peep2_regno_dead_p (0, FLAGS_REG)"
18100   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18101               (clobber (reg:CC FLAGS_REG))])]
18102   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18104 (define_peephole2
18105   [(set (match_operand:DI 0 "register_operand")
18106         (zero_extend:DI
18107           (mult:SI (match_operand:SI 1 "register_operand")
18108                    (match_operand:SI 2 "const_int_operand"))))]
18109   "TARGET_64BIT
18110    && exact_log2 (INTVAL (operands[2])) >= 0
18111    && REGNO (operands[0]) == REGNO (operands[1])
18112    && peep2_regno_dead_p (0, FLAGS_REG)"
18113   [(parallel [(set (match_dup 0)
18114                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18115               (clobber (reg:CC FLAGS_REG))])]
18116   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18118 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18119 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18120 ;; On many CPUs it is also faster, since special hardware to avoid esp
18121 ;; dependencies is present.
18123 ;; While some of these conversions may be done using splitters, we use
18124 ;; peepholes in order to allow combine_stack_adjustments pass to see
18125 ;; nonobfuscated RTL.
18127 ;; Convert prologue esp subtractions to push.
18128 ;; We need register to push.  In order to keep verify_flow_info happy we have
18129 ;; two choices
18130 ;; - use scratch and clobber it in order to avoid dependencies
18131 ;; - use already live register
18132 ;; We can't use the second way right now, since there is no reliable way how to
18133 ;; verify that given register is live.  First choice will also most likely in
18134 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18135 ;; call clobbered registers are dead.  We may want to use base pointer as an
18136 ;; alternative when no register is available later.
18138 (define_peephole2
18139   [(match_scratch:W 1 "r")
18140    (parallel [(set (reg:P SP_REG)
18141                    (plus:P (reg:P SP_REG)
18142                            (match_operand:P 0 "const_int_operand")))
18143               (clobber (reg:CC FLAGS_REG))
18144               (clobber (mem:BLK (scratch)))])]
18145   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18146    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
18147   [(clobber (match_dup 1))
18148    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18149               (clobber (mem:BLK (scratch)))])])
18151 (define_peephole2
18152   [(match_scratch:W 1 "r")
18153    (parallel [(set (reg:P SP_REG)
18154                    (plus:P (reg:P SP_REG)
18155                            (match_operand:P 0 "const_int_operand")))
18156               (clobber (reg:CC FLAGS_REG))
18157               (clobber (mem:BLK (scratch)))])]
18158   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18159    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
18160   [(clobber (match_dup 1))
18161    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18162    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18163               (clobber (mem:BLK (scratch)))])])
18165 ;; Convert esp subtractions to push.
18166 (define_peephole2
18167   [(match_scratch:W 1 "r")
18168    (parallel [(set (reg:P SP_REG)
18169                    (plus:P (reg:P SP_REG)
18170                            (match_operand:P 0 "const_int_operand")))
18171               (clobber (reg:CC FLAGS_REG))])]
18172   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18173    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
18174   [(clobber (match_dup 1))
18175    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18177 (define_peephole2
18178   [(match_scratch:W 1 "r")
18179    (parallel [(set (reg:P SP_REG)
18180                    (plus:P (reg:P SP_REG)
18181                            (match_operand:P 0 "const_int_operand")))
18182               (clobber (reg:CC FLAGS_REG))])]
18183   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18184    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
18185   [(clobber (match_dup 1))
18186    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18187    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18189 ;; Convert epilogue deallocator to pop.
18190 (define_peephole2
18191   [(match_scratch:W 1 "r")
18192    (parallel [(set (reg:P SP_REG)
18193                    (plus:P (reg:P SP_REG)
18194                            (match_operand:P 0 "const_int_operand")))
18195               (clobber (reg:CC FLAGS_REG))
18196               (clobber (mem:BLK (scratch)))])]
18197   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18198    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18199   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18200               (clobber (mem:BLK (scratch)))])])
18202 ;; Two pops case is tricky, since pop causes dependency
18203 ;; on destination register.  We use two registers if available.
18204 (define_peephole2
18205   [(match_scratch:W 1 "r")
18206    (match_scratch:W 2 "r")
18207    (parallel [(set (reg:P SP_REG)
18208                    (plus:P (reg:P SP_REG)
18209                            (match_operand:P 0 "const_int_operand")))
18210               (clobber (reg:CC FLAGS_REG))
18211               (clobber (mem:BLK (scratch)))])]
18212   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18213    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18214   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18215               (clobber (mem:BLK (scratch)))])
18216    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18218 (define_peephole2
18219   [(match_scratch:W 1 "r")
18220    (parallel [(set (reg:P SP_REG)
18221                    (plus:P (reg:P SP_REG)
18222                            (match_operand:P 0 "const_int_operand")))
18223               (clobber (reg:CC FLAGS_REG))
18224               (clobber (mem:BLK (scratch)))])]
18225   "optimize_insn_for_size_p ()
18226    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18227   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18228               (clobber (mem:BLK (scratch)))])
18229    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18231 ;; Convert esp additions to pop.
18232 (define_peephole2
18233   [(match_scratch:W 1 "r")
18234    (parallel [(set (reg:P SP_REG)
18235                    (plus:P (reg:P SP_REG)
18236                            (match_operand:P 0 "const_int_operand")))
18237               (clobber (reg:CC FLAGS_REG))])]
18238   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18239   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18241 ;; Two pops case is tricky, since pop causes dependency
18242 ;; on destination register.  We use two registers if available.
18243 (define_peephole2
18244   [(match_scratch:W 1 "r")
18245    (match_scratch:W 2 "r")
18246    (parallel [(set (reg:P SP_REG)
18247                    (plus:P (reg:P SP_REG)
18248                            (match_operand:P 0 "const_int_operand")))
18249               (clobber (reg:CC FLAGS_REG))])]
18250   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18251   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18252    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18254 (define_peephole2
18255   [(match_scratch:W 1 "r")
18256    (parallel [(set (reg:P SP_REG)
18257                    (plus:P (reg:P SP_REG)
18258                            (match_operand:P 0 "const_int_operand")))
18259               (clobber (reg:CC FLAGS_REG))])]
18260   "optimize_insn_for_size_p ()
18261    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18262   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18263    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18265 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18266 ;; required and register dies.  Similarly for 128 to -128.
18267 (define_peephole2
18268   [(set (match_operand 0 "flags_reg_operand")
18269         (match_operator 1 "compare_operator"
18270           [(match_operand 2 "register_operand")
18271            (match_operand 3 "const_int_operand")]))]
18272   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18273      && incdec_operand (operands[3], GET_MODE (operands[3])))
18274     || (!TARGET_FUSE_CMP_AND_BRANCH
18275         && INTVAL (operands[3]) == 128))
18276    && ix86_match_ccmode (insn, CCGCmode)
18277    && peep2_reg_dead_p (1, operands[2])"
18278   [(parallel [(set (match_dup 0)
18279                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18280               (clobber (match_dup 2))])])
18282 ;; Convert imul by three, five and nine into lea
18283 (define_peephole2
18284   [(parallel
18285     [(set (match_operand:SWI48 0 "register_operand")
18286           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18287                       (match_operand:SWI48 2 "const359_operand")))
18288      (clobber (reg:CC FLAGS_REG))])]
18289   "!TARGET_PARTIAL_REG_STALL
18290    || <MODE>mode == SImode
18291    || optimize_function_for_size_p (cfun)"
18292   [(set (match_dup 0)
18293         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18294                     (match_dup 1)))]
18295   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18297 (define_peephole2
18298   [(parallel
18299     [(set (match_operand:SWI48 0 "register_operand")
18300           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18301                       (match_operand:SWI48 2 "const359_operand")))
18302      (clobber (reg:CC FLAGS_REG))])]
18303   "optimize_insn_for_speed_p ()
18304    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18305   [(set (match_dup 0) (match_dup 1))
18306    (set (match_dup 0)
18307         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18308                     (match_dup 0)))]
18309   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18311 ;; imul $32bit_imm, mem, reg is vector decoded, while
18312 ;; imul $32bit_imm, reg, reg is direct decoded.
18313 (define_peephole2
18314   [(match_scratch:SWI48 3 "r")
18315    (parallel [(set (match_operand:SWI48 0 "register_operand")
18316                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18317                                (match_operand:SWI48 2 "immediate_operand")))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18320    && !satisfies_constraint_K (operands[2])"
18321   [(set (match_dup 3) (match_dup 1))
18322    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18323               (clobber (reg:CC FLAGS_REG))])])
18325 (define_peephole2
18326   [(match_scratch:SI 3 "r")
18327    (parallel [(set (match_operand:DI 0 "register_operand")
18328                    (zero_extend:DI
18329                      (mult:SI (match_operand:SI 1 "memory_operand")
18330                               (match_operand:SI 2 "immediate_operand"))))
18331               (clobber (reg:CC FLAGS_REG))])]
18332   "TARGET_64BIT
18333    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18334    && !satisfies_constraint_K (operands[2])"
18335   [(set (match_dup 3) (match_dup 1))
18336    (parallel [(set (match_dup 0)
18337                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18338               (clobber (reg:CC FLAGS_REG))])])
18340 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18341 ;; Convert it into imul reg, reg
18342 ;; It would be better to force assembler to encode instruction using long
18343 ;; immediate, but there is apparently no way to do so.
18344 (define_peephole2
18345   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18346                    (mult:SWI248
18347                     (match_operand:SWI248 1 "nonimmediate_operand")
18348                     (match_operand:SWI248 2 "const_int_operand")))
18349               (clobber (reg:CC FLAGS_REG))])
18350    (match_scratch:SWI248 3 "r")]
18351   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18352    && satisfies_constraint_K (operands[2])"
18353   [(set (match_dup 3) (match_dup 2))
18354    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18355               (clobber (reg:CC FLAGS_REG))])]
18357   if (!rtx_equal_p (operands[0], operands[1]))
18358     emit_move_insn (operands[0], operands[1]);
18361 ;; After splitting up read-modify operations, array accesses with memory
18362 ;; operands might end up in form:
18363 ;;  sall    $2, %eax
18364 ;;  movl    4(%esp), %edx
18365 ;;  addl    %edx, %eax
18366 ;; instead of pre-splitting:
18367 ;;  sall    $2, %eax
18368 ;;  addl    4(%esp), %eax
18369 ;; Turn it into:
18370 ;;  movl    4(%esp), %edx
18371 ;;  leal    (%edx,%eax,4), %eax
18373 (define_peephole2
18374   [(match_scratch:W 5 "r")
18375    (parallel [(set (match_operand 0 "register_operand")
18376                    (ashift (match_operand 1 "register_operand")
18377                            (match_operand 2 "const_int_operand")))
18378                (clobber (reg:CC FLAGS_REG))])
18379    (parallel [(set (match_operand 3 "register_operand")
18380                    (plus (match_dup 0)
18381                          (match_operand 4 "x86_64_general_operand")))
18382                    (clobber (reg:CC FLAGS_REG))])]
18383   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18384    /* Validate MODE for lea.  */
18385    && ((!TARGET_PARTIAL_REG_STALL
18386         && (GET_MODE (operands[0]) == QImode
18387             || GET_MODE (operands[0]) == HImode))
18388        || GET_MODE (operands[0]) == SImode
18389        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18390    && (rtx_equal_p (operands[0], operands[3])
18391        || peep2_reg_dead_p (2, operands[0]))
18392    /* We reorder load and the shift.  */
18393    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18394   [(set (match_dup 5) (match_dup 4))
18395    (set (match_dup 0) (match_dup 1))]
18397   machine_mode op1mode = GET_MODE (operands[1]);
18398   machine_mode mode = op1mode == DImode ? DImode : SImode;
18399   int scale = 1 << INTVAL (operands[2]);
18400   rtx index = gen_lowpart (word_mode, operands[1]);
18401   rtx base = gen_lowpart (word_mode, operands[5]);
18402   rtx dest = gen_lowpart (mode, operands[3]);
18404   operands[1] = gen_rtx_PLUS (word_mode, base,
18405                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18406   if (mode != word_mode)
18407     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18409   operands[5] = base;
18410   if (op1mode != word_mode)
18411     operands[5] = gen_lowpart (op1mode, operands[5]);
18413   operands[0] = dest;
18416 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18417 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18418 ;; caught for use by garbage collectors and the like.  Using an insn that
18419 ;; maps to SIGILL makes it more likely the program will rightfully die.
18420 ;; Keeping with tradition, "6" is in honor of #UD.
18421 (define_insn "trap"
18422   [(trap_if (const_int 1) (const_int 6))]
18423   ""
18425 #ifdef HAVE_AS_IX86_UD2
18426   return "ud2";
18427 #else
18428   return ASM_SHORT "0x0b0f";
18429 #endif
18431   [(set_attr "length" "2")])
18433 (define_expand "prefetch"
18434   [(prefetch (match_operand 0 "address_operand")
18435              (match_operand:SI 1 "const_int_operand")
18436              (match_operand:SI 2 "const_int_operand"))]
18437   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18439   bool write = INTVAL (operands[1]) != 0;
18440   int locality = INTVAL (operands[2]);
18442   gcc_assert (IN_RANGE (locality, 0, 3));
18444   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18445      supported by SSE counterpart or the SSE prefetch is not available
18446      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18447      of locality.  */
18448   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18449     operands[2] = const2_rtx;
18450   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18451     operands[2] = GEN_INT (3);
18452   else
18453     operands[1] = const0_rtx;
18456 (define_insn "*prefetch_sse"
18457   [(prefetch (match_operand 0 "address_operand" "p")
18458              (const_int 0)
18459              (match_operand:SI 1 "const_int_operand"))]
18460   "TARGET_PREFETCH_SSE"
18462   static const char * const patterns[4] = {
18463    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18464   };
18466   int locality = INTVAL (operands[1]);
18467   gcc_assert (IN_RANGE (locality, 0, 3));
18469   return patterns[locality];
18471   [(set_attr "type" "sse")
18472    (set_attr "atom_sse_attr" "prefetch")
18473    (set (attr "length_address")
18474         (symbol_ref "memory_address_length (operands[0], false)"))
18475    (set_attr "memory" "none")])
18477 (define_insn "*prefetch_3dnow"
18478   [(prefetch (match_operand 0 "address_operand" "p")
18479              (match_operand:SI 1 "const_int_operand" "n")
18480              (const_int 3))]
18481   "TARGET_PRFCHW"
18483   if (INTVAL (operands[1]) == 0)
18484     return "prefetch\t%a0";
18485   else
18486     return "prefetchw\t%a0";
18488   [(set_attr "type" "mmx")
18489    (set (attr "length_address")
18490         (symbol_ref "memory_address_length (operands[0], false)"))
18491    (set_attr "memory" "none")])
18493 (define_insn "*prefetch_prefetchwt1"
18494   [(prefetch (match_operand 0 "address_operand" "p")
18495              (const_int 1)
18496              (const_int 2))]
18497   "TARGET_PREFETCHWT1"
18498   "prefetchwt1\t%a0";
18499   [(set_attr "type" "sse")
18500    (set (attr "length_address")
18501         (symbol_ref "memory_address_length (operands[0], false)"))
18502    (set_attr "memory" "none")])
18504 (define_expand "stack_protect_set"
18505   [(match_operand 0 "memory_operand")
18506    (match_operand 1 "memory_operand")]
18507   "TARGET_SSP_TLS_GUARD"
18509   rtx (*insn)(rtx, rtx);
18511 #ifdef TARGET_THREAD_SSP_OFFSET
18512   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18513   insn = (TARGET_LP64
18514           ? gen_stack_tls_protect_set_di
18515           : gen_stack_tls_protect_set_si);
18516 #else
18517   insn = (TARGET_LP64
18518           ? gen_stack_protect_set_di
18519           : gen_stack_protect_set_si);
18520 #endif
18522   emit_insn (insn (operands[0], operands[1]));
18523   DONE;
18526 (define_insn "stack_protect_set_<mode>"
18527   [(set (match_operand:PTR 0 "memory_operand" "=m")
18528         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18529                     UNSPEC_SP_SET))
18530    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18531    (clobber (reg:CC FLAGS_REG))]
18532   "TARGET_SSP_TLS_GUARD"
18533   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18534   [(set_attr "type" "multi")])
18536 (define_insn "stack_tls_protect_set_<mode>"
18537   [(set (match_operand:PTR 0 "memory_operand" "=m")
18538         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18539                     UNSPEC_SP_TLS_SET))
18540    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18541    (clobber (reg:CC FLAGS_REG))]
18542   ""
18543   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18544   [(set_attr "type" "multi")])
18546 (define_expand "stack_protect_test"
18547   [(match_operand 0 "memory_operand")
18548    (match_operand 1 "memory_operand")
18549    (match_operand 2)]
18550   "TARGET_SSP_TLS_GUARD"
18552   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18554   rtx (*insn)(rtx, rtx, rtx);
18556 #ifdef TARGET_THREAD_SSP_OFFSET
18557   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18558   insn = (TARGET_LP64
18559           ? gen_stack_tls_protect_test_di
18560           : gen_stack_tls_protect_test_si);
18561 #else
18562   insn = (TARGET_LP64
18563           ? gen_stack_protect_test_di
18564           : gen_stack_protect_test_si);
18565 #endif
18567   emit_insn (insn (flags, operands[0], operands[1]));
18569   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18570                                   flags, const0_rtx, operands[2]));
18571   DONE;
18574 (define_insn "stack_protect_test_<mode>"
18575   [(set (match_operand:CCZ 0 "flags_reg_operand")
18576         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18577                      (match_operand:PTR 2 "memory_operand" "m")]
18578                     UNSPEC_SP_TEST))
18579    (clobber (match_scratch:PTR 3 "=&r"))]
18580   "TARGET_SSP_TLS_GUARD"
18581   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18582   [(set_attr "type" "multi")])
18584 (define_insn "stack_tls_protect_test_<mode>"
18585   [(set (match_operand:CCZ 0 "flags_reg_operand")
18586         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18587                      (match_operand:PTR 2 "const_int_operand" "i")]
18588                     UNSPEC_SP_TLS_TEST))
18589    (clobber (match_scratch:PTR 3 "=r"))]
18590   ""
18591   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18592   [(set_attr "type" "multi")])
18594 (define_insn "sse4_2_crc32<mode>"
18595   [(set (match_operand:SI 0 "register_operand" "=r")
18596         (unspec:SI
18597           [(match_operand:SI 1 "register_operand" "0")
18598            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18599           UNSPEC_CRC32))]
18600   "TARGET_SSE4_2 || TARGET_CRC32"
18601   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18602   [(set_attr "type" "sselog1")
18603    (set_attr "prefix_rep" "1")
18604    (set_attr "prefix_extra" "1")
18605    (set (attr "prefix_data16")
18606      (if_then_else (match_operand:HI 2)
18607        (const_string "1")
18608        (const_string "*")))
18609    (set (attr "prefix_rex")
18610      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18611        (const_string "1")
18612        (const_string "*")))
18613    (set_attr "mode" "SI")])
18615 (define_insn "sse4_2_crc32di"
18616   [(set (match_operand:DI 0 "register_operand" "=r")
18617         (unspec:DI
18618           [(match_operand:DI 1 "register_operand" "0")
18619            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18620           UNSPEC_CRC32))]
18621   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18622   "crc32{q}\t{%2, %0|%0, %2}"
18623   [(set_attr "type" "sselog1")
18624    (set_attr "prefix_rep" "1")
18625    (set_attr "prefix_extra" "1")
18626    (set_attr "mode" "DI")])
18628 (define_insn "rdpmc"
18629   [(set (match_operand:DI 0 "register_operand" "=A")
18630         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18631                             UNSPECV_RDPMC))]
18632   "!TARGET_64BIT"
18633   "rdpmc"
18634   [(set_attr "type" "other")
18635    (set_attr "length" "2")])
18637 (define_insn "rdpmc_rex64"
18638   [(set (match_operand:DI 0 "register_operand" "=a")
18639         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18640                             UNSPECV_RDPMC))
18641    (set (match_operand:DI 1 "register_operand" "=d")
18642         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18643   "TARGET_64BIT"
18644   "rdpmc"
18645   [(set_attr "type" "other")
18646    (set_attr "length" "2")])
18648 (define_insn "rdtsc"
18649   [(set (match_operand:DI 0 "register_operand" "=A")
18650         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18651   "!TARGET_64BIT"
18652   "rdtsc"
18653   [(set_attr "type" "other")
18654    (set_attr "length" "2")])
18656 (define_insn "rdtsc_rex64"
18657   [(set (match_operand:DI 0 "register_operand" "=a")
18658         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18659    (set (match_operand:DI 1 "register_operand" "=d")
18660         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18661   "TARGET_64BIT"
18662   "rdtsc"
18663   [(set_attr "type" "other")
18664    (set_attr "length" "2")])
18666 (define_insn "rdtscp"
18667   [(set (match_operand:DI 0 "register_operand" "=A")
18668         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18669    (set (match_operand:SI 1 "register_operand" "=c")
18670         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18671   "!TARGET_64BIT"
18672   "rdtscp"
18673   [(set_attr "type" "other")
18674    (set_attr "length" "3")])
18676 (define_insn "rdtscp_rex64"
18677   [(set (match_operand:DI 0 "register_operand" "=a")
18678         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18679    (set (match_operand:DI 1 "register_operand" "=d")
18680         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18681    (set (match_operand:SI 2 "register_operand" "=c")
18682         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18683   "TARGET_64BIT"
18684   "rdtscp"
18685   [(set_attr "type" "other")
18686    (set_attr "length" "3")])
18688 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18690 ;; FXSR, XSAVE and XSAVEOPT instructions
18692 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18694 (define_insn "fxsave"
18695   [(set (match_operand:BLK 0 "memory_operand" "=m")
18696         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18697   "TARGET_FXSR"
18698   "fxsave\t%0"
18699   [(set_attr "type" "other")
18700    (set_attr "memory" "store")
18701    (set (attr "length")
18702         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18704 (define_insn "fxsave64"
18705   [(set (match_operand:BLK 0 "memory_operand" "=m")
18706         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18707   "TARGET_64BIT && TARGET_FXSR"
18708   "fxsave64\t%0"
18709   [(set_attr "type" "other")
18710    (set_attr "memory" "store")
18711    (set (attr "length")
18712         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18714 (define_insn "fxrstor"
18715   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18716                     UNSPECV_FXRSTOR)]
18717   "TARGET_FXSR"
18718   "fxrstor\t%0"
18719   [(set_attr "type" "other")
18720    (set_attr "memory" "load")
18721    (set (attr "length")
18722         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18724 (define_insn "fxrstor64"
18725   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18726                     UNSPECV_FXRSTOR64)]
18727   "TARGET_64BIT && TARGET_FXSR"
18728   "fxrstor64\t%0"
18729   [(set_attr "type" "other")
18730    (set_attr "memory" "load")
18731    (set (attr "length")
18732         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18734 (define_int_iterator ANY_XSAVE
18735         [UNSPECV_XSAVE
18736          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18737          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18738          (UNSPECV_XSAVES "TARGET_XSAVES")])
18740 (define_int_iterator ANY_XSAVE64
18741         [UNSPECV_XSAVE64
18742          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18743          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18744          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18746 (define_int_attr xsave
18747         [(UNSPECV_XSAVE "xsave")
18748          (UNSPECV_XSAVE64 "xsave64")
18749          (UNSPECV_XSAVEOPT "xsaveopt")
18750          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18751          (UNSPECV_XSAVEC "xsavec")
18752          (UNSPECV_XSAVEC64 "xsavec64")
18753          (UNSPECV_XSAVES "xsaves")
18754          (UNSPECV_XSAVES64 "xsaves64")])
18756 (define_int_iterator ANY_XRSTOR
18757         [UNSPECV_XRSTOR
18758          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18760 (define_int_iterator ANY_XRSTOR64
18761         [UNSPECV_XRSTOR64
18762          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18764 (define_int_attr xrstor
18765         [(UNSPECV_XRSTOR "xrstor")
18766          (UNSPECV_XRSTOR64 "xrstor")
18767          (UNSPECV_XRSTORS "xrstors")
18768          (UNSPECV_XRSTORS64 "xrstors")])
18770 (define_insn "<xsave>"
18771   [(set (match_operand:BLK 0 "memory_operand" "=m")
18772         (unspec_volatile:BLK
18773          [(match_operand:DI 1 "register_operand" "A")]
18774          ANY_XSAVE))]
18775   "!TARGET_64BIT && TARGET_XSAVE"
18776   "<xsave>\t%0"
18777   [(set_attr "type" "other")
18778    (set_attr "memory" "store")
18779    (set (attr "length")
18780         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18782 (define_insn "<xsave>_rex64"
18783   [(set (match_operand:BLK 0 "memory_operand" "=m")
18784         (unspec_volatile:BLK
18785          [(match_operand:SI 1 "register_operand" "a")
18786           (match_operand:SI 2 "register_operand" "d")]
18787          ANY_XSAVE))]
18788   "TARGET_64BIT && TARGET_XSAVE"
18789   "<xsave>\t%0"
18790   [(set_attr "type" "other")
18791    (set_attr "memory" "store")
18792    (set (attr "length")
18793         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18795 (define_insn "<xsave>"
18796   [(set (match_operand:BLK 0 "memory_operand" "=m")
18797         (unspec_volatile:BLK
18798          [(match_operand:SI 1 "register_operand" "a")
18799           (match_operand:SI 2 "register_operand" "d")]
18800          ANY_XSAVE64))]
18801   "TARGET_64BIT && TARGET_XSAVE"
18802   "<xsave>\t%0"
18803   [(set_attr "type" "other")
18804    (set_attr "memory" "store")
18805    (set (attr "length")
18806         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18808 (define_insn "<xrstor>"
18809    [(unspec_volatile:BLK
18810      [(match_operand:BLK 0 "memory_operand" "m")
18811       (match_operand:DI 1 "register_operand" "A")]
18812      ANY_XRSTOR)]
18813   "!TARGET_64BIT && TARGET_XSAVE"
18814   "<xrstor>\t%0"
18815   [(set_attr "type" "other")
18816    (set_attr "memory" "load")
18817    (set (attr "length")
18818         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18820 (define_insn "<xrstor>_rex64"
18821    [(unspec_volatile:BLK
18822      [(match_operand:BLK 0 "memory_operand" "m")
18823       (match_operand:SI 1 "register_operand" "a")
18824       (match_operand:SI 2 "register_operand" "d")]
18825      ANY_XRSTOR)]
18826   "TARGET_64BIT && TARGET_XSAVE"
18827   "<xrstor>\t%0"
18828   [(set_attr "type" "other")
18829    (set_attr "memory" "load")
18830    (set (attr "length")
18831         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18833 (define_insn "<xrstor>64"
18834    [(unspec_volatile:BLK
18835      [(match_operand:BLK 0 "memory_operand" "m")
18836       (match_operand:SI 1 "register_operand" "a")
18837       (match_operand:SI 2 "register_operand" "d")]
18838      ANY_XRSTOR64)]
18839   "TARGET_64BIT && TARGET_XSAVE"
18840   "<xrstor>64\t%0"
18841   [(set_attr "type" "other")
18842    (set_attr "memory" "load")
18843    (set (attr "length")
18844         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18848 ;; Floating-point instructions for atomic compound assignments
18850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18852 ; Clobber all floating-point registers on environment save and restore
18853 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18854 (define_insn "fnstenv"
18855   [(set (match_operand:BLK 0 "memory_operand" "=m")
18856         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18857    (clobber (reg:HI FPCR_REG))
18858    (clobber (reg:XF ST0_REG))
18859    (clobber (reg:XF ST1_REG))
18860    (clobber (reg:XF ST2_REG))
18861    (clobber (reg:XF ST3_REG))
18862    (clobber (reg:XF ST4_REG))
18863    (clobber (reg:XF ST5_REG))
18864    (clobber (reg:XF ST6_REG))
18865    (clobber (reg:XF ST7_REG))]
18866   "TARGET_80387"
18867   "fnstenv\t%0"
18868   [(set_attr "type" "other")
18869    (set_attr "memory" "store")
18870    (set (attr "length")
18871         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18873 (define_insn "fldenv"
18874   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18875                     UNSPECV_FLDENV)
18876    (clobber (reg:CCFP FPSR_REG))
18877    (clobber (reg:HI FPCR_REG))
18878    (clobber (reg:XF ST0_REG))
18879    (clobber (reg:XF ST1_REG))
18880    (clobber (reg:XF ST2_REG))
18881    (clobber (reg:XF ST3_REG))
18882    (clobber (reg:XF ST4_REG))
18883    (clobber (reg:XF ST5_REG))
18884    (clobber (reg:XF ST6_REG))
18885    (clobber (reg:XF ST7_REG))]
18886   "TARGET_80387"
18887   "fldenv\t%0"
18888   [(set_attr "type" "other")
18889    (set_attr "memory" "load")
18890    (set (attr "length")
18891         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18893 (define_insn "fnstsw"
18894   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18895         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18896   "TARGET_80387"
18897   "fnstsw\t%0"
18898   [(set_attr "type" "other,other")
18899    (set_attr "memory" "none,store")
18900    (set (attr "length")
18901         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18903 (define_insn "fnclex"
18904   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18905   "TARGET_80387"
18906   "fnclex"
18907   [(set_attr "type" "other")
18908    (set_attr "memory" "none")
18909    (set_attr "length" "2")])
18911 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18913 ;; LWP instructions
18915 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18917 (define_expand "lwp_llwpcb"
18918   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18919                     UNSPECV_LLWP_INTRINSIC)]
18920   "TARGET_LWP")
18922 (define_insn "*lwp_llwpcb<mode>1"
18923   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18924                     UNSPECV_LLWP_INTRINSIC)]
18925   "TARGET_LWP"
18926   "llwpcb\t%0"
18927   [(set_attr "type" "lwp")
18928    (set_attr "mode" "<MODE>")
18929    (set_attr "length" "5")])
18931 (define_expand "lwp_slwpcb"
18932   [(set (match_operand 0 "register_operand" "=r")
18933         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18934   "TARGET_LWP"
18936   rtx (*insn)(rtx);
18938   insn = (Pmode == DImode
18939           ? gen_lwp_slwpcbdi
18940           : gen_lwp_slwpcbsi);
18942   emit_insn (insn (operands[0]));
18943   DONE;
18946 (define_insn "lwp_slwpcb<mode>"
18947   [(set (match_operand:P 0 "register_operand" "=r")
18948         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18949   "TARGET_LWP"
18950   "slwpcb\t%0"
18951   [(set_attr "type" "lwp")
18952    (set_attr "mode" "<MODE>")
18953    (set_attr "length" "5")])
18955 (define_expand "lwp_lwpval<mode>3"
18956   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18957                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18958                      (match_operand:SI 3 "const_int_operand" "i")]
18959                     UNSPECV_LWPVAL_INTRINSIC)]
18960   "TARGET_LWP"
18961   ;; Avoid unused variable warning.
18962   "(void) operands[0];")
18964 (define_insn "*lwp_lwpval<mode>3_1"
18965   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18966                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18967                      (match_operand:SI 2 "const_int_operand" "i")]
18968                     UNSPECV_LWPVAL_INTRINSIC)]
18969   "TARGET_LWP"
18970   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18971   [(set_attr "type" "lwp")
18972    (set_attr "mode" "<MODE>")
18973    (set (attr "length")
18974         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18976 (define_expand "lwp_lwpins<mode>3"
18977   [(set (reg:CCC FLAGS_REG)
18978         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18979                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18980                               (match_operand:SI 3 "const_int_operand" "i")]
18981                              UNSPECV_LWPINS_INTRINSIC))
18982    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18983         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18984   "TARGET_LWP")
18986 (define_insn "*lwp_lwpins<mode>3_1"
18987   [(set (reg:CCC FLAGS_REG)
18988         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18989                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18990                               (match_operand:SI 2 "const_int_operand" "i")]
18991                              UNSPECV_LWPINS_INTRINSIC))]
18992   "TARGET_LWP"
18993   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18994   [(set_attr "type" "lwp")
18995    (set_attr "mode" "<MODE>")
18996    (set (attr "length")
18997         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18999 (define_int_iterator RDFSGSBASE
19000         [UNSPECV_RDFSBASE
19001          UNSPECV_RDGSBASE])
19003 (define_int_iterator WRFSGSBASE
19004         [UNSPECV_WRFSBASE
19005          UNSPECV_WRGSBASE])
19007 (define_int_attr fsgs
19008         [(UNSPECV_RDFSBASE "fs")
19009          (UNSPECV_RDGSBASE "gs")
19010          (UNSPECV_WRFSBASE "fs")
19011          (UNSPECV_WRGSBASE "gs")])
19013 (define_insn "rd<fsgs>base<mode>"
19014   [(set (match_operand:SWI48 0 "register_operand" "=r")
19015         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19016   "TARGET_64BIT && TARGET_FSGSBASE"
19017   "rd<fsgs>base\t%0"
19018   [(set_attr "type" "other")
19019    (set_attr "prefix_extra" "2")])
19021 (define_insn "wr<fsgs>base<mode>"
19022   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19023                     WRFSGSBASE)]
19024   "TARGET_64BIT && TARGET_FSGSBASE"
19025   "wr<fsgs>base\t%0"
19026   [(set_attr "type" "other")
19027    (set_attr "prefix_extra" "2")])
19029 (define_insn "rdrand<mode>_1"
19030   [(set (match_operand:SWI248 0 "register_operand" "=r")
19031         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19032    (set (reg:CCC FLAGS_REG)
19033         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19034   "TARGET_RDRND"
19035   "rdrand\t%0"
19036   [(set_attr "type" "other")
19037    (set_attr "prefix_extra" "1")])
19039 (define_insn "rdseed<mode>_1"
19040   [(set (match_operand:SWI248 0 "register_operand" "=r")
19041         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19042    (set (reg:CCC FLAGS_REG)
19043         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19044   "TARGET_RDSEED"
19045   "rdseed\t%0"
19046   [(set_attr "type" "other")
19047    (set_attr "prefix_extra" "1")])
19049 (define_expand "pause"
19050   [(set (match_dup 0)
19051         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19052   ""
19054   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19055   MEM_VOLATILE_P (operands[0]) = 1;
19058 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19059 ;; They have the same encoding.
19060 (define_insn "*pause"
19061   [(set (match_operand:BLK 0)
19062         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19063   ""
19064   "rep%; nop"
19065   [(set_attr "length" "2")
19066    (set_attr "memory" "unknown")])
19068 (define_expand "xbegin"
19069   [(set (match_operand:SI 0 "register_operand")
19070         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19071   "TARGET_RTM"
19073   rtx_code_label *label = gen_label_rtx ();
19075   /* xbegin is emitted as jump_insn, so reload won't be able
19076      to reload its operand.  Force the value into AX hard register.  */
19077   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19078   emit_move_insn (ax_reg, constm1_rtx);
19080   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19082   emit_label (label);
19083   LABEL_NUSES (label) = 1;
19085   emit_move_insn (operands[0], ax_reg);
19087   DONE;
19090 (define_insn "xbegin_1"
19091   [(set (pc)
19092         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19093                           (const_int 0))
19094                       (label_ref (match_operand 1))
19095                       (pc)))
19096    (set (match_operand:SI 0 "register_operand" "+a")
19097         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19098   "TARGET_RTM"
19099   "xbegin\t%l1"
19100   [(set_attr "type" "other")
19101    (set_attr "length" "6")])
19103 (define_insn "xend"
19104   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19105   "TARGET_RTM"
19106   "xend"
19107   [(set_attr "type" "other")
19108    (set_attr "length" "3")])
19110 (define_insn "xabort"
19111   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19112                     UNSPECV_XABORT)]
19113   "TARGET_RTM"
19114   "xabort\t%0"
19115   [(set_attr "type" "other")
19116    (set_attr "length" "3")])
19118 (define_expand "xtest"
19119   [(set (match_operand:QI 0 "register_operand")
19120         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19121   "TARGET_RTM"
19123   emit_insn (gen_xtest_1 ());
19125   ix86_expand_setcc (operands[0], NE,
19126                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19127   DONE;
19130 (define_insn "xtest_1"
19131   [(set (reg:CCZ FLAGS_REG)
19132         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19133   "TARGET_RTM"
19134   "xtest"
19135   [(set_attr "type" "other")
19136    (set_attr "length" "3")])
19138 (define_insn "pcommit"
19139   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19140   "TARGET_PCOMMIT"
19141   "pcommit"
19142   [(set_attr "type" "other")
19143    (set_attr "length" "4")])
19145 (define_insn "clwb"
19146   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19147                    UNSPECV_CLWB)]
19148   "TARGET_CLWB"
19149   "clwb\t%a0"
19150   [(set_attr "type" "sse")
19151    (set_attr "atom_sse_attr" "fence")
19152    (set_attr "memory" "unknown")])
19154 (define_insn "clflushopt"
19155   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19156                    UNSPECV_CLFLUSHOPT)]
19157   "TARGET_CLFLUSHOPT"
19158   "clflushopt\t%a0"
19159   [(set_attr "type" "sse")
19160    (set_attr "atom_sse_attr" "fence")
19161    (set_attr "memory" "unknown")])
19163 ;; MONITORX and MWAITX
19164 (define_insn "mwaitx"
19165   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19166                      (match_operand:SI 1 "register_operand" "a")
19167                      (match_operand:SI 2 "register_operand" "b")]
19168                    UNSPECV_MWAITX)]
19169   "TARGET_MWAITX"
19170 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19171 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19172 ;; we only need to set up 32bit registers.
19173   "mwaitx"
19174   [(set_attr "length" "3")])
19176 (define_insn "monitorx_<mode>"
19177   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19178                      (match_operand:SI 1 "register_operand" "c")
19179                      (match_operand:SI 2 "register_operand" "d")]
19180                    UNSPECV_MONITORX)]
19181   "TARGET_MWAITX"
19182 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19183 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19184 ;; zero extended to 64bit, we only need to set up 32bit registers.
19185   "%^monitorx"
19186   [(set (attr "length")
19187      (symbol_ref ("(Pmode != word_mode) + 3")))])
19189 ;; MPX instructions
19191 (define_expand "<mode>_mk"
19192   [(set (match_operand:BND 0 "register_operand")
19193         (unspec:BND
19194           [(mem:<bnd_ptr>
19195            (match_par_dup 3
19196              [(match_operand:<bnd_ptr> 1 "register_operand")
19197               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19198           UNSPEC_BNDMK))]
19199   "TARGET_MPX"
19201   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19202                                                   operands[2]),
19203                                 UNSPEC_BNDMK_ADDR);
19206 (define_insn "*<mode>_mk"
19207   [(set (match_operand:BND 0 "register_operand" "=w")
19208         (unspec:BND
19209           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19210              [(unspec:<bnd_ptr>
19211                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19212                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19213                 UNSPEC_BNDMK_ADDR)])]
19214           UNSPEC_BNDMK))]
19215   "TARGET_MPX"
19216   "bndmk\t{%3, %0|%0, %3}"
19217   [(set_attr "type" "mpxmk")])
19219 (define_expand "mov<mode>"
19220   [(set (match_operand:BND 0 "general_operand")
19221         (match_operand:BND 1 "general_operand"))]
19222   "TARGET_MPX"
19223   "ix86_expand_move (<MODE>mode, operands); DONE;")
19225 (define_insn "*mov<mode>_internal_mpx"
19226   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19227         (match_operand:BND 1 "general_operand" "wm,w"))]
19228   "TARGET_MPX"
19229   "bndmov\t{%1, %0|%0, %1}"
19230   [(set_attr "type" "mpxmov")])
19232 (define_expand "<mode>_<bndcheck>"
19233   [(parallel
19234      [(unspec
19235         [(match_operand:BND 0 "register_operand")
19236          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19237       (set (match_dup 2)
19238            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19239   "TARGET_MPX"
19241   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19242   MEM_VOLATILE_P (operands[2]) = 1;
19245 (define_insn "*<mode>_<bndcheck>"
19246   [(unspec
19247      [(match_operand:BND 0 "register_operand" "w")
19248       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19249    (set (match_operand:BLK 2 "bnd_mem_operator")
19250         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19251   "TARGET_MPX"
19252   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19253   [(set_attr "type" "mpxchk")])
19255 (define_expand "<mode>_ldx"
19256   [(parallel
19257      [(set (match_operand:BND 0 "register_operand")
19258            (unspec:BND
19259              [(mem:<bnd_ptr>
19260                 (match_par_dup 3
19261                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19262                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
19263              UNSPEC_BNDLDX))
19264       (use (mem:BLK (match_dup 1)))])]
19265   "TARGET_MPX"
19267   /* Avoid registers which cannot be used as index.  */
19268   if (!index_register_operand (operands[2], Pmode))
19269     operands[2] = copy_addr_to_reg (operands[2]);
19271   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19272                                                   operands[2]),
19273                                 UNSPEC_BNDLDX_ADDR);
19276 (define_insn "*<mode>_ldx"
19277   [(set (match_operand:BND 0 "register_operand" "=w")
19278         (unspec:BND
19279           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19280              [(unspec:<bnd_ptr>
19281                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19282                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19283                 UNSPEC_BNDLDX_ADDR)])]
19284           UNSPEC_BNDLDX))
19285    (use (mem:BLK (match_dup 1)))]
19286   "TARGET_MPX"
19287   "bndldx\t{%3, %0|%0, %3}"
19288   [(set_attr "type" "mpxld")])
19290 (define_expand "<mode>_stx"
19291   [(parallel
19292      [(unspec
19293         [(mem:<bnd_ptr>
19294            (match_par_dup 3
19295              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19296               (match_operand:<bnd_ptr> 1 "register_operand")]))
19297          (match_operand:BND 2 "register_operand")]
19298         UNSPEC_BNDSTX)
19299       (set (match_dup 4)
19300            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19301   "TARGET_MPX"
19303   /* Avoid registers which cannot be used as index.  */
19304   if (!index_register_operand (operands[1], Pmode))
19305     operands[1] = copy_addr_to_reg (operands[1]);
19307   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19308                                                   operands[1]),
19309                                 UNSPEC_BNDLDX_ADDR);
19310   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19311   MEM_VOLATILE_P (operands[4]) = 1;
19314 (define_insn "*<mode>_stx"
19315   [(unspec
19316      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19317         [(unspec:<bnd_ptr>
19318            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19319             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19320            UNSPEC_BNDLDX_ADDR)])
19321          (match_operand:BND 2 "register_operand" "w")]
19322         UNSPEC_BNDSTX)
19323    (set (match_operand:BLK 4 "bnd_mem_operator")
19324         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19325   "TARGET_MPX"
19326   "bndstx\t{%2, %3|%3, %2}"
19327   [(set_attr "type" "mpxst")])
19329 (define_insn "move_size_reloc_<mode>"
19330   [(set (match_operand:SWI48 0 "register_operand" "=r")
19331         (unspec:SWI48
19332           [(match_operand:SWI48 1 "symbol_operand")]
19333         UNSPEC_SIZEOF))]
19334   "TARGET_MPX"
19336   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19337     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19338   else
19339     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19341   [(set_attr "type" "imov")
19342    (set_attr "mode" "<MODE>")])
19344 (include "mmx.md")
19345 (include "sse.md")
19346 (include "sync.md")