PR target/66866
[official-gcc.git] / gcc / config / i386 / i386.md
blob2b3b6e98f65baaa7397cb1f0df69fbff81a436fe
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
115   UNSPEC_PEEPSIB
116   UNSPEC_INSN_FALSE_DEP
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For BMI support
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; For AVX512F support
186   UNSPEC_KMOV
188   UNSPEC_BNDMK
189   UNSPEC_BNDMK_ADDR
190   UNSPEC_BNDSTX
191   UNSPEC_BNDLDX
192   UNSPEC_BNDLDX_ADDR
193   UNSPEC_BNDCL
194   UNSPEC_BNDCU
195   UNSPEC_BNDCN
196   UNSPEC_MPX_FENCE
199 (define_c_enum "unspecv" [
200   UNSPECV_BLOCKAGE
201   UNSPECV_STACK_PROBE
202   UNSPECV_PROBE_STACK_RANGE
203   UNSPECV_ALIGN
204   UNSPECV_PROLOGUE_USE
205   UNSPECV_SPLIT_STACK_RETURN
206   UNSPECV_CLD
207   UNSPECV_NOPS
208   UNSPECV_RDTSC
209   UNSPECV_RDTSCP
210   UNSPECV_RDPMC
211   UNSPECV_LLWP_INTRINSIC
212   UNSPECV_SLWP_INTRINSIC
213   UNSPECV_LWPVAL_INTRINSIC
214   UNSPECV_LWPINS_INTRINSIC
215   UNSPECV_RDFSBASE
216   UNSPECV_RDGSBASE
217   UNSPECV_WRFSBASE
218   UNSPECV_WRGSBASE
219   UNSPECV_FXSAVE
220   UNSPECV_FXRSTOR
221   UNSPECV_FXSAVE64
222   UNSPECV_FXRSTOR64
223   UNSPECV_XSAVE
224   UNSPECV_XRSTOR
225   UNSPECV_XSAVE64
226   UNSPECV_XRSTOR64
227   UNSPECV_XSAVEOPT
228   UNSPECV_XSAVEOPT64
229   UNSPECV_XSAVES
230   UNSPECV_XRSTORS
231   UNSPECV_XSAVES64
232   UNSPECV_XRSTORS64
233   UNSPECV_XSAVEC
234   UNSPECV_XSAVEC64
236   ;; For atomic compound assignments.
237   UNSPECV_FNSTENV
238   UNSPECV_FLDENV
239   UNSPECV_FNSTSW
240   UNSPECV_FNCLEX
242   ;; For RDRAND support
243   UNSPECV_RDRAND
245   ;; For RDSEED support
246   UNSPECV_RDSEED
248   ;; For RTM support
249   UNSPECV_XBEGIN
250   UNSPECV_XEND
251   UNSPECV_XABORT
252   UNSPECV_XTEST
254   UNSPECV_NLGR
256   ;; For CLWB support
257   UNSPECV_CLWB
259   ;; For PCOMMIT support
260   UNSPECV_PCOMMIT
262   ;; For CLFLUSHOPT support
263   UNSPECV_CLFLUSHOPT
265   ;; For MONITORX and MWAITX support 
266   UNSPECV_MONITORX
267   UNSPECV_MWAITX
271 ;; Constants to represent rounding modes in the ROUND instruction
272 (define_constants
273   [(ROUND_FLOOR                 0x1)
274    (ROUND_CEIL                  0x2)
275    (ROUND_TRUNC                 0x3)
276    (ROUND_MXCSR                 0x4)
277    (ROUND_NO_EXC                0x8)
278   ])
280 ;; Constants to represent AVX512F embeded rounding
281 (define_constants
282   [(ROUND_NEAREST_INT                   0)
283    (ROUND_NEG_INF                       1)
284    (ROUND_POS_INF                       2)
285    (ROUND_ZERO                          3)
286    (NO_ROUND                            4)
287    (ROUND_SAE                           8)
288   ])
290 ;; Constants to represent pcomtrue/pcomfalse variants
291 (define_constants
292   [(PCOM_FALSE                  0)
293    (PCOM_TRUE                   1)
294    (COM_FALSE_S                 2)
295    (COM_FALSE_P                 3)
296    (COM_TRUE_S                  4)
297    (COM_TRUE_P                  5)
298   ])
300 ;; Constants used in the XOP pperm instruction
301 (define_constants
302   [(PPERM_SRC                   0x00)   /* copy source */
303    (PPERM_INVERT                0x20)   /* invert source */
304    (PPERM_REVERSE               0x40)   /* bit reverse source */
305    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
306    (PPERM_ZERO                  0x80)   /* all 0's */
307    (PPERM_ONES                  0xa0)   /* all 1's */
308    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
309    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
310    (PPERM_SRC1                  0x00)   /* use first source byte */
311    (PPERM_SRC2                  0x10)   /* use second source byte */
312    ])
314 ;; Registers by name.
315 (define_constants
316   [(AX_REG                       0)
317    (DX_REG                       1)
318    (CX_REG                       2)
319    (BX_REG                       3)
320    (SI_REG                       4)
321    (DI_REG                       5)
322    (BP_REG                       6)
323    (SP_REG                       7)
324    (ST0_REG                      8)
325    (ST1_REG                      9)
326    (ST2_REG                     10)
327    (ST3_REG                     11)
328    (ST4_REG                     12)
329    (ST5_REG                     13)
330    (ST6_REG                     14)
331    (ST7_REG                     15)
332    (ARGP_REG                    16)
333    (FLAGS_REG                   17)
334    (FPSR_REG                    18)
335    (FPCR_REG                    19)
336    (FRAME_REG                   20)
337    (XMM0_REG                    21)
338    (XMM1_REG                    22)
339    (XMM2_REG                    23)
340    (XMM3_REG                    24)
341    (XMM4_REG                    25)
342    (XMM5_REG                    26)
343    (XMM6_REG                    27)
344    (XMM7_REG                    28)
345    (MM0_REG                     29)
346    (MM1_REG                     30)
347    (MM2_REG                     31)
348    (MM3_REG                     32)
349    (MM4_REG                     33)
350    (MM5_REG                     34)
351    (MM6_REG                     35)
352    (MM7_REG                     36)
353    (R8_REG                      37)
354    (R9_REG                      38)
355    (R10_REG                     39)
356    (R11_REG                     40)
357    (R12_REG                     41)
358    (R13_REG                     42)
359    (R14_REG                     43)
360    (R15_REG                     44)
361    (XMM8_REG                    45)
362    (XMM9_REG                    46)
363    (XMM10_REG                   47)
364    (XMM11_REG                   48)
365    (XMM12_REG                   49)
366    (XMM13_REG                   50)
367    (XMM14_REG                   51)
368    (XMM15_REG                   52)
369    (XMM16_REG                   53)
370    (XMM17_REG                   54)
371    (XMM18_REG                   55)
372    (XMM19_REG                   56)
373    (XMM20_REG                   57)
374    (XMM21_REG                   58)
375    (XMM22_REG                   59)
376    (XMM23_REG                   60)
377    (XMM24_REG                   61)
378    (XMM25_REG                   62)
379    (XMM26_REG                   63)
380    (XMM27_REG                   64)
381    (XMM28_REG                   65)
382    (XMM29_REG                   66)
383    (XMM30_REG                   67)
384    (XMM31_REG                   68)
385    (MASK0_REG                   69)
386    (MASK1_REG                   70)
387    (MASK2_REG                   71)
388    (MASK3_REG                   72)
389    (MASK4_REG                   73)
390    (MASK5_REG                   74)
391    (MASK6_REG                   75)
392    (MASK7_REG                   76)
393    (BND0_REG                    77)
394    (BND1_REG                    78)
395    (BND2_REG                    79)
396    (BND3_REG                    80)
397    (FIRST_PSEUDO_REG            81)
398   ])
400 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
401 ;; from i386.c.
403 ;; In C guard expressions, put expressions which may be compile-time
404 ;; constants first.  This allows for better optimization.  For
405 ;; example, write "TARGET_64BIT && reload_completed", not
406 ;; "reload_completed && TARGET_64BIT".
409 ;; Processor type.
410 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
411                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
412                     btver2,knl"
413   (const (symbol_ref "ix86_schedule")))
415 ;; A basic instruction type.  Refinements due to arguments to be
416 ;; provided in other attributes.
417 (define_attr "type"
418   "other,multi,
419    alu,alu1,negnot,imov,imovx,lea,
420    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
421    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
422    push,pop,call,callv,leave,
423    str,bitmanip,
424    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
425    fxch,fistp,fisttp,frndint,
426    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
427    ssemul,sseimul,ssediv,sselog,sselog1,
428    sseishft,sseishft1,ssecmp,ssecomi,
429    ssecvt,ssecvt1,sseicvt,sseins,
430    sseshuf,sseshuf1,ssemuladd,sse4arg,
431    lwp,mskmov,msklog,
432    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
433    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
434   (const_string "other"))
436 ;; Main data type used by the insn
437 (define_attr "mode"
438   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
439   V2DF,V2SF,V1DF,V8DF"
440   (const_string "unknown"))
442 ;; The CPU unit operations uses.
443 (define_attr "unit" "integer,i387,sse,mmx,unknown"
444   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
445                           fxch,fistp,fisttp,frndint")
446            (const_string "i387")
447          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
448                           ssemul,sseimul,ssediv,sselog,sselog1,
449                           sseishft,sseishft1,ssecmp,ssecomi,
450                           ssecvt,ssecvt1,sseicvt,sseins,
451                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
452            (const_string "sse")
453          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
454            (const_string "mmx")
455          (eq_attr "type" "other")
456            (const_string "unknown")]
457          (const_string "integer")))
459 ;; The minimum required alignment of vector mode memory operands of the SSE
460 ;; (non-VEX/EVEX) instruction in bits, if it is different from
461 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
462 ;; multiple alternatives, this should be conservative maximum of those minimum
463 ;; required alignments.
464 (define_attr "ssememalign" "" (const_int 0))
466 ;; The (bounding maximum) length of an instruction immediate.
467 (define_attr "length_immediate" ""
468   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
469                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
470                           mpxld,mpxst")
471            (const_int 0)
472          (eq_attr "unit" "i387,sse,mmx")
473            (const_int 0)
474          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
475                           rotate,rotatex,rotate1,imul,icmp,push,pop")
476            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
477          (eq_attr "type" "imov,test")
478            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
479          (eq_attr "type" "call")
480            (if_then_else (match_operand 0 "constant_call_address_operand")
481              (const_int 4)
482              (const_int 0))
483          (eq_attr "type" "callv")
484            (if_then_else (match_operand 1 "constant_call_address_operand")
485              (const_int 4)
486              (const_int 0))
487          ;; We don't know the size before shorten_branches.  Expect
488          ;; the instruction to fit for better scheduling.
489          (eq_attr "type" "ibr")
490            (const_int 1)
491          ]
492          (symbol_ref "/* Update immediate_length and other attributes! */
493                       gcc_unreachable (),1")))
495 ;; The (bounding maximum) length of an instruction address.
496 (define_attr "length_address" ""
497   (cond [(eq_attr "type" "str,other,multi,fxch")
498            (const_int 0)
499          (and (eq_attr "type" "call")
500               (match_operand 0 "constant_call_address_operand"))
501              (const_int 0)
502          (and (eq_attr "type" "callv")
503               (match_operand 1 "constant_call_address_operand"))
504              (const_int 0)
505          ]
506          (symbol_ref "ix86_attr_length_address_default (insn)")))
508 ;; Set when length prefix is used.
509 (define_attr "prefix_data16" ""
510   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
511            (const_int 0)
512          (eq_attr "mode" "HI")
513            (const_int 1)
514          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
515            (const_int 1)
516         ]
517         (const_int 0)))
519 ;; Set when string REP prefix is used.
520 (define_attr "prefix_rep" ""
521   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
522            (const_int 0)
523          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
524            (const_int 1)
525          (and (eq_attr "type" "ibr,call,callv")
526               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
527            (const_int 1)
528         ]
529         (const_int 0)))
531 ;; Set when 0f opcode prefix is used.
532 (define_attr "prefix_0f" ""
533   (if_then_else
534     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
535                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
536          (eq_attr "unit" "sse,mmx"))
537     (const_int 1)
538     (const_int 0)))
540 ;; Set when REX opcode prefix is used.
541 (define_attr "prefix_rex" ""
542   (cond [(not (match_test "TARGET_64BIT"))
543            (const_int 0)
544          (and (eq_attr "mode" "DI")
545               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
546                    (eq_attr "unit" "!mmx")))
547            (const_int 1)
548          (and (eq_attr "mode" "QI")
549               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
550            (const_int 1)
551          (match_test "x86_extended_reg_mentioned_p (insn)")
552            (const_int 1)
553          (and (eq_attr "type" "imovx")
554               (match_operand:QI 1 "ext_QIreg_operand"))
555            (const_int 1)
556         ]
557         (const_int 0)))
559 ;; There are also additional prefixes in 3DNOW, SSSE3.
560 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
561 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
562 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
563 (define_attr "prefix_extra" ""
564   (cond [(eq_attr "type" "ssemuladd,sse4arg")
565            (const_int 2)
566          (eq_attr "type" "sseiadd1,ssecvt1")
567            (const_int 1)
568         ]
569         (const_int 0)))
571 ;; Prefix used: original, VEX or maybe VEX.
572 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
573   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
574            (const_string "vex")
575          (eq_attr "mode" "XI,V16SF,V8DF")
576            (const_string "evex")
577         ]
578         (const_string "orig")))
580 ;; VEX W bit is used.
581 (define_attr "prefix_vex_w" "" (const_int 0))
583 ;; The length of VEX prefix
584 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
585 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
586 ;; still prefix_0f 1, with prefix_extra 1.
587 (define_attr "length_vex" ""
588   (if_then_else (and (eq_attr "prefix_0f" "1")
589                      (eq_attr "prefix_extra" "0"))
590     (if_then_else (eq_attr "prefix_vex_w" "1")
591       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
592       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
593     (if_then_else (eq_attr "prefix_vex_w" "1")
594       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
595       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
597 ;; 4-bytes evex prefix and 1 byte opcode.
598 (define_attr "length_evex" "" (const_int 5))
600 ;; Set when modrm byte is used.
601 (define_attr "modrm" ""
602   (cond [(eq_attr "type" "str,leave")
603            (const_int 0)
604          (eq_attr "unit" "i387")
605            (const_int 0)
606          (and (eq_attr "type" "incdec")
607               (and (not (match_test "TARGET_64BIT"))
608                    (ior (match_operand:SI 1 "register_operand")
609                         (match_operand:HI 1 "register_operand"))))
610            (const_int 0)
611          (and (eq_attr "type" "push")
612               (not (match_operand 1 "memory_operand")))
613            (const_int 0)
614          (and (eq_attr "type" "pop")
615               (not (match_operand 0 "memory_operand")))
616            (const_int 0)
617          (and (eq_attr "type" "imov")
618               (and (not (eq_attr "mode" "DI"))
619                    (ior (and (match_operand 0 "register_operand")
620                              (match_operand 1 "immediate_operand"))
621                         (ior (and (match_operand 0 "ax_reg_operand")
622                                   (match_operand 1 "memory_displacement_only_operand"))
623                              (and (match_operand 0 "memory_displacement_only_operand")
624                                   (match_operand 1 "ax_reg_operand"))))))
625            (const_int 0)
626          (and (eq_attr "type" "call")
627               (match_operand 0 "constant_call_address_operand"))
628              (const_int 0)
629          (and (eq_attr "type" "callv")
630               (match_operand 1 "constant_call_address_operand"))
631              (const_int 0)
632          (and (eq_attr "type" "alu,alu1,icmp,test")
633               (match_operand 0 "ax_reg_operand"))
634              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
635          ]
636          (const_int 1)))
638 ;; When this attribute is set, calculate total insn length from
639 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
640 (define_attr "length_nobnd" "" (const_int 0))
642 ;; The (bounding maximum) length of an instruction in bytes.
643 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
644 ;; Later we may want to split them and compute proper length as for
645 ;; other insns.
646 (define_attr "length" ""
647   (cond [(eq_attr "length_nobnd" "!0")
648            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
649                  (attr "length_nobnd"))
650          (eq_attr "type" "other,multi,fistp,frndint")
651            (const_int 16)
652          (eq_attr "type" "fcmp")
653            (const_int 4)
654          (eq_attr "unit" "i387")
655            (plus (const_int 2)
656                  (plus (attr "prefix_data16")
657                        (attr "length_address")))
658          (ior (eq_attr "prefix" "evex")
659               (and (ior (eq_attr "prefix" "maybe_evex")
660                         (eq_attr "prefix" "maybe_vex"))
661                    (match_test "TARGET_AVX512F")))
662            (plus (attr "length_evex")
663                  (plus (attr "length_immediate")
664                        (plus (attr "modrm")
665                              (attr "length_address"))))
666          (ior (eq_attr "prefix" "vex")
667               (and (ior (eq_attr "prefix" "maybe_vex")
668                         (eq_attr "prefix" "maybe_evex"))
669                    (match_test "TARGET_AVX")))
670            (plus (attr "length_vex")
671                  (plus (attr "length_immediate")
672                        (plus (attr "modrm")
673                              (attr "length_address"))))]
674          (plus (plus (attr "modrm")
675                      (plus (attr "prefix_0f")
676                            (plus (attr "prefix_rex")
677                                  (plus (attr "prefix_extra")
678                                        (const_int 1)))))
679                (plus (attr "prefix_rep")
680                      (plus (attr "prefix_data16")
681                            (plus (attr "length_immediate")
682                                  (attr "length_address")))))))
684 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
685 ;; `store' if there is a simple memory reference therein, or `unknown'
686 ;; if the instruction is complex.
688 (define_attr "memory" "none,load,store,both,unknown"
689   (cond [(eq_attr "type" "other,multi,str,lwp")
690            (const_string "unknown")
691          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
692            (const_string "none")
693          (eq_attr "type" "fistp,leave")
694            (const_string "both")
695          (eq_attr "type" "frndint")
696            (const_string "load")
697          (eq_attr "type" "mpxld")
698            (const_string "load")
699          (eq_attr "type" "mpxst")
700            (const_string "store")
701          (eq_attr "type" "push")
702            (if_then_else (match_operand 1 "memory_operand")
703              (const_string "both")
704              (const_string "store"))
705          (eq_attr "type" "pop")
706            (if_then_else (match_operand 0 "memory_operand")
707              (const_string "both")
708              (const_string "load"))
709          (eq_attr "type" "setcc")
710            (if_then_else (match_operand 0 "memory_operand")
711              (const_string "store")
712              (const_string "none"))
713          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
714            (if_then_else (ior (match_operand 0 "memory_operand")
715                               (match_operand 1 "memory_operand"))
716              (const_string "load")
717              (const_string "none"))
718          (eq_attr "type" "ibr")
719            (if_then_else (match_operand 0 "memory_operand")
720              (const_string "load")
721              (const_string "none"))
722          (eq_attr "type" "call")
723            (if_then_else (match_operand 0 "constant_call_address_operand")
724              (const_string "none")
725              (const_string "load"))
726          (eq_attr "type" "callv")
727            (if_then_else (match_operand 1 "constant_call_address_operand")
728              (const_string "none")
729              (const_string "load"))
730          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
731               (match_operand 1 "memory_operand"))
732            (const_string "both")
733          (and (match_operand 0 "memory_operand")
734               (match_operand 1 "memory_operand"))
735            (const_string "both")
736          (match_operand 0 "memory_operand")
737            (const_string "store")
738          (match_operand 1 "memory_operand")
739            (const_string "load")
740          (and (eq_attr "type"
741                  "!alu1,negnot,ishift1,
742                    imov,imovx,icmp,test,bitmanip,
743                    fmov,fcmp,fsgn,
744                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
745                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
746                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
747               (match_operand 2 "memory_operand"))
748            (const_string "load")
749          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
750               (match_operand 3 "memory_operand"))
751            (const_string "load")
752         ]
753         (const_string "none")))
755 ;; Indicates if an instruction has both an immediate and a displacement.
757 (define_attr "imm_disp" "false,true,unknown"
758   (cond [(eq_attr "type" "other,multi")
759            (const_string "unknown")
760          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
761               (and (match_operand 0 "memory_displacement_operand")
762                    (match_operand 1 "immediate_operand")))
763            (const_string "true")
764          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
765               (and (match_operand 0 "memory_displacement_operand")
766                    (match_operand 2 "immediate_operand")))
767            (const_string "true")
768         ]
769         (const_string "false")))
771 ;; Indicates if an FP operation has an integer source.
773 (define_attr "fp_int_src" "false,true"
774   (const_string "false"))
776 ;; Defines rounding mode of an FP operation.
778 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
779   (const_string "any"))
781 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
782 (define_attr "use_carry" "0,1" (const_string "0"))
784 ;; Define attribute to indicate unaligned ssemov insns
785 (define_attr "movu" "0,1" (const_string "0"))
787 ;; Used to control the "enabled" attribute on a per-instruction basis.
788 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
789                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
790                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
791                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
792   (const_string "base"))
794 (define_attr "enabled" ""
795   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
796          (eq_attr "isa" "x64_sse4")
797            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
798          (eq_attr "isa" "x64_sse4_noavx")
799            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
800          (eq_attr "isa" "x64_avx")
801            (symbol_ref "TARGET_64BIT && TARGET_AVX")
802          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
803          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
804          (eq_attr "isa" "sse2_noavx")
805            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
806          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
807          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
808          (eq_attr "isa" "sse4_noavx")
809            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
810          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
811          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
812          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
813          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
814          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
815          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
816          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
817          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
818          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
819          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
820          (eq_attr "isa" "fma_avx512f")
821            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
822          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
823          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
824          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
825          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
826         ]
827         (const_int 1)))
829 (define_attr "preferred_for_size" "" (const_int 1))
830 (define_attr "preferred_for_speed" "" (const_int 1))
832 ;; Describe a user's asm statement.
833 (define_asm_attributes
834   [(set_attr "length" "128")
835    (set_attr "type" "multi")])
837 (define_code_iterator plusminus [plus minus])
839 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
841 (define_code_iterator multdiv [mult div])
843 ;; Base name for define_insn
844 (define_code_attr plusminus_insn
845   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
846    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
848 ;; Base name for insn mnemonic.
849 (define_code_attr plusminus_mnemonic
850   [(plus "add") (ss_plus "adds") (us_plus "addus")
851    (minus "sub") (ss_minus "subs") (us_minus "subus")])
852 (define_code_attr plusminus_carry_mnemonic
853   [(plus "adc") (minus "sbb")])
854 (define_code_attr multdiv_mnemonic
855   [(mult "mul") (div "div")])
857 ;; Mark commutative operators as such in constraints.
858 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
859                         (minus "") (ss_minus "") (us_minus "")])
861 ;; Mapping of max and min
862 (define_code_iterator maxmin [smax smin umax umin])
864 ;; Mapping of signed max and min
865 (define_code_iterator smaxmin [smax smin])
867 ;; Mapping of unsigned max and min
868 (define_code_iterator umaxmin [umax umin])
870 ;; Base name for integer and FP insn mnemonic
871 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
872                               (umax "maxu") (umin "minu")])
873 (define_code_attr maxmin_float [(smax "max") (smin "min")])
875 ;; Mapping of logic operators
876 (define_code_iterator any_logic [and ior xor])
877 (define_code_iterator any_or [ior xor])
878 (define_code_iterator fpint_logic [and xor])
880 ;; Base name for insn mnemonic.
881 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
883 ;; Mapping of logic-shift operators
884 (define_code_iterator any_lshift [ashift lshiftrt])
886 ;; Mapping of shift-right operators
887 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
889 ;; Mapping of all shift operators
890 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
892 ;; Base name for define_insn
893 (define_code_attr shift_insn
894   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
896 ;; Base name for insn mnemonic.
897 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
898 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
900 ;; Mapping of rotate operators
901 (define_code_iterator any_rotate [rotate rotatert])
903 ;; Base name for define_insn
904 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
906 ;; Base name for insn mnemonic.
907 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
909 ;; Mapping of abs neg operators
910 (define_code_iterator absneg [abs neg])
912 ;; Base name for x87 insn mnemonic.
913 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
915 ;; Used in signed and unsigned widening multiplications.
916 (define_code_iterator any_extend [sign_extend zero_extend])
918 ;; Prefix for insn menmonic.
919 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
921 ;; Prefix for define_insn
922 (define_code_attr u [(sign_extend "") (zero_extend "u")])
923 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
924 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
926 ;; Used in signed and unsigned truncations.
927 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
928 ;; Instruction suffix for truncations.
929 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
931 ;; Used in signed and unsigned fix.
932 (define_code_iterator any_fix [fix unsigned_fix])
933 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
935 ;; Used in signed and unsigned float.
936 (define_code_iterator any_float [float unsigned_float])
937 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
939 ;; All integer modes.
940 (define_mode_iterator SWI1248x [QI HI SI DI])
942 ;; All integer modes with AVX512BW.
943 (define_mode_iterator SWI1248_AVX512BW
944   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
946 ;; All integer modes without QImode.
947 (define_mode_iterator SWI248x [HI SI DI])
949 ;; All integer modes without QImode and HImode.
950 (define_mode_iterator SWI48x [SI DI])
952 ;; All integer modes without SImode and DImode.
953 (define_mode_iterator SWI12 [QI HI])
955 ;; All integer modes without DImode.
956 (define_mode_iterator SWI124 [QI HI SI])
958 ;; All integer modes without QImode and DImode.
959 (define_mode_iterator SWI24 [HI SI])
961 ;; Single word integer modes.
962 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
964 ;; Single word integer modes without QImode.
965 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
967 ;; Single word integer modes without QImode and HImode.
968 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
970 ;; All math-dependant single and double word integer modes.
971 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
972                              (HI "TARGET_HIMODE_MATH")
973                              SI DI (TI "TARGET_64BIT")])
975 ;; Math-dependant single word integer modes.
976 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
977                             (HI "TARGET_HIMODE_MATH")
978                             SI (DI "TARGET_64BIT")])
980 ;; Math-dependant integer modes without DImode.
981 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
982                                (HI "TARGET_HIMODE_MATH")
983                                SI])
985 ;; Math-dependant single word integer modes without QImode.
986 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
987                                SI (DI "TARGET_64BIT")])
989 ;; Double word integer modes.
990 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
991                            (TI "TARGET_64BIT")])
993 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
994 ;; compile time constant, it is faster to use <MODE_SIZE> than
995 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
996 ;; command line options just use GET_MODE_SIZE macro.
997 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
998                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
999                              (V16QI "16") (V32QI "32") (V64QI "64")
1000                              (V8HI "16") (V16HI "32") (V32HI "64")
1001                              (V4SI "16") (V8SI "32") (V16SI "64")
1002                              (V2DI "16") (V4DI "32") (V8DI "64")
1003                              (V1TI "16") (V2TI "32") (V4TI "64")
1004                              (V2DF "16") (V4DF "32") (V8DF "64")
1005                              (V4SF "16") (V8SF "32") (V16SF "64")])
1007 ;; Double word integer modes as mode attribute.
1008 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1009 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1011 ;; Half mode for double word integer modes.
1012 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1013                             (DI "TARGET_64BIT")])
1015 ;; Bound modes.
1016 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1017                            (BND64 "TARGET_LP64")])
1019 ;; Pointer mode corresponding to bound mode.
1020 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1022 ;; MPX check types
1023 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1025 ;; Check name
1026 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1027                            (UNSPEC_BNDCU "cu")
1028                            (UNSPEC_BNDCN "cn")])
1030 ;; Instruction suffix for integer modes.
1031 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1033 ;; Instruction suffix for masks.
1034 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1036 ;; Pointer size prefix for integer modes (Intel asm dialect)
1037 (define_mode_attr iptrsize [(QI "BYTE")
1038                             (HI "WORD")
1039                             (SI "DWORD")
1040                             (DI "QWORD")])
1042 ;; Register class for integer modes.
1043 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1045 ;; Immediate operand constraint for integer modes.
1046 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1048 ;; General operand constraint for word modes.
1049 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1051 ;; Immediate operand constraint for double integer modes.
1052 (define_mode_attr di [(SI "nF") (DI "e")])
1054 ;; Immediate operand constraint for shifts.
1055 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1057 ;; General operand predicate for integer modes.
1058 (define_mode_attr general_operand
1059         [(QI "general_operand")
1060          (HI "general_operand")
1061          (SI "x86_64_general_operand")
1062          (DI "x86_64_general_operand")
1063          (TI "x86_64_general_operand")])
1065 ;; General sign extend operand predicate for integer modes,
1066 ;; which disallows VOIDmode operands and thus it is suitable
1067 ;; for use inside sign_extend.
1068 (define_mode_attr general_sext_operand
1069         [(QI "sext_operand")
1070          (HI "sext_operand")
1071          (SI "x86_64_sext_operand")
1072          (DI "x86_64_sext_operand")])
1074 ;; General sign/zero extend operand predicate for integer modes.
1075 (define_mode_attr general_szext_operand
1076         [(QI "general_operand")
1077          (HI "general_operand")
1078          (SI "x86_64_szext_general_operand")
1079          (DI "x86_64_szext_general_operand")])
1081 ;; Immediate operand predicate for integer modes.
1082 (define_mode_attr immediate_operand
1083         [(QI "immediate_operand")
1084          (HI "immediate_operand")
1085          (SI "x86_64_immediate_operand")
1086          (DI "x86_64_immediate_operand")])
1088 ;; Nonmemory operand predicate for integer modes.
1089 (define_mode_attr nonmemory_operand
1090         [(QI "nonmemory_operand")
1091          (HI "nonmemory_operand")
1092          (SI "x86_64_nonmemory_operand")
1093          (DI "x86_64_nonmemory_operand")])
1095 ;; Operand predicate for shifts.
1096 (define_mode_attr shift_operand
1097         [(QI "nonimmediate_operand")
1098          (HI "nonimmediate_operand")
1099          (SI "nonimmediate_operand")
1100          (DI "shiftdi_operand")
1101          (TI "register_operand")])
1103 ;; Operand predicate for shift argument.
1104 (define_mode_attr shift_immediate_operand
1105         [(QI "const_1_to_31_operand")
1106          (HI "const_1_to_31_operand")
1107          (SI "const_1_to_31_operand")
1108          (DI "const_1_to_63_operand")])
1110 ;; Input operand predicate for arithmetic left shifts.
1111 (define_mode_attr ashl_input_operand
1112         [(QI "nonimmediate_operand")
1113          (HI "nonimmediate_operand")
1114          (SI "nonimmediate_operand")
1115          (DI "ashldi_input_operand")
1116          (TI "reg_or_pm1_operand")])
1118 ;; SSE and x87 SFmode and DFmode floating point modes
1119 (define_mode_iterator MODEF [SF DF])
1121 ;; All x87 floating point modes
1122 (define_mode_iterator X87MODEF [SF DF XF])
1124 ;; SSE instruction suffix for various modes
1125 (define_mode_attr ssemodesuffix
1126   [(SF "ss") (DF "sd")
1127    (V16SF "ps") (V8DF "pd")
1128    (V8SF "ps") (V4DF "pd")
1129    (V4SF "ps") (V2DF "pd")
1130    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1131    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1132    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1134 ;; SSE vector suffix for floating point modes
1135 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1137 ;; SSE vector mode corresponding to a scalar mode
1138 (define_mode_attr ssevecmode
1139   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1140 (define_mode_attr ssevecmodelower
1141   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1143 ;; Instruction suffix for REX 64bit operators.
1144 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1146 ;; This mode iterator allows :P to be used for patterns that operate on
1147 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1148 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1150 ;; This mode iterator allows :W to be used for patterns that operate on
1151 ;; word_mode sized quantities.
1152 (define_mode_iterator W
1153   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1155 ;; This mode iterator allows :PTR to be used for patterns that operate on
1156 ;; ptr_mode sized quantities.
1157 (define_mode_iterator PTR
1158   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1160 ;; Scheduling descriptions
1162 (include "pentium.md")
1163 (include "ppro.md")
1164 (include "k6.md")
1165 (include "athlon.md")
1166 (include "bdver1.md")
1167 (include "bdver3.md")
1168 (include "btver2.md")
1169 (include "geode.md")
1170 (include "atom.md")
1171 (include "slm.md")
1172 (include "core2.md")
1175 ;; Operand and operator predicates and constraints
1177 (include "predicates.md")
1178 (include "constraints.md")
1181 ;; Compare and branch/compare and store instructions.
1183 (define_expand "cbranch<mode>4"
1184   [(set (reg:CC FLAGS_REG)
1185         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1186                     (match_operand:SDWIM 2 "<general_operand>")))
1187    (set (pc) (if_then_else
1188                (match_operator 0 "ordered_comparison_operator"
1189                 [(reg:CC FLAGS_REG) (const_int 0)])
1190                (label_ref (match_operand 3))
1191                (pc)))]
1192   ""
1194   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1195     operands[1] = force_reg (<MODE>mode, operands[1]);
1196   ix86_expand_branch (GET_CODE (operands[0]),
1197                       operands[1], operands[2], operands[3]);
1198   DONE;
1201 (define_expand "cstore<mode>4"
1202   [(set (reg:CC FLAGS_REG)
1203         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1204                     (match_operand:SWIM 3 "<general_operand>")))
1205    (set (match_operand:QI 0 "register_operand")
1206         (match_operator 1 "ordered_comparison_operator"
1207           [(reg:CC FLAGS_REG) (const_int 0)]))]
1208   ""
1210   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1211     operands[2] = force_reg (<MODE>mode, operands[2]);
1212   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1213                      operands[2], operands[3]);
1214   DONE;
1217 (define_expand "cmp<mode>_1"
1218   [(set (reg:CC FLAGS_REG)
1219         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1220                     (match_operand:SWI48 1 "<general_operand>")))])
1222 (define_insn "*cmp<mode>_ccno_1"
1223   [(set (reg FLAGS_REG)
1224         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1225                  (match_operand:SWI 1 "const0_operand")))]
1226   "ix86_match_ccmode (insn, CCNOmode)"
1227   "@
1228    test{<imodesuffix>}\t%0, %0
1229    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1230   [(set_attr "type" "test,icmp")
1231    (set_attr "length_immediate" "0,1")
1232    (set_attr "mode" "<MODE>")])
1234 (define_insn "*cmp<mode>_1"
1235   [(set (reg FLAGS_REG)
1236         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1237                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1238   "ix86_match_ccmode (insn, CCmode)"
1239   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1240   [(set_attr "type" "icmp")
1241    (set_attr "mode" "<MODE>")])
1243 (define_insn "*cmp<mode>_minus_1"
1244   [(set (reg FLAGS_REG)
1245         (compare
1246           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1247                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1248           (const_int 0)))]
1249   "ix86_match_ccmode (insn, CCGOCmode)"
1250   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1251   [(set_attr "type" "icmp")
1252    (set_attr "mode" "<MODE>")])
1254 (define_insn "*cmpqi_ext_1"
1255   [(set (reg FLAGS_REG)
1256         (compare
1257           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1258           (subreg:QI
1259             (zero_extract:SI
1260               (match_operand 1 "ext_register_operand" "Q,Q")
1261               (const_int 8)
1262               (const_int 8)) 0)))]
1263   "ix86_match_ccmode (insn, CCmode)"
1264   "cmp{b}\t{%h1, %0|%0, %h1}"
1265   [(set_attr "isa" "*,nox64")
1266    (set_attr "type" "icmp")
1267    (set_attr "mode" "QI")])
1269 (define_insn "*cmpqi_ext_2"
1270   [(set (reg FLAGS_REG)
1271         (compare
1272           (subreg:QI
1273             (zero_extract:SI
1274               (match_operand 0 "ext_register_operand" "Q")
1275               (const_int 8)
1276               (const_int 8)) 0)
1277           (match_operand:QI 1 "const0_operand")))]
1278   "ix86_match_ccmode (insn, CCNOmode)"
1279   "test{b}\t%h0, %h0"
1280   [(set_attr "type" "test")
1281    (set_attr "length_immediate" "0")
1282    (set_attr "mode" "QI")])
1284 (define_expand "cmpqi_ext_3"
1285   [(set (reg:CC FLAGS_REG)
1286         (compare:CC
1287           (subreg:QI
1288             (zero_extract:SI
1289               (match_operand 0 "ext_register_operand")
1290               (const_int 8)
1291               (const_int 8)) 0)
1292           (match_operand:QI 1 "const_int_operand")))])
1294 (define_insn "*cmpqi_ext_3"
1295   [(set (reg FLAGS_REG)
1296         (compare
1297           (subreg:QI
1298             (zero_extract:SI
1299               (match_operand 0 "ext_register_operand" "Q,Q")
1300               (const_int 8)
1301               (const_int 8)) 0)
1302           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1303   "ix86_match_ccmode (insn, CCmode)"
1304   "cmp{b}\t{%1, %h0|%h0, %1}"
1305   [(set_attr "isa" "*,nox64")
1306    (set_attr "type" "icmp")
1307    (set_attr "modrm" "1")
1308    (set_attr "mode" "QI")])
1310 (define_insn "*cmpqi_ext_4"
1311   [(set (reg FLAGS_REG)
1312         (compare
1313           (subreg:QI
1314             (zero_extract:SI
1315               (match_operand 0 "ext_register_operand" "Q")
1316               (const_int 8)
1317               (const_int 8)) 0)
1318           (subreg:QI
1319             (zero_extract:SI
1320               (match_operand 1 "ext_register_operand" "Q")
1321               (const_int 8)
1322               (const_int 8)) 0)))]
1323   "ix86_match_ccmode (insn, CCmode)"
1324   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1325   [(set_attr "type" "icmp")
1326    (set_attr "mode" "QI")])
1328 ;; These implement float point compares.
1329 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1330 ;; which would allow mix and match FP modes on the compares.  Which is what
1331 ;; the old patterns did, but with many more of them.
1333 (define_expand "cbranchxf4"
1334   [(set (reg:CC FLAGS_REG)
1335         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1336                     (match_operand:XF 2 "nonmemory_operand")))
1337    (set (pc) (if_then_else
1338               (match_operator 0 "ix86_fp_comparison_operator"
1339                [(reg:CC FLAGS_REG)
1340                 (const_int 0)])
1341               (label_ref (match_operand 3))
1342               (pc)))]
1343   "TARGET_80387"
1345   ix86_expand_branch (GET_CODE (operands[0]),
1346                       operands[1], operands[2], operands[3]);
1347   DONE;
1350 (define_expand "cstorexf4"
1351   [(set (reg:CC FLAGS_REG)
1352         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1353                     (match_operand:XF 3 "nonmemory_operand")))
1354    (set (match_operand:QI 0 "register_operand")
1355               (match_operator 1 "ix86_fp_comparison_operator"
1356                [(reg:CC FLAGS_REG)
1357                 (const_int 0)]))]
1358   "TARGET_80387"
1360   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1361                      operands[2], operands[3]);
1362   DONE;
1365 (define_expand "cbranch<mode>4"
1366   [(set (reg:CC FLAGS_REG)
1367         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1368                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1369    (set (pc) (if_then_else
1370               (match_operator 0 "ix86_fp_comparison_operator"
1371                [(reg:CC FLAGS_REG)
1372                 (const_int 0)])
1373               (label_ref (match_operand 3))
1374               (pc)))]
1375   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1377   ix86_expand_branch (GET_CODE (operands[0]),
1378                       operands[1], operands[2], operands[3]);
1379   DONE;
1382 (define_expand "cstore<mode>4"
1383   [(set (reg:CC FLAGS_REG)
1384         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1385                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1386    (set (match_operand:QI 0 "register_operand")
1387               (match_operator 1 "ix86_fp_comparison_operator"
1388                [(reg:CC FLAGS_REG)
1389                 (const_int 0)]))]
1390   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1392   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1393                      operands[2], operands[3]);
1394   DONE;
1397 (define_expand "cbranchcc4"
1398   [(set (pc) (if_then_else
1399               (match_operator 0 "comparison_operator"
1400                [(match_operand 1 "flags_reg_operand")
1401                 (match_operand 2 "const0_operand")])
1402               (label_ref (match_operand 3))
1403               (pc)))]
1404   ""
1406   ix86_expand_branch (GET_CODE (operands[0]),
1407                       operands[1], operands[2], operands[3]);
1408   DONE;
1411 (define_expand "cstorecc4"
1412   [(set (match_operand:QI 0 "register_operand")
1413               (match_operator 1 "comparison_operator"
1414                [(match_operand 2 "flags_reg_operand")
1415                 (match_operand 3 "const0_operand")]))]
1416   ""
1418   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1419                      operands[2], operands[3]);
1420   DONE;
1424 ;; FP compares, step 1:
1425 ;; Set the FP condition codes.
1427 ;; CCFPmode     compare with exceptions
1428 ;; CCFPUmode    compare with no exceptions
1430 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1431 ;; used to manage the reg stack popping would not be preserved.
1433 (define_insn "*cmp<mode>_0_i387"
1434   [(set (match_operand:HI 0 "register_operand" "=a")
1435         (unspec:HI
1436           [(compare:CCFP
1437              (match_operand:X87MODEF 1 "register_operand" "f")
1438              (match_operand:X87MODEF 2 "const0_operand"))]
1439         UNSPEC_FNSTSW))]
1440   "TARGET_80387"
1441   "* return output_fp_compare (insn, operands, false, false);"
1442   [(set_attr "type" "multi")
1443    (set_attr "unit" "i387")
1444    (set_attr "mode" "<MODE>")])
1446 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1447   [(set (reg:CCFP FLAGS_REG)
1448         (compare:CCFP
1449           (match_operand:X87MODEF 1 "register_operand" "f")
1450           (match_operand:X87MODEF 2 "const0_operand")))
1451    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1452   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1453   "#"
1454   "&& reload_completed"
1455   [(set (match_dup 0)
1456         (unspec:HI
1457           [(compare:CCFP (match_dup 1)(match_dup 2))]
1458         UNSPEC_FNSTSW))
1459    (set (reg:CC FLAGS_REG)
1460         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1461   ""
1462   [(set_attr "type" "multi")
1463    (set_attr "unit" "i387")
1464    (set_attr "mode" "<MODE>")])
1466 (define_insn "*cmpxf_i387"
1467   [(set (match_operand:HI 0 "register_operand" "=a")
1468         (unspec:HI
1469           [(compare:CCFP
1470              (match_operand:XF 1 "register_operand" "f")
1471              (match_operand:XF 2 "register_operand" "f"))]
1472           UNSPEC_FNSTSW))]
1473   "TARGET_80387"
1474   "* return output_fp_compare (insn, operands, false, false);"
1475   [(set_attr "type" "multi")
1476    (set_attr "unit" "i387")
1477    (set_attr "mode" "XF")])
1479 (define_insn_and_split "*cmpxf_cc_i387"
1480   [(set (reg:CCFP FLAGS_REG)
1481         (compare:CCFP
1482           (match_operand:XF 1 "register_operand" "f")
1483           (match_operand:XF 2 "register_operand" "f")))
1484    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1485   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1486   "#"
1487   "&& reload_completed"
1488   [(set (match_dup 0)
1489         (unspec:HI
1490           [(compare:CCFP (match_dup 1)(match_dup 2))]
1491         UNSPEC_FNSTSW))
1492    (set (reg:CC FLAGS_REG)
1493         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1494   ""
1495   [(set_attr "type" "multi")
1496    (set_attr "unit" "i387")
1497    (set_attr "mode" "XF")])
1499 (define_insn "*cmp<mode>_i387"
1500   [(set (match_operand:HI 0 "register_operand" "=a")
1501         (unspec:HI
1502           [(compare:CCFP
1503              (match_operand:MODEF 1 "register_operand" "f")
1504              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1505           UNSPEC_FNSTSW))]
1506   "TARGET_80387"
1507   "* return output_fp_compare (insn, operands, false, false);"
1508   [(set_attr "type" "multi")
1509    (set_attr "unit" "i387")
1510    (set_attr "mode" "<MODE>")])
1512 (define_insn_and_split "*cmp<mode>_cc_i387"
1513   [(set (reg:CCFP FLAGS_REG)
1514         (compare:CCFP
1515           (match_operand:MODEF 1 "register_operand" "f")
1516           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1517    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1518   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1519   "#"
1520   "&& reload_completed"
1521   [(set (match_dup 0)
1522         (unspec:HI
1523           [(compare:CCFP (match_dup 1)(match_dup 2))]
1524         UNSPEC_FNSTSW))
1525    (set (reg:CC FLAGS_REG)
1526         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1527   ""
1528   [(set_attr "type" "multi")
1529    (set_attr "unit" "i387")
1530    (set_attr "mode" "<MODE>")])
1532 (define_insn "*cmpu<mode>_i387"
1533   [(set (match_operand:HI 0 "register_operand" "=a")
1534         (unspec:HI
1535           [(compare:CCFPU
1536              (match_operand:X87MODEF 1 "register_operand" "f")
1537              (match_operand:X87MODEF 2 "register_operand" "f"))]
1538           UNSPEC_FNSTSW))]
1539   "TARGET_80387"
1540   "* return output_fp_compare (insn, operands, false, true);"
1541   [(set_attr "type" "multi")
1542    (set_attr "unit" "i387")
1543    (set_attr "mode" "<MODE>")])
1545 (define_insn_and_split "*cmpu<mode>_cc_i387"
1546   [(set (reg:CCFPU FLAGS_REG)
1547         (compare:CCFPU
1548           (match_operand:X87MODEF 1 "register_operand" "f")
1549           (match_operand:X87MODEF 2 "register_operand" "f")))
1550    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1551   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1552   "#"
1553   "&& reload_completed"
1554   [(set (match_dup 0)
1555         (unspec:HI
1556           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1557         UNSPEC_FNSTSW))
1558    (set (reg:CC FLAGS_REG)
1559         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1560   ""
1561   [(set_attr "type" "multi")
1562    (set_attr "unit" "i387")
1563    (set_attr "mode" "<MODE>")])
1565 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1566   [(set (match_operand:HI 0 "register_operand" "=a")
1567         (unspec:HI
1568           [(compare:CCFP
1569              (match_operand:X87MODEF 1 "register_operand" "f")
1570              (match_operator:X87MODEF 3 "float_operator"
1571                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1572           UNSPEC_FNSTSW))]
1573   "TARGET_80387
1574    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1575        || optimize_function_for_size_p (cfun))"
1576   "* return output_fp_compare (insn, operands, false, false);"
1577   [(set_attr "type" "multi")
1578    (set_attr "unit" "i387")
1579    (set_attr "fp_int_src" "true")
1580    (set_attr "mode" "<SWI24:MODE>")])
1582 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1583   [(set (reg:CCFP FLAGS_REG)
1584         (compare:CCFP
1585           (match_operand:X87MODEF 1 "register_operand" "f")
1586           (match_operator:X87MODEF 3 "float_operator"
1587             [(match_operand:SWI24 2 "memory_operand" "m")])))
1588    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1589   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1590    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1591        || optimize_function_for_size_p (cfun))"
1592   "#"
1593   "&& reload_completed"
1594   [(set (match_dup 0)
1595         (unspec:HI
1596           [(compare:CCFP
1597              (match_dup 1)
1598              (match_op_dup 3 [(match_dup 2)]))]
1599         UNSPEC_FNSTSW))
1600    (set (reg:CC FLAGS_REG)
1601         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1602   ""
1603   [(set_attr "type" "multi")
1604    (set_attr "unit" "i387")
1605    (set_attr "fp_int_src" "true")
1606    (set_attr "mode" "<SWI24:MODE>")])
1608 ;; FP compares, step 2
1609 ;; Move the fpsw to ax.
1611 (define_insn "x86_fnstsw_1"
1612   [(set (match_operand:HI 0 "register_operand" "=a")
1613         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1614   "TARGET_80387"
1615   "fnstsw\t%0"
1616   [(set_attr "length" "2")
1617    (set_attr "mode" "SI")
1618    (set_attr "unit" "i387")])
1620 ;; FP compares, step 3
1621 ;; Get ax into flags, general case.
1623 (define_insn "x86_sahf_1"
1624   [(set (reg:CC FLAGS_REG)
1625         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1626                    UNSPEC_SAHF))]
1627   "TARGET_SAHF"
1629 #ifndef HAVE_AS_IX86_SAHF
1630   if (TARGET_64BIT)
1631     return ASM_BYTE "0x9e";
1632   else
1633 #endif
1634   return "sahf";
1636   [(set_attr "length" "1")
1637    (set_attr "athlon_decode" "vector")
1638    (set_attr "amdfam10_decode" "direct")
1639    (set_attr "bdver1_decode" "direct")
1640    (set_attr "mode" "SI")])
1642 ;; Pentium Pro can do steps 1 through 3 in one go.
1643 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1644 ;; (these i387 instructions set flags directly)
1646 (define_mode_iterator FPCMP [CCFP CCFPU])
1647 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1649 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1650   [(set (reg:FPCMP FLAGS_REG)
1651         (compare:FPCMP
1652           (match_operand:MODEF 0 "register_operand" "f,v")
1653           (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
1654   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
1655   "* return output_fp_compare (insn, operands, true,
1656                                <FPCMP:MODE>mode == CCFPUmode);"
1657   [(set_attr "type" "fcmp,ssecomi")
1658    (set_attr "prefix" "orig,maybe_vex")
1659    (set_attr "mode" "<MODEF:MODE>")
1660    (set_attr "prefix_rep" "*,0")
1661    (set (attr "prefix_data16")
1662         (cond [(eq_attr "alternative" "0")
1663                  (const_string "*")
1664                (eq_attr "mode" "DF")
1665                  (const_string "1")
1666               ]
1667               (const_string "0")))
1668    (set_attr "athlon_decode" "vector")
1669    (set_attr "amdfam10_decode" "direct")
1670    (set_attr "bdver1_decode" "double")
1671    (set (attr "enabled")
1672      (cond [(eq_attr "alternative" "0")
1673               (symbol_ref "TARGET_MIX_SSE_I387")
1674            ]
1675            (symbol_ref "true")))])
1677 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1678   [(set (reg:FPCMP FLAGS_REG)
1679         (compare:FPCMP
1680           (match_operand:X87MODEF 0 "register_operand" "f")
1681           (match_operand:X87MODEF 1 "register_operand" "f")))]
1682   "TARGET_80387 && TARGET_CMOVE
1683    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1684   "* return output_fp_compare (insn, operands, true,
1685                                <FPCMP:MODE>mode == CCFPUmode);"
1686   [(set_attr "type" "fcmp")
1687    (set_attr "mode" "<X87MODEF:MODE>")
1688    (set_attr "athlon_decode" "vector")
1689    (set_attr "amdfam10_decode" "direct")
1690    (set_attr "bdver1_decode" "double")])
1692 ;; Push/pop instructions.
1694 (define_insn "*push<mode>2"
1695   [(set (match_operand:DWI 0 "push_operand" "=<")
1696         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1697   ""
1698   "#"
1699   [(set_attr "type" "multi")
1700    (set_attr "mode" "<MODE>")])
1702 (define_split
1703   [(set (match_operand:TI 0 "push_operand")
1704         (match_operand:TI 1 "general_operand"))]
1705   "TARGET_64BIT && reload_completed
1706    && !SSE_REG_P (operands[1])"
1707   [(const_int 0)]
1708   "ix86_split_long_move (operands); DONE;")
1710 (define_insn "*pushdi2_rex64"
1711   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1712         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1713   "TARGET_64BIT"
1714   "@
1715    push{q}\t%1
1716    #"
1717   [(set_attr "type" "push,multi")
1718    (set_attr "mode" "DI")])
1720 ;; Convert impossible pushes of immediate to existing instructions.
1721 ;; First try to get scratch register and go through it.  In case this
1722 ;; fails, push sign extended lower part first and then overwrite
1723 ;; upper part by 32bit move.
1724 (define_peephole2
1725   [(match_scratch:DI 2 "r")
1726    (set (match_operand:DI 0 "push_operand")
1727         (match_operand:DI 1 "immediate_operand"))]
1728   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1729    && !x86_64_immediate_operand (operands[1], DImode)"
1730   [(set (match_dup 2) (match_dup 1))
1731    (set (match_dup 0) (match_dup 2))])
1733 ;; We need to define this as both peepholer and splitter for case
1734 ;; peephole2 pass is not run.
1735 ;; "&& 1" is needed to keep it from matching the previous pattern.
1736 (define_peephole2
1737   [(set (match_operand:DI 0 "push_operand")
1738         (match_operand:DI 1 "immediate_operand"))]
1739   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1740    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1741   [(set (match_dup 0) (match_dup 1))
1742    (set (match_dup 2) (match_dup 3))]
1744   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1746   operands[1] = gen_lowpart (DImode, operands[2]);
1747   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1748                                                    GEN_INT (4)));
1751 (define_split
1752   [(set (match_operand:DI 0 "push_operand")
1753         (match_operand:DI 1 "immediate_operand"))]
1754   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1755                     ? epilogue_completed : reload_completed)
1756    && !symbolic_operand (operands[1], DImode)
1757    && !x86_64_immediate_operand (operands[1], DImode)"
1758   [(set (match_dup 0) (match_dup 1))
1759    (set (match_dup 2) (match_dup 3))]
1761   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1763   operands[1] = gen_lowpart (DImode, operands[2]);
1764   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1765                                                    GEN_INT (4)));
1768 (define_split
1769   [(set (match_operand:DI 0 "push_operand")
1770         (match_operand:DI 1 "general_operand"))]
1771   "!TARGET_64BIT && reload_completed
1772    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1773   [(const_int 0)]
1774   "ix86_split_long_move (operands); DONE;")
1776 (define_insn "*pushsi2"
1777   [(set (match_operand:SI 0 "push_operand" "=<")
1778         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1779   "!TARGET_64BIT"
1780   "push{l}\t%1"
1781   [(set_attr "type" "push")
1782    (set_attr "mode" "SI")])
1784 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1785 ;; "push a byte/word".  But actually we use pushl, which has the effect
1786 ;; of rounding the amount pushed up to a word.
1788 ;; For TARGET_64BIT we always round up to 8 bytes.
1789 (define_insn "*push<mode>2_rex64"
1790   [(set (match_operand:SWI124 0 "push_operand" "=X")
1791         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1792   "TARGET_64BIT"
1793   "push{q}\t%q1"
1794   [(set_attr "type" "push")
1795    (set_attr "mode" "DI")])
1797 (define_insn "*push<mode>2"
1798   [(set (match_operand:SWI12 0 "push_operand" "=X")
1799         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1800   "!TARGET_64BIT"
1801   "push{l}\t%k1"
1802   [(set_attr "type" "push")
1803    (set_attr "mode" "SI")])
1805 (define_insn "*push<mode>2_prologue"
1806   [(set (match_operand:W 0 "push_operand" "=<")
1807         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1808    (clobber (mem:BLK (scratch)))]
1809   ""
1810   "push{<imodesuffix>}\t%1"
1811   [(set_attr "type" "push")
1812    (set_attr "mode" "<MODE>")])
1814 (define_insn "*pop<mode>1"
1815   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1816         (match_operand:W 1 "pop_operand" ">"))]
1817   ""
1818   "pop{<imodesuffix>}\t%0"
1819   [(set_attr "type" "pop")
1820    (set_attr "mode" "<MODE>")])
1822 (define_insn "*pop<mode>1_epilogue"
1823   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1824         (match_operand:W 1 "pop_operand" ">"))
1825    (clobber (mem:BLK (scratch)))]
1826   ""
1827   "pop{<imodesuffix>}\t%0"
1828   [(set_attr "type" "pop")
1829    (set_attr "mode" "<MODE>")])
1831 (define_insn "*pushfl<mode>2"
1832   [(set (match_operand:W 0 "push_operand" "=<")
1833         (match_operand:W 1 "flags_reg_operand"))]
1834   ""
1835   "pushf{<imodesuffix>}"
1836   [(set_attr "type" "push")
1837    (set_attr "mode" "<MODE>")])
1839 (define_insn "*popfl<mode>1"
1840   [(set (match_operand:W 0 "flags_reg_operand")
1841         (match_operand:W 1 "pop_operand" ">"))]
1842   ""
1843   "popf{<imodesuffix>}"
1844   [(set_attr "type" "pop")
1845    (set_attr "mode" "<MODE>")])
1848 ;; Move instructions.
1850 (define_expand "movxi"
1851   [(set (match_operand:XI 0 "nonimmediate_operand")
1852         (match_operand:XI 1 "general_operand"))]
1853   "TARGET_AVX512F"
1854   "ix86_expand_move (XImode, operands); DONE;")
1856 ;; Reload patterns to support multi-word load/store
1857 ;; with non-offsetable address.
1858 (define_expand "reload_noff_store"
1859   [(parallel [(match_operand 0 "memory_operand" "=m")
1860               (match_operand 1 "register_operand" "r")
1861               (match_operand:DI 2 "register_operand" "=&r")])]
1862   "TARGET_64BIT"
1864   rtx mem = operands[0];
1865   rtx addr = XEXP (mem, 0);
1867   emit_move_insn (operands[2], addr);
1868   mem = replace_equiv_address_nv (mem, operands[2]);
1870   emit_insn (gen_rtx_SET (mem, operands[1]));
1871   DONE;
1874 (define_expand "reload_noff_load"
1875   [(parallel [(match_operand 0 "register_operand" "=r")
1876               (match_operand 1 "memory_operand" "m")
1877               (match_operand:DI 2 "register_operand" "=r")])]
1878   "TARGET_64BIT"
1880   rtx mem = operands[1];
1881   rtx addr = XEXP (mem, 0);
1883   emit_move_insn (operands[2], addr);
1884   mem = replace_equiv_address_nv (mem, operands[2]);
1886   emit_insn (gen_rtx_SET (operands[0], mem));
1887   DONE;
1890 (define_expand "movoi"
1891   [(set (match_operand:OI 0 "nonimmediate_operand")
1892         (match_operand:OI 1 "general_operand"))]
1893   "TARGET_AVX"
1894   "ix86_expand_move (OImode, operands); DONE;")
1896 (define_expand "movti"
1897   [(set (match_operand:TI 0 "nonimmediate_operand")
1898         (match_operand:TI 1 "nonimmediate_operand"))]
1899   "TARGET_64BIT || TARGET_SSE"
1901   if (TARGET_64BIT)
1902     ix86_expand_move (TImode, operands);
1903   else
1904     ix86_expand_vector_move (TImode, operands);
1905   DONE;
1908 ;; This expands to what emit_move_complex would generate if we didn't
1909 ;; have a movti pattern.  Having this avoids problems with reload on
1910 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1911 ;; to have around all the time.
1912 (define_expand "movcdi"
1913   [(set (match_operand:CDI 0 "nonimmediate_operand")
1914         (match_operand:CDI 1 "general_operand"))]
1915   ""
1917   if (push_operand (operands[0], CDImode))
1918     emit_move_complex_push (CDImode, operands[0], operands[1]);
1919   else
1920     emit_move_complex_parts (operands[0], operands[1]);
1921   DONE;
1924 (define_expand "mov<mode>"
1925   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1926         (match_operand:SWI1248x 1 "general_operand"))]
1927   ""
1928   "ix86_expand_move (<MODE>mode, operands); DONE;")
1930 (define_insn "*mov<mode>_xor"
1931   [(set (match_operand:SWI48 0 "register_operand" "=r")
1932         (match_operand:SWI48 1 "const0_operand"))
1933    (clobber (reg:CC FLAGS_REG))]
1934   "reload_completed"
1935   "xor{l}\t%k0, %k0"
1936   [(set_attr "type" "alu1")
1937    (set_attr "mode" "SI")
1938    (set_attr "length_immediate" "0")])
1940 (define_insn "*mov<mode>_or"
1941   [(set (match_operand:SWI48 0 "register_operand" "=r")
1942         (match_operand:SWI48 1 "const_int_operand"))
1943    (clobber (reg:CC FLAGS_REG))]
1944   "reload_completed
1945    && operands[1] == constm1_rtx"
1946   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1947   [(set_attr "type" "alu1")
1948    (set_attr "mode" "<MODE>")
1949    (set_attr "length_immediate" "1")])
1951 (define_insn "*movxi_internal_avx512f"
1952   [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,m")
1953         (match_operand:XI 1 "vector_move_operand"  "C ,vm,v"))]
1954   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1956   switch (which_alternative)
1957     {
1958     case 0:
1959       return standard_sse_constant_opcode (insn, operands[1]);
1960     case 1:
1961     case 2:
1962       if (misaligned_operand (operands[0], XImode)
1963           || misaligned_operand (operands[1], XImode))
1964         return "vmovdqu32\t{%1, %0|%0, %1}";
1965       else
1966         return "vmovdqa32\t{%1, %0|%0, %1}";
1967     default:
1968       gcc_unreachable ();
1969     }
1971   [(set_attr "type" "sselog1,ssemov,ssemov")
1972    (set_attr "prefix" "evex")
1973    (set_attr "mode" "XI")])
1975 (define_insn "*movoi_internal_avx"
1976   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1977         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1978   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1980   switch (get_attr_type (insn))
1981     {
1982     case TYPE_SSELOG1:
1983       return standard_sse_constant_opcode (insn, operands[1]);
1985     case TYPE_SSEMOV:
1986       if (misaligned_operand (operands[0], OImode)
1987           || misaligned_operand (operands[1], OImode))
1988         {
1989           if (get_attr_mode (insn) == MODE_V8SF)
1990             return "vmovups\t{%1, %0|%0, %1}";
1991           else if (get_attr_mode (insn) == MODE_XI)
1992             return "vmovdqu32\t{%1, %0|%0, %1}";
1993           else
1994             return "vmovdqu\t{%1, %0|%0, %1}";
1995         }
1996       else
1997         {
1998           if (get_attr_mode (insn) == MODE_V8SF)
1999             return "vmovaps\t{%1, %0|%0, %1}";
2000           else if (get_attr_mode (insn) == MODE_XI)
2001             return "vmovdqa32\t{%1, %0|%0, %1}";
2002           else
2003             return "vmovdqa\t{%1, %0|%0, %1}";
2004         }
2006     default:
2007       gcc_unreachable ();
2008     }
2010   [(set_attr "type" "sselog1,ssemov,ssemov")
2011    (set_attr "prefix" "vex")
2012    (set (attr "mode")
2013         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2014                     (match_operand 1 "ext_sse_reg_operand"))
2015                  (const_string "XI")
2016                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2017                  (const_string "V8SF")
2018                (and (eq_attr "alternative" "2")
2019                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2020                  (const_string "V8SF")
2021               ]
2022               (const_string "OI")))])
2024 (define_insn "*movti_internal"
2025   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2026         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2027   "(TARGET_64BIT || TARGET_SSE)
2028    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_MULTI:
2033       return "#";
2035     case TYPE_SSELOG1:
2036       return standard_sse_constant_opcode (insn, operands[1]);
2038     case TYPE_SSEMOV:
2039       /* TDmode values are passed as TImode on the stack.  Moving them
2040          to stack may result in unaligned memory access.  */
2041       if (misaligned_operand (operands[0], TImode)
2042           || misaligned_operand (operands[1], TImode))
2043         {
2044           if (get_attr_mode (insn) == MODE_V4SF)
2045             return "%vmovups\t{%1, %0|%0, %1}";
2046           else if (get_attr_mode (insn) == MODE_XI)
2047             return "vmovdqu32\t{%1, %0|%0, %1}";
2048           else
2049             return "%vmovdqu\t{%1, %0|%0, %1}";
2050         }
2051       else
2052         {
2053           if (get_attr_mode (insn) == MODE_V4SF)
2054             return "%vmovaps\t{%1, %0|%0, %1}";
2055           else if (get_attr_mode (insn) == MODE_XI)
2056             return "vmovdqa32\t{%1, %0|%0, %1}";
2057           else
2058             return "%vmovdqa\t{%1, %0|%0, %1}";
2059         }
2061     default:
2062       gcc_unreachable ();
2063     }
2065   [(set_attr "isa" "x64,x64,*,*,*")
2066    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2067    (set (attr "prefix")
2068      (if_then_else (eq_attr "type" "sselog1,ssemov")
2069        (const_string "maybe_vex")
2070        (const_string "orig")))
2071    (set (attr "mode")
2072         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2073                     (match_operand 1 "ext_sse_reg_operand"))
2074                  (const_string "XI")
2075                (eq_attr "alternative" "0,1")
2076                  (const_string "DI")
2077                (ior (not (match_test "TARGET_SSE2"))
2078                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2079                  (const_string "V4SF")
2080                (and (eq_attr "alternative" "4")
2081                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2082                  (const_string "V4SF")
2083                (match_test "TARGET_AVX")
2084                  (const_string "TI")
2085                (match_test "optimize_function_for_size_p (cfun)")
2086                  (const_string "V4SF")
2087                ]
2088                (const_string "TI")))])
2090 (define_split
2091   [(set (match_operand:TI 0 "nonimmediate_operand")
2092         (match_operand:TI 1 "general_operand"))]
2093   "reload_completed
2094    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2095   [(const_int 0)]
2096   "ix86_split_long_move (operands); DONE;")
2098 (define_insn "*movdi_internal"
2099   [(set (match_operand:DI 0 "nonimmediate_operand"
2100     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2101         (match_operand:DI 1 "general_operand"
2102     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2103   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2105   switch (get_attr_type (insn))
2106     {
2107     case TYPE_MSKMOV:
2108       return "kmovq\t{%1, %0|%0, %1}";
2110     case TYPE_MULTI:
2111       return "#";
2113     case TYPE_MMX:
2114       return "pxor\t%0, %0";
2116     case TYPE_MMXMOV:
2117       /* Handle broken assemblers that require movd instead of movq.  */
2118       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2119           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2120         return "movd\t{%1, %0|%0, %1}";
2121       return "movq\t{%1, %0|%0, %1}";
2123     case TYPE_SSELOG1:
2124       if (GENERAL_REG_P (operands[0]))
2125         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2127       return standard_sse_constant_opcode (insn, operands[1]);
2129     case TYPE_SSEMOV:
2130       switch (get_attr_mode (insn))
2131         {
2132         case MODE_DI:
2133           /* Handle broken assemblers that require movd instead of movq.  */
2134           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2135               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2136             return "%vmovd\t{%1, %0|%0, %1}";
2137           return "%vmovq\t{%1, %0|%0, %1}";
2138         case MODE_TI:
2139           return "%vmovdqa\t{%1, %0|%0, %1}";
2140         case MODE_XI:
2141           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2143         case MODE_V2SF:
2144           gcc_assert (!TARGET_AVX);
2145           return "movlps\t{%1, %0|%0, %1}";
2146         case MODE_V4SF:
2147           return "%vmovaps\t{%1, %0|%0, %1}";
2149         default:
2150           gcc_unreachable ();
2151         }
2153     case TYPE_SSECVT:
2154       if (SSE_REG_P (operands[0]))
2155         return "movq2dq\t{%1, %0|%0, %1}";
2156       else
2157         return "movdq2q\t{%1, %0|%0, %1}";
2159     case TYPE_LEA:
2160       return "lea{q}\t{%E1, %0|%0, %E1}";
2162     case TYPE_IMOV:
2163       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2164       if (get_attr_mode (insn) == MODE_SI)
2165         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2166       else if (which_alternative == 4)
2167         return "movabs{q}\t{%1, %0|%0, %1}";
2168       else if (ix86_use_lea_for_mov (insn, operands))
2169         return "lea{q}\t{%E1, %0|%0, %E1}";
2170       else
2171         return "mov{q}\t{%1, %0|%0, %1}";
2173     default:
2174       gcc_unreachable ();
2175     }
2177   [(set (attr "isa")
2178      (cond [(eq_attr "alternative" "0,1")
2179               (const_string "nox64")
2180             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2181               (const_string "x64")
2182             (eq_attr "alternative" "17")
2183               (const_string "x64_sse4")
2184            ]
2185            (const_string "*")))
2186    (set (attr "type")
2187      (cond [(eq_attr "alternative" "0,1")
2188               (const_string "multi")
2189             (eq_attr "alternative" "6")
2190               (const_string "mmx")
2191             (eq_attr "alternative" "7,8,9,10,11")
2192               (const_string "mmxmov")
2193             (eq_attr "alternative" "12,17")
2194               (const_string "sselog1")
2195             (eq_attr "alternative" "13,14,15,16,18")
2196               (const_string "ssemov")
2197             (eq_attr "alternative" "19,20")
2198               (const_string "ssecvt")
2199             (eq_attr "alternative" "21,22,23,24")
2200               (const_string "mskmov")
2201             (and (match_operand 0 "register_operand")
2202                  (match_operand 1 "pic_32bit_operand"))
2203               (const_string "lea")
2204            ]
2205            (const_string "imov")))
2206    (set (attr "modrm")
2207      (if_then_else
2208        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2209          (const_string "0")
2210          (const_string "*")))
2211    (set (attr "length_immediate")
2212      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2213               (const_string "8")
2214             (eq_attr "alternative" "17")
2215               (const_string "1")
2216            ]
2217            (const_string "*")))
2218    (set (attr "prefix_rex")
2219      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2220        (const_string "1")
2221        (const_string "*")))
2222    (set (attr "prefix_extra")
2223      (if_then_else (eq_attr "alternative" "17")
2224        (const_string "1")
2225        (const_string "*")))
2226    (set (attr "prefix")
2227      (if_then_else (eq_attr "type" "sselog1,ssemov")
2228        (const_string "maybe_vex")
2229        (const_string "orig")))
2230    (set (attr "prefix_data16")
2231      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2232        (const_string "1")
2233        (const_string "*")))
2234    (set (attr "mode")
2235      (cond [(eq_attr "alternative" "2")
2236               (const_string "SI")
2237             (eq_attr "alternative" "12,13")
2238               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2239                           (match_operand 1 "ext_sse_reg_operand"))
2240                        (const_string "XI")
2241                      (ior (not (match_test "TARGET_SSE2"))
2242                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2243                        (const_string "V4SF")
2244                      (match_test "TARGET_AVX")
2245                        (const_string "TI")
2246                      (match_test "optimize_function_for_size_p (cfun)")
2247                        (const_string "V4SF")
2248                     ]
2249                     (const_string "TI"))
2251             (and (eq_attr "alternative" "14,15")
2252                  (not (match_test "TARGET_SSE2")))
2253               (const_string "V2SF")
2254             (eq_attr "alternative" "17")
2255               (const_string "TI")
2256            ]
2257            (const_string "DI")))])
2259 (define_split
2260   [(set (match_operand:DI 0 "nonimmediate_operand")
2261         (match_operand:DI 1 "general_operand"))]
2262   "!TARGET_64BIT && reload_completed
2263    && !(MMX_REG_P (operands[0])
2264         || SSE_REG_P (operands[0])
2265         || MASK_REG_P (operands[0]))
2266    && !(MMX_REG_P (operands[1])
2267         || SSE_REG_P (operands[1])
2268         || MASK_REG_P (operands[1]))"
2269   [(const_int 0)]
2270   "ix86_split_long_move (operands); DONE;")
2272 (define_insn "*movsi_internal"
2273   [(set (match_operand:SI 0 "nonimmediate_operand"
2274                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2275         (match_operand:SI 1 "general_operand"
2276                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2277   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2279   switch (get_attr_type (insn))
2280     {
2281     case TYPE_SSELOG1:
2282       if (GENERAL_REG_P (operands[0]))
2283         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2285       return standard_sse_constant_opcode (insn, operands[1]);
2287     case TYPE_MSKMOV:
2288       return "kmovd\t{%1, %0|%0, %1}";
2290     case TYPE_SSEMOV:
2291       switch (get_attr_mode (insn))
2292         {
2293         case MODE_SI:
2294           return "%vmovd\t{%1, %0|%0, %1}";
2295         case MODE_TI:
2296           return "%vmovdqa\t{%1, %0|%0, %1}";
2297         case MODE_XI:
2298           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2300         case MODE_V4SF:
2301           return "%vmovaps\t{%1, %0|%0, %1}";
2303         case MODE_SF:
2304           gcc_assert (!TARGET_AVX);
2305           return "movss\t{%1, %0|%0, %1}";
2307         default:
2308           gcc_unreachable ();
2309         }
2311     case TYPE_MMX:
2312       return "pxor\t%0, %0";
2314     case TYPE_MMXMOV:
2315       switch (get_attr_mode (insn))
2316         {
2317         case MODE_DI:
2318           return "movq\t{%1, %0|%0, %1}";
2319         case MODE_SI:
2320           return "movd\t{%1, %0|%0, %1}";
2322         default:
2323           gcc_unreachable ();
2324         }
2326     case TYPE_LEA:
2327       return "lea{l}\t{%E1, %0|%0, %E1}";
2329     case TYPE_IMOV:
2330       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2331       if (ix86_use_lea_for_mov (insn, operands))
2332         return "lea{l}\t{%E1, %0|%0, %E1}";
2333       else
2334         return "mov{l}\t{%1, %0|%0, %1}";
2336     default:
2337       gcc_unreachable ();
2338     }
2340   [(set (attr "isa")
2341      (if_then_else (eq_attr "alternative" "11")
2342        (const_string "sse4")
2343        (const_string "*")))
2344    (set (attr "type")
2345      (cond [(eq_attr "alternative" "2")
2346               (const_string "mmx")
2347             (eq_attr "alternative" "3,4,5")
2348               (const_string "mmxmov")
2349             (eq_attr "alternative" "6,11")
2350               (const_string "sselog1")
2351             (eq_attr "alternative" "7,8,9,10,12")
2352               (const_string "ssemov")
2353             (eq_attr "alternative" "13,14")
2354               (const_string "mskmov")
2355             (and (match_operand 0 "register_operand")
2356                  (match_operand 1 "pic_32bit_operand"))
2357               (const_string "lea")
2358            ]
2359            (const_string "imov")))
2360    (set (attr "length_immediate")
2361      (if_then_else (eq_attr "alternative" "11")
2362        (const_string "1")
2363        (const_string "*")))
2364    (set (attr "prefix_extra")
2365      (if_then_else (eq_attr "alternative" "11")
2366        (const_string "1")
2367        (const_string "*")))
2368    (set (attr "prefix")
2369      (if_then_else (eq_attr "type" "sselog1,ssemov")
2370        (const_string "maybe_vex")
2371        (const_string "orig")))
2372    (set (attr "prefix_data16")
2373      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2374        (const_string "1")
2375        (const_string "*")))
2376    (set (attr "mode")
2377      (cond [(eq_attr "alternative" "2,3")
2378               (const_string "DI")
2379             (eq_attr "alternative" "6,7")
2380               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2381                           (match_operand 1 "ext_sse_reg_operand"))
2382                        (const_string "XI")
2383                      (ior (not (match_test "TARGET_SSE2"))
2384                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2385                        (const_string "V4SF")
2386                      (match_test "TARGET_AVX")
2387                        (const_string "TI")
2388                      (match_test "optimize_function_for_size_p (cfun)")
2389                        (const_string "V4SF")
2390                     ]
2391                     (const_string "TI"))
2393             (and (eq_attr "alternative" "8,9")
2394                  (not (match_test "TARGET_SSE2")))
2395               (const_string "SF")
2396             (eq_attr "alternative" "11")
2397               (const_string "TI")
2398            ]
2399            (const_string "SI")))])
2401 (define_insn "kmovw"
2402   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2403         (unspec:HI
2404           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2405           UNSPEC_KMOV))]
2406   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2407   "@
2408    kmovw\t{%k1, %0|%0, %k1}
2409    kmovw\t{%1, %0|%0, %1}";
2410   [(set_attr "mode" "HI")
2411    (set_attr "type" "mskmov")
2412    (set_attr "prefix" "vex")])
2415 (define_insn "*movhi_internal"
2416   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2417         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2418   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420   switch (get_attr_type (insn))
2421     {
2422     case TYPE_IMOVX:
2423       /* movzwl is faster than movw on p2 due to partial word stalls,
2424          though not as fast as an aligned movl.  */
2425       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2427     case TYPE_MSKMOV:
2428       switch (which_alternative)
2429         {
2430         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2431         case 5: return "kmovw\t{%1, %0|%0, %1}";
2432         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2433         default: gcc_unreachable ();
2434         }
2436     default:
2437       if (get_attr_mode (insn) == MODE_SI)
2438         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2439       else
2440         return "mov{w}\t{%1, %0|%0, %1}";
2441     }
2443   [(set (attr "type")
2444      (cond [(eq_attr "alternative" "4,5,6")
2445               (const_string "mskmov")
2446             (match_test "optimize_function_for_size_p (cfun)")
2447               (const_string "imov")
2448             (and (eq_attr "alternative" "0")
2449                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2450                       (not (match_test "TARGET_HIMODE_MATH"))))
2451               (const_string "imov")
2452             (and (eq_attr "alternative" "1,2")
2453                  (match_operand:HI 1 "aligned_operand"))
2454               (const_string "imov")
2455             (and (match_test "TARGET_MOVX")
2456                  (eq_attr "alternative" "0,2"))
2457               (const_string "imovx")
2458            ]
2459            (const_string "imov")))
2460     (set (attr "prefix")
2461       (if_then_else (eq_attr "alternative" "4,5,6")
2462         (const_string "vex")
2463         (const_string "orig")))
2464     (set (attr "mode")
2465       (cond [(eq_attr "type" "imovx")
2466                (const_string "SI")
2467              (and (eq_attr "alternative" "1,2")
2468                   (match_operand:HI 1 "aligned_operand"))
2469                (const_string "SI")
2470              (and (eq_attr "alternative" "0")
2471                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2472                        (not (match_test "TARGET_HIMODE_MATH"))))
2473                (const_string "SI")
2474             ]
2475             (const_string "HI")))])
2477 ;; Situation is quite tricky about when to choose full sized (SImode) move
2478 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2479 ;; partial register dependency machines (such as AMD Athlon), where QImode
2480 ;; moves issue extra dependency and for partial register stalls machines
2481 ;; that don't use QImode patterns (and QImode move cause stall on the next
2482 ;; instruction).
2484 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2485 ;; register stall machines with, where we use QImode instructions, since
2486 ;; partial register stall can be caused there.  Then we use movzx.
2488 (define_insn "*movqi_internal"
2489   [(set (match_operand:QI 0 "nonimmediate_operand"
2490                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2491         (match_operand:QI 1 "general_operand"
2492                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2493   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2495   switch (get_attr_type (insn))
2496     {
2497     case TYPE_IMOVX:
2498       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2499       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2501     case TYPE_MSKMOV:
2502       switch (which_alternative)
2503         {
2504         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2505                                        : "kmovw\t{%k1, %0|%0, %k1}";
2506         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2507                                        : "kmovw\t{%1, %0|%0, %1}";
2508         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2509                                        : "kmovw\t{%1, %k0|%k0, %1}";
2510         case 10:
2511         case 11:
2512           gcc_assert (TARGET_AVX512DQ);
2513           return "kmovb\t{%1, %0|%0, %1}";
2514         default: gcc_unreachable ();
2515         }
2517     default:
2518       if (get_attr_mode (insn) == MODE_SI)
2519         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2520       else
2521         return "mov{b}\t{%1, %0|%0, %1}";
2522     }
2524   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2525    (set (attr "type")
2526      (cond [(eq_attr "alternative" "7,8,9,10,11")
2527               (const_string "mskmov")
2528             (and (eq_attr "alternative" "5")
2529                  (not (match_operand:QI 1 "aligned_operand")))
2530               (const_string "imovx")
2531             (match_test "optimize_function_for_size_p (cfun)")
2532               (const_string "imov")
2533             (and (eq_attr "alternative" "3")
2534                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2535                       (not (match_test "TARGET_QIMODE_MATH"))))
2536               (const_string "imov")
2537             (eq_attr "alternative" "3,5")
2538               (const_string "imovx")
2539             (and (match_test "TARGET_MOVX")
2540                  (eq_attr "alternative" "2"))
2541               (const_string "imovx")
2542            ]
2543            (const_string "imov")))
2544    (set (attr "prefix")
2545      (if_then_else (eq_attr "alternative" "7,8,9")
2546        (const_string "vex")
2547        (const_string "orig")))
2548    (set (attr "mode")
2549       (cond [(eq_attr "alternative" "3,4,5")
2550                (const_string "SI")
2551              (eq_attr "alternative" "6")
2552                (const_string "QI")
2553              (eq_attr "type" "imovx")
2554                (const_string "SI")
2555              (and (eq_attr "type" "imov")
2556                   (and (eq_attr "alternative" "0,1")
2557                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2558                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2559                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2560                (const_string "SI")
2561              ;; Avoid partial register stalls when not using QImode arithmetic
2562              (and (eq_attr "type" "imov")
2563                   (and (eq_attr "alternative" "0,1")
2564                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2565                             (not (match_test "TARGET_QIMODE_MATH")))))
2566                (const_string "SI")
2567            ]
2568            (const_string "QI")))])
2570 ;; Stores and loads of ax to arbitrary constant address.
2571 ;; We fake an second form of instruction to force reload to load address
2572 ;; into register when rax is not available
2573 (define_insn "*movabs<mode>_1"
2574   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2575         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2576   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2577   "@
2578    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2579    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2580   [(set_attr "type" "imov")
2581    (set_attr "modrm" "0,*")
2582    (set_attr "length_address" "8,0")
2583    (set_attr "length_immediate" "0,*")
2584    (set_attr "memory" "store")
2585    (set_attr "mode" "<MODE>")])
2587 (define_insn "*movabs<mode>_2"
2588   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2589         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2590   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2591   "@
2592    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2593    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2594   [(set_attr "type" "imov")
2595    (set_attr "modrm" "0,*")
2596    (set_attr "length_address" "8,0")
2597    (set_attr "length_immediate" "0")
2598    (set_attr "memory" "load")
2599    (set_attr "mode" "<MODE>")])
2601 (define_insn "*swap<mode>"
2602   [(set (match_operand:SWI48 0 "register_operand" "+r")
2603         (match_operand:SWI48 1 "register_operand" "+r"))
2604    (set (match_dup 1)
2605         (match_dup 0))]
2606   ""
2607   "xchg{<imodesuffix>}\t%1, %0"
2608   [(set_attr "type" "imov")
2609    (set_attr "mode" "<MODE>")
2610    (set_attr "pent_pair" "np")
2611    (set_attr "athlon_decode" "vector")
2612    (set_attr "amdfam10_decode" "double")
2613    (set_attr "bdver1_decode" "double")])
2615 (define_insn "*swap<mode>_1"
2616   [(set (match_operand:SWI12 0 "register_operand" "+r")
2617         (match_operand:SWI12 1 "register_operand" "+r"))
2618    (set (match_dup 1)
2619         (match_dup 0))]
2620   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2621   "xchg{l}\t%k1, %k0"
2622   [(set_attr "type" "imov")
2623    (set_attr "mode" "SI")
2624    (set_attr "pent_pair" "np")
2625    (set_attr "athlon_decode" "vector")
2626    (set_attr "amdfam10_decode" "double")
2627    (set_attr "bdver1_decode" "double")])
2629 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2630 ;; is disabled for AMDFAM10
2631 (define_insn "*swap<mode>_2"
2632   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2633         (match_operand:SWI12 1 "register_operand" "+<r>"))
2634    (set (match_dup 1)
2635         (match_dup 0))]
2636   "TARGET_PARTIAL_REG_STALL"
2637   "xchg{<imodesuffix>}\t%1, %0"
2638   [(set_attr "type" "imov")
2639    (set_attr "mode" "<MODE>")
2640    (set_attr "pent_pair" "np")
2641    (set_attr "athlon_decode" "vector")])
2643 (define_expand "movstrict<mode>"
2644   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2645         (match_operand:SWI12 1 "general_operand"))]
2646   ""
2648   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2649     FAIL;
2650   if (GET_CODE (operands[0]) == SUBREG
2651       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2652     FAIL;
2653   /* Don't generate memory->memory moves, go through a register */
2654   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2655     operands[1] = force_reg (<MODE>mode, operands[1]);
2658 (define_insn "*movstrict<mode>_1"
2659   [(set (strict_low_part
2660           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2661         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2662   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2663    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2664   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2665   [(set_attr "type" "imov")
2666    (set_attr "mode" "<MODE>")])
2668 (define_insn "*movstrict<mode>_xor"
2669   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2670         (match_operand:SWI12 1 "const0_operand"))
2671    (clobber (reg:CC FLAGS_REG))]
2672   "reload_completed"
2673   "xor{<imodesuffix>}\t%0, %0"
2674   [(set_attr "type" "alu1")
2675    (set_attr "mode" "<MODE>")
2676    (set_attr "length_immediate" "0")])
2678 (define_expand "extv<mode>"
2679   [(set (match_operand:SWI24 0 "register_operand")
2680         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2681                             (match_operand:SI 2 "const_int_operand")
2682                             (match_operand:SI 3 "const_int_operand")))]
2683   ""
2685   /* Handle extractions from %ah et al.  */
2686   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2687     FAIL;
2689   if (! ext_register_operand (operands[1], VOIDmode))
2690     operands[1] = copy_to_reg (operands[1]);
2693 (define_insn "*extv<mode>"
2694   [(set (match_operand:SWI24 0 "register_operand" "=R")
2695         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2696                             (const_int 8)
2697                             (const_int 8)))]
2698   ""
2699   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2700   [(set_attr "type" "imovx")
2701    (set_attr "mode" "SI")])
2703 (define_insn "*extvqi"
2704   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2705         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2706                          (const_int 8)
2707                          (const_int 8)))]
2708   ""
2710   switch (get_attr_type (insn))
2711     {
2712     case TYPE_IMOVX:
2713       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2714     default:
2715       return "mov{b}\t{%h1, %0|%0, %h1}";
2716     }
2718   [(set_attr "isa" "*,*,nox64")
2719    (set (attr "type")
2720      (if_then_else (and (match_operand:QI 0 "register_operand")
2721                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2722                              (match_test "TARGET_MOVX")))
2723         (const_string "imovx")
2724         (const_string "imov")))
2725    (set (attr "mode")
2726      (if_then_else (eq_attr "type" "imovx")
2727         (const_string "SI")
2728         (const_string "QI")))])
2730 (define_expand "extzv<mode>"
2731   [(set (match_operand:SWI248 0 "register_operand")
2732         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2733                              (match_operand:SI 2 "const_int_operand")
2734                              (match_operand:SI 3 "const_int_operand")))]
2735   ""
2737   if (ix86_expand_pextr (operands))
2738     DONE;
2740   /* Handle extractions from %ah et al.  */
2741   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2742     FAIL;
2744   if (! ext_register_operand (operands[1], VOIDmode))
2745     operands[1] = copy_to_reg (operands[1]);
2748 (define_insn "*extzv<mode>"
2749   [(set (match_operand:SWI248 0 "register_operand" "=R")
2750         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2751                              (const_int 8)
2752                              (const_int 8)))]
2753   ""
2754   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2755   [(set_attr "type" "imovx")
2756    (set_attr "mode" "SI")])
2758 (define_insn "*extzvqi"
2759   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2760         (subreg:QI
2761           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2762                            (const_int 8)
2763                            (const_int 8)) 0))]
2764   ""
2766   switch (get_attr_type (insn))
2767     {
2768     case TYPE_IMOVX:
2769       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2770     default:
2771       return "mov{b}\t{%h1, %0|%0, %h1}";
2772     }
2774   [(set_attr "isa" "*,*,nox64")
2775    (set (attr "type")
2776      (if_then_else (and (match_operand:QI 0 "register_operand")
2777                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2778                              (match_test "TARGET_MOVX")))
2779         (const_string "imovx")
2780         (const_string "imov")))
2781    (set (attr "mode")
2782      (if_then_else (eq_attr "type" "imovx")
2783         (const_string "SI")
2784         (const_string "QI")))])
2786 (define_expand "insv<mode>"
2787   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2788                              (match_operand:SI 1 "const_int_operand")
2789                              (match_operand:SI 2 "const_int_operand"))
2790         (match_operand:SWI248 3 "register_operand"))]
2791   ""
2793   rtx dst;
2795   if (ix86_expand_pinsr (operands))
2796     DONE;
2798   /* Handle insertions to %ah et al.  */
2799   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2800     FAIL;
2802   dst = operands[0];
2803   
2804   if (!ext_register_operand (dst, VOIDmode))
2805     dst = copy_to_reg (dst);
2807   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2809   /* Fix up the destination if needed.  */
2810   if (dst != operands[0])
2811     emit_move_insn (operands[0], dst);
2813   DONE;
2816 (define_insn "insv<mode>_1"
2817   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2818                              (const_int 8)
2819                              (const_int 8))
2820         (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2821   ""
2823   if (CONST_INT_P (operands[1]))
2824     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2825   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2827   [(set_attr "isa" "*,nox64")
2828    (set_attr "type" "imov")
2829    (set_attr "mode" "QI")])
2831 (define_insn "*insvqi"
2832   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2833                          (const_int 8)
2834                          (const_int 8))
2835         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2836                      (const_int 8)))]
2837   ""
2838   "mov{b}\t{%h1, %h0|%h0, %h1}"
2839   [(set_attr "type" "imov")
2840    (set_attr "mode" "QI")])
2842 ;; Floating point push instructions.
2844 (define_insn "*pushtf"
2845   [(set (match_operand:TF 0 "push_operand" "=<,<")
2846         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2847   "TARGET_64BIT || TARGET_SSE"
2849   /* This insn should be already split before reg-stack.  */
2850   gcc_unreachable ();
2852   [(set_attr "isa" "*,x64")
2853    (set_attr "type" "multi")
2854    (set_attr "unit" "sse,*")
2855    (set_attr "mode" "TF,DI")])
2857 ;; %%% Kill this when call knows how to work this out.
2858 (define_split
2859   [(set (match_operand:TF 0 "push_operand")
2860         (match_operand:TF 1 "sse_reg_operand"))]
2861   "TARGET_SSE && reload_completed"
2862   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2863    (set (match_dup 0) (match_dup 1))]
2865   /* Preserve memory attributes. */
2866   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2869 (define_insn "*pushxf"
2870   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2871         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2872   ""
2874   /* This insn should be already split before reg-stack.  */
2875   gcc_unreachable ();
2877   [(set_attr "type" "multi")
2878    (set_attr "unit" "i387,*,*,*")
2879    (set (attr "mode")
2880         (cond [(eq_attr "alternative" "1,2,3")
2881                  (if_then_else (match_test "TARGET_64BIT")
2882                    (const_string "DI")
2883                    (const_string "SI"))
2884               ]
2885               (const_string "XF")))
2886    (set (attr "preferred_for_size")
2887      (cond [(eq_attr "alternative" "1")
2888               (symbol_ref "false")]
2889            (symbol_ref "true")))])
2891 ;; %%% Kill this when call knows how to work this out.
2892 (define_split
2893   [(set (match_operand:XF 0 "push_operand")
2894         (match_operand:XF 1 "fp_register_operand"))]
2895   "reload_completed"
2896   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2897    (set (match_dup 0) (match_dup 1))]
2899   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2900   /* Preserve memory attributes. */
2901   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2904 (define_insn "*pushdf"
2905   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2906         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2907   ""
2909   /* This insn should be already split before reg-stack.  */
2910   gcc_unreachable ();
2912   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2913    (set_attr "type" "multi")
2914    (set_attr "unit" "i387,*,*,*,*,sse")
2915    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2916    (set (attr "preferred_for_size")
2917      (cond [(eq_attr "alternative" "1")
2918               (symbol_ref "false")]
2919            (symbol_ref "true")))
2920    (set (attr "preferred_for_speed")
2921      (cond [(eq_attr "alternative" "1")
2922               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2923            (symbol_ref "true")))])
2924    
2925 ;; %%% Kill this when call knows how to work this out.
2926 (define_split
2927   [(set (match_operand:DF 0 "push_operand")
2928         (match_operand:DF 1 "any_fp_register_operand"))]
2929   "reload_completed"
2930   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2931    (set (match_dup 0) (match_dup 1))]
2933   /* Preserve memory attributes. */
2934   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2937 (define_insn "*pushsf_rex64"
2938   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2939         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2940   "TARGET_64BIT"
2942   /* Anything else should be already split before reg-stack.  */
2943   gcc_assert (which_alternative == 1);
2944   return "push{q}\t%q1";
2946   [(set_attr "type" "multi,push,multi")
2947    (set_attr "unit" "i387,*,*")
2948    (set_attr "mode" "SF,DI,SF")])
2950 (define_insn "*pushsf"
2951   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2952         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2953   "!TARGET_64BIT"
2955   /* Anything else should be already split before reg-stack.  */
2956   gcc_assert (which_alternative == 1);
2957   return "push{l}\t%1";
2959   [(set_attr "type" "multi,push,multi")
2960    (set_attr "unit" "i387,*,*")
2961    (set_attr "mode" "SF,SI,SF")])
2963 ;; %%% Kill this when call knows how to work this out.
2964 (define_split
2965   [(set (match_operand:SF 0 "push_operand")
2966         (match_operand:SF 1 "any_fp_register_operand"))]
2967   "reload_completed"
2968   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2969    (set (match_dup 0) (match_dup 1))]
2971   rtx op = XEXP (operands[0], 0);
2972   if (GET_CODE (op) == PRE_DEC)
2973     {
2974       gcc_assert (!TARGET_64BIT);
2975       op = GEN_INT (-4);
2976     }
2977   else
2978     {
2979       op = XEXP (XEXP (op, 1), 1);
2980       gcc_assert (CONST_INT_P (op));
2981     }
2982   operands[2] = op;
2983   /* Preserve memory attributes. */
2984   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2987 (define_split
2988   [(set (match_operand:SF 0 "push_operand")
2989         (match_operand:SF 1 "memory_operand"))]
2990   "reload_completed
2991    && (operands[2] = find_constant_src (insn))"
2992   [(set (match_dup 0) (match_dup 2))])
2994 (define_split
2995   [(set (match_operand 0 "push_operand")
2996         (match_operand 1 "general_operand"))]
2997   "reload_completed
2998    && (GET_MODE (operands[0]) == TFmode
2999        || GET_MODE (operands[0]) == XFmode
3000        || GET_MODE (operands[0]) == DFmode)
3001    && !ANY_FP_REG_P (operands[1])"
3002   [(const_int 0)]
3003   "ix86_split_long_move (operands); DONE;")
3005 ;; Floating point move instructions.
3007 (define_expand "movtf"
3008   [(set (match_operand:TF 0 "nonimmediate_operand")
3009         (match_operand:TF 1 "nonimmediate_operand"))]
3010   "TARGET_64BIT || TARGET_SSE"
3011   "ix86_expand_move (TFmode, operands); DONE;")
3013 (define_expand "mov<mode>"
3014   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3015         (match_operand:X87MODEF 1 "general_operand"))]
3016   ""
3017   "ix86_expand_move (<MODE>mode, operands); DONE;")
3019 (define_insn "*movtf_internal"
3020   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
3021         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
3022   "(TARGET_64BIT || TARGET_SSE)
3023    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3024    && (!can_create_pseudo_p ()
3025        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3026        || !CONST_DOUBLE_P (operands[1])
3027        || (optimize_function_for_size_p (cfun)
3028            && standard_sse_constant_p (operands[1])
3029            && !memory_operand (operands[0], TFmode))
3030        || (!TARGET_MEMORY_MISMATCH_STALL
3031            && memory_operand (operands[0], TFmode)))"
3033   switch (get_attr_type (insn))
3034     {
3035     case TYPE_SSELOG1:
3036       return standard_sse_constant_opcode (insn, operands[1]);
3038     case TYPE_SSEMOV:
3039       /* Handle misaligned load/store since we
3040          don't have movmisaligntf pattern. */
3041       if (misaligned_operand (operands[0], TFmode)
3042           || misaligned_operand (operands[1], TFmode))
3043         {
3044           if (get_attr_mode (insn) == MODE_V4SF)
3045             return "%vmovups\t{%1, %0|%0, %1}";
3046           else
3047             return "%vmovdqu\t{%1, %0|%0, %1}";
3048         }
3049       else
3050         {
3051           if (get_attr_mode (insn) == MODE_V4SF)
3052             return "%vmovaps\t{%1, %0|%0, %1}";
3053           else
3054             return "%vmovdqa\t{%1, %0|%0, %1}";
3055         }
3057     case TYPE_MULTI:
3058         return "#";
3060     default:
3061       gcc_unreachable ();
3062     }
3064   [(set_attr "isa" "*,*,*,x64,x64")
3065    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3066    (set (attr "prefix")
3067      (if_then_else (eq_attr "type" "sselog1,ssemov")
3068        (const_string "maybe_vex")
3069        (const_string "orig")))
3070    (set (attr "mode")
3071         (cond [(eq_attr "alternative" "3,4")
3072                  (const_string "DI")
3073                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3074                  (const_string "V4SF")
3075                (and (eq_attr "alternative" "2")
3076                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3077                  (const_string "V4SF")
3078                (match_test "TARGET_AVX")
3079                  (const_string "TI")
3080                (ior (not (match_test "TARGET_SSE2"))
3081                     (match_test "optimize_function_for_size_p (cfun)"))
3082                  (const_string "V4SF")
3083                ]
3084                (const_string "TI")))])
3086 ;; Possible store forwarding (partial memory) stall
3087 ;; in alternatives 4, 6, 7 and 8.
3088 (define_insn "*movxf_internal"
3089   [(set (match_operand:XF 0 "nonimmediate_operand"
3090          "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3091         (match_operand:XF 1 "general_operand"
3092          "fm,f,G,roF,r , *roF,*r,F ,C"))]
3093   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3094    && (!can_create_pseudo_p ()
3095        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3096        || !CONST_DOUBLE_P (operands[1])
3097        || (optimize_function_for_size_p (cfun)
3098            && standard_80387_constant_p (operands[1]) > 0
3099            && !memory_operand (operands[0], XFmode))
3100        || (!TARGET_MEMORY_MISMATCH_STALL
3101            && memory_operand (operands[0], XFmode)))"
3103   switch (get_attr_type (insn))
3104     {
3105     case TYPE_FMOV:
3106       if (which_alternative == 2)
3107         return standard_80387_constant_opcode (operands[1]);
3108       return output_387_reg_move (insn, operands);
3110     case TYPE_MULTI:
3111       return "#";
3113     default:
3114       gcc_unreachable ();
3115     }
3117   [(set (attr "isa")
3118         (cond [(eq_attr "alternative" "7")
3119                  (const_string "nox64")
3120                (eq_attr "alternative" "8")
3121                  (const_string "x64")
3122               ]
3123               (const_string "*")))
3124    (set (attr "type")
3125         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3126                  (const_string "multi")
3127               ]
3128               (const_string "fmov")))
3129    (set (attr "mode")
3130         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3131                  (if_then_else (match_test "TARGET_64BIT")
3132                    (const_string "DI")
3133                    (const_string "SI"))
3134               ]
3135               (const_string "XF")))
3136    (set (attr "preferred_for_size")
3137      (cond [(eq_attr "alternative" "3,4")
3138               (symbol_ref "false")]
3139            (symbol_ref "true")))])
3140    
3141 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3142 (define_insn "*movdf_internal"
3143   [(set (match_operand:DF 0 "nonimmediate_operand"
3144     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3145         (match_operand:DF 1 "general_operand"
3146     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3147   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3148    && (!can_create_pseudo_p ()
3149        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3150        || !CONST_DOUBLE_P (operands[1])
3151        || (optimize_function_for_size_p (cfun)
3152            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3153                 && standard_80387_constant_p (operands[1]) > 0)
3154                || (TARGET_SSE2 && TARGET_SSE_MATH
3155                    && standard_sse_constant_p (operands[1])))
3156            && !memory_operand (operands[0], DFmode))
3157        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3158            && memory_operand (operands[0], DFmode)))"
3160   switch (get_attr_type (insn))
3161     {
3162     case TYPE_FMOV:
3163       if (which_alternative == 2)
3164         return standard_80387_constant_opcode (operands[1]);
3165       return output_387_reg_move (insn, operands);
3167     case TYPE_MULTI:
3168       return "#";
3170     case TYPE_IMOV:
3171       if (get_attr_mode (insn) == MODE_SI)
3172         return "mov{l}\t{%1, %k0|%k0, %1}";
3173       else if (which_alternative == 11)
3174         return "movabs{q}\t{%1, %0|%0, %1}";
3175       else
3176         return "mov{q}\t{%1, %0|%0, %1}";
3178     case TYPE_SSELOG1:
3179       return standard_sse_constant_opcode (insn, operands[1]);
3181     case TYPE_SSEMOV:
3182       switch (get_attr_mode (insn))
3183         {
3184         case MODE_DF:
3185           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3186             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3187           return "%vmovsd\t{%1, %0|%0, %1}";
3189         case MODE_V4SF:
3190           return "%vmovaps\t{%1, %0|%0, %1}";
3191         case MODE_V8DF:
3192           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3193         case MODE_V2DF:
3194           return "%vmovapd\t{%1, %0|%0, %1}";
3196         case MODE_V2SF:
3197           gcc_assert (!TARGET_AVX);
3198           return "movlps\t{%1, %0|%0, %1}";
3199         case MODE_V1DF:
3200           gcc_assert (!TARGET_AVX);
3201           return "movlpd\t{%1, %0|%0, %1}";
3203         case MODE_DI:
3204           /* Handle broken assemblers that require movd instead of movq.  */
3205           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3206               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3207             return "%vmovd\t{%1, %0|%0, %1}";
3208           return "%vmovq\t{%1, %0|%0, %1}";
3210         default:
3211           gcc_unreachable ();
3212         }
3214     default:
3215       gcc_unreachable ();
3216     }
3218   [(set (attr "isa")
3219         (cond [(eq_attr "alternative" "3,4,5,6,7")
3220                  (const_string "nox64")
3221                (eq_attr "alternative" "8,9,10,11,20,21")
3222                  (const_string "x64")
3223                (eq_attr "alternative" "12,13,14,15")
3224                  (const_string "sse2")
3225               ]
3226               (const_string "*")))
3227    (set (attr "type")
3228         (cond [(eq_attr "alternative" "0,1,2")
3229                  (const_string "fmov")
3230                (eq_attr "alternative" "3,4,5,6,7")
3231                  (const_string "multi")
3232                (eq_attr "alternative" "8,9,10,11")
3233                  (const_string "imov")
3234                (eq_attr "alternative" "12,16")
3235                  (const_string "sselog1")
3236               ]
3237               (const_string "ssemov")))
3238    (set (attr "modrm")
3239      (if_then_else (eq_attr "alternative" "11")
3240        (const_string "0")
3241        (const_string "*")))
3242    (set (attr "length_immediate")
3243      (if_then_else (eq_attr "alternative" "11")
3244        (const_string "8")
3245        (const_string "*")))
3246    (set (attr "prefix")
3247      (if_then_else (eq_attr "type" "sselog1,ssemov")
3248        (const_string "maybe_vex")
3249        (const_string "orig")))
3250    (set (attr "prefix_data16")
3251      (if_then_else
3252        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3253             (eq_attr "mode" "V1DF"))
3254        (const_string "1")
3255        (const_string "*")))
3256    (set (attr "mode")
3257         (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3258                  (const_string "SI")
3259                (eq_attr "alternative" "8,9,11,20,21")
3260                  (const_string "DI")
3262                /* xorps is one byte shorter for non-AVX targets.  */
3263                (eq_attr "alternative" "12,16")
3264                  (cond [(not (match_test "TARGET_SSE2"))
3265                           (const_string "V4SF")
3266                         (match_test "TARGET_AVX512F")
3267                           (const_string "XI")
3268                         (match_test "TARGET_AVX")
3269                           (const_string "V2DF")
3270                         (match_test "optimize_function_for_size_p (cfun)")
3271                           (const_string "V4SF")
3272                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3273                           (const_string "TI")
3274                        ]
3275                        (const_string "V2DF"))
3277                /* For architectures resolving dependencies on
3278                   whole SSE registers use movapd to break dependency
3279                   chains, otherwise use short move to avoid extra work.  */
3281                /* movaps is one byte shorter for non-AVX targets.  */
3282                (eq_attr "alternative" "13,17")
3283                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3284                              (match_operand 1 "ext_sse_reg_operand"))
3285                           (const_string "V8DF")
3286                         (ior (not (match_test "TARGET_SSE2"))
3287                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3288                           (const_string "V4SF")
3289                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3290                           (const_string "V2DF")
3291                         (match_test "TARGET_AVX")
3292                           (const_string "DF")
3293                         (match_test "optimize_function_for_size_p (cfun)")
3294                           (const_string "V4SF")
3295                        ]
3296                        (const_string "DF"))
3298                /* For architectures resolving dependencies on register
3299                   parts we may avoid extra work to zero out upper part
3300                   of register.  */
3301                (eq_attr "alternative" "14,18")
3302                  (cond [(not (match_test "TARGET_SSE2"))
3303                           (const_string "V2SF")
3304                         (match_test "TARGET_AVX")
3305                           (const_string "DF")
3306                         (match_test "TARGET_SSE_SPLIT_REGS")
3307                           (const_string "V1DF")
3308                        ]
3309                        (const_string "DF"))
3311                (and (eq_attr "alternative" "15,19")
3312                     (not (match_test "TARGET_SSE2")))
3313                  (const_string "V2SF")
3314               ]
3315               (const_string "DF")))
3316    (set (attr "preferred_for_size")
3317      (cond [(eq_attr "alternative" "3,4")
3318               (symbol_ref "false")]
3319            (symbol_ref "true")))
3320    (set (attr "preferred_for_speed")
3321      (cond [(eq_attr "alternative" "3,4")
3322               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3323            (symbol_ref "true")))])
3325 (define_insn "*movsf_internal"
3326   [(set (match_operand:SF 0 "nonimmediate_operand"
3327           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3328         (match_operand:SF 1 "general_operand"
3329           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3331    && (!can_create_pseudo_p ()
3332        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3333        || !CONST_DOUBLE_P (operands[1])
3334        || (optimize_function_for_size_p (cfun)
3335            && ((!TARGET_SSE_MATH
3336                 && standard_80387_constant_p (operands[1]) > 0)
3337                || (TARGET_SSE_MATH
3338                    && standard_sse_constant_p (operands[1]))))
3339        || memory_operand (operands[0], SFmode))"
3341   switch (get_attr_type (insn))
3342     {
3343     case TYPE_FMOV:
3344       if (which_alternative == 2)
3345         return standard_80387_constant_opcode (operands[1]);
3346       return output_387_reg_move (insn, operands);
3348     case TYPE_IMOV:
3349       return "mov{l}\t{%1, %0|%0, %1}";
3351     case TYPE_SSELOG1:
3352       return standard_sse_constant_opcode (insn, operands[1]);
3354     case TYPE_SSEMOV:
3355       switch (get_attr_mode (insn))
3356         {
3357         case MODE_SF:
3358           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3359             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3360           return "%vmovss\t{%1, %0|%0, %1}";
3362         case MODE_V16SF:
3363           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3364         case MODE_V4SF:
3365           return "%vmovaps\t{%1, %0|%0, %1}";
3367         case MODE_SI:
3368           return "%vmovd\t{%1, %0|%0, %1}";
3370         default:
3371           gcc_unreachable ();
3372         }
3374     case TYPE_MMXMOV:
3375       switch (get_attr_mode (insn))
3376         {
3377         case MODE_DI:
3378           return "movq\t{%1, %0|%0, %1}";
3379         case MODE_SI:
3380           return "movd\t{%1, %0|%0, %1}";
3382         default:
3383           gcc_unreachable ();
3384         }
3386     default:
3387       gcc_unreachable ();
3388     }
3390   [(set (attr "type")
3391         (cond [(eq_attr "alternative" "0,1,2")
3392                  (const_string "fmov")
3393                (eq_attr "alternative" "3,4")
3394                  (const_string "imov")
3395                (eq_attr "alternative" "5")
3396                  (const_string "sselog1")
3397                (eq_attr "alternative" "11,12,13,14,15")
3398                  (const_string "mmxmov")
3399               ]
3400               (const_string "ssemov")))
3401    (set (attr "prefix")
3402      (if_then_else (eq_attr "type" "sselog1,ssemov")
3403        (const_string "maybe_vex")
3404        (const_string "orig")))
3405    (set (attr "prefix_data16")
3406      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3407        (const_string "1")
3408        (const_string "*")))
3409    (set (attr "mode")
3410         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3411                  (const_string "SI")
3412                (eq_attr "alternative" "11")
3413                  (const_string "DI")
3414                (eq_attr "alternative" "5")
3415                  (cond [(not (match_test "TARGET_SSE2"))
3416                           (const_string "V4SF")
3417                         (match_test "TARGET_AVX512F")
3418                           (const_string "V16SF")
3419                         (match_test "TARGET_AVX")
3420                           (const_string "V4SF")
3421                         (match_test "optimize_function_for_size_p (cfun)")
3422                           (const_string "V4SF")
3423                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3424                           (const_string "TI")
3425                        ]
3426                        (const_string "V4SF"))
3428                /* For architectures resolving dependencies on
3429                   whole SSE registers use APS move to break dependency
3430                   chains, otherwise use short move to avoid extra work.
3432                   Do the same for architectures resolving dependencies on
3433                   the parts.  While in DF mode it is better to always handle
3434                   just register parts, the SF mode is different due to lack
3435                   of instructions to load just part of the register.  It is
3436                   better to maintain the whole registers in single format
3437                   to avoid problems on using packed logical operations.  */
3438                (eq_attr "alternative" "6")
3439                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3440                               (match_operand 1 "ext_sse_reg_operand"))
3441                           (const_string "V16SF")
3442                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3443                              (match_test "TARGET_SSE_SPLIT_REGS"))
3444                           (const_string "V4SF")
3445                        ]
3446                        (const_string "SF"))
3447               ]
3448               (const_string "SF")))])
3450 (define_split
3451   [(set (match_operand 0 "any_fp_register_operand")
3452         (match_operand 1 "memory_operand"))]
3453   "reload_completed
3454    && (GET_MODE (operands[0]) == TFmode
3455        || GET_MODE (operands[0]) == XFmode
3456        || GET_MODE (operands[0]) == DFmode
3457        || GET_MODE (operands[0]) == SFmode)
3458    && (operands[2] = find_constant_src (insn))"
3459   [(set (match_dup 0) (match_dup 2))]
3461   rtx c = operands[2];
3462   int r = REGNO (operands[0]);
3464   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3465       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3466     FAIL;
3469 (define_split
3470   [(set (match_operand 0 "any_fp_register_operand")
3471         (float_extend (match_operand 1 "memory_operand")))]
3472   "reload_completed
3473    && (GET_MODE (operands[0]) == TFmode
3474        || GET_MODE (operands[0]) == XFmode
3475        || GET_MODE (operands[0]) == DFmode)
3476    && (operands[2] = find_constant_src (insn))"
3477   [(set (match_dup 0) (match_dup 2))]
3479   rtx c = operands[2];
3480   int r = REGNO (operands[0]);
3482   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3483       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3484     FAIL;
3487 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3488 (define_split
3489   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3490         (match_operand:X87MODEF 1 "immediate_operand"))]
3491   "reload_completed
3492    && (standard_80387_constant_p (operands[1]) == 8
3493        || standard_80387_constant_p (operands[1]) == 9)"
3494   [(set (match_dup 0)(match_dup 1))
3495    (set (match_dup 0)
3496         (neg:X87MODEF (match_dup 0)))]
3498   REAL_VALUE_TYPE r;
3500   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3501   if (real_isnegzero (&r))
3502     operands[1] = CONST0_RTX (<MODE>mode);
3503   else
3504     operands[1] = CONST1_RTX (<MODE>mode);
3507 (define_split
3508   [(set (match_operand 0 "nonimmediate_operand")
3509         (match_operand 1 "general_operand"))]
3510   "reload_completed
3511    && (GET_MODE (operands[0]) == TFmode
3512        || GET_MODE (operands[0]) == XFmode
3513        || GET_MODE (operands[0]) == DFmode)
3514    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3515   [(const_int 0)]
3516   "ix86_split_long_move (operands); DONE;")
3518 (define_insn "swapxf"
3519   [(set (match_operand:XF 0 "register_operand" "+f")
3520         (match_operand:XF 1 "register_operand" "+f"))
3521    (set (match_dup 1)
3522         (match_dup 0))]
3523   "TARGET_80387"
3525   if (STACK_TOP_P (operands[0]))
3526     return "fxch\t%1";
3527   else
3528     return "fxch\t%0";
3530   [(set_attr "type" "fxch")
3531    (set_attr "mode" "XF")])
3533 (define_insn "*swap<mode>"
3534   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3535         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3536    (set (match_dup 1)
3537         (match_dup 0))]
3538   "TARGET_80387 || reload_completed"
3540   if (STACK_TOP_P (operands[0]))
3541     return "fxch\t%1";
3542   else
3543     return "fxch\t%0";
3545   [(set_attr "type" "fxch")
3546    (set_attr "mode" "<MODE>")])
3548 ;; Zero extension instructions
3550 (define_expand "zero_extendsidi2"
3551   [(set (match_operand:DI 0 "nonimmediate_operand")
3552         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3554 (define_insn "*zero_extendsidi2"
3555   [(set (match_operand:DI 0 "nonimmediate_operand"
3556                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3557         (zero_extend:DI
3558          (match_operand:SI 1 "x86_64_zext_operand"
3559                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3560   ""
3562   switch (get_attr_type (insn))
3563     {
3564     case TYPE_IMOVX:
3565       if (ix86_use_lea_for_mov (insn, operands))
3566         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3567       else
3568         return "mov{l}\t{%1, %k0|%k0, %1}";
3570     case TYPE_MULTI:
3571       return "#";
3573     case TYPE_MMXMOV:
3574       return "movd\t{%1, %0|%0, %1}";
3576     case TYPE_SSELOG1:
3577       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3579     case TYPE_SSEMOV:
3580       if (GENERAL_REG_P (operands[0]))
3581         return "%vmovd\t{%1, %k0|%k0, %1}";
3583       return "%vmovd\t{%1, %0|%0, %1}";
3585     default:
3586       gcc_unreachable ();
3587     }
3589   [(set (attr "isa")
3590      (cond [(eq_attr "alternative" "0,1,2")
3591               (const_string "nox64")
3592             (eq_attr "alternative" "3,7")
3593               (const_string "x64")
3594             (eq_attr "alternative" "8")
3595               (const_string "x64_sse4")
3596             (eq_attr "alternative" "10")
3597               (const_string "sse2")
3598            ]
3599            (const_string "*")))
3600    (set (attr "type")
3601      (cond [(eq_attr "alternative" "0,1,2,4")
3602               (const_string "multi")
3603             (eq_attr "alternative" "5,6")
3604               (const_string "mmxmov")
3605             (eq_attr "alternative" "7,9,10")
3606               (const_string "ssemov")
3607             (eq_attr "alternative" "8")
3608               (const_string "sselog1")
3609            ]
3610            (const_string "imovx")))
3611    (set (attr "prefix_extra")
3612      (if_then_else (eq_attr "alternative" "8")
3613        (const_string "1")
3614        (const_string "*")))
3615    (set (attr "length_immediate")
3616      (if_then_else (eq_attr "alternative" "8")
3617        (const_string "1")
3618        (const_string "*")))
3619    (set (attr "prefix")
3620      (if_then_else (eq_attr "type" "ssemov,sselog1")
3621        (const_string "maybe_vex")
3622        (const_string "orig")))
3623    (set (attr "prefix_0f")
3624      (if_then_else (eq_attr "type" "imovx")
3625        (const_string "0")
3626        (const_string "*")))
3627    (set (attr "mode")
3628      (cond [(eq_attr "alternative" "5,6")
3629               (const_string "DI")
3630             (eq_attr "alternative" "7,8,9")
3631               (const_string "TI")
3632            ]
3633            (const_string "SI")))])
3635 (define_split
3636   [(set (match_operand:DI 0 "memory_operand")
3637         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3638   "reload_completed"
3639   [(set (match_dup 4) (const_int 0))]
3640   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3642 (define_split
3643   [(set (match_operand:DI 0 "register_operand")
3644         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3645   "!TARGET_64BIT && reload_completed
3646    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3647    && true_regnum (operands[0]) == true_regnum (operands[1])"
3648   [(set (match_dup 4) (const_int 0))]
3649   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3651 (define_split
3652   [(set (match_operand:DI 0 "nonimmediate_operand")
3653         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3654   "!TARGET_64BIT && reload_completed
3655    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3656    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3657   [(set (match_dup 3) (match_dup 1))
3658    (set (match_dup 4) (const_int 0))]
3659   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3661 (define_insn "zero_extend<mode>di2"
3662   [(set (match_operand:DI 0 "register_operand" "=r")
3663         (zero_extend:DI
3664          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3665   "TARGET_64BIT"
3666   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3667   [(set_attr "type" "imovx")
3668    (set_attr "mode" "SI")])
3670 (define_expand "zero_extend<mode>si2"
3671   [(set (match_operand:SI 0 "register_operand")
3672         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3673   ""
3675   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3676     {
3677       operands[1] = force_reg (<MODE>mode, operands[1]);
3678       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3679       DONE;
3680     }
3683 (define_insn_and_split "zero_extend<mode>si2_and"
3684   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3685         (zero_extend:SI
3686           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3687    (clobber (reg:CC FLAGS_REG))]
3688   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3689   "#"
3690   "&& reload_completed"
3691   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3692               (clobber (reg:CC FLAGS_REG))])]
3694   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3695     {
3696       ix86_expand_clear (operands[0]);
3698       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3699       emit_insn (gen_movstrict<mode>
3700                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3701       DONE;
3702     }
3704   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3706   [(set_attr "type" "alu1")
3707    (set_attr "mode" "SI")])
3709 (define_insn "*zero_extend<mode>si2"
3710   [(set (match_operand:SI 0 "register_operand" "=r")
3711         (zero_extend:SI
3712           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3713   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3714   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3715   [(set_attr "type" "imovx")
3716    (set_attr "mode" "SI")])
3718 (define_expand "zero_extendqihi2"
3719   [(set (match_operand:HI 0 "register_operand")
3720         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3721   ""
3723   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3724     {
3725       operands[1] = force_reg (QImode, operands[1]);
3726       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3727       DONE;
3728     }
3731 (define_insn_and_split "zero_extendqihi2_and"
3732   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3733         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3734    (clobber (reg:CC FLAGS_REG))]
3735   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3736   "#"
3737   "&& reload_completed"
3738   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3739               (clobber (reg:CC FLAGS_REG))])]
3741   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3742     {
3743       ix86_expand_clear (operands[0]);
3745       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3746       emit_insn (gen_movstrictqi
3747                   (gen_lowpart (QImode, operands[0]), operands[1]));
3748       DONE;
3749     }
3751   operands[0] = gen_lowpart (SImode, operands[0]);
3753   [(set_attr "type" "alu1")
3754    (set_attr "mode" "SI")])
3756 ; zero extend to SImode to avoid partial register stalls
3757 (define_insn "*zero_extendqihi2"
3758   [(set (match_operand:HI 0 "register_operand" "=r")
3759         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3760   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3761   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3762   [(set_attr "type" "imovx")
3763    (set_attr "mode" "SI")])
3765 ;; Sign extension instructions
3767 (define_expand "extendsidi2"
3768   [(set (match_operand:DI 0 "register_operand")
3769         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3770   ""
3772   if (!TARGET_64BIT)
3773     {
3774       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3775       DONE;
3776     }
3779 (define_insn "*extendsidi2_rex64"
3780   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3781         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3782   "TARGET_64BIT"
3783   "@
3784    {cltq|cdqe}
3785    movs{lq|x}\t{%1, %0|%0, %1}"
3786   [(set_attr "type" "imovx")
3787    (set_attr "mode" "DI")
3788    (set_attr "prefix_0f" "0")
3789    (set_attr "modrm" "0,1")])
3791 (define_insn "extendsidi2_1"
3792   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3793         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3794    (clobber (reg:CC FLAGS_REG))
3795    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3796   "!TARGET_64BIT"
3797   "#")
3799 ;; Split the memory case.  If the source register doesn't die, it will stay
3800 ;; this way, if it does die, following peephole2s take care of it.
3801 (define_split
3802   [(set (match_operand:DI 0 "memory_operand")
3803         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3804    (clobber (reg:CC FLAGS_REG))
3805    (clobber (match_operand:SI 2 "register_operand"))]
3806   "reload_completed"
3807   [(const_int 0)]
3809   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3811   emit_move_insn (operands[3], operands[1]);
3813   /* Generate a cltd if possible and doing so it profitable.  */
3814   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3815       && true_regnum (operands[1]) == AX_REG
3816       && true_regnum (operands[2]) == DX_REG)
3817     {
3818       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3819     }
3820   else
3821     {
3822       emit_move_insn (operands[2], operands[1]);
3823       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3824     }
3825   emit_move_insn (operands[4], operands[2]);
3826   DONE;
3829 ;; Peepholes for the case where the source register does die, after
3830 ;; being split with the above splitter.
3831 (define_peephole2
3832   [(set (match_operand:SI 0 "memory_operand")
3833         (match_operand:SI 1 "register_operand"))
3834    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3835    (parallel [(set (match_dup 2)
3836                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3837                (clobber (reg:CC FLAGS_REG))])
3838    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3839   "REGNO (operands[1]) != REGNO (operands[2])
3840    && peep2_reg_dead_p (2, operands[1])
3841    && peep2_reg_dead_p (4, operands[2])
3842    && !reg_mentioned_p (operands[2], operands[3])"
3843   [(set (match_dup 0) (match_dup 1))
3844    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3845               (clobber (reg:CC FLAGS_REG))])
3846    (set (match_dup 3) (match_dup 1))])
3848 (define_peephole2
3849   [(set (match_operand:SI 0 "memory_operand")
3850         (match_operand:SI 1 "register_operand"))
3851    (parallel [(set (match_operand:SI 2 "register_operand")
3852                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3853                (clobber (reg:CC FLAGS_REG))])
3854    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3855   "/* cltd is shorter than sarl $31, %eax */
3856    !optimize_function_for_size_p (cfun)
3857    && true_regnum (operands[1]) == AX_REG
3858    && true_regnum (operands[2]) == DX_REG
3859    && peep2_reg_dead_p (2, operands[1])
3860    && peep2_reg_dead_p (3, operands[2])
3861    && !reg_mentioned_p (operands[2], operands[3])"
3862   [(set (match_dup 0) (match_dup 1))
3863    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3864               (clobber (reg:CC FLAGS_REG))])
3865    (set (match_dup 3) (match_dup 1))])
3867 ;; Extend to register case.  Optimize case where source and destination
3868 ;; registers match and cases where we can use cltd.
3869 (define_split
3870   [(set (match_operand:DI 0 "register_operand")
3871         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3872    (clobber (reg:CC FLAGS_REG))
3873    (clobber (match_scratch:SI 2))]
3874   "reload_completed"
3875   [(const_int 0)]
3877   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3879   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3880     emit_move_insn (operands[3], operands[1]);
3882   /* Generate a cltd if possible and doing so it profitable.  */
3883   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3884       && true_regnum (operands[3]) == AX_REG
3885       && true_regnum (operands[4]) == DX_REG)
3886     {
3887       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3888       DONE;
3889     }
3891   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3892     emit_move_insn (operands[4], operands[1]);
3894   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3895   DONE;
3898 (define_insn "extend<mode>di2"
3899   [(set (match_operand:DI 0 "register_operand" "=r")
3900         (sign_extend:DI
3901          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3902   "TARGET_64BIT"
3903   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3904   [(set_attr "type" "imovx")
3905    (set_attr "mode" "DI")])
3907 (define_insn "extendhisi2"
3908   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3909         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3910   ""
3912   switch (get_attr_prefix_0f (insn))
3913     {
3914     case 0:
3915       return "{cwtl|cwde}";
3916     default:
3917       return "movs{wl|x}\t{%1, %0|%0, %1}";
3918     }
3920   [(set_attr "type" "imovx")
3921    (set_attr "mode" "SI")
3922    (set (attr "prefix_0f")
3923      ;; movsx is short decodable while cwtl is vector decoded.
3924      (if_then_else (and (eq_attr "cpu" "!k6")
3925                         (eq_attr "alternative" "0"))
3926         (const_string "0")
3927         (const_string "1")))
3928    (set (attr "modrm")
3929      (if_then_else (eq_attr "prefix_0f" "0")
3930         (const_string "0")
3931         (const_string "1")))])
3933 (define_insn "*extendhisi2_zext"
3934   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3935         (zero_extend:DI
3936          (sign_extend:SI
3937           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3938   "TARGET_64BIT"
3940   switch (get_attr_prefix_0f (insn))
3941     {
3942     case 0:
3943       return "{cwtl|cwde}";
3944     default:
3945       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3946     }
3948   [(set_attr "type" "imovx")
3949    (set_attr "mode" "SI")
3950    (set (attr "prefix_0f")
3951      ;; movsx is short decodable while cwtl is vector decoded.
3952      (if_then_else (and (eq_attr "cpu" "!k6")
3953                         (eq_attr "alternative" "0"))
3954         (const_string "0")
3955         (const_string "1")))
3956    (set (attr "modrm")
3957      (if_then_else (eq_attr "prefix_0f" "0")
3958         (const_string "0")
3959         (const_string "1")))])
3961 (define_insn "extendqisi2"
3962   [(set (match_operand:SI 0 "register_operand" "=r")
3963         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3964   ""
3965   "movs{bl|x}\t{%1, %0|%0, %1}"
3966    [(set_attr "type" "imovx")
3967     (set_attr "mode" "SI")])
3969 (define_insn "*extendqisi2_zext"
3970   [(set (match_operand:DI 0 "register_operand" "=r")
3971         (zero_extend:DI
3972           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3973   "TARGET_64BIT"
3974   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3975    [(set_attr "type" "imovx")
3976     (set_attr "mode" "SI")])
3978 (define_insn "extendqihi2"
3979   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3980         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3981   ""
3983   switch (get_attr_prefix_0f (insn))
3984     {
3985     case 0:
3986       return "{cbtw|cbw}";
3987     default:
3988       return "movs{bw|x}\t{%1, %0|%0, %1}";
3989     }
3991   [(set_attr "type" "imovx")
3992    (set_attr "mode" "HI")
3993    (set (attr "prefix_0f")
3994      ;; movsx is short decodable while cwtl is vector decoded.
3995      (if_then_else (and (eq_attr "cpu" "!k6")
3996                         (eq_attr "alternative" "0"))
3997         (const_string "0")
3998         (const_string "1")))
3999    (set (attr "modrm")
4000      (if_then_else (eq_attr "prefix_0f" "0")
4001         (const_string "0")
4002         (const_string "1")))])
4004 ;; Conversions between float and double.
4006 ;; These are all no-ops in the model used for the 80387.
4007 ;; So just emit moves.
4009 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4010 (define_split
4011   [(set (match_operand:DF 0 "push_operand")
4012         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4013   "reload_completed"
4014   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4015    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4017 (define_split
4018   [(set (match_operand:XF 0 "push_operand")
4019         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4020   "reload_completed"
4021   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4022    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4023   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4025 (define_expand "extendsfdf2"
4026   [(set (match_operand:DF 0 "nonimmediate_operand")
4027         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4028   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4030   /* ??? Needed for compress_float_constant since all fp constants
4031      are TARGET_LEGITIMATE_CONSTANT_P.  */
4032   if (CONST_DOUBLE_P (operands[1]))
4033     {
4034       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4035           && standard_80387_constant_p (operands[1]) > 0)
4036         {
4037           operands[1] = simplify_const_unary_operation
4038             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4039           emit_move_insn_1 (operands[0], operands[1]);
4040           DONE;
4041         }
4042       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4043     }
4046 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4047    cvtss2sd:
4048       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4049       cvtps2pd xmm2,xmm1
4050    We do the conversion post reload to avoid producing of 128bit spills
4051    that might lead to ICE on 32bit target.  The sequence unlikely combine
4052    anyway.  */
4053 (define_split
4054   [(set (match_operand:DF 0 "register_operand")
4055         (float_extend:DF
4056           (match_operand:SF 1 "nonimmediate_operand")))]
4057   "TARGET_USE_VECTOR_FP_CONVERTS
4058    && optimize_insn_for_speed_p ()
4059    && reload_completed && SSE_REG_P (operands[0])
4060    && (!EXT_REX_SSE_REG_P (operands[0])
4061        || TARGET_AVX512VL)"
4062    [(set (match_dup 2)
4063          (float_extend:V2DF
4064            (vec_select:V2SF
4065              (match_dup 3)
4066              (parallel [(const_int 0) (const_int 1)]))))]
4068   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4069   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4070   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4071      Try to avoid move when unpacking can be done in source.  */
4072   if (REG_P (operands[1]))
4073     {
4074       /* If it is unsafe to overwrite upper half of source, we need
4075          to move to destination and unpack there.  */
4076       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4077            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4078           && true_regnum (operands[0]) != true_regnum (operands[1]))
4079         {
4080           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4081           emit_move_insn (tmp, operands[1]);
4082         }
4083       else
4084         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4085       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4086                                              operands[3]));
4087     }
4088   else
4089     emit_insn (gen_vec_setv4sf_0 (operands[3],
4090                                   CONST0_RTX (V4SFmode), operands[1]));
4093 ;; It's more profitable to split and then extend in the same register.
4094 (define_peephole2
4095   [(set (match_operand:DF 0 "register_operand")
4096         (float_extend:DF
4097           (match_operand:SF 1 "memory_operand")))]
4098   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4099    && optimize_insn_for_speed_p ()
4100    && SSE_REG_P (operands[0])"
4101   [(set (match_dup 2) (match_dup 1))
4102    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4103   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4105 (define_insn "*extendsfdf2_mixed"
4106   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
4107         (float_extend:DF
4108           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4109   "TARGET_SSE2 && TARGET_SSE_MATH"
4111   switch (which_alternative)
4112     {
4113     case 0:
4114     case 1:
4115       return output_387_reg_move (insn, operands);
4117     case 2:
4118       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4120     default:
4121       gcc_unreachable ();
4122     }
4124   [(set_attr "type" "fmov,fmov,ssecvt")
4125    (set_attr "prefix" "orig,orig,maybe_vex")
4126    (set_attr "mode" "SF,XF,DF")
4127    (set (attr "enabled")
4128      (cond [(eq_attr "alternative" "0,1")
4129               (symbol_ref "TARGET_MIX_SSE_I387")
4130            ]
4131            (symbol_ref "true")))])
4133 (define_insn "*extendsfdf2_i387"
4134   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4135         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4136   "TARGET_80387"
4137   "* return output_387_reg_move (insn, operands);"
4138   [(set_attr "type" "fmov")
4139    (set_attr "mode" "SF,XF")])
4141 (define_expand "extend<mode>xf2"
4142   [(set (match_operand:XF 0 "nonimmediate_operand")
4143         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4144   "TARGET_80387"
4146   /* ??? Needed for compress_float_constant since all fp constants
4147      are TARGET_LEGITIMATE_CONSTANT_P.  */
4148   if (CONST_DOUBLE_P (operands[1]))
4149     {
4150       if (standard_80387_constant_p (operands[1]) > 0)
4151         {
4152           operands[1] = simplify_const_unary_operation
4153             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4154           emit_move_insn_1 (operands[0], operands[1]);
4155           DONE;
4156         }
4157       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4158     }
4161 (define_insn "*extend<mode>xf2_i387"
4162   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4163         (float_extend:XF
4164           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4165   "TARGET_80387"
4166   "* return output_387_reg_move (insn, operands);"
4167   [(set_attr "type" "fmov")
4168    (set_attr "mode" "<MODE>,XF")])
4170 ;; %%% This seems like bad news.
4171 ;; This cannot output into an f-reg because there is no way to be sure
4172 ;; of truncating in that case.  Otherwise this is just like a simple move
4173 ;; insn.  So we pretend we can output to a reg in order to get better
4174 ;; register preferencing, but we really use a stack slot.
4176 ;; Conversion from DFmode to SFmode.
4178 (define_expand "truncdfsf2"
4179   [(set (match_operand:SF 0 "nonimmediate_operand")
4180         (float_truncate:SF
4181           (match_operand:DF 1 "nonimmediate_operand")))]
4182   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4184   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4185     ;
4186   else if (flag_unsafe_math_optimizations)
4187     ;
4188   else
4189     {
4190       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4191       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4192       DONE;
4193     }
4196 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4197    cvtsd2ss:
4198       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4199       cvtpd2ps xmm2,xmm1
4200    We do the conversion post reload to avoid producing of 128bit spills
4201    that might lead to ICE on 32bit target.  The sequence unlikely combine
4202    anyway.  */
4203 (define_split
4204   [(set (match_operand:SF 0 "register_operand")
4205         (float_truncate:SF
4206           (match_operand:DF 1 "nonimmediate_operand")))]
4207   "TARGET_USE_VECTOR_FP_CONVERTS
4208    && optimize_insn_for_speed_p ()
4209    && reload_completed && SSE_REG_P (operands[0])
4210    && (!EXT_REX_SSE_REG_P (operands[0])
4211        || TARGET_AVX512VL)"
4212    [(set (match_dup 2)
4213          (vec_concat:V4SF
4214            (float_truncate:V2SF
4215              (match_dup 4))
4216            (match_dup 3)))]
4218   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4219   operands[3] = CONST0_RTX (V2SFmode);
4220   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4221   /* Use movsd for loading from memory, unpcklpd for registers.
4222      Try to avoid move when unpacking can be done in source, or SSE3
4223      movddup is available.  */
4224   if (REG_P (operands[1]))
4225     {
4226       if (!TARGET_SSE3
4227           && true_regnum (operands[0]) != true_regnum (operands[1])
4228           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4229               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4230         {
4231           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4232           emit_move_insn (tmp, operands[1]);
4233           operands[1] = tmp;
4234         }
4235       else if (!TARGET_SSE3)
4236         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4237       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4238     }
4239   else
4240     emit_insn (gen_sse2_loadlpd (operands[4],
4241                                  CONST0_RTX (V2DFmode), operands[1]));
4244 ;; It's more profitable to split and then extend in the same register.
4245 (define_peephole2
4246   [(set (match_operand:SF 0 "register_operand")
4247         (float_truncate:SF
4248           (match_operand:DF 1 "memory_operand")))]
4249   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4250    && optimize_insn_for_speed_p ()
4251    && SSE_REG_P (operands[0])"
4252   [(set (match_dup 2) (match_dup 1))
4253    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4254   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4256 (define_expand "truncdfsf2_with_temp"
4257   [(parallel [(set (match_operand:SF 0)
4258                    (float_truncate:SF (match_operand:DF 1)))
4259               (clobber (match_operand:SF 2))])])
4261 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4262 ;; because nothing we do there is unsafe.
4263 (define_insn "*truncdfsf_fast_mixed"
4264   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4265         (float_truncate:SF
4266           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4267   "TARGET_SSE2 && TARGET_SSE_MATH"
4269   switch (which_alternative)
4270     {
4271     case 0:
4272       return output_387_reg_move (insn, operands);
4273     case 1:
4274       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4275     default:
4276       gcc_unreachable ();
4277     }
4279   [(set_attr "type" "fmov,ssecvt")
4280    (set_attr "prefix" "orig,maybe_vex")
4281    (set_attr "mode" "SF")
4282    (set (attr "enabled")
4283      (cond [(eq_attr "alternative" "0")
4284               (symbol_ref "TARGET_MIX_SSE_I387
4285                            && flag_unsafe_math_optimizations")
4286            ]
4287            (symbol_ref "true")))])
4289 (define_insn "*truncdfsf_fast_i387"
4290   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4291         (float_truncate:SF
4292           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4293   "TARGET_80387 && flag_unsafe_math_optimizations"
4294   "* return output_387_reg_move (insn, operands);"
4295   [(set_attr "type" "fmov")
4296    (set_attr "mode" "SF")])
4298 (define_insn "*truncdfsf_mixed"
4299   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4300         (float_truncate:SF
4301           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4302    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4303   "TARGET_MIX_SSE_I387"
4305   switch (which_alternative)
4306     {
4307     case 0:
4308       return output_387_reg_move (insn, operands);
4309     case 1:
4310       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4312     default:
4313       return "#";
4314     }
4316   [(set_attr "isa" "*,sse2,*,*,*")
4317    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4318    (set_attr "unit" "*,*,i387,i387,i387")
4319    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4320    (set_attr "mode" "SF")])
4322 (define_insn "*truncdfsf_i387"
4323   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4324         (float_truncate:SF
4325           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4326    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4327   "TARGET_80387"
4329   switch (which_alternative)
4330     {
4331     case 0:
4332       return output_387_reg_move (insn, operands);
4334     default:
4335       return "#";
4336     }
4338   [(set_attr "type" "fmov,multi,multi,multi")
4339    (set_attr "unit" "*,i387,i387,i387")
4340    (set_attr "mode" "SF")])
4342 (define_insn "*truncdfsf2_i387_1"
4343   [(set (match_operand:SF 0 "memory_operand" "=m")
4344         (float_truncate:SF
4345           (match_operand:DF 1 "register_operand" "f")))]
4346   "TARGET_80387
4347    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4348    && !TARGET_MIX_SSE_I387"
4349   "* return output_387_reg_move (insn, operands);"
4350   [(set_attr "type" "fmov")
4351    (set_attr "mode" "SF")])
4353 (define_split
4354   [(set (match_operand:SF 0 "register_operand")
4355         (float_truncate:SF
4356          (match_operand:DF 1 "fp_register_operand")))
4357    (clobber (match_operand 2))]
4358   "reload_completed"
4359   [(set (match_dup 2) (match_dup 1))
4360    (set (match_dup 0) (match_dup 2))]
4361   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4363 ;; Conversion from XFmode to {SF,DF}mode
4365 (define_expand "truncxf<mode>2"
4366   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4367                    (float_truncate:MODEF
4368                      (match_operand:XF 1 "register_operand")))
4369               (clobber (match_dup 2))])]
4370   "TARGET_80387"
4372   if (flag_unsafe_math_optimizations)
4373     {
4374       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4375       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4376       if (reg != operands[0])
4377         emit_move_insn (operands[0], reg);
4378       DONE;
4379     }
4380   else
4381     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4384 (define_insn "*truncxfsf2_mixed"
4385   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4386         (float_truncate:SF
4387           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4388    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4389   "TARGET_80387"
4391   gcc_assert (!which_alternative);
4392   return output_387_reg_move (insn, operands);
4394   [(set_attr "type" "fmov,multi,multi,multi")
4395    (set_attr "unit" "*,i387,i387,i387")
4396    (set_attr "mode" "SF")])
4398 (define_insn "*truncxfdf2_mixed"
4399   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4400         (float_truncate:DF
4401           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4402    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4403   "TARGET_80387"
4405   gcc_assert (!which_alternative);
4406   return output_387_reg_move (insn, operands);
4408   [(set_attr "isa" "*,*,sse2,*")
4409    (set_attr "type" "fmov,multi,multi,multi")
4410    (set_attr "unit" "*,i387,i387,i387")
4411    (set_attr "mode" "DF")])
4413 (define_insn "truncxf<mode>2_i387_noop"
4414   [(set (match_operand:MODEF 0 "register_operand" "=f")
4415         (float_truncate:MODEF
4416           (match_operand:XF 1 "register_operand" "f")))]
4417   "TARGET_80387 && flag_unsafe_math_optimizations"
4418   "* return output_387_reg_move (insn, operands);"
4419   [(set_attr "type" "fmov")
4420    (set_attr "mode" "<MODE>")])
4422 (define_insn "*truncxf<mode>2_i387"
4423   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4424         (float_truncate:MODEF
4425           (match_operand:XF 1 "register_operand" "f")))]
4426   "TARGET_80387"
4427   "* return output_387_reg_move (insn, operands);"
4428   [(set_attr "type" "fmov")
4429    (set_attr "mode" "<MODE>")])
4431 (define_split
4432   [(set (match_operand:MODEF 0 "register_operand")
4433         (float_truncate:MODEF
4434           (match_operand:XF 1 "register_operand")))
4435    (clobber (match_operand:MODEF 2 "memory_operand"))]
4436   "TARGET_80387 && reload_completed"
4437   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4438    (set (match_dup 0) (match_dup 2))])
4440 (define_split
4441   [(set (match_operand:MODEF 0 "memory_operand")
4442         (float_truncate:MODEF
4443           (match_operand:XF 1 "register_operand")))
4444    (clobber (match_operand:MODEF 2 "memory_operand"))]
4445   "TARGET_80387"
4446   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4448 ;; Signed conversion to DImode.
4450 (define_expand "fix_truncxfdi2"
4451   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4452                    (fix:DI (match_operand:XF 1 "register_operand")))
4453               (clobber (reg:CC FLAGS_REG))])]
4454   "TARGET_80387"
4456   if (TARGET_FISTTP)
4457    {
4458      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4459      DONE;
4460    }
4463 (define_expand "fix_trunc<mode>di2"
4464   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4465                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4466               (clobber (reg:CC FLAGS_REG))])]
4467   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4469   if (TARGET_FISTTP
4470       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4471    {
4472      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4473      DONE;
4474    }
4475   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4476    {
4477      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4478      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4479      if (out != operands[0])
4480         emit_move_insn (operands[0], out);
4481      DONE;
4482    }
4485 ;; Signed conversion to SImode.
4487 (define_expand "fix_truncxfsi2"
4488   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4489                    (fix:SI (match_operand:XF 1 "register_operand")))
4490               (clobber (reg:CC FLAGS_REG))])]
4491   "TARGET_80387"
4493   if (TARGET_FISTTP)
4494    {
4495      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4496      DONE;
4497    }
4500 (define_expand "fix_trunc<mode>si2"
4501   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4502                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4503               (clobber (reg:CC FLAGS_REG))])]
4504   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4506   if (TARGET_FISTTP
4507       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4508    {
4509      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4510      DONE;
4511    }
4512   if (SSE_FLOAT_MODE_P (<MODE>mode))
4513    {
4514      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4515      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4516      if (out != operands[0])
4517         emit_move_insn (operands[0], out);
4518      DONE;
4519    }
4522 ;; Signed conversion to HImode.
4524 (define_expand "fix_trunc<mode>hi2"
4525   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4526                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4527               (clobber (reg:CC FLAGS_REG))])]
4528   "TARGET_80387
4529    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4531   if (TARGET_FISTTP)
4532    {
4533      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4534      DONE;
4535    }
4538 ;; Unsigned conversion to SImode.
4540 (define_expand "fixuns_trunc<mode>si2"
4541   [(parallel
4542     [(set (match_operand:SI 0 "register_operand")
4543           (unsigned_fix:SI
4544             (match_operand:MODEF 1 "nonimmediate_operand")))
4545      (use (match_dup 2))
4546      (clobber (match_scratch:<ssevecmode> 3))
4547      (clobber (match_scratch:<ssevecmode> 4))])]
4548   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4550   machine_mode mode = <MODE>mode;
4551   machine_mode vecmode = <ssevecmode>mode;
4552   REAL_VALUE_TYPE TWO31r;
4553   rtx two31;
4555   if (optimize_insn_for_size_p ())
4556     FAIL;
4558   real_ldexp (&TWO31r, &dconst1, 31);
4559   two31 = const_double_from_real_value (TWO31r, mode);
4560   two31 = ix86_build_const_vector (vecmode, true, two31);
4561   operands[2] = force_reg (vecmode, two31);
4564 (define_insn_and_split "*fixuns_trunc<mode>_1"
4565   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4566         (unsigned_fix:SI
4567           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4568    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4569    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4570    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4571   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4572    && optimize_function_for_speed_p (cfun)"
4573   "#"
4574   "&& reload_completed"
4575   [(const_int 0)]
4577   ix86_split_convert_uns_si_sse (operands);
4578   DONE;
4581 ;; Unsigned conversion to HImode.
4582 ;; Without these patterns, we'll try the unsigned SI conversion which
4583 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4585 (define_expand "fixuns_trunc<mode>hi2"
4586   [(set (match_dup 2)
4587         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4588    (set (match_operand:HI 0 "nonimmediate_operand")
4589         (subreg:HI (match_dup 2) 0))]
4590   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4591   "operands[2] = gen_reg_rtx (SImode);")
4593 ;; When SSE is available, it is always faster to use it!
4594 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4595   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4596         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4597   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4598    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4599   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4600   [(set_attr "type" "sseicvt")
4601    (set_attr "prefix" "maybe_vex")
4602    (set (attr "prefix_rex")
4603         (if_then_else
4604           (match_test "<SWI48:MODE>mode == DImode")
4605           (const_string "1")
4606           (const_string "*")))
4607    (set_attr "mode" "<MODEF:MODE>")
4608    (set_attr "athlon_decode" "double,vector")
4609    (set_attr "amdfam10_decode" "double,double")
4610    (set_attr "bdver1_decode" "double,double")])
4612 ;; Avoid vector decoded forms of the instruction.
4613 (define_peephole2
4614   [(match_scratch:MODEF 2 "x")
4615    (set (match_operand:SWI48 0 "register_operand")
4616         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4617   "TARGET_AVOID_VECTOR_DECODE
4618    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4619    && optimize_insn_for_speed_p ()"
4620   [(set (match_dup 2) (match_dup 1))
4621    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4623 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4624   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4625         (fix:SWI248x (match_operand 1 "register_operand")))]
4626   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4627    && TARGET_FISTTP
4628    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4629          && (TARGET_64BIT || <MODE>mode != DImode))
4630         && TARGET_SSE_MATH)
4631    && can_create_pseudo_p ()"
4632   "#"
4633   "&& 1"
4634   [(const_int 0)]
4636   if (memory_operand (operands[0], VOIDmode))
4637     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4638   else
4639     {
4640       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4641       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4642                                                             operands[1],
4643                                                             operands[2]));
4644     }
4645   DONE;
4647   [(set_attr "type" "fisttp")
4648    (set_attr "mode" "<MODE>")])
4650 (define_insn "fix_trunc<mode>_i387_fisttp"
4651   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4652         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4653    (clobber (match_scratch:XF 2 "=&1f"))]
4654   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655    && TARGET_FISTTP
4656    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4657          && (TARGET_64BIT || <MODE>mode != DImode))
4658         && TARGET_SSE_MATH)"
4659   "* return output_fix_trunc (insn, operands, true);"
4660   [(set_attr "type" "fisttp")
4661    (set_attr "mode" "<MODE>")])
4663 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4664   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4665         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4666    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4667    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4668   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4669    && TARGET_FISTTP
4670    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4671         && (TARGET_64BIT || <MODE>mode != DImode))
4672         && TARGET_SSE_MATH)"
4673   "#"
4674   [(set_attr "type" "fisttp")
4675    (set_attr "mode" "<MODE>")])
4677 (define_split
4678   [(set (match_operand:SWI248x 0 "register_operand")
4679         (fix:SWI248x (match_operand 1 "register_operand")))
4680    (clobber (match_operand:SWI248x 2 "memory_operand"))
4681    (clobber (match_scratch 3))]
4682   "reload_completed"
4683   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4684               (clobber (match_dup 3))])
4685    (set (match_dup 0) (match_dup 2))])
4687 (define_split
4688   [(set (match_operand:SWI248x 0 "memory_operand")
4689         (fix:SWI248x (match_operand 1 "register_operand")))
4690    (clobber (match_operand:SWI248x 2 "memory_operand"))
4691    (clobber (match_scratch 3))]
4692   "reload_completed"
4693   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4694               (clobber (match_dup 3))])])
4696 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4697 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4698 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4699 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4700 ;; function in i386.c.
4701 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4702   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4703         (fix:SWI248x (match_operand 1 "register_operand")))
4704    (clobber (reg:CC FLAGS_REG))]
4705   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4706    && !TARGET_FISTTP
4707    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4708          && (TARGET_64BIT || <MODE>mode != DImode))
4709    && can_create_pseudo_p ()"
4710   "#"
4711   "&& 1"
4712   [(const_int 0)]
4714   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4716   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4717   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4718   if (memory_operand (operands[0], VOIDmode))
4719     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4720                                          operands[2], operands[3]));
4721   else
4722     {
4723       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4724       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4725                                                      operands[2], operands[3],
4726                                                      operands[4]));
4727     }
4728   DONE;
4730   [(set_attr "type" "fistp")
4731    (set_attr "i387_cw" "trunc")
4732    (set_attr "mode" "<MODE>")])
4734 (define_insn "fix_truncdi_i387"
4735   [(set (match_operand:DI 0 "memory_operand" "=m")
4736         (fix:DI (match_operand 1 "register_operand" "f")))
4737    (use (match_operand:HI 2 "memory_operand" "m"))
4738    (use (match_operand:HI 3 "memory_operand" "m"))
4739    (clobber (match_scratch:XF 4 "=&1f"))]
4740   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4741    && !TARGET_FISTTP
4742    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4743   "* return output_fix_trunc (insn, operands, false);"
4744   [(set_attr "type" "fistp")
4745    (set_attr "i387_cw" "trunc")
4746    (set_attr "mode" "DI")])
4748 (define_insn "fix_truncdi_i387_with_temp"
4749   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4750         (fix:DI (match_operand 1 "register_operand" "f,f")))
4751    (use (match_operand:HI 2 "memory_operand" "m,m"))
4752    (use (match_operand:HI 3 "memory_operand" "m,m"))
4753    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4754    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4755   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4756    && !TARGET_FISTTP
4757    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4758   "#"
4759   [(set_attr "type" "fistp")
4760    (set_attr "i387_cw" "trunc")
4761    (set_attr "mode" "DI")])
4763 (define_split
4764   [(set (match_operand:DI 0 "register_operand")
4765         (fix:DI (match_operand 1 "register_operand")))
4766    (use (match_operand:HI 2 "memory_operand"))
4767    (use (match_operand:HI 3 "memory_operand"))
4768    (clobber (match_operand:DI 4 "memory_operand"))
4769    (clobber (match_scratch 5))]
4770   "reload_completed"
4771   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4772               (use (match_dup 2))
4773               (use (match_dup 3))
4774               (clobber (match_dup 5))])
4775    (set (match_dup 0) (match_dup 4))])
4777 (define_split
4778   [(set (match_operand:DI 0 "memory_operand")
4779         (fix:DI (match_operand 1 "register_operand")))
4780    (use (match_operand:HI 2 "memory_operand"))
4781    (use (match_operand:HI 3 "memory_operand"))
4782    (clobber (match_operand:DI 4 "memory_operand"))
4783    (clobber (match_scratch 5))]
4784   "reload_completed"
4785   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4786               (use (match_dup 2))
4787               (use (match_dup 3))
4788               (clobber (match_dup 5))])])
4790 (define_insn "fix_trunc<mode>_i387"
4791   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4792         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4793    (use (match_operand:HI 2 "memory_operand" "m"))
4794    (use (match_operand:HI 3 "memory_operand" "m"))]
4795   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4796    && !TARGET_FISTTP
4797    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4798   "* return output_fix_trunc (insn, operands, false);"
4799   [(set_attr "type" "fistp")
4800    (set_attr "i387_cw" "trunc")
4801    (set_attr "mode" "<MODE>")])
4803 (define_insn "fix_trunc<mode>_i387_with_temp"
4804   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4805         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4806    (use (match_operand:HI 2 "memory_operand" "m,m"))
4807    (use (match_operand:HI 3 "memory_operand" "m,m"))
4808    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4809   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4810    && !TARGET_FISTTP
4811    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4812   "#"
4813   [(set_attr "type" "fistp")
4814    (set_attr "i387_cw" "trunc")
4815    (set_attr "mode" "<MODE>")])
4817 (define_split
4818   [(set (match_operand:SWI24 0 "register_operand")
4819         (fix:SWI24 (match_operand 1 "register_operand")))
4820    (use (match_operand:HI 2 "memory_operand"))
4821    (use (match_operand:HI 3 "memory_operand"))
4822    (clobber (match_operand:SWI24 4 "memory_operand"))]
4823   "reload_completed"
4824   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4825               (use (match_dup 2))
4826               (use (match_dup 3))])
4827    (set (match_dup 0) (match_dup 4))])
4829 (define_split
4830   [(set (match_operand:SWI24 0 "memory_operand")
4831         (fix:SWI24 (match_operand 1 "register_operand")))
4832    (use (match_operand:HI 2 "memory_operand"))
4833    (use (match_operand:HI 3 "memory_operand"))
4834    (clobber (match_operand:SWI24 4 "memory_operand"))]
4835   "reload_completed"
4836   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4837               (use (match_dup 2))
4838               (use (match_dup 3))])])
4840 (define_insn "x86_fnstcw_1"
4841   [(set (match_operand:HI 0 "memory_operand" "=m")
4842         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4843   "TARGET_80387"
4844   "fnstcw\t%0"
4845   [(set (attr "length")
4846         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4847    (set_attr "mode" "HI")
4848    (set_attr "unit" "i387")
4849    (set_attr "bdver1_decode" "vector")])
4851 (define_insn "x86_fldcw_1"
4852   [(set (reg:HI FPCR_REG)
4853         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4854   "TARGET_80387"
4855   "fldcw\t%0"
4856   [(set (attr "length")
4857         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4858    (set_attr "mode" "HI")
4859    (set_attr "unit" "i387")
4860    (set_attr "athlon_decode" "vector")
4861    (set_attr "amdfam10_decode" "vector")
4862    (set_attr "bdver1_decode" "vector")])
4864 ;; Conversion between fixed point and floating point.
4866 ;; Even though we only accept memory inputs, the backend _really_
4867 ;; wants to be able to do this between registers.  Thankfully, LRA
4868 ;; will fix this up for us during register allocation.
4870 (define_insn "floathi<mode>2"
4871   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4872         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4873   "TARGET_80387
4874    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4875        || TARGET_MIX_SSE_I387)"
4876   "fild%Z1\t%1"
4877   [(set_attr "type" "fmov")
4878    (set_attr "mode" "<MODE>")
4879    (set_attr "fp_int_src" "true")])
4881 (define_insn "float<SWI48x:mode>xf2"
4882   [(set (match_operand:XF 0 "register_operand" "=f")
4883         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4884   "TARGET_80387"
4885   "fild%Z1\t%1"
4886   [(set_attr "type" "fmov")
4887    (set_attr "mode" "XF")
4888    (set_attr "fp_int_src" "true")])
4890 (define_expand "float<SWI48:mode><MODEF:mode>2"
4891   [(set (match_operand:MODEF 0 "register_operand")
4892         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4893   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4895   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4896       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4897     {
4898       rtx reg = gen_reg_rtx (XFmode);
4899       rtx (*insn)(rtx, rtx);
4901       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4903       if (<MODEF:MODE>mode == SFmode)
4904         insn = gen_truncxfsf2;
4905       else if (<MODEF:MODE>mode == DFmode)
4906         insn = gen_truncxfdf2;
4907       else
4908         gcc_unreachable ();
4910       emit_insn (insn (operands[0], reg));
4911       DONE;
4912     }
4915 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
4916   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4917         (float:MODEF
4918           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4919   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4920   "@
4921    fild%Z1\t%1
4922    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4923    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4924   [(set_attr "type" "fmov,sseicvt,sseicvt")
4925    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4926    (set_attr "mode" "<MODEF:MODE>")
4927    (set (attr "prefix_rex")
4928      (if_then_else
4929        (and (eq_attr "prefix" "maybe_vex")
4930             (match_test "<SWI48:MODE>mode == DImode"))
4931        (const_string "1")
4932        (const_string "*")))
4933    (set_attr "unit" "i387,*,*")
4934    (set_attr "athlon_decode" "*,double,direct")
4935    (set_attr "amdfam10_decode" "*,vector,double")
4936    (set_attr "bdver1_decode" "*,double,direct")
4937    (set_attr "fp_int_src" "true")
4938    (set (attr "enabled")
4939      (cond [(eq_attr "alternative" "0")
4940               (symbol_ref "TARGET_MIX_SSE_I387
4941                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4942                                                 <SWI48:MODE>mode)")
4943            ]
4944            (symbol_ref "true")))
4945    (set (attr "preferred_for_speed")
4946      (cond [(eq_attr "alternative" "1")
4947               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4948            (symbol_ref "true")))])
4950 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4951   [(set (match_operand:MODEF 0 "register_operand" "=f")
4952         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4953   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4954   "fild%Z1\t%1"
4955   [(set_attr "type" "fmov")
4956    (set_attr "mode" "<MODEF:MODE>")
4957    (set_attr "fp_int_src" "true")])
4959 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4960 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4961 ;; alternative in sse2_loadld.
4962 (define_split
4963   [(set (match_operand:MODEF 0 "register_operand")
4964         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4965   "TARGET_SSE2 && TARGET_SSE_MATH
4966    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4967    && reload_completed && SSE_REG_P (operands[0])
4968    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4969    && (!EXT_REX_SSE_REG_P (operands[0])
4970        || TARGET_AVX512VL)"
4971   [(const_int 0)]
4973   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4974                                      <MODE>mode, 0);
4975   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4977   emit_insn (gen_sse2_loadld (operands[4],
4978                               CONST0_RTX (V4SImode), operands[1]));
4980   if (<ssevecmode>mode == V4SFmode)
4981     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4982   else
4983     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4984   DONE;
4987 ;; Avoid partial SSE register dependency stalls
4988 (define_split
4989   [(set (match_operand:MODEF 0 "register_operand")
4990         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4991   "TARGET_SSE2 && TARGET_SSE_MATH
4992    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4993    && optimize_function_for_speed_p (cfun)
4994    && reload_completed && SSE_REG_P (operands[0])
4995    && (!EXT_REX_SSE_REG_P (operands[0])
4996        || TARGET_AVX512VL)"
4997   [(const_int 0)]
4999   const machine_mode vmode = <MODEF:ssevecmode>mode;
5000   const machine_mode mode = <MODEF:MODE>mode;
5001   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
5003   emit_move_insn (op0, CONST0_RTX (vmode));
5005   t = gen_rtx_FLOAT (mode, operands[1]);
5006   t = gen_rtx_VEC_DUPLICATE (vmode, t);
5007   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
5008   emit_insn (gen_rtx_SET (op0, t));
5009   DONE;
5012 ;; Break partial reg stall for cvtsd2ss.
5014 (define_peephole2
5015   [(set (match_operand:SF 0 "register_operand")
5016         (float_truncate:SF
5017           (match_operand:DF 1 "nonimmediate_operand")))]
5018   "TARGET_SSE2 && TARGET_SSE_MATH
5019    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5020    && optimize_function_for_speed_p (cfun)
5021    && SSE_REG_P (operands[0])
5022    && (!SSE_REG_P (operands[1])
5023        || REGNO (operands[0]) != REGNO (operands[1]))
5024    && (!EXT_REX_SSE_REG_P (operands[0])
5025        || TARGET_AVX512VL)"
5026   [(set (match_dup 0)
5027         (vec_merge:V4SF
5028           (vec_duplicate:V4SF
5029             (float_truncate:V2SF
5030               (match_dup 1)))
5031           (match_dup 0)
5032           (const_int 1)))]
5034   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
5035                                      SFmode, 0);
5036   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
5037                                      DFmode, 0);
5038   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5041 ;; Break partial reg stall for cvtss2sd.
5043 (define_peephole2
5044   [(set (match_operand:DF 0 "register_operand")
5045         (float_extend:DF
5046           (match_operand:SF 1 "nonimmediate_operand")))]
5047   "TARGET_SSE2 && TARGET_SSE_MATH
5048    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5049    && optimize_function_for_speed_p (cfun)
5050    && SSE_REG_P (operands[0])
5051    && (!SSE_REG_P (operands[1])
5052        || REGNO (operands[0]) != REGNO (operands[1]))
5053    && (!EXT_REX_SSE_REG_P (operands[0])
5054        || TARGET_AVX512VL)"
5055   [(set (match_dup 0)
5056         (vec_merge:V2DF
5057           (float_extend:V2DF
5058             (vec_select:V2SF
5059               (match_dup 1)
5060               (parallel [(const_int 0) (const_int 1)])))
5061           (match_dup 0)
5062           (const_int 1)))]
5064   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5065                                      DFmode, 0);
5066   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5067                                      SFmode, 0);
5068   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5071 ;; Avoid store forwarding (partial memory) stall penalty
5072 ;; by passing DImode value through XMM registers.  */
5074 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5075   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5076         (float:X87MODEF
5077           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5078    (clobber (match_scratch:V4SI 3 "=X,x"))
5079    (clobber (match_scratch:V4SI 4 "=X,x"))
5080    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5081   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5082    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5083    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5084   "#"
5085   [(set_attr "type" "multi")
5086    (set_attr "mode" "<X87MODEF:MODE>")
5087    (set_attr "unit" "i387")
5088    (set_attr "fp_int_src" "true")])
5090 (define_split
5091   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5092         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5093    (clobber (match_scratch:V4SI 3))
5094    (clobber (match_scratch:V4SI 4))
5095    (clobber (match_operand:DI 2 "memory_operand"))]
5096   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5097    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5098    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5099    && reload_completed"
5100   [(set (match_dup 2) (match_dup 3))
5101    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5103   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5104      Assemble the 64-bit DImode value in an xmm register.  */
5105   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5106                               gen_lowpart (SImode, operands[1])));
5107   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5108                               gen_highpart (SImode, operands[1])));
5109   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5110                                          operands[4]));
5112   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5115 (define_split
5116   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5117         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5118    (clobber (match_scratch:V4SI 3))
5119    (clobber (match_scratch:V4SI 4))
5120    (clobber (match_operand:DI 2 "memory_operand"))]
5121   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5122    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5123    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5124    && reload_completed"
5125   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5127 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5128   [(set (match_operand:MODEF 0 "register_operand")
5129         (unsigned_float:MODEF
5130           (match_operand:SWI12 1 "nonimmediate_operand")))]
5131   "!TARGET_64BIT
5132    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5134   operands[1] = convert_to_mode (SImode, operands[1], 1);
5135   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5136   DONE;
5139 ;; Avoid store forwarding (partial memory) stall penalty by extending
5140 ;; SImode value to DImode through XMM register instead of pushing two
5141 ;; SImode values to stack. Also note that fild loads from memory only.
5143 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5144   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5145         (unsigned_float:X87MODEF
5146           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5147    (clobber (match_scratch:DI 3 "=x"))
5148    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5149   "!TARGET_64BIT
5150    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5151    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5152   "#"
5153   "&& reload_completed"
5154   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5155    (set (match_dup 2) (match_dup 3))
5156    (set (match_dup 0)
5157         (float:X87MODEF (match_dup 2)))]
5158   ""
5159   [(set_attr "type" "multi")
5160    (set_attr "mode" "<MODE>")])
5162 (define_expand "floatunssi<mode>2"
5163   [(parallel
5164      [(set (match_operand:X87MODEF 0 "register_operand")
5165            (unsigned_float:X87MODEF
5166              (match_operand:SI 1 "nonimmediate_operand")))
5167       (clobber (match_scratch:DI 3))
5168       (clobber (match_dup 2))])]
5169   "!TARGET_64BIT
5170    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5171         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5172        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5174   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5175     {
5176       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5177       DONE;
5178     }
5179   else
5180     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5183 (define_expand "floatunsdisf2"
5184   [(use (match_operand:SF 0 "register_operand"))
5185    (use (match_operand:DI 1 "nonimmediate_operand"))]
5186   "TARGET_64BIT && TARGET_SSE_MATH"
5187   "x86_emit_floatuns (operands); DONE;")
5189 (define_expand "floatunsdidf2"
5190   [(use (match_operand:DF 0 "register_operand"))
5191    (use (match_operand:DI 1 "nonimmediate_operand"))]
5192   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5193    && TARGET_SSE2 && TARGET_SSE_MATH"
5195   if (TARGET_64BIT)
5196     x86_emit_floatuns (operands);
5197   else
5198     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5199   DONE;
5202 ;; Load effective address instructions
5204 (define_insn_and_split "*lea<mode>"
5205   [(set (match_operand:SWI48 0 "register_operand" "=r")
5206         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5207   ""
5209   if (SImode_address_operand (operands[1], VOIDmode))
5210     {
5211       gcc_assert (TARGET_64BIT);
5212       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5213     }
5214   else 
5215     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5217   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5218   [(const_int 0)]
5220   machine_mode mode = <MODE>mode;
5221   rtx pat;
5223   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5224      change operands[] array behind our back.  */
5225   pat = PATTERN (curr_insn);
5227   operands[0] = SET_DEST (pat);
5228   operands[1] = SET_SRC (pat);
5230   /* Emit all operations in SImode for zero-extended addresses.  */
5231   if (SImode_address_operand (operands[1], VOIDmode))
5232     mode = SImode;
5234   ix86_split_lea_for_addr (curr_insn, operands, mode);
5236   /* Zero-extend return register to DImode for zero-extended addresses.  */
5237   if (mode != <MODE>mode)
5238     emit_insn (gen_zero_extendsidi2
5239                (operands[0], gen_lowpart (mode, operands[0])));
5241   DONE;
5243   [(set_attr "type" "lea")
5244    (set (attr "mode")
5245      (if_then_else
5246        (match_operand 1 "SImode_address_operand")
5247        (const_string "SI")
5248        (const_string "<MODE>")))])
5250 ;; Add instructions
5252 (define_expand "add<mode>3"
5253   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5254         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5255                     (match_operand:SDWIM 2 "<general_operand>")))]
5256   ""
5257   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5259 (define_insn_and_split "*add<dwi>3_doubleword"
5260   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5261         (plus:<DWI>
5262           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5263           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5264    (clobber (reg:CC FLAGS_REG))]
5265   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5266   "#"
5267   "reload_completed"
5268   [(parallel [(set (reg:CC FLAGS_REG)
5269                    (unspec:CC [(match_dup 1) (match_dup 2)]
5270                               UNSPEC_ADD_CARRY))
5271               (set (match_dup 0)
5272                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5273    (parallel [(set (match_dup 3)
5274                    (plus:DWIH
5275                      (match_dup 4)
5276                      (plus:DWIH
5277                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5278                        (match_dup 5))))
5279               (clobber (reg:CC FLAGS_REG))])]
5280   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5282 (define_insn "*add<mode>3_cc"
5283   [(set (reg:CC FLAGS_REG)
5284         (unspec:CC
5285           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5286            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5287           UNSPEC_ADD_CARRY))
5288    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5289         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5290   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5291   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5292   [(set_attr "type" "alu")
5293    (set_attr "mode" "<MODE>")])
5295 (define_insn "addqi3_cc"
5296   [(set (reg:CC FLAGS_REG)
5297         (unspec:CC
5298           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5299            (match_operand:QI 2 "general_operand" "qn,qm")]
5300           UNSPEC_ADD_CARRY))
5301    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5302         (plus:QI (match_dup 1) (match_dup 2)))]
5303   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5304   "add{b}\t{%2, %0|%0, %2}"
5305   [(set_attr "type" "alu")
5306    (set_attr "mode" "QI")])
5308 (define_insn "*add<mode>_1"
5309   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5310         (plus:SWI48
5311           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5312           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5313    (clobber (reg:CC FLAGS_REG))]
5314   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5316   switch (get_attr_type (insn))
5317     {
5318     case TYPE_LEA:
5319       return "#";
5321     case TYPE_INCDEC:
5322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323       if (operands[2] == const1_rtx)
5324         return "inc{<imodesuffix>}\t%0";
5325       else
5326         {
5327           gcc_assert (operands[2] == constm1_rtx);
5328           return "dec{<imodesuffix>}\t%0";
5329         }
5331     default:
5332       /* For most processors, ADD is faster than LEA.  This alternative
5333          was added to use ADD as much as possible.  */
5334       if (which_alternative == 2)
5335         std::swap (operands[1], operands[2]);
5336         
5337       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5338       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5339         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5341       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5342     }
5344   [(set (attr "type")
5345      (cond [(eq_attr "alternative" "3")
5346               (const_string "lea")
5347             (match_operand:SWI48 2 "incdec_operand")
5348               (const_string "incdec")
5349            ]
5350            (const_string "alu")))
5351    (set (attr "length_immediate")
5352       (if_then_else
5353         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5354         (const_string "1")
5355         (const_string "*")))
5356    (set_attr "mode" "<MODE>")])
5358 ;; It may seem that nonimmediate operand is proper one for operand 1.
5359 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5360 ;; we take care in ix86_binary_operator_ok to not allow two memory
5361 ;; operands so proper swapping will be done in reload.  This allow
5362 ;; patterns constructed from addsi_1 to match.
5364 (define_insn "addsi_1_zext"
5365   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5366         (zero_extend:DI
5367           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5368                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5369    (clobber (reg:CC FLAGS_REG))]
5370   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5372   switch (get_attr_type (insn))
5373     {
5374     case TYPE_LEA:
5375       return "#";
5377     case TYPE_INCDEC:
5378       if (operands[2] == const1_rtx)
5379         return "inc{l}\t%k0";
5380       else
5381         {
5382           gcc_assert (operands[2] == constm1_rtx);
5383           return "dec{l}\t%k0";
5384         }
5386     default:
5387       /* For most processors, ADD is faster than LEA.  This alternative
5388          was added to use ADD as much as possible.  */
5389       if (which_alternative == 1)
5390         std::swap (operands[1], operands[2]);
5392       if (x86_maybe_negate_const_int (&operands[2], SImode))
5393         return "sub{l}\t{%2, %k0|%k0, %2}";
5395       return "add{l}\t{%2, %k0|%k0, %2}";
5396     }
5398   [(set (attr "type")
5399      (cond [(eq_attr "alternative" "2")
5400               (const_string "lea")
5401             (match_operand:SI 2 "incdec_operand")
5402               (const_string "incdec")
5403            ]
5404            (const_string "alu")))
5405    (set (attr "length_immediate")
5406       (if_then_else
5407         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5408         (const_string "1")
5409         (const_string "*")))
5410    (set_attr "mode" "SI")])
5412 (define_insn "*addhi_1"
5413   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5414         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5415                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5416    (clobber (reg:CC FLAGS_REG))]
5417   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5419   switch (get_attr_type (insn))
5420     {
5421     case TYPE_LEA:
5422       return "#";
5424     case TYPE_INCDEC:
5425       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5426       if (operands[2] == const1_rtx)
5427         return "inc{w}\t%0";
5428       else
5429         {
5430           gcc_assert (operands[2] == constm1_rtx);
5431           return "dec{w}\t%0";
5432         }
5434     default:
5435       /* For most processors, ADD is faster than LEA.  This alternative
5436          was added to use ADD as much as possible.  */
5437       if (which_alternative == 2)
5438         std::swap (operands[1], operands[2]);
5440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441       if (x86_maybe_negate_const_int (&operands[2], HImode))
5442         return "sub{w}\t{%2, %0|%0, %2}";
5444       return "add{w}\t{%2, %0|%0, %2}";
5445     }
5447   [(set (attr "type")
5448      (cond [(eq_attr "alternative" "3")
5449               (const_string "lea")
5450             (match_operand:HI 2 "incdec_operand")
5451               (const_string "incdec")
5452            ]
5453            (const_string "alu")))
5454    (set (attr "length_immediate")
5455       (if_then_else
5456         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5457         (const_string "1")
5458         (const_string "*")))
5459    (set_attr "mode" "HI,HI,HI,SI")])
5461 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5462 (define_insn "*addqi_1"
5463   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5464         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5465                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5466    (clobber (reg:CC FLAGS_REG))]
5467   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5469   bool widen = (which_alternative == 3 || which_alternative == 4);
5471   switch (get_attr_type (insn))
5472     {
5473     case TYPE_LEA:
5474       return "#";
5476     case TYPE_INCDEC:
5477       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5478       if (operands[2] == const1_rtx)
5479         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5480       else
5481         {
5482           gcc_assert (operands[2] == constm1_rtx);
5483           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5484         }
5486     default:
5487       /* For most processors, ADD is faster than LEA.  These alternatives
5488          were added to use ADD as much as possible.  */
5489       if (which_alternative == 2 || which_alternative == 4)
5490         std::swap (operands[1], operands[2]);
5492       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5493       if (x86_maybe_negate_const_int (&operands[2], QImode))
5494         {
5495           if (widen)
5496             return "sub{l}\t{%2, %k0|%k0, %2}";
5497           else
5498             return "sub{b}\t{%2, %0|%0, %2}";
5499         }
5500       if (widen)
5501         return "add{l}\t{%k2, %k0|%k0, %k2}";
5502       else
5503         return "add{b}\t{%2, %0|%0, %2}";
5504     }
5506   [(set (attr "type")
5507      (cond [(eq_attr "alternative" "5")
5508               (const_string "lea")
5509             (match_operand:QI 2 "incdec_operand")
5510               (const_string "incdec")
5511            ]
5512            (const_string "alu")))
5513    (set (attr "length_immediate")
5514       (if_then_else
5515         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5516         (const_string "1")
5517         (const_string "*")))
5518    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5520 (define_insn "*addqi_1_slp"
5521   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5522         (plus:QI (match_dup 0)
5523                  (match_operand:QI 1 "general_operand" "qn,qm")))
5524    (clobber (reg:CC FLAGS_REG))]
5525   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5526    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5528   switch (get_attr_type (insn))
5529     {
5530     case TYPE_INCDEC:
5531       if (operands[1] == const1_rtx)
5532         return "inc{b}\t%0";
5533       else
5534         {
5535           gcc_assert (operands[1] == constm1_rtx);
5536           return "dec{b}\t%0";
5537         }
5539     default:
5540       if (x86_maybe_negate_const_int (&operands[1], QImode))
5541         return "sub{b}\t{%1, %0|%0, %1}";
5543       return "add{b}\t{%1, %0|%0, %1}";
5544     }
5546   [(set (attr "type")
5547      (if_then_else (match_operand:QI 1 "incdec_operand")
5548         (const_string "incdec")
5549         (const_string "alu1")))
5550    (set (attr "memory")
5551      (if_then_else (match_operand 1 "memory_operand")
5552         (const_string "load")
5553         (const_string "none")))
5554    (set_attr "mode" "QI")])
5556 ;; Split non destructive adds if we cannot use lea.
5557 (define_split
5558   [(set (match_operand:SWI48 0 "register_operand")
5559         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5560                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5561    (clobber (reg:CC FLAGS_REG))]
5562   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5563   [(set (match_dup 0) (match_dup 1))
5564    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5565               (clobber (reg:CC FLAGS_REG))])])
5567 ;; Convert add to the lea pattern to avoid flags dependency.
5568 (define_split
5569   [(set (match_operand:SWI 0 "register_operand")
5570         (plus:SWI (match_operand:SWI 1 "register_operand")
5571                   (match_operand:SWI 2 "<nonmemory_operand>")))
5572    (clobber (reg:CC FLAGS_REG))]
5573   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5574   [(const_int 0)]
5576   machine_mode mode = <MODE>mode;
5577   rtx pat;
5579   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5580     { 
5581       mode = SImode; 
5582       operands[0] = gen_lowpart (mode, operands[0]);
5583       operands[1] = gen_lowpart (mode, operands[1]);
5584       operands[2] = gen_lowpart (mode, operands[2]);
5585     }
5587   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5589   emit_insn (gen_rtx_SET (operands[0], pat));
5590   DONE;
5593 ;; Split non destructive adds if we cannot use lea.
5594 (define_split
5595   [(set (match_operand:DI 0 "register_operand")
5596         (zero_extend:DI
5597           (plus:SI (match_operand:SI 1 "register_operand")
5598                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5599    (clobber (reg:CC FLAGS_REG))]
5600   "TARGET_64BIT
5601    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5602   [(set (match_dup 3) (match_dup 1))
5603    (parallel [(set (match_dup 0)
5604                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5605               (clobber (reg:CC FLAGS_REG))])]
5606   "operands[3] = gen_lowpart (SImode, operands[0]);")
5608 ;; Convert add to the lea pattern to avoid flags dependency.
5609 (define_split
5610   [(set (match_operand:DI 0 "register_operand")
5611         (zero_extend:DI
5612           (plus:SI (match_operand:SI 1 "register_operand")
5613                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5614    (clobber (reg:CC FLAGS_REG))]
5615   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5616   [(set (match_dup 0)
5617         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5619 (define_insn "*add<mode>_2"
5620   [(set (reg FLAGS_REG)
5621         (compare
5622           (plus:SWI
5623             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5624             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5625           (const_int 0)))
5626    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5627         (plus:SWI (match_dup 1) (match_dup 2)))]
5628   "ix86_match_ccmode (insn, CCGOCmode)
5629    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5631   switch (get_attr_type (insn))
5632     {
5633     case TYPE_INCDEC:
5634       if (operands[2] == const1_rtx)
5635         return "inc{<imodesuffix>}\t%0";
5636       else
5637         {
5638           gcc_assert (operands[2] == constm1_rtx);
5639           return "dec{<imodesuffix>}\t%0";
5640         }
5642     default:
5643       if (which_alternative == 2)
5644         std::swap (operands[1], operands[2]);
5645         
5646       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5647       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5648         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5650       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5651     }
5653   [(set (attr "type")
5654      (if_then_else (match_operand:SWI 2 "incdec_operand")
5655         (const_string "incdec")
5656         (const_string "alu")))
5657    (set (attr "length_immediate")
5658       (if_then_else
5659         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5660         (const_string "1")
5661         (const_string "*")))
5662    (set_attr "mode" "<MODE>")])
5664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5665 (define_insn "*addsi_2_zext"
5666   [(set (reg FLAGS_REG)
5667         (compare
5668           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5669                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5670           (const_int 0)))
5671    (set (match_operand:DI 0 "register_operand" "=r,r")
5672         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5673   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5674    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5676   switch (get_attr_type (insn))
5677     {
5678     case TYPE_INCDEC:
5679       if (operands[2] == const1_rtx)
5680         return "inc{l}\t%k0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return "dec{l}\t%k0";
5685         }
5687     default:
5688       if (which_alternative == 1)
5689         std::swap (operands[1], operands[2]);
5691       if (x86_maybe_negate_const_int (&operands[2], SImode))
5692         return "sub{l}\t{%2, %k0|%k0, %2}";
5694       return "add{l}\t{%2, %k0|%k0, %2}";
5695     }
5697   [(set (attr "type")
5698      (if_then_else (match_operand:SI 2 "incdec_operand")
5699         (const_string "incdec")
5700         (const_string "alu")))
5701    (set (attr "length_immediate")
5702       (if_then_else
5703         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5704         (const_string "1")
5705         (const_string "*")))
5706    (set_attr "mode" "SI")])
5708 (define_insn "*add<mode>_3"
5709   [(set (reg FLAGS_REG)
5710         (compare
5711           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5712           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5713    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5714   "ix86_match_ccmode (insn, CCZmode)
5715    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5717   switch (get_attr_type (insn))
5718     {
5719     case TYPE_INCDEC:
5720       if (operands[2] == const1_rtx)
5721         return "inc{<imodesuffix>}\t%0";
5722       else
5723         {
5724           gcc_assert (operands[2] == constm1_rtx);
5725           return "dec{<imodesuffix>}\t%0";
5726         }
5728     default:
5729       if (which_alternative == 1)
5730         std::swap (operands[1], operands[2]);
5732       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5733       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5734         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5736       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5737     }
5739   [(set (attr "type")
5740      (if_then_else (match_operand:SWI 2 "incdec_operand")
5741         (const_string "incdec")
5742         (const_string "alu")))
5743    (set (attr "length_immediate")
5744       (if_then_else
5745         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5746         (const_string "1")
5747         (const_string "*")))
5748    (set_attr "mode" "<MODE>")])
5750 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5751 (define_insn "*addsi_3_zext"
5752   [(set (reg FLAGS_REG)
5753         (compare
5754           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5755           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5756    (set (match_operand:DI 0 "register_operand" "=r,r")
5757         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5758   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5759    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5761   switch (get_attr_type (insn))
5762     {
5763     case TYPE_INCDEC:
5764       if (operands[2] == const1_rtx)
5765         return "inc{l}\t%k0";
5766       else
5767         {
5768           gcc_assert (operands[2] == constm1_rtx);
5769           return "dec{l}\t%k0";
5770         }
5772     default:
5773       if (which_alternative == 1)
5774         std::swap (operands[1], operands[2]);
5776       if (x86_maybe_negate_const_int (&operands[2], SImode))
5777         return "sub{l}\t{%2, %k0|%k0, %2}";
5779       return "add{l}\t{%2, %k0|%k0, %2}";
5780     }
5782   [(set (attr "type")
5783      (if_then_else (match_operand:SI 2 "incdec_operand")
5784         (const_string "incdec")
5785         (const_string "alu")))
5786    (set (attr "length_immediate")
5787       (if_then_else
5788         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5789         (const_string "1")
5790         (const_string "*")))
5791    (set_attr "mode" "SI")])
5793 ; For comparisons against 1, -1 and 128, we may generate better code
5794 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5795 ; is matched then.  We can't accept general immediate, because for
5796 ; case of overflows,  the result is messed up.
5797 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5798 ; only for comparisons not depending on it.
5800 (define_insn "*adddi_4"
5801   [(set (reg FLAGS_REG)
5802         (compare
5803           (match_operand:DI 1 "nonimmediate_operand" "0")
5804           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5805    (clobber (match_scratch:DI 0 "=rm"))]
5806   "TARGET_64BIT
5807    && ix86_match_ccmode (insn, CCGCmode)"
5809   switch (get_attr_type (insn))
5810     {
5811     case TYPE_INCDEC:
5812       if (operands[2] == constm1_rtx)
5813         return "inc{q}\t%0";
5814       else
5815         {
5816           gcc_assert (operands[2] == const1_rtx);
5817           return "dec{q}\t%0";
5818         }
5820     default:
5821       if (x86_maybe_negate_const_int (&operands[2], DImode))
5822         return "add{q}\t{%2, %0|%0, %2}";
5824       return "sub{q}\t{%2, %0|%0, %2}";
5825     }
5827   [(set (attr "type")
5828      (if_then_else (match_operand:DI 2 "incdec_operand")
5829         (const_string "incdec")
5830         (const_string "alu")))
5831    (set (attr "length_immediate")
5832       (if_then_else
5833         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5834         (const_string "1")
5835         (const_string "*")))
5836    (set_attr "mode" "DI")])
5838 ; For comparisons against 1, -1 and 128, we may generate better code
5839 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5840 ; is matched then.  We can't accept general immediate, because for
5841 ; case of overflows,  the result is messed up.
5842 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5843 ; only for comparisons not depending on it.
5845 (define_insn "*add<mode>_4"
5846   [(set (reg FLAGS_REG)
5847         (compare
5848           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5849           (match_operand:SWI124 2 "const_int_operand" "n")))
5850    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5851   "ix86_match_ccmode (insn, CCGCmode)"
5853   switch (get_attr_type (insn))
5854     {
5855     case TYPE_INCDEC:
5856       if (operands[2] == constm1_rtx)
5857         return "inc{<imodesuffix>}\t%0";
5858       else
5859         {
5860           gcc_assert (operands[2] == const1_rtx);
5861           return "dec{<imodesuffix>}\t%0";
5862         }
5864     default:
5865       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5866         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5868       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5869     }
5871   [(set (attr "type")
5872      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5873         (const_string "incdec")
5874         (const_string "alu")))
5875    (set (attr "length_immediate")
5876       (if_then_else
5877         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5878         (const_string "1")
5879         (const_string "*")))
5880    (set_attr "mode" "<MODE>")])
5882 (define_insn "*add<mode>_5"
5883   [(set (reg FLAGS_REG)
5884         (compare
5885           (plus:SWI
5886             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5887             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5888           (const_int 0)))
5889    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5890   "ix86_match_ccmode (insn, CCGOCmode)
5891    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5893   switch (get_attr_type (insn))
5894     {
5895     case TYPE_INCDEC:
5896       if (operands[2] == const1_rtx)
5897         return "inc{<imodesuffix>}\t%0";
5898       else
5899         {
5900           gcc_assert (operands[2] == constm1_rtx);
5901           return "dec{<imodesuffix>}\t%0";
5902         }
5904     default:
5905       if (which_alternative == 1)
5906         std::swap (operands[1], operands[2]);
5908       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5909       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5910         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5912       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5913     }
5915   [(set (attr "type")
5916      (if_then_else (match_operand:SWI 2 "incdec_operand")
5917         (const_string "incdec")
5918         (const_string "alu")))
5919    (set (attr "length_immediate")
5920       (if_then_else
5921         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5922         (const_string "1")
5923         (const_string "*")))
5924    (set_attr "mode" "<MODE>")])
5926 (define_insn "addqi_ext_1"
5927   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5928                          (const_int 8)
5929                          (const_int 8))
5930         (plus:SI
5931           (zero_extract:SI
5932             (match_operand 1 "ext_register_operand" "0,0")
5933             (const_int 8)
5934             (const_int 8))
5935           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5936    (clobber (reg:CC FLAGS_REG))]
5937   ""
5939   switch (get_attr_type (insn))
5940     {
5941     case TYPE_INCDEC:
5942       if (operands[2] == const1_rtx)
5943         return "inc{b}\t%h0";
5944       else
5945         {
5946           gcc_assert (operands[2] == constm1_rtx);
5947           return "dec{b}\t%h0";
5948         }
5950     default:
5951       return "add{b}\t{%2, %h0|%h0, %2}";
5952     }
5954   [(set_attr "isa" "*,nox64")
5955    (set (attr "type")
5956      (if_then_else (match_operand:QI 2 "incdec_operand")
5957         (const_string "incdec")
5958         (const_string "alu")))
5959    (set_attr "modrm" "1")
5960    (set_attr "mode" "QI")])
5962 (define_insn "*addqi_ext_2"
5963   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5964                          (const_int 8)
5965                          (const_int 8))
5966         (plus:SI
5967           (zero_extract:SI
5968             (match_operand 1 "ext_register_operand" "%0")
5969             (const_int 8)
5970             (const_int 8))
5971           (zero_extract:SI
5972             (match_operand 2 "ext_register_operand" "Q")
5973             (const_int 8)
5974             (const_int 8))))
5975    (clobber (reg:CC FLAGS_REG))]
5976   ""
5977   "add{b}\t{%h2, %h0|%h0, %h2}"
5978   [(set_attr "type" "alu")
5979    (set_attr "mode" "QI")])
5981 ;; Add with jump on overflow.
5982 (define_expand "addv<mode>4"
5983   [(parallel [(set (reg:CCO FLAGS_REG)
5984                    (eq:CCO (plus:<DWI>
5985                               (sign_extend:<DWI>
5986                                  (match_operand:SWI 1 "nonimmediate_operand"))
5987                               (match_dup 4))
5988                            (sign_extend:<DWI>
5989                               (plus:SWI (match_dup 1)
5990                                         (match_operand:SWI 2
5991                                            "<general_operand>")))))
5992               (set (match_operand:SWI 0 "register_operand")
5993                    (plus:SWI (match_dup 1) (match_dup 2)))])
5994    (set (pc) (if_then_else
5995                (eq (reg:CCO FLAGS_REG) (const_int 0))
5996                (label_ref (match_operand 3))
5997                (pc)))]
5998   ""
6000   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6001   if (CONST_INT_P (operands[2]))
6002     operands[4] = operands[2];
6003   else
6004     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6007 (define_insn "*addv<mode>4"
6008   [(set (reg:CCO FLAGS_REG)
6009         (eq:CCO (plus:<DWI>
6010                    (sign_extend:<DWI>
6011                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6012                    (sign_extend:<DWI>
6013                       (match_operand:SWI 2 "<general_sext_operand>"
6014                                            "<r>mWe,<r>We")))
6015                 (sign_extend:<DWI>
6016                    (plus:SWI (match_dup 1) (match_dup 2)))))
6017    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6018         (plus:SWI (match_dup 1) (match_dup 2)))]
6019   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6020   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6021   [(set_attr "type" "alu")
6022    (set_attr "mode" "<MODE>")])
6024 (define_insn "*addv<mode>4_1"
6025   [(set (reg:CCO FLAGS_REG)
6026         (eq:CCO (plus:<DWI>
6027                    (sign_extend:<DWI>
6028                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6029                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6030                 (sign_extend:<DWI>
6031                    (plus:SWI (match_dup 1)
6032                              (match_operand:SWI 2 "x86_64_immediate_operand"
6033                                                   "<i>")))))
6034    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6035         (plus:SWI (match_dup 1) (match_dup 2)))]
6036   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6037    && CONST_INT_P (operands[2])
6038    && INTVAL (operands[2]) == INTVAL (operands[3])"
6039   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6040   [(set_attr "type" "alu")
6041    (set_attr "mode" "<MODE>")
6042    (set (attr "length_immediate")
6043         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6044                   (const_string "1")
6045                (match_test "<MODE_SIZE> == 8")
6046                   (const_string "4")]
6047               (const_string "<MODE_SIZE>")))])
6049 ;; The lea patterns for modes less than 32 bits need to be matched by
6050 ;; several insns converted to real lea by splitters.
6052 (define_insn_and_split "*lea_general_1"
6053   [(set (match_operand 0 "register_operand" "=r")
6054         (plus (plus (match_operand 1 "index_register_operand" "l")
6055                     (match_operand 2 "register_operand" "r"))
6056               (match_operand 3 "immediate_operand" "i")))]
6057   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6058    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6059    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6060    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6061    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6062        || GET_MODE (operands[3]) == VOIDmode)"
6063   "#"
6064   "&& reload_completed"
6065   [(const_int 0)]
6067   machine_mode mode = SImode;
6068   rtx pat;
6070   operands[0] = gen_lowpart (mode, operands[0]);
6071   operands[1] = gen_lowpart (mode, operands[1]);
6072   operands[2] = gen_lowpart (mode, operands[2]);
6073   operands[3] = gen_lowpart (mode, operands[3]);
6075   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6076                       operands[3]);
6078   emit_insn (gen_rtx_SET (operands[0], pat));
6079   DONE;
6081   [(set_attr "type" "lea")
6082    (set_attr "mode" "SI")])
6084 (define_insn_and_split "*lea_general_2"
6085   [(set (match_operand 0 "register_operand" "=r")
6086         (plus (mult (match_operand 1 "index_register_operand" "l")
6087                     (match_operand 2 "const248_operand" "n"))
6088               (match_operand 3 "nonmemory_operand" "ri")))]
6089   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6090    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6091    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6092    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6093        || GET_MODE (operands[3]) == VOIDmode)"
6094   "#"
6095   "&& reload_completed"
6096   [(const_int 0)]
6098   machine_mode mode = SImode;
6099   rtx pat;
6101   operands[0] = gen_lowpart (mode, operands[0]);
6102   operands[1] = gen_lowpart (mode, operands[1]);
6103   operands[3] = gen_lowpart (mode, operands[3]);
6105   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6106                       operands[3]);
6108   emit_insn (gen_rtx_SET (operands[0], pat));
6109   DONE;
6111   [(set_attr "type" "lea")
6112    (set_attr "mode" "SI")])
6114 (define_insn_and_split "*lea_general_3"
6115   [(set (match_operand 0 "register_operand" "=r")
6116         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6117                           (match_operand 2 "const248_operand" "n"))
6118                     (match_operand 3 "register_operand" "r"))
6119               (match_operand 4 "immediate_operand" "i")))]
6120   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6121    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6122    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6123    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6124   "#"
6125   "&& reload_completed"
6126   [(const_int 0)]
6128   machine_mode mode = SImode;
6129   rtx pat;
6131   operands[0] = gen_lowpart (mode, operands[0]);
6132   operands[1] = gen_lowpart (mode, operands[1]);
6133   operands[3] = gen_lowpart (mode, operands[3]);
6134   operands[4] = gen_lowpart (mode, operands[4]);
6136   pat = gen_rtx_PLUS (mode,
6137                       gen_rtx_PLUS (mode,
6138                                     gen_rtx_MULT (mode, operands[1],
6139                                                         operands[2]),
6140                                     operands[3]),
6141                       operands[4]);
6143   emit_insn (gen_rtx_SET (operands[0], pat));
6144   DONE;
6146   [(set_attr "type" "lea")
6147    (set_attr "mode" "SI")])
6149 (define_insn_and_split "*lea_general_4"
6150   [(set (match_operand 0 "register_operand" "=r")
6151         (any_or (ashift
6152                   (match_operand 1 "index_register_operand" "l")
6153                   (match_operand 2 "const_int_operand" "n"))
6154                 (match_operand 3 "const_int_operand" "n")))]
6155   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6156       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6157     || GET_MODE (operands[0]) == SImode
6158     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6159    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6160    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6161    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6162        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6163   "#"
6164   "&& reload_completed"
6165   [(const_int 0)]
6167   machine_mode mode = GET_MODE (operands[0]);
6168   rtx pat;
6170   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6171     { 
6172       mode = SImode; 
6173       operands[0] = gen_lowpart (mode, operands[0]);
6174       operands[1] = gen_lowpart (mode, operands[1]);
6175     }
6177   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6179   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6180                        INTVAL (operands[3]));
6182   emit_insn (gen_rtx_SET (operands[0], pat));
6183   DONE;
6185   [(set_attr "type" "lea")
6186    (set (attr "mode")
6187       (if_then_else (match_operand:DI 0)
6188         (const_string "DI")
6189         (const_string "SI")))])
6191 ;; Subtract instructions
6193 (define_expand "sub<mode>3"
6194   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6195         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6196                      (match_operand:SDWIM 2 "<general_operand>")))]
6197   ""
6198   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6200 (define_insn_and_split "*sub<dwi>3_doubleword"
6201   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6202         (minus:<DWI>
6203           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6204           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6205    (clobber (reg:CC FLAGS_REG))]
6206   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6207   "#"
6208   "reload_completed"
6209   [(parallel [(set (reg:CC FLAGS_REG)
6210                    (compare:CC (match_dup 1) (match_dup 2)))
6211               (set (match_dup 0)
6212                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6213    (parallel [(set (match_dup 3)
6214                    (minus:DWIH
6215                      (match_dup 4)
6216                      (plus:DWIH
6217                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6218                        (match_dup 5))))
6219               (clobber (reg:CC FLAGS_REG))])]
6220   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6222 (define_insn "*sub<mode>_1"
6223   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6224         (minus:SWI
6225           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6226           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6227    (clobber (reg:CC FLAGS_REG))]
6228   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6229   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6230   [(set_attr "type" "alu")
6231    (set_attr "mode" "<MODE>")])
6233 (define_insn "*subsi_1_zext"
6234   [(set (match_operand:DI 0 "register_operand" "=r")
6235         (zero_extend:DI
6236           (minus:SI (match_operand:SI 1 "register_operand" "0")
6237                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6238    (clobber (reg:CC FLAGS_REG))]
6239   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6240   "sub{l}\t{%2, %k0|%k0, %2}"
6241   [(set_attr "type" "alu")
6242    (set_attr "mode" "SI")])
6244 (define_insn "*subqi_1_slp"
6245   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6246         (minus:QI (match_dup 0)
6247                   (match_operand:QI 1 "general_operand" "qn,qm")))
6248    (clobber (reg:CC FLAGS_REG))]
6249   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6251   "sub{b}\t{%1, %0|%0, %1}"
6252   [(set_attr "type" "alu1")
6253    (set_attr "mode" "QI")])
6255 (define_insn "*sub<mode>_2"
6256   [(set (reg FLAGS_REG)
6257         (compare
6258           (minus:SWI
6259             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6260             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6261           (const_int 0)))
6262    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6263         (minus:SWI (match_dup 1) (match_dup 2)))]
6264   "ix86_match_ccmode (insn, CCGOCmode)
6265    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6266   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6267   [(set_attr "type" "alu")
6268    (set_attr "mode" "<MODE>")])
6270 (define_insn "*subsi_2_zext"
6271   [(set (reg FLAGS_REG)
6272         (compare
6273           (minus:SI (match_operand:SI 1 "register_operand" "0")
6274                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6275           (const_int 0)))
6276    (set (match_operand:DI 0 "register_operand" "=r")
6277         (zero_extend:DI
6278           (minus:SI (match_dup 1)
6279                     (match_dup 2))))]
6280   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6281    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6282   "sub{l}\t{%2, %k0|%k0, %2}"
6283   [(set_attr "type" "alu")
6284    (set_attr "mode" "SI")])
6286 ;; Subtract with jump on overflow.
6287 (define_expand "subv<mode>4"
6288   [(parallel [(set (reg:CCO FLAGS_REG)
6289                    (eq:CCO (minus:<DWI>
6290                               (sign_extend:<DWI>
6291                                  (match_operand:SWI 1 "nonimmediate_operand"))
6292                               (match_dup 4))
6293                            (sign_extend:<DWI>
6294                               (minus:SWI (match_dup 1)
6295                                          (match_operand:SWI 2
6296                                             "<general_operand>")))))
6297               (set (match_operand:SWI 0 "register_operand")
6298                    (minus:SWI (match_dup 1) (match_dup 2)))])
6299    (set (pc) (if_then_else
6300                (eq (reg:CCO FLAGS_REG) (const_int 0))
6301                (label_ref (match_operand 3))
6302                (pc)))]
6303   ""
6305   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6306   if (CONST_INT_P (operands[2]))
6307     operands[4] = operands[2];
6308   else
6309     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6312 (define_insn "*subv<mode>4"
6313   [(set (reg:CCO FLAGS_REG)
6314         (eq:CCO (minus:<DWI>
6315                    (sign_extend:<DWI>
6316                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6317                    (sign_extend:<DWI>
6318                       (match_operand:SWI 2 "<general_sext_operand>"
6319                                            "<r>We,<r>m")))
6320                 (sign_extend:<DWI>
6321                    (minus:SWI (match_dup 1) (match_dup 2)))))
6322    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6323         (minus:SWI (match_dup 1) (match_dup 2)))]
6324   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6325   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6326   [(set_attr "type" "alu")
6327    (set_attr "mode" "<MODE>")])
6329 (define_insn "*subv<mode>4_1"
6330   [(set (reg:CCO FLAGS_REG)
6331         (eq:CCO (minus:<DWI>
6332                    (sign_extend:<DWI>
6333                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6334                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6335                 (sign_extend:<DWI>
6336                    (minus:SWI (match_dup 1)
6337                               (match_operand:SWI 2 "x86_64_immediate_operand"
6338                                                    "<i>")))))
6339    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6340         (minus:SWI (match_dup 1) (match_dup 2)))]
6341   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6342    && CONST_INT_P (operands[2])
6343    && INTVAL (operands[2]) == INTVAL (operands[3])"
6344   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6345   [(set_attr "type" "alu")
6346    (set_attr "mode" "<MODE>")
6347    (set (attr "length_immediate")
6348         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6349                   (const_string "1")
6350                (match_test "<MODE_SIZE> == 8")
6351                   (const_string "4")]
6352               (const_string "<MODE_SIZE>")))])
6354 (define_insn "*sub<mode>_3"
6355   [(set (reg FLAGS_REG)
6356         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6357                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6358    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6359         (minus:SWI (match_dup 1) (match_dup 2)))]
6360   "ix86_match_ccmode (insn, CCmode)
6361    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6362   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6363   [(set_attr "type" "alu")
6364    (set_attr "mode" "<MODE>")])
6366 (define_insn "*subsi_3_zext"
6367   [(set (reg FLAGS_REG)
6368         (compare (match_operand:SI 1 "register_operand" "0")
6369                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6370    (set (match_operand:DI 0 "register_operand" "=r")
6371         (zero_extend:DI
6372           (minus:SI (match_dup 1)
6373                     (match_dup 2))))]
6374   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6375    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6376   "sub{l}\t{%2, %1|%1, %2}"
6377   [(set_attr "type" "alu")
6378    (set_attr "mode" "SI")])
6380 ;; Add with carry and subtract with borrow
6382 (define_expand "<plusminus_insn><mode>3_carry"
6383   [(parallel
6384     [(set (match_operand:SWI 0 "nonimmediate_operand")
6385           (plusminus:SWI
6386             (match_operand:SWI 1 "nonimmediate_operand")
6387             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6388                        [(match_operand 3 "flags_reg_operand")
6389                         (const_int 0)])
6390                       (match_operand:SWI 2 "<general_operand>"))))
6391      (clobber (reg:CC FLAGS_REG))])]
6392   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6394 (define_insn "*<plusminus_insn><mode>3_carry"
6395   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6396         (plusminus:SWI
6397           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6398           (plus:SWI
6399             (match_operator 3 "ix86_carry_flag_operator"
6400              [(reg FLAGS_REG) (const_int 0)])
6401             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6402    (clobber (reg:CC FLAGS_REG))]
6403   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6404   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6405   [(set_attr "type" "alu")
6406    (set_attr "use_carry" "1")
6407    (set_attr "pent_pair" "pu")
6408    (set_attr "mode" "<MODE>")])
6410 (define_insn "*addsi3_carry_zext"
6411   [(set (match_operand:DI 0 "register_operand" "=r")
6412         (zero_extend:DI
6413           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6415                              [(reg FLAGS_REG) (const_int 0)])
6416                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6417    (clobber (reg:CC FLAGS_REG))]
6418   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6419   "adc{l}\t{%2, %k0|%k0, %2}"
6420   [(set_attr "type" "alu")
6421    (set_attr "use_carry" "1")
6422    (set_attr "pent_pair" "pu")
6423    (set_attr "mode" "SI")])
6425 (define_insn "*subsi3_carry_zext"
6426   [(set (match_operand:DI 0 "register_operand" "=r")
6427         (zero_extend:DI
6428           (minus:SI (match_operand:SI 1 "register_operand" "0")
6429                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6430                               [(reg FLAGS_REG) (const_int 0)])
6431                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6432    (clobber (reg:CC FLAGS_REG))]
6433   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6434   "sbb{l}\t{%2, %k0|%k0, %2}"
6435   [(set_attr "type" "alu")
6436    (set_attr "pent_pair" "pu")
6437    (set_attr "mode" "SI")])
6439 ;; ADCX instruction
6441 (define_insn "adcx<mode>3"
6442   [(set (reg:CCC FLAGS_REG)
6443         (compare:CCC
6444           (plus:SWI48
6445             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6446             (plus:SWI48
6447               (match_operator 4 "ix86_carry_flag_operator"
6448                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6449               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6450           (const_int 0)))
6451    (set (match_operand:SWI48 0 "register_operand" "=r")
6452         (plus:SWI48 (match_dup 1)
6453                     (plus:SWI48 (match_op_dup 4
6454                                  [(match_dup 3) (const_int 0)])
6455                                 (match_dup 2))))]
6456   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6457   "adcx\t{%2, %0|%0, %2}"
6458   [(set_attr "type" "alu")
6459    (set_attr "use_carry" "1")
6460    (set_attr "mode" "<MODE>")])
6462 ;; Overflow setting add instructions
6464 (define_insn "*add<mode>3_cconly_overflow"
6465   [(set (reg:CCC FLAGS_REG)
6466         (compare:CCC
6467           (plus:SWI
6468             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6469             (match_operand:SWI 2 "<general_operand>" "<g>"))
6470           (match_dup 1)))
6471    (clobber (match_scratch:SWI 0 "=<r>"))]
6472   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6473   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6474   [(set_attr "type" "alu")
6475    (set_attr "mode" "<MODE>")])
6477 (define_insn "*add<mode>3_cc_overflow"
6478   [(set (reg:CCC FLAGS_REG)
6479         (compare:CCC
6480             (plus:SWI
6481                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6482                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6483             (match_dup 1)))
6484    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6485         (plus:SWI (match_dup 1) (match_dup 2)))]
6486   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6487   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6488   [(set_attr "type" "alu")
6489    (set_attr "mode" "<MODE>")])
6491 (define_insn "*addsi3_zext_cc_overflow"
6492   [(set (reg:CCC FLAGS_REG)
6493         (compare:CCC
6494           (plus:SI
6495             (match_operand:SI 1 "nonimmediate_operand" "%0")
6496             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6497           (match_dup 1)))
6498    (set (match_operand:DI 0 "register_operand" "=r")
6499         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6500   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6501   "add{l}\t{%2, %k0|%k0, %2}"
6502   [(set_attr "type" "alu")
6503    (set_attr "mode" "SI")])
6505 ;; The patterns that match these are at the end of this file.
6507 (define_expand "<plusminus_insn>xf3"
6508   [(set (match_operand:XF 0 "register_operand")
6509         (plusminus:XF
6510           (match_operand:XF 1 "register_operand")
6511           (match_operand:XF 2 "register_operand")))]
6512   "TARGET_80387")
6514 (define_expand "<plusminus_insn><mode>3"
6515   [(set (match_operand:MODEF 0 "register_operand")
6516         (plusminus:MODEF
6517           (match_operand:MODEF 1 "register_operand")
6518           (match_operand:MODEF 2 "nonimmediate_operand")))]
6519   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6520     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6522 ;; Multiply instructions
6524 (define_expand "mul<mode>3"
6525   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6526                    (mult:SWIM248
6527                      (match_operand:SWIM248 1 "register_operand")
6528                      (match_operand:SWIM248 2 "<general_operand>")))
6529               (clobber (reg:CC FLAGS_REG))])])
6531 (define_expand "mulqi3"
6532   [(parallel [(set (match_operand:QI 0 "register_operand")
6533                    (mult:QI
6534                      (match_operand:QI 1 "register_operand")
6535                      (match_operand:QI 2 "nonimmediate_operand")))
6536               (clobber (reg:CC FLAGS_REG))])]
6537   "TARGET_QIMODE_MATH")
6539 ;; On AMDFAM10
6540 ;; IMUL reg32/64, reg32/64, imm8        Direct
6541 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6542 ;; IMUL reg32/64, reg32/64, imm32       Direct
6543 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6544 ;; IMUL reg32/64, reg32/64              Direct
6545 ;; IMUL reg32/64, mem32/64              Direct
6547 ;; On BDVER1, all above IMULs use DirectPath
6549 ;; On AMDFAM10
6550 ;; IMUL reg16, reg16, imm8      VectorPath
6551 ;; IMUL reg16, mem16, imm8      VectorPath
6552 ;; IMUL reg16, reg16, imm16     VectorPath
6553 ;; IMUL reg16, mem16, imm16     VectorPath
6554 ;; IMUL reg16, reg16            Direct
6555 ;; IMUL reg16, mem16            Direct
6557 ;; On BDVER1, all HI MULs use DoublePath
6559 (define_insn "*mul<mode>3_1"
6560   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6561         (mult:SWIM248
6562           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6563           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6564    (clobber (reg:CC FLAGS_REG))]
6565   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6566   "@
6567    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6568    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6569    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6570   [(set_attr "type" "imul")
6571    (set_attr "prefix_0f" "0,0,1")
6572    (set (attr "athlon_decode")
6573         (cond [(eq_attr "cpu" "athlon")
6574                   (const_string "vector")
6575                (eq_attr "alternative" "1")
6576                   (const_string "vector")
6577                (and (eq_attr "alternative" "2")
6578                     (ior (match_test "<MODE>mode == HImode")
6579                          (match_operand 1 "memory_operand")))
6580                   (const_string "vector")]
6581               (const_string "direct")))
6582    (set (attr "amdfam10_decode")
6583         (cond [(and (eq_attr "alternative" "0,1")
6584                     (ior (match_test "<MODE>mode == HImode")
6585                          (match_operand 1 "memory_operand")))
6586                   (const_string "vector")]
6587               (const_string "direct")))
6588    (set (attr "bdver1_decode")
6589         (if_then_else
6590           (match_test "<MODE>mode == HImode")
6591             (const_string "double")
6592             (const_string "direct")))
6593    (set_attr "mode" "<MODE>")])
6595 (define_insn "*mulsi3_1_zext"
6596   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6597         (zero_extend:DI
6598           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6599                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6600    (clobber (reg:CC FLAGS_REG))]
6601   "TARGET_64BIT
6602    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6603   "@
6604    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6605    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6606    imul{l}\t{%2, %k0|%k0, %2}"
6607   [(set_attr "type" "imul")
6608    (set_attr "prefix_0f" "0,0,1")
6609    (set (attr "athlon_decode")
6610         (cond [(eq_attr "cpu" "athlon")
6611                   (const_string "vector")
6612                (eq_attr "alternative" "1")
6613                   (const_string "vector")
6614                (and (eq_attr "alternative" "2")
6615                     (match_operand 1 "memory_operand"))
6616                   (const_string "vector")]
6617               (const_string "direct")))
6618    (set (attr "amdfam10_decode")
6619         (cond [(and (eq_attr "alternative" "0,1")
6620                     (match_operand 1 "memory_operand"))
6621                   (const_string "vector")]
6622               (const_string "direct")))
6623    (set_attr "bdver1_decode" "direct")
6624    (set_attr "mode" "SI")])
6626 ;;On AMDFAM10 and BDVER1
6627 ;; MUL reg8     Direct
6628 ;; MUL mem8     Direct
6630 (define_insn "*mulqi3_1"
6631   [(set (match_operand:QI 0 "register_operand" "=a")
6632         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "TARGET_QIMODE_MATH
6636    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6637   "mul{b}\t%2"
6638   [(set_attr "type" "imul")
6639    (set_attr "length_immediate" "0")
6640    (set (attr "athlon_decode")
6641      (if_then_else (eq_attr "cpu" "athlon")
6642         (const_string "vector")
6643         (const_string "direct")))
6644    (set_attr "amdfam10_decode" "direct")
6645    (set_attr "bdver1_decode" "direct")
6646    (set_attr "mode" "QI")])
6648 ;; Multiply with jump on overflow.
6649 (define_expand "mulv<mode>4"
6650   [(parallel [(set (reg:CCO FLAGS_REG)
6651                    (eq:CCO (mult:<DWI>
6652                               (sign_extend:<DWI>
6653                                  (match_operand:SWI248 1 "register_operand"))
6654                               (match_dup 4))
6655                            (sign_extend:<DWI>
6656                               (mult:SWI248 (match_dup 1)
6657                                            (match_operand:SWI248 2
6658                                               "<general_operand>")))))
6659               (set (match_operand:SWI248 0 "register_operand")
6660                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6661    (set (pc) (if_then_else
6662                (eq (reg:CCO FLAGS_REG) (const_int 0))
6663                (label_ref (match_operand 3))
6664                (pc)))]
6665   ""
6667   if (CONST_INT_P (operands[2]))
6668     operands[4] = operands[2];
6669   else
6670     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6673 (define_insn "*mulv<mode>4"
6674   [(set (reg:CCO FLAGS_REG)
6675         (eq:CCO (mult:<DWI>
6676                    (sign_extend:<DWI>
6677                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6678                    (sign_extend:<DWI>
6679                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6680                 (sign_extend:<DWI>
6681                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6682    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6683         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6684   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6685   "@
6686    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6687    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6688   [(set_attr "type" "imul")
6689    (set_attr "prefix_0f" "0,1")
6690    (set (attr "athlon_decode")
6691         (cond [(eq_attr "cpu" "athlon")
6692                   (const_string "vector")
6693                (eq_attr "alternative" "0")
6694                   (const_string "vector")
6695                (and (eq_attr "alternative" "1")
6696                     (match_operand 1 "memory_operand"))
6697                   (const_string "vector")]
6698               (const_string "direct")))
6699    (set (attr "amdfam10_decode")
6700         (cond [(and (eq_attr "alternative" "1")
6701                     (match_operand 1 "memory_operand"))
6702                   (const_string "vector")]
6703               (const_string "direct")))
6704    (set_attr "bdver1_decode" "direct")
6705    (set_attr "mode" "<MODE>")])
6707 (define_insn "*mulvhi4"
6708   [(set (reg:CCO FLAGS_REG)
6709         (eq:CCO (mult:SI
6710                    (sign_extend:SI
6711                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6712                    (sign_extend:SI
6713                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6714                 (sign_extend:SI
6715                    (mult:HI (match_dup 1) (match_dup 2)))))
6716    (set (match_operand:HI 0 "register_operand" "=r")
6717         (mult:HI (match_dup 1) (match_dup 2)))]
6718   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6719   "imul{w}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "imul")
6721    (set_attr "prefix_0f" "1")
6722    (set_attr "athlon_decode" "vector")
6723    (set_attr "amdfam10_decode" "direct")
6724    (set_attr "bdver1_decode" "double")
6725    (set_attr "mode" "HI")])
6727 (define_insn "*mulv<mode>4_1"
6728   [(set (reg:CCO FLAGS_REG)
6729         (eq:CCO (mult:<DWI>
6730                    (sign_extend:<DWI>
6731                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6732                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6733                 (sign_extend:<DWI>
6734                    (mult:SWI248 (match_dup 1)
6735                                 (match_operand:SWI248 2
6736                                    "<immediate_operand>" "K,<i>")))))
6737    (set (match_operand:SWI248 0 "register_operand" "=r,r")
6738         (mult:SWI248 (match_dup 1) (match_dup 2)))]
6739   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6740    && CONST_INT_P (operands[2])
6741    && INTVAL (operands[2]) == INTVAL (operands[3])"
6742   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6743   [(set_attr "type" "imul")
6744    (set (attr "prefix_0f")
6745         (if_then_else
6746           (match_test "<MODE>mode == HImode")
6747             (const_string "0")
6748             (const_string "*")))
6749    (set (attr "athlon_decode")
6750         (cond [(eq_attr "cpu" "athlon")
6751                   (const_string "vector")
6752                (eq_attr "alternative" "1")
6753                   (const_string "vector")]
6754               (const_string "direct")))
6755    (set (attr "amdfam10_decode")
6756         (cond [(ior (match_test "<MODE>mode == HImode")
6757                     (match_operand 1 "memory_operand"))
6758                   (const_string "vector")]
6759               (const_string "direct")))
6760    (set (attr "bdver1_decode")
6761         (if_then_else
6762           (match_test "<MODE>mode == HImode")
6763             (const_string "double")
6764             (const_string "direct")))
6765    (set_attr "mode" "<MODE>")
6766    (set (attr "length_immediate")
6767         (cond [(eq_attr "alternative" "0")
6768                   (const_string "1")
6769                (match_test "<MODE_SIZE> == 8")
6770                   (const_string "4")]
6771               (const_string "<MODE_SIZE>")))])
6773 (define_expand "umulv<mode>4"
6774   [(parallel [(set (reg:CCO FLAGS_REG)
6775                    (eq:CCO (mult:<DWI>
6776                               (zero_extend:<DWI>
6777                                  (match_operand:SWI248 1
6778                                                       "nonimmediate_operand"))
6779                               (zero_extend:<DWI>
6780                                  (match_operand:SWI248 2
6781                                                       "nonimmediate_operand")))
6782                            (zero_extend:<DWI>
6783                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
6784               (set (match_operand:SWI248 0 "register_operand")
6785                    (mult:SWI248 (match_dup 1) (match_dup 2)))
6786               (clobber (match_scratch:SWI248 4))])
6787    (set (pc) (if_then_else
6788                (eq (reg:CCO FLAGS_REG) (const_int 0))
6789                (label_ref (match_operand 3))
6790                (pc)))]
6791   ""
6793   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6794     operands[1] = force_reg (<MODE>mode, operands[1]);
6797 (define_insn "*umulv<mode>4"
6798   [(set (reg:CCO FLAGS_REG)
6799         (eq:CCO (mult:<DWI>
6800                    (zero_extend:<DWI>
6801                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
6802                    (zero_extend:<DWI>
6803                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
6804                 (zero_extend:<DWI>
6805                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
6806    (set (match_operand:SWI248 0 "register_operand" "=a")
6807         (mult:SWI248 (match_dup 1) (match_dup 2)))
6808    (clobber (match_scratch:SWI248 3 "=d"))]
6809   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810   "mul{<imodesuffix>}\t%2"
6811   [(set_attr "type" "imul")
6812    (set_attr "length_immediate" "0")
6813    (set (attr "athlon_decode")
6814      (if_then_else (eq_attr "cpu" "athlon")
6815        (const_string "vector")
6816        (const_string "double")))
6817    (set_attr "amdfam10_decode" "double")
6818    (set_attr "bdver1_decode" "direct")
6819    (set_attr "mode" "<MODE>")])
6821 (define_expand "<u>mulvqi4"
6822   [(parallel [(set (reg:CCO FLAGS_REG)
6823                    (eq:CCO (mult:HI
6824                               (any_extend:HI
6825                                  (match_operand:QI 1 "nonimmediate_operand"))
6826                               (any_extend:HI
6827                                  (match_operand:QI 2 "nonimmediate_operand")))
6828                            (any_extend:HI
6829                               (mult:QI (match_dup 1) (match_dup 2)))))
6830               (set (match_operand:QI 0 "register_operand")
6831                    (mult:QI (match_dup 1) (match_dup 2)))])
6832    (set (pc) (if_then_else
6833                (eq (reg:CCO FLAGS_REG) (const_int 0))
6834                (label_ref (match_operand 3))
6835                (pc)))]
6836   "TARGET_QIMODE_MATH"
6838   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6839     operands[1] = force_reg (QImode, operands[1]);
6842 (define_insn "*<u>mulvqi4"
6843   [(set (reg:CCO FLAGS_REG)
6844         (eq:CCO (mult:HI
6845                    (any_extend:HI
6846                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
6847                    (any_extend:HI
6848                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
6849                 (any_extend:HI
6850                    (mult:QI (match_dup 1) (match_dup 2)))))
6851    (set (match_operand:QI 0 "register_operand" "=a")
6852         (mult:QI (match_dup 1) (match_dup 2)))]
6853   "TARGET_QIMODE_MATH
6854    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855   "<sgnprefix>mul{b}\t%2"
6856   [(set_attr "type" "imul")
6857    (set_attr "length_immediate" "0")
6858    (set (attr "athlon_decode")
6859      (if_then_else (eq_attr "cpu" "athlon")
6860         (const_string "vector")
6861         (const_string "direct")))
6862    (set_attr "amdfam10_decode" "direct")
6863    (set_attr "bdver1_decode" "direct")
6864    (set_attr "mode" "QI")])
6866 (define_expand "<u>mul<mode><dwi>3"
6867   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6868                    (mult:<DWI>
6869                      (any_extend:<DWI>
6870                        (match_operand:DWIH 1 "nonimmediate_operand"))
6871                      (any_extend:<DWI>
6872                        (match_operand:DWIH 2 "register_operand"))))
6873               (clobber (reg:CC FLAGS_REG))])])
6875 (define_expand "<u>mulqihi3"
6876   [(parallel [(set (match_operand:HI 0 "register_operand")
6877                    (mult:HI
6878                      (any_extend:HI
6879                        (match_operand:QI 1 "nonimmediate_operand"))
6880                      (any_extend:HI
6881                        (match_operand:QI 2 "register_operand"))))
6882               (clobber (reg:CC FLAGS_REG))])]
6883   "TARGET_QIMODE_MATH")
6885 (define_insn "*bmi2_umul<mode><dwi>3_1"
6886   [(set (match_operand:DWIH 0 "register_operand" "=r")
6887         (mult:DWIH
6888           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
6889           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
6890    (set (match_operand:DWIH 1 "register_operand" "=r")
6891         (truncate:DWIH
6892           (lshiftrt:<DWI>
6893             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
6894                         (zero_extend:<DWI> (match_dup 3)))
6895             (match_operand:QI 4 "const_int_operand" "n"))))]
6896   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
6897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6898   "mulx\t{%3, %0, %1|%1, %0, %3}"
6899   [(set_attr "type" "imulx")
6900    (set_attr "prefix" "vex")
6901    (set_attr "mode" "<MODE>")])
6903 (define_insn "*umul<mode><dwi>3_1"
6904   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6905         (mult:<DWI>
6906           (zero_extend:<DWI>
6907             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6908           (zero_extend:<DWI>
6909             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6910    (clobber (reg:CC FLAGS_REG))]
6911   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6912   "@
6913    #
6914    mul{<imodesuffix>}\t%2"
6915   [(set_attr "isa" "bmi2,*")
6916    (set_attr "type" "imulx,imul")
6917    (set_attr "length_immediate" "*,0")
6918    (set (attr "athlon_decode")
6919         (cond [(eq_attr "alternative" "1")
6920                  (if_then_else (eq_attr "cpu" "athlon")
6921                    (const_string "vector")
6922                    (const_string "double"))]
6923               (const_string "*")))
6924    (set_attr "amdfam10_decode" "*,double")
6925    (set_attr "bdver1_decode" "*,direct")
6926    (set_attr "prefix" "vex,orig")
6927    (set_attr "mode" "<MODE>")])
6929 ;; Convert mul to the mulx pattern to avoid flags dependency.
6930 (define_split
6931  [(set (match_operand:<DWI> 0 "register_operand")
6932        (mult:<DWI>
6933          (zero_extend:<DWI>
6934            (match_operand:DWIH 1 "register_operand"))
6935          (zero_extend:<DWI>
6936            (match_operand:DWIH 2 "nonimmediate_operand"))))
6937   (clobber (reg:CC FLAGS_REG))]
6938  "TARGET_BMI2 && reload_completed
6939   && true_regnum (operands[1]) == DX_REG"
6940   [(parallel [(set (match_dup 3)
6941                    (mult:DWIH (match_dup 1) (match_dup 2)))
6942               (set (match_dup 4)
6943                    (truncate:DWIH
6944                      (lshiftrt:<DWI>
6945                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6946                                    (zero_extend:<DWI> (match_dup 2)))
6947                        (match_dup 5))))])]
6949   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6951   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
6954 (define_insn "*mul<mode><dwi>3_1"
6955   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6956         (mult:<DWI>
6957           (sign_extend:<DWI>
6958             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6959           (sign_extend:<DWI>
6960             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6961    (clobber (reg:CC FLAGS_REG))]
6962   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6963   "imul{<imodesuffix>}\t%2"
6964   [(set_attr "type" "imul")
6965    (set_attr "length_immediate" "0")
6966    (set (attr "athlon_decode")
6967      (if_then_else (eq_attr "cpu" "athlon")
6968         (const_string "vector")
6969         (const_string "double")))
6970    (set_attr "amdfam10_decode" "double")
6971    (set_attr "bdver1_decode" "direct")
6972    (set_attr "mode" "<MODE>")])
6974 (define_insn "*<u>mulqihi3_1"
6975   [(set (match_operand:HI 0 "register_operand" "=a")
6976         (mult:HI
6977           (any_extend:HI
6978             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6979           (any_extend:HI
6980             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6981    (clobber (reg:CC FLAGS_REG))]
6982   "TARGET_QIMODE_MATH
6983    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6984   "<sgnprefix>mul{b}\t%2"
6985   [(set_attr "type" "imul")
6986    (set_attr "length_immediate" "0")
6987    (set (attr "athlon_decode")
6988      (if_then_else (eq_attr "cpu" "athlon")
6989         (const_string "vector")
6990         (const_string "direct")))
6991    (set_attr "amdfam10_decode" "direct")
6992    (set_attr "bdver1_decode" "direct")
6993    (set_attr "mode" "QI")])
6995 (define_expand "<s>mul<mode>3_highpart"
6996   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6997                    (truncate:SWI48
6998                      (lshiftrt:<DWI>
6999                        (mult:<DWI>
7000                          (any_extend:<DWI>
7001                            (match_operand:SWI48 1 "nonimmediate_operand"))
7002                          (any_extend:<DWI>
7003                            (match_operand:SWI48 2 "register_operand")))
7004                        (match_dup 4))))
7005               (clobber (match_scratch:SWI48 3))
7006               (clobber (reg:CC FLAGS_REG))])]
7007   ""
7008   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7010 (define_insn "*<s>muldi3_highpart_1"
7011   [(set (match_operand:DI 0 "register_operand" "=d")
7012         (truncate:DI
7013           (lshiftrt:TI
7014             (mult:TI
7015               (any_extend:TI
7016                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7017               (any_extend:TI
7018                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7019             (const_int 64))))
7020    (clobber (match_scratch:DI 3 "=1"))
7021    (clobber (reg:CC FLAGS_REG))]
7022   "TARGET_64BIT
7023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024   "<sgnprefix>mul{q}\t%2"
7025   [(set_attr "type" "imul")
7026    (set_attr "length_immediate" "0")
7027    (set (attr "athlon_decode")
7028      (if_then_else (eq_attr "cpu" "athlon")
7029         (const_string "vector")
7030         (const_string "double")))
7031    (set_attr "amdfam10_decode" "double")
7032    (set_attr "bdver1_decode" "direct")
7033    (set_attr "mode" "DI")])
7035 (define_insn "*<s>mulsi3_highpart_1"
7036   [(set (match_operand:SI 0 "register_operand" "=d")
7037         (truncate:SI
7038           (lshiftrt:DI
7039             (mult:DI
7040               (any_extend:DI
7041                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7042               (any_extend:DI
7043                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7044             (const_int 32))))
7045    (clobber (match_scratch:SI 3 "=1"))
7046    (clobber (reg:CC FLAGS_REG))]
7047   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048   "<sgnprefix>mul{l}\t%2"
7049   [(set_attr "type" "imul")
7050    (set_attr "length_immediate" "0")
7051    (set (attr "athlon_decode")
7052      (if_then_else (eq_attr "cpu" "athlon")
7053         (const_string "vector")
7054         (const_string "double")))
7055    (set_attr "amdfam10_decode" "double")
7056    (set_attr "bdver1_decode" "direct")
7057    (set_attr "mode" "SI")])
7059 (define_insn "*<s>mulsi3_highpart_zext"
7060   [(set (match_operand:DI 0 "register_operand" "=d")
7061         (zero_extend:DI (truncate:SI
7062           (lshiftrt:DI
7063             (mult:DI (any_extend:DI
7064                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7065                      (any_extend:DI
7066                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7067             (const_int 32)))))
7068    (clobber (match_scratch:SI 3 "=1"))
7069    (clobber (reg:CC FLAGS_REG))]
7070   "TARGET_64BIT
7071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072   "<sgnprefix>mul{l}\t%2"
7073   [(set_attr "type" "imul")
7074    (set_attr "length_immediate" "0")
7075    (set (attr "athlon_decode")
7076      (if_then_else (eq_attr "cpu" "athlon")
7077         (const_string "vector")
7078         (const_string "double")))
7079    (set_attr "amdfam10_decode" "double")
7080    (set_attr "bdver1_decode" "direct")
7081    (set_attr "mode" "SI")])
7083 ;; The patterns that match these are at the end of this file.
7085 (define_expand "mulxf3"
7086   [(set (match_operand:XF 0 "register_operand")
7087         (mult:XF (match_operand:XF 1 "register_operand")
7088                  (match_operand:XF 2 "register_operand")))]
7089   "TARGET_80387")
7091 (define_expand "mul<mode>3"
7092   [(set (match_operand:MODEF 0 "register_operand")
7093         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7094                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7095   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7096     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7098 ;; Divide instructions
7100 ;; The patterns that match these are at the end of this file.
7102 (define_expand "divxf3"
7103   [(set (match_operand:XF 0 "register_operand")
7104         (div:XF (match_operand:XF 1 "register_operand")
7105                 (match_operand:XF 2 "register_operand")))]
7106   "TARGET_80387")
7108 (define_expand "divdf3"
7109   [(set (match_operand:DF 0 "register_operand")
7110         (div:DF (match_operand:DF 1 "register_operand")
7111                 (match_operand:DF 2 "nonimmediate_operand")))]
7112    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7113     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7115 (define_expand "divsf3"
7116   [(set (match_operand:SF 0 "register_operand")
7117         (div:SF (match_operand:SF 1 "register_operand")
7118                 (match_operand:SF 2 "nonimmediate_operand")))]
7119   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7120     || TARGET_SSE_MATH"
7122   if (TARGET_SSE_MATH
7123       && TARGET_RECIP_DIV
7124       && optimize_insn_for_speed_p ()
7125       && flag_finite_math_only && !flag_trapping_math
7126       && flag_unsafe_math_optimizations)
7127     {
7128       ix86_emit_swdivsf (operands[0], operands[1],
7129                          operands[2], SFmode);
7130       DONE;
7131     }
7134 ;; Divmod instructions.
7136 (define_expand "divmod<mode>4"
7137   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7138                    (div:SWIM248
7139                      (match_operand:SWIM248 1 "register_operand")
7140                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7141               (set (match_operand:SWIM248 3 "register_operand")
7142                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7143               (clobber (reg:CC FLAGS_REG))])])
7145 ;; Split with 8bit unsigned divide:
7146 ;;      if (dividend an divisor are in [0-255])
7147 ;;         use 8bit unsigned integer divide
7148 ;;       else
7149 ;;         use original integer divide
7150 (define_split
7151   [(set (match_operand:SWI48 0 "register_operand")
7152         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7153                     (match_operand:SWI48 3 "nonimmediate_operand")))
7154    (set (match_operand:SWI48 1 "register_operand")
7155         (mod:SWI48 (match_dup 2) (match_dup 3)))
7156    (clobber (reg:CC FLAGS_REG))]
7157   "TARGET_USE_8BIT_IDIV
7158    && TARGET_QIMODE_MATH
7159    && can_create_pseudo_p ()
7160    && !optimize_insn_for_size_p ()"
7161   [(const_int 0)]
7162   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7164 (define_insn_and_split "divmod<mode>4_1"
7165   [(set (match_operand:SWI48 0 "register_operand" "=a")
7166         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7167                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7168    (set (match_operand:SWI48 1 "register_operand" "=&d")
7169         (mod:SWI48 (match_dup 2) (match_dup 3)))
7170    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7171    (clobber (reg:CC FLAGS_REG))]
7172   ""
7173   "#"
7174   "reload_completed"
7175   [(parallel [(set (match_dup 1)
7176                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7177               (clobber (reg:CC FLAGS_REG))])
7178    (parallel [(set (match_dup 0)
7179                    (div:SWI48 (match_dup 2) (match_dup 3)))
7180               (set (match_dup 1)
7181                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7182               (use (match_dup 1))
7183               (clobber (reg:CC FLAGS_REG))])]
7185   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7187   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7188     operands[4] = operands[2];
7189   else
7190     {
7191       /* Avoid use of cltd in favor of a mov+shift.  */
7192       emit_move_insn (operands[1], operands[2]);
7193       operands[4] = operands[1];
7194     }
7196   [(set_attr "type" "multi")
7197    (set_attr "mode" "<MODE>")])
7199 (define_insn_and_split "*divmod<mode>4"
7200   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7201         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7202                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7203    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7204         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7205    (clobber (reg:CC FLAGS_REG))]
7206   ""
7207   "#"
7208   "reload_completed"
7209   [(parallel [(set (match_dup 1)
7210                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7211               (clobber (reg:CC FLAGS_REG))])
7212    (parallel [(set (match_dup 0)
7213                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7214               (set (match_dup 1)
7215                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7216               (use (match_dup 1))
7217               (clobber (reg:CC FLAGS_REG))])]
7219   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7221   if (<MODE>mode != HImode
7222       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7223     operands[4] = operands[2];
7224   else
7225     {
7226       /* Avoid use of cltd in favor of a mov+shift.  */
7227       emit_move_insn (operands[1], operands[2]);
7228       operands[4] = operands[1];
7229     }
7231   [(set_attr "type" "multi")
7232    (set_attr "mode" "<MODE>")])
7234 (define_insn "*divmod<mode>4_noext"
7235   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7236         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7237                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7238    (set (match_operand:SWIM248 1 "register_operand" "=d")
7239         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7240    (use (match_operand:SWIM248 4 "register_operand" "1"))
7241    (clobber (reg:CC FLAGS_REG))]
7242   ""
7243   "idiv{<imodesuffix>}\t%3"
7244   [(set_attr "type" "idiv")
7245    (set_attr "mode" "<MODE>")])
7247 (define_expand "divmodqi4"
7248   [(parallel [(set (match_operand:QI 0 "register_operand")
7249                    (div:QI
7250                      (match_operand:QI 1 "register_operand")
7251                      (match_operand:QI 2 "nonimmediate_operand")))
7252               (set (match_operand:QI 3 "register_operand")
7253                    (mod:QI (match_dup 1) (match_dup 2)))
7254               (clobber (reg:CC FLAGS_REG))])]
7255   "TARGET_QIMODE_MATH"
7257   rtx div, mod;
7258   rtx tmp0, tmp1;
7259   
7260   tmp0 = gen_reg_rtx (HImode);
7261   tmp1 = gen_reg_rtx (HImode);
7263   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7264      in AX.  */
7265   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7266   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7268   /* Extract remainder from AH.  */
7269   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7270   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7272   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7273   set_unique_reg_note (insn, REG_EQUAL, mod);
7275   /* Extract quotient from AL.  */
7276   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7278   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7279   set_unique_reg_note (insn, REG_EQUAL, div);
7281   DONE;
7284 ;; Divide AX by r/m8, with result stored in
7285 ;; AL <- Quotient
7286 ;; AH <- Remainder
7287 ;; Change div/mod to HImode and extend the second argument to HImode
7288 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7289 ;; combine may fail.
7290 (define_insn "divmodhiqi3"
7291   [(set (match_operand:HI 0 "register_operand" "=a")
7292         (ior:HI
7293           (ashift:HI
7294             (zero_extend:HI
7295               (truncate:QI
7296                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7297                         (sign_extend:HI
7298                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7299             (const_int 8))
7300           (zero_extend:HI
7301             (truncate:QI
7302               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "TARGET_QIMODE_MATH"
7305   "idiv{b}\t%2"
7306   [(set_attr "type" "idiv")
7307    (set_attr "mode" "QI")])
7309 (define_expand "udivmod<mode>4"
7310   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7311                    (udiv:SWIM248
7312                      (match_operand:SWIM248 1 "register_operand")
7313                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7314               (set (match_operand:SWIM248 3 "register_operand")
7315                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7316               (clobber (reg:CC FLAGS_REG))])])
7318 ;; Split with 8bit unsigned divide:
7319 ;;      if (dividend an divisor are in [0-255])
7320 ;;         use 8bit unsigned integer divide
7321 ;;       else
7322 ;;         use original integer divide
7323 (define_split
7324   [(set (match_operand:SWI48 0 "register_operand")
7325         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7326                     (match_operand:SWI48 3 "nonimmediate_operand")))
7327    (set (match_operand:SWI48 1 "register_operand")
7328         (umod:SWI48 (match_dup 2) (match_dup 3)))
7329    (clobber (reg:CC FLAGS_REG))]
7330   "TARGET_USE_8BIT_IDIV
7331    && TARGET_QIMODE_MATH
7332    && can_create_pseudo_p ()
7333    && !optimize_insn_for_size_p ()"
7334   [(const_int 0)]
7335   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7337 (define_insn_and_split "udivmod<mode>4_1"
7338   [(set (match_operand:SWI48 0 "register_operand" "=a")
7339         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7340                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7341    (set (match_operand:SWI48 1 "register_operand" "=&d")
7342         (umod:SWI48 (match_dup 2) (match_dup 3)))
7343    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7344    (clobber (reg:CC FLAGS_REG))]
7345   ""
7346   "#"
7347   "reload_completed"
7348   [(set (match_dup 1) (const_int 0))
7349    (parallel [(set (match_dup 0)
7350                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7351               (set (match_dup 1)
7352                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7353               (use (match_dup 1))
7354               (clobber (reg:CC FLAGS_REG))])]
7355   ""
7356   [(set_attr "type" "multi")
7357    (set_attr "mode" "<MODE>")])
7359 (define_insn_and_split "*udivmod<mode>4"
7360   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7361         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7362                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7363    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7364         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7365    (clobber (reg:CC FLAGS_REG))]
7366   ""
7367   "#"
7368   "reload_completed"
7369   [(set (match_dup 1) (const_int 0))
7370    (parallel [(set (match_dup 0)
7371                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7372               (set (match_dup 1)
7373                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374               (use (match_dup 1))
7375               (clobber (reg:CC FLAGS_REG))])]
7376   ""
7377   [(set_attr "type" "multi")
7378    (set_attr "mode" "<MODE>")])
7380 ;; Optimize division or modulo by constant power of 2, if the constant
7381 ;; materializes only after expansion.
7382 (define_insn_and_split "*udivmod<mode>4_pow2"
7383   [(set (match_operand:SWI48 0 "register_operand" "=r")
7384         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7385                     (match_operand:SWI48 3 "const_int_operand" "n")))
7386    (set (match_operand:SWI48 1 "register_operand" "=r")
7387         (umod:SWI48 (match_dup 2) (match_dup 3)))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7390    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7391   "#"
7392   "&& 1"
7393   [(set (match_dup 1) (match_dup 2))
7394    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7395               (clobber (reg:CC FLAGS_REG))])
7396    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7397               (clobber (reg:CC FLAGS_REG))])]
7399   int v = exact_log2 (UINTVAL (operands[3]));
7400   operands[4] = GEN_INT (v);
7401   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7403   [(set_attr "type" "multi")
7404    (set_attr "mode" "<MODE>")])
7406 (define_insn "*udivmod<mode>4_noext"
7407   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7408         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7409                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7410    (set (match_operand:SWIM248 1 "register_operand" "=d")
7411         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7412    (use (match_operand:SWIM248 4 "register_operand" "1"))
7413    (clobber (reg:CC FLAGS_REG))]
7414   ""
7415   "div{<imodesuffix>}\t%3"
7416   [(set_attr "type" "idiv")
7417    (set_attr "mode" "<MODE>")])
7419 (define_expand "udivmodqi4"
7420   [(parallel [(set (match_operand:QI 0 "register_operand")
7421                    (udiv:QI
7422                      (match_operand:QI 1 "register_operand")
7423                      (match_operand:QI 2 "nonimmediate_operand")))
7424               (set (match_operand:QI 3 "register_operand")
7425                    (umod:QI (match_dup 1) (match_dup 2)))
7426               (clobber (reg:CC FLAGS_REG))])]
7427   "TARGET_QIMODE_MATH"
7429   rtx div, mod;
7430   rtx tmp0, tmp1;
7431   
7432   tmp0 = gen_reg_rtx (HImode);
7433   tmp1 = gen_reg_rtx (HImode);
7435   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7436      in AX.  */
7437   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7438   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7440   /* Extract remainder from AH.  */
7441   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7442   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7443   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7445   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7446   set_unique_reg_note (insn, REG_EQUAL, mod);
7448   /* Extract quotient from AL.  */
7449   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7451   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7452   set_unique_reg_note (insn, REG_EQUAL, div);
7454   DONE;
7457 (define_insn "udivmodhiqi3"
7458   [(set (match_operand:HI 0 "register_operand" "=a")
7459         (ior:HI
7460           (ashift:HI
7461             (zero_extend:HI
7462               (truncate:QI
7463                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7464                         (zero_extend:HI
7465                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7466             (const_int 8))
7467           (zero_extend:HI
7468             (truncate:QI
7469               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_QIMODE_MATH"
7472   "div{b}\t%2"
7473   [(set_attr "type" "idiv")
7474    (set_attr "mode" "QI")])
7476 ;; We cannot use div/idiv for double division, because it causes
7477 ;; "division by zero" on the overflow and that's not what we expect
7478 ;; from truncate.  Because true (non truncating) double division is
7479 ;; never generated, we can't create this insn anyway.
7481 ;(define_insn ""
7482 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7483 ;       (truncate:SI
7484 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7485 ;                  (zero_extend:DI
7486 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7487 ;   (set (match_operand:SI 3 "register_operand" "=d")
7488 ;       (truncate:SI
7489 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7490 ;   (clobber (reg:CC FLAGS_REG))]
7491 ;  ""
7492 ;  "div{l}\t{%2, %0|%0, %2}"
7493 ;  [(set_attr "type" "idiv")])
7495 ;;- Logical AND instructions
7497 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7498 ;; Note that this excludes ah.
7500 (define_expand "testsi_ccno_1"
7501   [(set (reg:CCNO FLAGS_REG)
7502         (compare:CCNO
7503           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7504                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7505           (const_int 0)))])
7507 (define_expand "testqi_ccz_1"
7508   [(set (reg:CCZ FLAGS_REG)
7509         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7510                              (match_operand:QI 1 "nonmemory_operand"))
7511                  (const_int 0)))])
7513 (define_expand "testdi_ccno_1"
7514   [(set (reg:CCNO FLAGS_REG)
7515         (compare:CCNO
7516           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7517                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7518           (const_int 0)))]
7519   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7521 (define_insn "*testdi_1"
7522   [(set (reg FLAGS_REG)
7523         (compare
7524          (and:DI
7525           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7526           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7527          (const_int 0)))]
7528   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7529    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7530   "@
7531    test{l}\t{%k1, %k0|%k0, %k1}
7532    test{l}\t{%k1, %k0|%k0, %k1}
7533    test{q}\t{%1, %0|%0, %1}
7534    test{q}\t{%1, %0|%0, %1}
7535    test{q}\t{%1, %0|%0, %1}"
7536   [(set_attr "type" "test")
7537    (set_attr "modrm" "0,1,0,1,1")
7538    (set_attr "mode" "SI,SI,DI,DI,DI")])
7540 (define_insn "*testqi_1_maybe_si"
7541   [(set (reg FLAGS_REG)
7542         (compare
7543           (and:QI
7544             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7545             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7546           (const_int 0)))]
7547    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7548     && ix86_match_ccmode (insn,
7549                          CONST_INT_P (operands[1])
7550                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7552   if (which_alternative == 3)
7553     {
7554       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7555         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7556       return "test{l}\t{%1, %k0|%k0, %1}";
7557     }
7558   return "test{b}\t{%1, %0|%0, %1}";
7560   [(set_attr "type" "test")
7561    (set_attr "modrm" "0,1,1,1")
7562    (set_attr "mode" "QI,QI,QI,SI")
7563    (set_attr "pent_pair" "uv,np,uv,np")])
7565 (define_insn "*test<mode>_1"
7566   [(set (reg FLAGS_REG)
7567         (compare
7568          (and:SWI124
7569           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7570           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7571          (const_int 0)))]
7572   "ix86_match_ccmode (insn, CCNOmode)
7573    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7574   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7575   [(set_attr "type" "test")
7576    (set_attr "modrm" "0,1,1")
7577    (set_attr "mode" "<MODE>")
7578    (set_attr "pent_pair" "uv,np,uv")])
7580 (define_expand "testqi_ext_ccno_0"
7581   [(set (reg:CCNO FLAGS_REG)
7582         (compare:CCNO
7583           (and:SI
7584             (zero_extract:SI
7585               (match_operand 0 "ext_register_operand")
7586               (const_int 8)
7587               (const_int 8))
7588             (match_operand 1 "const_int_operand"))
7589           (const_int 0)))])
7591 (define_insn "*testqi_ext_0"
7592   [(set (reg FLAGS_REG)
7593         (compare
7594           (and:SI
7595             (zero_extract:SI
7596               (match_operand 0 "ext_register_operand" "Q")
7597               (const_int 8)
7598               (const_int 8))
7599             (match_operand 1 "const_int_operand" "n"))
7600           (const_int 0)))]
7601   "ix86_match_ccmode (insn, CCNOmode)"
7602   "test{b}\t{%1, %h0|%h0, %1}"
7603   [(set_attr "type" "test")
7604    (set_attr "mode" "QI")
7605    (set_attr "length_immediate" "1")
7606    (set_attr "modrm" "1")
7607    (set_attr "pent_pair" "np")])
7609 (define_insn "*testqi_ext_1"
7610   [(set (reg FLAGS_REG)
7611         (compare
7612           (and:SI
7613             (zero_extract:SI
7614               (match_operand 0 "ext_register_operand" "Q,Q")
7615               (const_int 8)
7616               (const_int 8))
7617             (zero_extend:SI
7618               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7619           (const_int 0)))]
7620   "ix86_match_ccmode (insn, CCNOmode)"
7621   "test{b}\t{%1, %h0|%h0, %1}"
7622   [(set_attr "isa" "*,nox64")
7623    (set_attr "type" "test")
7624    (set_attr "mode" "QI")])
7626 (define_insn "*testqi_ext_2"
7627   [(set (reg FLAGS_REG)
7628         (compare
7629           (and:SI
7630             (zero_extract:SI
7631               (match_operand 0 "ext_register_operand" "Q")
7632               (const_int 8)
7633               (const_int 8))
7634             (zero_extract:SI
7635               (match_operand 1 "ext_register_operand" "Q")
7636               (const_int 8)
7637               (const_int 8)))
7638           (const_int 0)))]
7639   "ix86_match_ccmode (insn, CCNOmode)"
7640   "test{b}\t{%h1, %h0|%h0, %h1}"
7641   [(set_attr "type" "test")
7642    (set_attr "mode" "QI")])
7644 ;; Combine likes to form bit extractions for some tests.  Humor it.
7645 (define_insn "*testqi_ext_3"
7646   [(set (reg FLAGS_REG)
7647         (compare (zero_extract:SWI48
7648                    (match_operand 0 "nonimmediate_operand" "rm")
7649                    (match_operand 1 "const_int_operand" "n")
7650                    (match_operand 2 "const_int_operand" "n"))
7651                  (const_int 0)))]
7652   "ix86_match_ccmode (insn, CCNOmode)
7653    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7654        || GET_MODE (operands[0]) == SImode
7655        || GET_MODE (operands[0]) == HImode
7656        || GET_MODE (operands[0]) == QImode)
7657    /* Ensure that resulting mask is zero or sign extended operand.  */
7658    && INTVAL (operands[2]) >= 0
7659    && ((INTVAL (operands[1]) > 0
7660         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7661        || (<MODE>mode == DImode
7662            && INTVAL (operands[1]) > 32
7663            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7664   "#")
7666 (define_split
7667   [(set (match_operand 0 "flags_reg_operand")
7668         (match_operator 1 "compare_operator"
7669           [(zero_extract
7670              (match_operand 2 "nonimmediate_operand")
7671              (match_operand 3 "const_int_operand")
7672              (match_operand 4 "const_int_operand"))
7673            (const_int 0)]))]
7674   "ix86_match_ccmode (insn, CCNOmode)"
7675   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7677   rtx val = operands[2];
7678   HOST_WIDE_INT len = INTVAL (operands[3]);
7679   HOST_WIDE_INT pos = INTVAL (operands[4]);
7680   HOST_WIDE_INT mask;
7681   machine_mode mode, submode;
7683   mode = GET_MODE (val);
7684   if (MEM_P (val))
7685     {
7686       /* ??? Combine likes to put non-volatile mem extractions in QImode
7687          no matter the size of the test.  So find a mode that works.  */
7688       if (! MEM_VOLATILE_P (val))
7689         {
7690           mode = smallest_mode_for_size (pos + len, MODE_INT);
7691           val = adjust_address (val, mode, 0);
7692         }
7693     }
7694   else if (GET_CODE (val) == SUBREG
7695            && (submode = GET_MODE (SUBREG_REG (val)),
7696                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7697            && pos + len <= GET_MODE_BITSIZE (submode)
7698            && GET_MODE_CLASS (submode) == MODE_INT)
7699     {
7700       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7701       mode = submode;
7702       val = SUBREG_REG (val);
7703     }
7704   else if (mode == HImode && pos + len <= 8)
7705     {
7706       /* Small HImode tests can be converted to QImode.  */
7707       mode = QImode;
7708       val = gen_lowpart (QImode, val);
7709     }
7711   if (len == HOST_BITS_PER_WIDE_INT)
7712     mask = -1;
7713   else
7714     mask = ((HOST_WIDE_INT)1 << len) - 1;
7715   mask <<= pos;
7717   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7720 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7721 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7722 ;; this is relatively important trick.
7723 ;; Do the conversion only post-reload to avoid limiting of the register class
7724 ;; to QI regs.
7725 (define_split
7726   [(set (match_operand 0 "flags_reg_operand")
7727         (match_operator 1 "compare_operator"
7728           [(and (match_operand 2 "QIreg_operand")
7729                 (match_operand 3 "const_int_operand"))
7730            (const_int 0)]))]
7731    "reload_completed
7732     && GET_MODE (operands[2]) != QImode
7733     && ((ix86_match_ccmode (insn, CCZmode)
7734          && !(INTVAL (operands[3]) & ~(255 << 8)))
7735         || (ix86_match_ccmode (insn, CCNOmode)
7736             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7737   [(set (match_dup 0)
7738         (match_op_dup 1
7739           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7740                    (match_dup 3))
7741            (const_int 0)]))]
7743   operands[2] = gen_lowpart (SImode, operands[2]);
7744   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7747 (define_split
7748   [(set (match_operand 0 "flags_reg_operand")
7749         (match_operator 1 "compare_operator"
7750           [(and (match_operand 2 "nonimmediate_operand")
7751                 (match_operand 3 "const_int_operand"))
7752            (const_int 0)]))]
7753    "reload_completed
7754     && GET_MODE (operands[2]) != QImode
7755     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7756     && ((ix86_match_ccmode (insn, CCZmode)
7757          && !(INTVAL (operands[3]) & ~255))
7758         || (ix86_match_ccmode (insn, CCNOmode)
7759             && !(INTVAL (operands[3]) & ~127)))"
7760   [(set (match_dup 0)
7761         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7762                          (const_int 0)]))]
7764   operands[2] = gen_lowpart (QImode, operands[2]);
7765   operands[3] = gen_lowpart (QImode, operands[3]);
7768 (define_split
7769   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7770         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7771                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_AVX512F && reload_completed"
7774   [(set (match_dup 0)
7775         (any_logic:SWI1248x (match_dup 1)
7776                             (match_dup 2)))])
7778 (define_insn "*k<logic><mode>"
7779   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7780         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7781                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7782   "TARGET_AVX512F"
7783   {
7784     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7785       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7786     else
7787       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7788   }
7789   [(set_attr "mode" "<MODE>")
7790    (set_attr "type" "msklog")
7791    (set_attr "prefix" "vex")])
7793 ;; %%% This used to optimize known byte-wide and operations to memory,
7794 ;; and sometimes to QImode registers.  If this is considered useful,
7795 ;; it should be done with splitters.
7797 (define_expand "and<mode>3"
7798   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7799         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7800                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7801   ""
7803   machine_mode mode = <MODE>mode;
7804   rtx (*insn) (rtx, rtx);
7806   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7807     {
7808       HOST_WIDE_INT ival = INTVAL (operands[2]);
7810       if (ival == (HOST_WIDE_INT) 0xffffffff)
7811         mode = SImode;
7812       else if (ival == 0xffff)
7813         mode = HImode;
7814       else if (ival == 0xff)
7815         mode = QImode;
7816       }
7818   if (mode == <MODE>mode)
7819     {
7820       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7821       DONE;
7822     }
7824   if (<MODE>mode == DImode)
7825     insn = (mode == SImode)
7826            ? gen_zero_extendsidi2
7827            : (mode == HImode)
7828            ? gen_zero_extendhidi2
7829            : gen_zero_extendqidi2;
7830   else if (<MODE>mode == SImode)
7831     insn = (mode == HImode)
7832            ? gen_zero_extendhisi2
7833            : gen_zero_extendqisi2;
7834   else if (<MODE>mode == HImode)
7835     insn = gen_zero_extendqihi2;
7836   else
7837     gcc_unreachable ();
7839   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7840   DONE;
7843 (define_insn "*anddi_1"
7844   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7845         (and:DI
7846          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7847          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7851   switch (get_attr_type (insn))
7852     {
7853     case TYPE_IMOVX:
7854       return "#";
7856     case TYPE_MSKLOG:
7857       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7859     default:
7860       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7861       if (get_attr_mode (insn) == MODE_SI)
7862         return "and{l}\t{%k2, %k0|%k0, %k2}";
7863       else
7864         return "and{q}\t{%2, %0|%0, %2}";
7865     }
7867   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7868    (set_attr "length_immediate" "*,*,*,0,0")
7869    (set (attr "prefix_rex")
7870      (if_then_else
7871        (and (eq_attr "type" "imovx")
7872             (and (match_test "INTVAL (operands[2]) == 0xff")
7873                  (match_operand 1 "ext_QIreg_operand")))
7874        (const_string "1")
7875        (const_string "*")))
7876    (set_attr "mode" "SI,DI,DI,SI,DI")])
7878 (define_insn "*andsi_1"
7879   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7880         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7881                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7882    (clobber (reg:CC FLAGS_REG))]
7883   "ix86_binary_operator_ok (AND, SImode, operands)"
7885   switch (get_attr_type (insn))
7886     {
7887     case TYPE_IMOVX:
7888       return "#";
7890     case TYPE_MSKLOG:
7891       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7893     default:
7894       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7895       return "and{l}\t{%2, %0|%0, %2}";
7896     }
7898   [(set_attr "type" "alu,alu,imovx,msklog")
7899    (set (attr "prefix_rex")
7900      (if_then_else
7901        (and (eq_attr "type" "imovx")
7902             (and (match_test "INTVAL (operands[2]) == 0xff")
7903                  (match_operand 1 "ext_QIreg_operand")))
7904        (const_string "1")
7905        (const_string "*")))
7906    (set_attr "length_immediate" "*,*,0,0")
7907    (set_attr "mode" "SI")])
7909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7910 (define_insn "*andsi_1_zext"
7911   [(set (match_operand:DI 0 "register_operand" "=r")
7912         (zero_extend:DI
7913           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7914                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7915    (clobber (reg:CC FLAGS_REG))]
7916   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7917   "and{l}\t{%2, %k0|%k0, %2}"
7918   [(set_attr "type" "alu")
7919    (set_attr "mode" "SI")])
7921 (define_insn "*andhi_1"
7922   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7923         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7924                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7925    (clobber (reg:CC FLAGS_REG))]
7926   "ix86_binary_operator_ok (AND, HImode, operands)"
7928   switch (get_attr_type (insn))
7929     {
7930     case TYPE_IMOVX:
7931       return "#";
7933     case TYPE_MSKLOG:
7934       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7936     default:
7937       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7938       return "and{w}\t{%2, %0|%0, %2}";
7939     }
7941   [(set_attr "type" "alu,alu,imovx,msklog")
7942    (set_attr "length_immediate" "*,*,0,*")
7943    (set (attr "prefix_rex")
7944      (if_then_else
7945        (and (eq_attr "type" "imovx")
7946             (match_operand 1 "ext_QIreg_operand"))
7947        (const_string "1")
7948        (const_string "*")))
7949    (set_attr "mode" "HI,HI,SI,HI")])
7951 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7952 (define_insn "*andqi_1"
7953   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7954         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7955                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7956    (clobber (reg:CC FLAGS_REG))]
7957   "ix86_binary_operator_ok (AND, QImode, operands)"
7959   switch (which_alternative)
7960     {
7961     case 0:
7962     case 1:
7963       return "and{b}\t{%2, %0|%0, %2}";
7964     case 2:
7965       return "and{l}\t{%k2, %k0|%k0, %k2}";
7966     case 3:
7967       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7968                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7969     default:
7970       gcc_unreachable ();
7971     }
7973   [(set_attr "type" "alu,alu,alu,msklog")
7974    (set_attr "mode" "QI,QI,SI,HI")])
7976 (define_insn "*andqi_1_slp"
7977   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7978         (and:QI (match_dup 0)
7979                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7980    (clobber (reg:CC FLAGS_REG))]
7981   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7982    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7983   "and{b}\t{%1, %0|%0, %1}"
7984   [(set_attr "type" "alu1")
7985    (set_attr "mode" "QI")])
7987 (define_insn "kandn<mode>"
7988   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7989         (and:SWI12
7990           (not:SWI12
7991             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7992           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7993    (clobber (reg:CC FLAGS_REG))]
7994   "TARGET_AVX512F"
7996   switch (which_alternative)
7997     {
7998     case 0:
7999       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8000     case 1:
8001       return "#";
8002     case 2:
8003       if (TARGET_AVX512DQ && <MODE>mode == QImode)
8004         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8005       else
8006         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8007     default:
8008       gcc_unreachable ();
8009     }
8011   [(set_attr "isa" "bmi,*,avx512f")
8012    (set_attr "type" "bitmanip,*,msklog")
8013    (set_attr "prefix" "*,*,vex")
8014    (set_attr "btver2_decode" "direct,*,*")
8015    (set_attr "mode" "<MODE>")])
8017 (define_split
8018   [(set (match_operand:SWI12 0 "general_reg_operand")
8019         (and:SWI12
8020           (not:SWI12
8021             (match_dup 0))
8022           (match_operand:SWI12 1 "general_reg_operand")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8025   [(set (match_dup 0)
8026         (not:HI (match_dup 0)))
8027    (parallel [(set (match_dup 0)
8028                    (and:HI (match_dup 0)
8029                            (match_dup 1)))
8030               (clobber (reg:CC FLAGS_REG))])])
8032 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8033 (define_split
8034   [(set (match_operand:DI 0 "register_operand")
8035         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8036                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8037    (clobber (reg:CC FLAGS_REG))]
8038   "TARGET_64BIT"
8039   [(parallel [(set (match_dup 0)
8040                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8041               (clobber (reg:CC FLAGS_REG))])]
8042   "operands[2] = gen_lowpart (SImode, operands[2]);")
8044 (define_split
8045   [(set (match_operand:SWI248 0 "register_operand")
8046         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8047                     (match_operand:SWI248 2 "const_int_operand")))
8048    (clobber (reg:CC FLAGS_REG))]
8049   "reload_completed
8050    && true_regnum (operands[0]) != true_regnum (operands[1])"
8051   [(const_int 0)]
8053   HOST_WIDE_INT ival = INTVAL (operands[2]);
8054   machine_mode mode;
8055   rtx (*insn) (rtx, rtx);
8057   if (ival == (HOST_WIDE_INT) 0xffffffff)
8058     mode = SImode;
8059   else if (ival == 0xffff)
8060     mode = HImode;
8061   else
8062     {
8063       gcc_assert (ival == 0xff);
8064       mode = QImode;
8065     }
8067   if (<MODE>mode == DImode)
8068     insn = (mode == SImode)
8069            ? gen_zero_extendsidi2
8070            : (mode == HImode)
8071            ? gen_zero_extendhidi2
8072            : gen_zero_extendqidi2;
8073   else
8074     {
8075       if (<MODE>mode != SImode)
8076         /* Zero extend to SImode to avoid partial register stalls.  */
8077         operands[0] = gen_lowpart (SImode, operands[0]);
8079       insn = (mode == HImode)
8080              ? gen_zero_extendhisi2
8081              : gen_zero_extendqisi2;
8082     }
8083   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8084   DONE;
8087 (define_split
8088   [(set (match_operand:SWI48 0 "register_operand")
8089         (and:SWI48 (match_dup 0)
8090                    (const_int -65536)))
8091    (clobber (reg:CC FLAGS_REG))]
8092   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8093     || optimize_function_for_size_p (cfun)"
8094   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8095   "operands[1] = gen_lowpart (HImode, operands[0]);")
8097 (define_split
8098   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8099         (and:SWI248 (match_dup 0)
8100                     (const_int -256)))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8103    && reload_completed"
8104   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8105   "operands[1] = gen_lowpart (QImode, operands[0]);")
8107 (define_split
8108   [(set (match_operand:SWI248 0 "QIreg_operand")
8109         (and:SWI248 (match_dup 0)
8110                     (const_int -65281)))
8111    (clobber (reg:CC FLAGS_REG))]
8112   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8113    && reload_completed"
8114   [(parallel [(set (zero_extract:SI (match_dup 0)
8115                                     (const_int 8)
8116                                     (const_int 8))
8117                    (xor:SI
8118                      (zero_extract:SI (match_dup 0)
8119                                       (const_int 8)
8120                                       (const_int 8))
8121                      (zero_extract:SI (match_dup 0)
8122                                       (const_int 8)
8123                                       (const_int 8))))
8124               (clobber (reg:CC FLAGS_REG))])]
8125   "operands[0] = gen_lowpart (SImode, operands[0]);")
8127 (define_insn "*anddi_2"
8128   [(set (reg FLAGS_REG)
8129         (compare
8130          (and:DI
8131           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8132           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8133          (const_int 0)))
8134    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8135         (and:DI (match_dup 1) (match_dup 2)))]
8136   "TARGET_64BIT
8137    && ix86_match_ccmode
8138         (insn,
8139          /* If we are going to emit andl instead of andq, and the operands[2]
8140             constant might have the SImode sign bit set, make sure the sign
8141             flag isn't tested, because the instruction will set the sign flag
8142             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8143             conservatively assume it might have bit 31 set.  */
8144          (satisfies_constraint_Z (operands[2])
8145           && (!CONST_INT_P (operands[2])
8146               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8147          ? CCZmode : CCNOmode)
8148    && ix86_binary_operator_ok (AND, DImode, operands)"
8149   "@
8150    and{l}\t{%k2, %k0|%k0, %k2}
8151    and{q}\t{%2, %0|%0, %2}
8152    and{q}\t{%2, %0|%0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI,DI,DI")])
8156 (define_insn "*andqi_2_maybe_si"
8157   [(set (reg FLAGS_REG)
8158         (compare (and:QI
8159                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8160                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8161                  (const_int 0)))
8162    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8163         (and:QI (match_dup 1) (match_dup 2)))]
8164   "ix86_binary_operator_ok (AND, QImode, operands)
8165    && ix86_match_ccmode (insn,
8166                          CONST_INT_P (operands[2])
8167                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8169   if (which_alternative == 2)
8170     {
8171       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8172         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8173       return "and{l}\t{%2, %k0|%k0, %2}";
8174     }
8175   return "and{b}\t{%2, %0|%0, %2}";
8177   [(set_attr "type" "alu")
8178    (set_attr "mode" "QI,QI,SI")])
8180 (define_insn "*and<mode>_2"
8181   [(set (reg FLAGS_REG)
8182         (compare (and:SWI124
8183                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8184                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8185                  (const_int 0)))
8186    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8187         (and:SWI124 (match_dup 1) (match_dup 2)))]
8188   "ix86_match_ccmode (insn, CCNOmode)
8189    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8190   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8191   [(set_attr "type" "alu")
8192    (set_attr "mode" "<MODE>")])
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*andsi_2_zext"
8196   [(set (reg FLAGS_REG)
8197         (compare (and:SI
8198                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8199                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8200                  (const_int 0)))
8201    (set (match_operand:DI 0 "register_operand" "=r")
8202         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8203   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8204    && ix86_binary_operator_ok (AND, SImode, operands)"
8205   "and{l}\t{%2, %k0|%k0, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "SI")])
8209 (define_insn "*andqi_2_slp"
8210   [(set (reg FLAGS_REG)
8211         (compare (and:QI
8212                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8213                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8214                  (const_int 0)))
8215    (set (strict_low_part (match_dup 0))
8216         (and:QI (match_dup 0) (match_dup 1)))]
8217   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8218    && ix86_match_ccmode (insn, CCNOmode)
8219    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8220   "and{b}\t{%1, %0|%0, %1}"
8221   [(set_attr "type" "alu1")
8222    (set_attr "mode" "QI")])
8224 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8225 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8226 ;; for a QImode operand, which of course failed.
8227 (define_insn "andqi_ext_0"
8228   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8229                          (const_int 8)
8230                          (const_int 8))
8231         (and:SI
8232           (zero_extract:SI
8233             (match_operand 1 "ext_register_operand" "0")
8234             (const_int 8)
8235             (const_int 8))
8236           (match_operand 2 "const_int_operand" "n")))
8237    (clobber (reg:CC FLAGS_REG))]
8238   ""
8239   "and{b}\t{%2, %h0|%h0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "length_immediate" "1")
8242    (set_attr "modrm" "1")
8243    (set_attr "mode" "QI")])
8245 ;; Generated by peephole translating test to and.  This shows up
8246 ;; often in fp comparisons.
8247 (define_insn "*andqi_ext_0_cc"
8248   [(set (reg FLAGS_REG)
8249         (compare
8250           (and:SI
8251             (zero_extract:SI
8252               (match_operand 1 "ext_register_operand" "0")
8253               (const_int 8)
8254               (const_int 8))
8255             (match_operand 2 "const_int_operand" "n"))
8256           (const_int 0)))
8257    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8258                          (const_int 8)
8259                          (const_int 8))
8260         (and:SI
8261           (zero_extract:SI
8262             (match_dup 1)
8263             (const_int 8)
8264             (const_int 8))
8265           (match_dup 2)))]
8266   "ix86_match_ccmode (insn, CCNOmode)"
8267   "and{b}\t{%2, %h0|%h0, %2}"
8268   [(set_attr "type" "alu")
8269    (set_attr "length_immediate" "1")
8270    (set_attr "modrm" "1")
8271    (set_attr "mode" "QI")])
8273 (define_insn "*andqi_ext_1"
8274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8275                          (const_int 8)
8276                          (const_int 8))
8277         (and:SI
8278           (zero_extract:SI
8279             (match_operand 1 "ext_register_operand" "0,0")
8280             (const_int 8)
8281             (const_int 8))
8282           (zero_extend:SI
8283             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8284    (clobber (reg:CC FLAGS_REG))]
8285   ""
8286   "and{b}\t{%2, %h0|%h0, %2}"
8287   [(set_attr "isa" "*,nox64")
8288    (set_attr "type" "alu")
8289    (set_attr "length_immediate" "0")
8290    (set_attr "mode" "QI")])
8292 (define_insn "*andqi_ext_2"
8293   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294                          (const_int 8)
8295                          (const_int 8))
8296         (and:SI
8297           (zero_extract:SI
8298             (match_operand 1 "ext_register_operand" "%0")
8299             (const_int 8)
8300             (const_int 8))
8301           (zero_extract:SI
8302             (match_operand 2 "ext_register_operand" "Q")
8303             (const_int 8)
8304             (const_int 8))))
8305    (clobber (reg:CC FLAGS_REG))]
8306   ""
8307   "and{b}\t{%h2, %h0|%h0, %h2}"
8308   [(set_attr "type" "alu")
8309    (set_attr "length_immediate" "0")
8310    (set_attr "mode" "QI")])
8312 ;; Convert wide AND instructions with immediate operand to shorter QImode
8313 ;; equivalents when possible.
8314 ;; Don't do the splitting with memory operands, since it introduces risk
8315 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8316 ;; for size, but that can (should?) be handled by generic code instead.
8317 (define_split
8318   [(set (match_operand 0 "QIreg_operand")
8319         (and (match_operand 1 "register_operand")
8320              (match_operand 2 "const_int_operand")))
8321    (clobber (reg:CC FLAGS_REG))]
8322    "reload_completed
8323     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8324     && !(~INTVAL (operands[2]) & ~(255 << 8))
8325     && GET_MODE (operands[0]) != QImode"
8326   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8327                    (and:SI (zero_extract:SI (match_dup 1)
8328                                             (const_int 8) (const_int 8))
8329                            (match_dup 2)))
8330               (clobber (reg:CC FLAGS_REG))])]
8332   operands[0] = gen_lowpart (SImode, operands[0]);
8333   operands[1] = gen_lowpart (SImode, operands[1]);
8334   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8337 ;; Since AND can be encoded with sign extended immediate, this is only
8338 ;; profitable when 7th bit is not set.
8339 (define_split
8340   [(set (match_operand 0 "any_QIreg_operand")
8341         (and (match_operand 1 "general_operand")
8342              (match_operand 2 "const_int_operand")))
8343    (clobber (reg:CC FLAGS_REG))]
8344    "reload_completed
8345     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8346     && !(~INTVAL (operands[2]) & ~255)
8347     && !(INTVAL (operands[2]) & 128)
8348     && GET_MODE (operands[0]) != QImode"
8349   [(parallel [(set (strict_low_part (match_dup 0))
8350                    (and:QI (match_dup 1)
8351                            (match_dup 2)))
8352               (clobber (reg:CC FLAGS_REG))])]
8354   operands[0] = gen_lowpart (QImode, operands[0]);
8355   operands[1] = gen_lowpart (QImode, operands[1]);
8356   operands[2] = gen_lowpart (QImode, operands[2]);
8359 ;; Logical inclusive and exclusive OR instructions
8361 ;; %%% This used to optimize known byte-wide and operations to memory.
8362 ;; If this is considered useful, it should be done with splitters.
8364 (define_expand "<code><mode>3"
8365   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8366         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8367                      (match_operand:SWIM 2 "<general_operand>")))]
8368   ""
8369   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8371 (define_insn "*<code><mode>_1"
8372   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8373         (any_or:SWI48
8374          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8375          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8376    (clobber (reg:CC FLAGS_REG))]
8377   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8378   "@
8379    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8380    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8381    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8382   [(set_attr "type" "alu,alu,msklog")
8383    (set_attr "mode" "<MODE>")])
8385 (define_insn "*<code>hi_1"
8386   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8387         (any_or:HI
8388          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8389          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8392   "@
8393   <logic>{w}\t{%2, %0|%0, %2}
8394   <logic>{w}\t{%2, %0|%0, %2}
8395   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8396   [(set_attr "type" "alu,alu,msklog")
8397    (set_attr "mode" "HI")])
8399 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8400 (define_insn "*<code>qi_1"
8401   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8402         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8403                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8404    (clobber (reg:CC FLAGS_REG))]
8405   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8406   "@
8407    <logic>{b}\t{%2, %0|%0, %2}
8408    <logic>{b}\t{%2, %0|%0, %2}
8409    <logic>{l}\t{%k2, %k0|%k0, %k2}
8410    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8411   [(set_attr "type" "alu,alu,alu,msklog")
8412    (set_attr "mode" "QI,QI,SI,HI")])
8414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8415 (define_insn "*<code>si_1_zext"
8416   [(set (match_operand:DI 0 "register_operand" "=r")
8417         (zero_extend:DI
8418          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8419                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8422   "<logic>{l}\t{%2, %k0|%k0, %2}"
8423   [(set_attr "type" "alu")
8424    (set_attr "mode" "SI")])
8426 (define_insn "*<code>si_1_zext_imm"
8427   [(set (match_operand:DI 0 "register_operand" "=r")
8428         (any_or:DI
8429          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8430          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8431    (clobber (reg:CC FLAGS_REG))]
8432   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8433   "<logic>{l}\t{%2, %k0|%k0, %2}"
8434   [(set_attr "type" "alu")
8435    (set_attr "mode" "SI")])
8437 (define_insn "*<code>qi_1_slp"
8438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8439         (any_or:QI (match_dup 0)
8440                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8443    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8444   "<logic>{b}\t{%1, %0|%0, %1}"
8445   [(set_attr "type" "alu1")
8446    (set_attr "mode" "QI")])
8448 (define_insn "*<code><mode>_2"
8449   [(set (reg FLAGS_REG)
8450         (compare (any_or:SWI
8451                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8452                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8453                  (const_int 0)))
8454    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8455         (any_or:SWI (match_dup 1) (match_dup 2)))]
8456   "ix86_match_ccmode (insn, CCNOmode)
8457    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8458   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8459   [(set_attr "type" "alu")
8460    (set_attr "mode" "<MODE>")])
8462 (define_insn "kxnor<mode>"
8463   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8464         (not:SWI12
8465           (xor:SWI12
8466             (match_operand:SWI12 1 "register_operand" "0,k")
8467             (match_operand:SWI12 2 "register_operand" "r,k"))))
8468    (clobber (reg:CC FLAGS_REG))]
8469   "TARGET_AVX512F"
8471   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8472     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8473   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8475   [(set_attr "type" "*,msklog")
8476    (set_attr "prefix" "*,vex")
8477    (set_attr "mode" "<MODE>")])
8479 (define_insn "kxnor<mode>"
8480   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8481         (not:SWI48x
8482           (xor:SWI48x
8483             (match_operand:SWI48x 1 "register_operand" "0,k")
8484             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_AVX512BW"
8487   "@
8488    #
8489    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8490   [(set_attr "type" "*,msklog")
8491    (set_attr "prefix" "*,vex")
8492    (set_attr "mode" "<MODE>")])
8494 (define_split
8495   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8496         (not:SWI1248x
8497           (xor:SWI1248x
8498             (match_dup 0)
8499             (match_operand:SWI1248x 1 "general_reg_operand"))))
8500    (clobber (reg:CC FLAGS_REG))]
8501   "TARGET_AVX512F && reload_completed"
8502    [(parallel [(set (match_dup 0)
8503                     (xor:HI (match_dup 0)
8504                             (match_dup 1)))
8505                (clobber (reg:CC FLAGS_REG))])
8506     (set (match_dup 0)
8507          (not:HI (match_dup 0)))])
8509 ;;There are kortrest[bdq] but no intrinsics for them.
8510 ;;We probably don't need to implement them.
8511 (define_insn "kortestzhi"
8512   [(set (reg:CCZ FLAGS_REG)
8513         (compare:CCZ
8514           (ior:HI
8515             (match_operand:HI 0 "register_operand" "k")
8516             (match_operand:HI 1 "register_operand" "k"))
8517           (const_int 0)))]
8518   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8519   "kortestw\t{%1, %0|%0, %1}"
8520   [(set_attr "mode" "HI")
8521    (set_attr "type" "msklog")
8522    (set_attr "prefix" "vex")])
8524 (define_insn "kortestchi"
8525   [(set (reg:CCC FLAGS_REG)
8526         (compare:CCC
8527           (ior:HI
8528             (match_operand:HI 0 "register_operand" "k")
8529             (match_operand:HI 1 "register_operand" "k"))
8530           (const_int -1)))]
8531   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8532   "kortestw\t{%1, %0|%0, %1}"
8533   [(set_attr "mode" "HI")
8534    (set_attr "type" "msklog")
8535    (set_attr "prefix" "vex")])
8537 (define_insn "kunpckhi"
8538   [(set (match_operand:HI 0 "register_operand" "=k")
8539         (ior:HI
8540           (ashift:HI
8541             (match_operand:HI 1 "register_operand" "k")
8542             (const_int 8))
8543           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8544   "TARGET_AVX512F"
8545   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8546   [(set_attr "mode" "HI")
8547    (set_attr "type" "msklog")
8548    (set_attr "prefix" "vex")])
8550 (define_insn "kunpcksi"
8551   [(set (match_operand:SI 0 "register_operand" "=k")
8552         (ior:SI
8553           (ashift:SI
8554             (match_operand:SI 1 "register_operand" "k")
8555             (const_int 16))
8556           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8557   "TARGET_AVX512BW"
8558   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8559   [(set_attr "mode" "SI")])
8561 (define_insn "kunpckdi"
8562   [(set (match_operand:DI 0 "register_operand" "=k")
8563         (ior:DI
8564           (ashift:DI
8565             (match_operand:DI 1 "register_operand" "k")
8566             (const_int 32))
8567           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8568   "TARGET_AVX512BW"
8569   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8570   [(set_attr "mode" "DI")])
8572 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8573 ;; ??? Special case for immediate operand is missing - it is tricky.
8574 (define_insn "*<code>si_2_zext"
8575   [(set (reg FLAGS_REG)
8576         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8577                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8578                  (const_int 0)))
8579    (set (match_operand:DI 0 "register_operand" "=r")
8580         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8581   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8582    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8583   "<logic>{l}\t{%2, %k0|%k0, %2}"
8584   [(set_attr "type" "alu")
8585    (set_attr "mode" "SI")])
8587 (define_insn "*<code>si_2_zext_imm"
8588   [(set (reg FLAGS_REG)
8589         (compare (any_or:SI
8590                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8591                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8592                  (const_int 0)))
8593    (set (match_operand:DI 0 "register_operand" "=r")
8594         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8595   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8596    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8597   "<logic>{l}\t{%2, %k0|%k0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "SI")])
8601 (define_insn "*<code>qi_2_slp"
8602   [(set (reg FLAGS_REG)
8603         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8604                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8605                  (const_int 0)))
8606    (set (strict_low_part (match_dup 0))
8607         (any_or:QI (match_dup 0) (match_dup 1)))]
8608   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8609    && ix86_match_ccmode (insn, CCNOmode)
8610    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8611   "<logic>{b}\t{%1, %0|%0, %1}"
8612   [(set_attr "type" "alu1")
8613    (set_attr "mode" "QI")])
8615 (define_insn "*<code><mode>_3"
8616   [(set (reg FLAGS_REG)
8617         (compare (any_or:SWI
8618                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8619                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8620                  (const_int 0)))
8621    (clobber (match_scratch:SWI 0 "=<r>"))]
8622   "ix86_match_ccmode (insn, CCNOmode)
8623    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8624   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "<MODE>")])
8628 (define_insn "*<code>qi_ext_0"
8629   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8630                          (const_int 8)
8631                          (const_int 8))
8632         (any_or:SI
8633           (zero_extract:SI
8634             (match_operand 1 "ext_register_operand" "0")
8635             (const_int 8)
8636             (const_int 8))
8637           (match_operand 2 "const_int_operand" "n")))
8638    (clobber (reg:CC FLAGS_REG))]
8639   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8640   "<logic>{b}\t{%2, %h0|%h0, %2}"
8641   [(set_attr "type" "alu")
8642    (set_attr "length_immediate" "1")
8643    (set_attr "modrm" "1")
8644    (set_attr "mode" "QI")])
8646 (define_insn "*<code>qi_ext_1"
8647   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8648                          (const_int 8)
8649                          (const_int 8))
8650         (any_or:SI
8651           (zero_extract:SI
8652             (match_operand 1 "ext_register_operand" "0,0")
8653             (const_int 8)
8654             (const_int 8))
8655           (zero_extend:SI
8656             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8659   "<logic>{b}\t{%2, %h0|%h0, %2}"
8660   [(set_attr "isa" "*,nox64")
8661    (set_attr "type" "alu")
8662    (set_attr "length_immediate" "0")
8663    (set_attr "mode" "QI")])
8665 (define_insn "*<code>qi_ext_2"
8666   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8667                          (const_int 8)
8668                          (const_int 8))
8669         (any_or:SI
8670           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8671                            (const_int 8)
8672                            (const_int 8))
8673           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8674                            (const_int 8)
8675                            (const_int 8))))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8678   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "length_immediate" "0")
8681    (set_attr "mode" "QI")])
8683 (define_split
8684   [(set (match_operand 0 "QIreg_operand")
8685         (any_or (match_operand 1 "register_operand")
8686                 (match_operand 2 "const_int_operand")))
8687    (clobber (reg:CC FLAGS_REG))]
8688    "reload_completed
8689     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8690     && !(INTVAL (operands[2]) & ~(255 << 8))
8691     && GET_MODE (operands[0]) != QImode"
8692   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8693                    (any_or:SI (zero_extract:SI (match_dup 1)
8694                                                (const_int 8) (const_int 8))
8695                               (match_dup 2)))
8696               (clobber (reg:CC FLAGS_REG))])]
8698   operands[0] = gen_lowpart (SImode, operands[0]);
8699   operands[1] = gen_lowpart (SImode, operands[1]);
8700   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8703 ;; Since OR can be encoded with sign extended immediate, this is only
8704 ;; profitable when 7th bit is set.
8705 (define_split
8706   [(set (match_operand 0 "any_QIreg_operand")
8707         (any_or (match_operand 1 "general_operand")
8708                 (match_operand 2 "const_int_operand")))
8709    (clobber (reg:CC FLAGS_REG))]
8710    "reload_completed
8711     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8712     && !(INTVAL (operands[2]) & ~255)
8713     && (INTVAL (operands[2]) & 128)
8714     && GET_MODE (operands[0]) != QImode"
8715   [(parallel [(set (strict_low_part (match_dup 0))
8716                    (any_or:QI (match_dup 1)
8717                               (match_dup 2)))
8718               (clobber (reg:CC FLAGS_REG))])]
8720   operands[0] = gen_lowpart (QImode, operands[0]);
8721   operands[1] = gen_lowpart (QImode, operands[1]);
8722   operands[2] = gen_lowpart (QImode, operands[2]);
8725 (define_expand "xorqi_cc_ext_1"
8726   [(parallel [
8727      (set (reg:CCNO FLAGS_REG)
8728           (compare:CCNO
8729             (xor:SI
8730               (zero_extract:SI
8731                 (match_operand 1 "ext_register_operand")
8732                 (const_int 8)
8733                 (const_int 8))
8734               (match_operand:QI 2 "const_int_operand"))
8735             (const_int 0)))
8736      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8737                            (const_int 8)
8738                            (const_int 8))
8739           (xor:SI
8740             (zero_extract:SI
8741              (match_dup 1)
8742              (const_int 8)
8743              (const_int 8))
8744             (match_dup 2)))])])
8746 (define_insn "*xorqi_cc_ext_1"
8747   [(set (reg FLAGS_REG)
8748         (compare
8749           (xor:SI
8750             (zero_extract:SI
8751               (match_operand 1 "ext_register_operand" "0,0")
8752               (const_int 8)
8753               (const_int 8))
8754             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8755           (const_int 0)))
8756    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8757                          (const_int 8)
8758                          (const_int 8))
8759         (xor:SI
8760           (zero_extract:SI
8761            (match_dup 1)
8762            (const_int 8)
8763            (const_int 8))
8764           (match_dup 2)))]
8765   "ix86_match_ccmode (insn, CCNOmode)"
8766   "xor{b}\t{%2, %h0|%h0, %2}"
8767   [(set_attr "isa" "*,nox64")
8768    (set_attr "type" "alu")
8769    (set_attr "modrm" "1")
8770    (set_attr "mode" "QI")])
8772 ;; Negation instructions
8774 (define_expand "neg<mode>2"
8775   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8776         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8777   ""
8778   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8780 (define_insn_and_split "*neg<dwi>2_doubleword"
8781   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8782         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8783    (clobber (reg:CC FLAGS_REG))]
8784   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8785   "#"
8786   "reload_completed"
8787   [(parallel
8788     [(set (reg:CCZ FLAGS_REG)
8789           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8790      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8791    (parallel
8792     [(set (match_dup 2)
8793           (plus:DWIH (match_dup 3)
8794                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8795                                 (const_int 0))))
8796      (clobber (reg:CC FLAGS_REG))])
8797    (parallel
8798     [(set (match_dup 2)
8799           (neg:DWIH (match_dup 2)))
8800      (clobber (reg:CC FLAGS_REG))])]
8801   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8803 (define_insn "*neg<mode>2_1"
8804   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8805         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8806    (clobber (reg:CC FLAGS_REG))]
8807   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8808   "neg{<imodesuffix>}\t%0"
8809   [(set_attr "type" "negnot")
8810    (set_attr "mode" "<MODE>")])
8812 ;; Combine is quite creative about this pattern.
8813 (define_insn "*negsi2_1_zext"
8814   [(set (match_operand:DI 0 "register_operand" "=r")
8815         (lshiftrt:DI
8816           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8817                              (const_int 32)))
8818         (const_int 32)))
8819    (clobber (reg:CC FLAGS_REG))]
8820   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8821   "neg{l}\t%k0"
8822   [(set_attr "type" "negnot")
8823    (set_attr "mode" "SI")])
8825 ;; The problem with neg is that it does not perform (compare x 0),
8826 ;; it really performs (compare 0 x), which leaves us with the zero
8827 ;; flag being the only useful item.
8829 (define_insn "*neg<mode>2_cmpz"
8830   [(set (reg:CCZ FLAGS_REG)
8831         (compare:CCZ
8832           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8833                    (const_int 0)))
8834    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8835         (neg:SWI (match_dup 1)))]
8836   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8837   "neg{<imodesuffix>}\t%0"
8838   [(set_attr "type" "negnot")
8839    (set_attr "mode" "<MODE>")])
8841 (define_insn "*negsi2_cmpz_zext"
8842   [(set (reg:CCZ FLAGS_REG)
8843         (compare:CCZ
8844           (lshiftrt:DI
8845             (neg:DI (ashift:DI
8846                       (match_operand:DI 1 "register_operand" "0")
8847                       (const_int 32)))
8848             (const_int 32))
8849           (const_int 0)))
8850    (set (match_operand:DI 0 "register_operand" "=r")
8851         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8852                                         (const_int 32)))
8853                      (const_int 32)))]
8854   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8855   "neg{l}\t%k0"
8856   [(set_attr "type" "negnot")
8857    (set_attr "mode" "SI")])
8859 ;; Negate with jump on overflow.
8860 (define_expand "negv<mode>3"
8861   [(parallel [(set (reg:CCO FLAGS_REG)
8862                    (ne:CCO (match_operand:SWI 1 "register_operand")
8863                            (match_dup 3)))
8864               (set (match_operand:SWI 0 "register_operand")
8865                    (neg:SWI (match_dup 1)))])
8866    (set (pc) (if_then_else
8867                (eq (reg:CCO FLAGS_REG) (const_int 0))
8868                (label_ref (match_operand 2))
8869                (pc)))]
8870   ""
8872   operands[3]
8873     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8874                     <MODE>mode);
8877 (define_insn "*negv<mode>3"
8878   [(set (reg:CCO FLAGS_REG)
8879         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8880                 (match_operand:SWI 2 "const_int_operand")))
8881    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8882         (neg:SWI (match_dup 1)))]
8883   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8884    && mode_signbit_p (<MODE>mode, operands[2])"
8885   "neg{<imodesuffix>}\t%0"
8886   [(set_attr "type" "negnot")
8887    (set_attr "mode" "<MODE>")])
8889 ;; Changing of sign for FP values is doable using integer unit too.
8891 (define_expand "<code><mode>2"
8892   [(set (match_operand:X87MODEF 0 "register_operand")
8893         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8894   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8895   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8897 (define_insn "*absneg<mode>2_mixed"
8898   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8899         (match_operator:MODEF 3 "absneg_operator"
8900           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8901    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8902    (clobber (reg:CC FLAGS_REG))]
8903   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8904   "#"
8905   [(set (attr "enabled")
8906      (cond [(eq_attr "alternative" "2")
8907               (symbol_ref "TARGET_MIX_SSE_I387")
8908            ]
8909            (symbol_ref "true")))])
8911 (define_insn "*absneg<mode>2_i387"
8912   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8913         (match_operator:X87MODEF 3 "absneg_operator"
8914           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8915    (use (match_operand 2))
8916    (clobber (reg:CC FLAGS_REG))]
8917   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8918   "#")
8920 (define_expand "<code>tf2"
8921   [(set (match_operand:TF 0 "register_operand")
8922         (absneg:TF (match_operand:TF 1 "register_operand")))]
8923   "TARGET_SSE"
8924   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8926 (define_insn "*absnegtf2_sse"
8927   [(set (match_operand:TF 0 "register_operand" "=x,x")
8928         (match_operator:TF 3 "absneg_operator"
8929           [(match_operand:TF 1 "register_operand" "0,x")]))
8930    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8931    (clobber (reg:CC FLAGS_REG))]
8932   "TARGET_SSE"
8933   "#")
8935 ;; Splitters for fp abs and neg.
8937 (define_split
8938   [(set (match_operand 0 "fp_register_operand")
8939         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8940    (use (match_operand 2))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "reload_completed"
8943   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8945 (define_split
8946   [(set (match_operand 0 "register_operand")
8947         (match_operator 3 "absneg_operator"
8948           [(match_operand 1 "register_operand")]))
8949    (use (match_operand 2 "nonimmediate_operand"))
8950    (clobber (reg:CC FLAGS_REG))]
8951   "reload_completed && SSE_REG_P (operands[0])"
8952   [(set (match_dup 0) (match_dup 3))]
8954   machine_mode mode = GET_MODE (operands[0]);
8955   machine_mode vmode = GET_MODE (operands[2]);
8956   rtx tmp;
8958   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8959   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8960   if (operands_match_p (operands[0], operands[2]))
8961     std::swap (operands[1], operands[2]);
8962   if (GET_CODE (operands[3]) == ABS)
8963     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8964   else
8965     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8966   operands[3] = tmp;
8969 (define_split
8970   [(set (match_operand:SF 0 "register_operand")
8971         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8972    (use (match_operand:V4SF 2))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "reload_completed"
8975   [(parallel [(set (match_dup 0) (match_dup 1))
8976               (clobber (reg:CC FLAGS_REG))])]
8978   rtx tmp;
8979   operands[0] = gen_lowpart (SImode, operands[0]);
8980   if (GET_CODE (operands[1]) == ABS)
8981     {
8982       tmp = gen_int_mode (0x7fffffff, SImode);
8983       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8984     }
8985   else
8986     {
8987       tmp = gen_int_mode (0x80000000, SImode);
8988       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8989     }
8990   operands[1] = tmp;
8993 (define_split
8994   [(set (match_operand:DF 0 "register_operand")
8995         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8996    (use (match_operand 2))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "reload_completed"
8999   [(parallel [(set (match_dup 0) (match_dup 1))
9000               (clobber (reg:CC FLAGS_REG))])]
9002   rtx tmp;
9003   if (TARGET_64BIT)
9004     {
9005       tmp = gen_lowpart (DImode, operands[0]);
9006       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9007       operands[0] = tmp;
9009       if (GET_CODE (operands[1]) == ABS)
9010         tmp = const0_rtx;
9011       else
9012         tmp = gen_rtx_NOT (DImode, tmp);
9013     }
9014   else
9015     {
9016       operands[0] = gen_highpart (SImode, operands[0]);
9017       if (GET_CODE (operands[1]) == ABS)
9018         {
9019           tmp = gen_int_mode (0x7fffffff, SImode);
9020           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9021         }
9022       else
9023         {
9024           tmp = gen_int_mode (0x80000000, SImode);
9025           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9026         }
9027     }
9028   operands[1] = tmp;
9031 (define_split
9032   [(set (match_operand:XF 0 "register_operand")
9033         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9034    (use (match_operand 2))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "reload_completed"
9037   [(parallel [(set (match_dup 0) (match_dup 1))
9038               (clobber (reg:CC FLAGS_REG))])]
9040   rtx tmp;
9041   operands[0] = gen_rtx_REG (SImode,
9042                              true_regnum (operands[0])
9043                              + (TARGET_64BIT ? 1 : 2));
9044   if (GET_CODE (operands[1]) == ABS)
9045     {
9046       tmp = GEN_INT (0x7fff);
9047       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9048     }
9049   else
9050     {
9051       tmp = GEN_INT (0x8000);
9052       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9053     }
9054   operands[1] = tmp;
9057 ;; Conditionalize these after reload. If they match before reload, we
9058 ;; lose the clobber and ability to use integer instructions.
9060 (define_insn "*<code><mode>2_1"
9061   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9062         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9063   "TARGET_80387
9064    && (reload_completed
9065        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9066   "f<absneg_mnemonic>"
9067   [(set_attr "type" "fsgn")
9068    (set_attr "mode" "<MODE>")])
9070 (define_insn "*<code>extendsfdf2"
9071   [(set (match_operand:DF 0 "register_operand" "=f")
9072         (absneg:DF (float_extend:DF
9073                      (match_operand:SF 1 "register_operand" "0"))))]
9074   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9075   "f<absneg_mnemonic>"
9076   [(set_attr "type" "fsgn")
9077    (set_attr "mode" "DF")])
9079 (define_insn "*<code>extendsfxf2"
9080   [(set (match_operand:XF 0 "register_operand" "=f")
9081         (absneg:XF (float_extend:XF
9082                      (match_operand:SF 1 "register_operand" "0"))))]
9083   "TARGET_80387"
9084   "f<absneg_mnemonic>"
9085   [(set_attr "type" "fsgn")
9086    (set_attr "mode" "XF")])
9088 (define_insn "*<code>extenddfxf2"
9089   [(set (match_operand:XF 0 "register_operand" "=f")
9090         (absneg:XF (float_extend:XF
9091                      (match_operand:DF 1 "register_operand" "0"))))]
9092   "TARGET_80387"
9093   "f<absneg_mnemonic>"
9094   [(set_attr "type" "fsgn")
9095    (set_attr "mode" "XF")])
9097 ;; Copysign instructions
9099 (define_mode_iterator CSGNMODE [SF DF TF])
9100 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9102 (define_expand "copysign<mode>3"
9103   [(match_operand:CSGNMODE 0 "register_operand")
9104    (match_operand:CSGNMODE 1 "nonmemory_operand")
9105    (match_operand:CSGNMODE 2 "register_operand")]
9106   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9107    || (TARGET_SSE && (<MODE>mode == TFmode))"
9108   "ix86_expand_copysign (operands); DONE;")
9110 (define_insn_and_split "copysign<mode>3_const"
9111   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9112         (unspec:CSGNMODE
9113           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9114            (match_operand:CSGNMODE 2 "register_operand" "0")
9115            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9116           UNSPEC_COPYSIGN))]
9117   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118    || (TARGET_SSE && (<MODE>mode == TFmode))"
9119   "#"
9120   "&& reload_completed"
9121   [(const_int 0)]
9122   "ix86_split_copysign_const (operands); DONE;")
9124 (define_insn "copysign<mode>3_var"
9125   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9126         (unspec:CSGNMODE
9127           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9128            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9129            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9130            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9131           UNSPEC_COPYSIGN))
9132    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9133   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9134    || (TARGET_SSE && (<MODE>mode == TFmode))"
9135   "#")
9137 (define_split
9138   [(set (match_operand:CSGNMODE 0 "register_operand")
9139         (unspec:CSGNMODE
9140           [(match_operand:CSGNMODE 2 "register_operand")
9141            (match_operand:CSGNMODE 3 "register_operand")
9142            (match_operand:<CSGNVMODE> 4)
9143            (match_operand:<CSGNVMODE> 5)]
9144           UNSPEC_COPYSIGN))
9145    (clobber (match_scratch:<CSGNVMODE> 1))]
9146   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9147     || (TARGET_SSE && (<MODE>mode == TFmode)))
9148    && reload_completed"
9149   [(const_int 0)]
9150   "ix86_split_copysign_var (operands); DONE;")
9152 ;; One complement instructions
9154 (define_expand "one_cmpl<mode>2"
9155   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9156         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9157   ""
9158   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9160 (define_insn "*one_cmpl<mode>2_1"
9161   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9162         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9163   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9164   "@
9165    not{<imodesuffix>}\t%0
9166    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9167   [(set_attr "isa" "*,avx512bw")
9168    (set_attr "type" "negnot,msklog")
9169    (set_attr "prefix" "*,vex")
9170    (set_attr "mode" "<MODE>")])
9172 (define_insn "*one_cmplhi2_1"
9173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9174         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9175   "ix86_unary_operator_ok (NOT, HImode, operands)"
9176   "@
9177    not{w}\t%0
9178    knotw\t{%1, %0|%0, %1}"
9179   [(set_attr "isa" "*,avx512f")
9180    (set_attr "type" "negnot,msklog")
9181    (set_attr "prefix" "*,vex")
9182    (set_attr "mode" "HI")])
9184 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9185 (define_insn "*one_cmplqi2_1"
9186   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9187         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9188   "ix86_unary_operator_ok (NOT, QImode, operands)"
9190   switch (which_alternative)
9191     {
9192     case 0:
9193       return "not{b}\t%0";
9194     case 1:
9195       return "not{l}\t%k0";
9196     case 2:
9197       if (TARGET_AVX512DQ)
9198         return "knotb\t{%1, %0|%0, %1}";
9199       return "knotw\t{%1, %0|%0, %1}";
9200     default:
9201       gcc_unreachable ();
9202     }
9204   [(set_attr "isa" "*,*,avx512f")
9205    (set_attr "type" "negnot,negnot,msklog")
9206    (set_attr "prefix" "*,*,vex")
9207    (set_attr "mode" "QI,SI,QI")])
9209 ;; ??? Currently never generated - xor is used instead.
9210 (define_insn "*one_cmplsi2_1_zext"
9211   [(set (match_operand:DI 0 "register_operand" "=r")
9212         (zero_extend:DI
9213           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9214   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9215   "not{l}\t%k0"
9216   [(set_attr "type" "negnot")
9217    (set_attr "mode" "SI")])
9219 (define_insn "*one_cmpl<mode>2_2"
9220   [(set (reg FLAGS_REG)
9221         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9222                  (const_int 0)))
9223    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9224         (not:SWI (match_dup 1)))]
9225   "ix86_match_ccmode (insn, CCNOmode)
9226    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9227   "#"
9228   [(set_attr "type" "alu1")
9229    (set_attr "mode" "<MODE>")])
9231 (define_split
9232   [(set (match_operand 0 "flags_reg_operand")
9233         (match_operator 2 "compare_operator"
9234           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9235            (const_int 0)]))
9236    (set (match_operand:SWI 1 "nonimmediate_operand")
9237         (not:SWI (match_dup 3)))]
9238   "ix86_match_ccmode (insn, CCNOmode)"
9239   [(parallel [(set (match_dup 0)
9240                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9241                                     (const_int 0)]))
9242               (set (match_dup 1)
9243                    (xor:SWI (match_dup 3) (const_int -1)))])])
9245 ;; ??? Currently never generated - xor is used instead.
9246 (define_insn "*one_cmplsi2_2_zext"
9247   [(set (reg FLAGS_REG)
9248         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9249                  (const_int 0)))
9250    (set (match_operand:DI 0 "register_operand" "=r")
9251         (zero_extend:DI (not:SI (match_dup 1))))]
9252   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9253    && ix86_unary_operator_ok (NOT, SImode, operands)"
9254   "#"
9255   [(set_attr "type" "alu1")
9256    (set_attr "mode" "SI")])
9258 (define_split
9259   [(set (match_operand 0 "flags_reg_operand")
9260         (match_operator 2 "compare_operator"
9261           [(not:SI (match_operand:SI 3 "register_operand"))
9262            (const_int 0)]))
9263    (set (match_operand:DI 1 "register_operand")
9264         (zero_extend:DI (not:SI (match_dup 3))))]
9265   "ix86_match_ccmode (insn, CCNOmode)"
9266   [(parallel [(set (match_dup 0)
9267                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9268                                     (const_int 0)]))
9269               (set (match_dup 1)
9270                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9272 ;; Shift instructions
9274 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9275 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9276 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9277 ;; from the assembler input.
9279 ;; This instruction shifts the target reg/mem as usual, but instead of
9280 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9281 ;; is a left shift double, bits are taken from the high order bits of
9282 ;; reg, else if the insn is a shift right double, bits are taken from the
9283 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9284 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9286 ;; Since sh[lr]d does not change the `reg' operand, that is done
9287 ;; separately, making all shifts emit pairs of shift double and normal
9288 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9289 ;; support a 63 bit shift, each shift where the count is in a reg expands
9290 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9292 ;; If the shift count is a constant, we need never emit more than one
9293 ;; shift pair, instead using moves and sign extension for counts greater
9294 ;; than 31.
9296 (define_expand "ashl<mode>3"
9297   [(set (match_operand:SDWIM 0 "<shift_operand>")
9298         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9299                       (match_operand:QI 2 "nonmemory_operand")))]
9300   ""
9301   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9303 (define_insn "*ashl<mode>3_doubleword"
9304   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9305         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9306                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9307    (clobber (reg:CC FLAGS_REG))]
9308   ""
9309   "#"
9310   [(set_attr "type" "multi")])
9312 (define_split
9313   [(set (match_operand:DWI 0 "register_operand")
9314         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9315                     (match_operand:QI 2 "nonmemory_operand")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9318   [(const_int 0)]
9319   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9321 ;; By default we don't ask for a scratch register, because when DWImode
9322 ;; values are manipulated, registers are already at a premium.  But if
9323 ;; we have one handy, we won't turn it away.
9325 (define_peephole2
9326   [(match_scratch:DWIH 3 "r")
9327    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9328                    (ashift:<DWI>
9329                      (match_operand:<DWI> 1 "nonmemory_operand")
9330                      (match_operand:QI 2 "nonmemory_operand")))
9331               (clobber (reg:CC FLAGS_REG))])
9332    (match_dup 3)]
9333   "TARGET_CMOVE"
9334   [(const_int 0)]
9335   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9337 (define_insn "x86_64_shld"
9338   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9339         (ior:DI (ashift:DI (match_dup 0)
9340                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9341                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9342                   (minus:QI (const_int 64) (match_dup 2)))))
9343    (clobber (reg:CC FLAGS_REG))]
9344   "TARGET_64BIT"
9345   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9346   [(set_attr "type" "ishift")
9347    (set_attr "prefix_0f" "1")
9348    (set_attr "mode" "DI")
9349    (set_attr "athlon_decode" "vector")
9350    (set_attr "amdfam10_decode" "vector")
9351    (set_attr "bdver1_decode" "vector")])
9353 (define_insn "x86_shld"
9354   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9355         (ior:SI (ashift:SI (match_dup 0)
9356                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9357                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9358                   (minus:QI (const_int 32) (match_dup 2)))))
9359    (clobber (reg:CC FLAGS_REG))]
9360   ""
9361   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9362   [(set_attr "type" "ishift")
9363    (set_attr "prefix_0f" "1")
9364    (set_attr "mode" "SI")
9365    (set_attr "pent_pair" "np")
9366    (set_attr "athlon_decode" "vector")
9367    (set_attr "amdfam10_decode" "vector")
9368    (set_attr "bdver1_decode" "vector")])
9370 (define_expand "x86_shift<mode>_adj_1"
9371   [(set (reg:CCZ FLAGS_REG)
9372         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9373                              (match_dup 4))
9374                      (const_int 0)))
9375    (set (match_operand:SWI48 0 "register_operand")
9376         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9377                             (match_operand:SWI48 1 "register_operand")
9378                             (match_dup 0)))
9379    (set (match_dup 1)
9380         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9381                             (match_operand:SWI48 3 "register_operand")
9382                             (match_dup 1)))]
9383   "TARGET_CMOVE"
9384   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9386 (define_expand "x86_shift<mode>_adj_2"
9387   [(use (match_operand:SWI48 0 "register_operand"))
9388    (use (match_operand:SWI48 1 "register_operand"))
9389    (use (match_operand:QI 2 "register_operand"))]
9390   ""
9392   rtx_code_label *label = gen_label_rtx ();
9393   rtx tmp;
9395   emit_insn (gen_testqi_ccz_1 (operands[2],
9396                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9398   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9399   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9400   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9401                               gen_rtx_LABEL_REF (VOIDmode, label),
9402                               pc_rtx);
9403   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9404   JUMP_LABEL (tmp) = label;
9406   emit_move_insn (operands[0], operands[1]);
9407   ix86_expand_clear (operands[1]);
9409   emit_label (label);
9410   LABEL_NUSES (label) = 1;
9412   DONE;
9415 ;; Avoid useless masking of count operand.
9416 (define_insn "*ashl<mode>3_mask"
9417   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9418         (ashift:SWI48
9419           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9420           (subreg:QI
9421             (and:SI
9422               (match_operand:SI 2 "register_operand" "c")
9423               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9424    (clobber (reg:CC FLAGS_REG))]
9425   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9426    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9427       == GET_MODE_BITSIZE (<MODE>mode)-1"
9429   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9431   [(set_attr "type" "ishift")
9432    (set_attr "mode" "<MODE>")])
9434 (define_insn "*bmi2_ashl<mode>3_1"
9435   [(set (match_operand:SWI48 0 "register_operand" "=r")
9436         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9437                       (match_operand:SWI48 2 "register_operand" "r")))]
9438   "TARGET_BMI2"
9439   "shlx\t{%2, %1, %0|%0, %1, %2}"
9440   [(set_attr "type" "ishiftx")
9441    (set_attr "mode" "<MODE>")])
9443 (define_insn "*ashl<mode>3_1"
9444   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9445         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9446                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9450   switch (get_attr_type (insn))
9451     {
9452     case TYPE_LEA:
9453     case TYPE_ISHIFTX:
9454       return "#";
9456     case TYPE_ALU:
9457       gcc_assert (operands[2] == const1_rtx);
9458       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9459       return "add{<imodesuffix>}\t%0, %0";
9461     default:
9462       if (operands[2] == const1_rtx
9463           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464         return "sal{<imodesuffix>}\t%0";
9465       else
9466         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9467     }
9469   [(set_attr "isa" "*,*,bmi2")
9470    (set (attr "type")
9471      (cond [(eq_attr "alternative" "1")
9472               (const_string "lea")
9473             (eq_attr "alternative" "2")
9474               (const_string "ishiftx")
9475             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9476                       (match_operand 0 "register_operand"))
9477                  (match_operand 2 "const1_operand"))
9478               (const_string "alu")
9479            ]
9480            (const_string "ishift")))
9481    (set (attr "length_immediate")
9482      (if_then_else
9483        (ior (eq_attr "type" "alu")
9484             (and (eq_attr "type" "ishift")
9485                  (and (match_operand 2 "const1_operand")
9486                       (ior (match_test "TARGET_SHIFT1")
9487                            (match_test "optimize_function_for_size_p (cfun)")))))
9488        (const_string "0")
9489        (const_string "*")))
9490    (set_attr "mode" "<MODE>")])
9492 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9493 (define_split
9494   [(set (match_operand:SWI48 0 "register_operand")
9495         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9496                       (match_operand:QI 2 "register_operand")))
9497    (clobber (reg:CC FLAGS_REG))]
9498   "TARGET_BMI2 && reload_completed"
9499   [(set (match_dup 0)
9500         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9501   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9503 (define_insn "*bmi2_ashlsi3_1_zext"
9504   [(set (match_operand:DI 0 "register_operand" "=r")
9505         (zero_extend:DI
9506           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9507                      (match_operand:SI 2 "register_operand" "r"))))]
9508   "TARGET_64BIT && TARGET_BMI2"
9509   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9510   [(set_attr "type" "ishiftx")
9511    (set_attr "mode" "SI")])
9513 (define_insn "*ashlsi3_1_zext"
9514   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9515         (zero_extend:DI
9516           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9517                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9521   switch (get_attr_type (insn))
9522     {
9523     case TYPE_LEA:
9524     case TYPE_ISHIFTX:
9525       return "#";
9527     case TYPE_ALU:
9528       gcc_assert (operands[2] == const1_rtx);
9529       return "add{l}\t%k0, %k0";
9531     default:
9532       if (operands[2] == const1_rtx
9533           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9534         return "sal{l}\t%k0";
9535       else
9536         return "sal{l}\t{%2, %k0|%k0, %2}";
9537     }
9539   [(set_attr "isa" "*,*,bmi2")
9540    (set (attr "type")
9541      (cond [(eq_attr "alternative" "1")
9542               (const_string "lea")
9543             (eq_attr "alternative" "2")
9544               (const_string "ishiftx")
9545             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9546                  (match_operand 2 "const1_operand"))
9547               (const_string "alu")
9548            ]
9549            (const_string "ishift")))
9550    (set (attr "length_immediate")
9551      (if_then_else
9552        (ior (eq_attr "type" "alu")
9553             (and (eq_attr "type" "ishift")
9554                  (and (match_operand 2 "const1_operand")
9555                       (ior (match_test "TARGET_SHIFT1")
9556                            (match_test "optimize_function_for_size_p (cfun)")))))
9557        (const_string "0")
9558        (const_string "*")))
9559    (set_attr "mode" "SI")])
9561 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9562 (define_split
9563   [(set (match_operand:DI 0 "register_operand")
9564         (zero_extend:DI
9565           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9566                      (match_operand:QI 2 "register_operand"))))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9569   [(set (match_dup 0)
9570         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9571   "operands[2] = gen_lowpart (SImode, operands[2]);")
9573 (define_insn "*ashlhi3_1"
9574   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9575         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9576                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9577    (clobber (reg:CC FLAGS_REG))]
9578   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9580   switch (get_attr_type (insn))
9581     {
9582     case TYPE_LEA:
9583       return "#";
9585     case TYPE_ALU:
9586       gcc_assert (operands[2] == const1_rtx);
9587       return "add{w}\t%0, %0";
9589     default:
9590       if (operands[2] == const1_rtx
9591           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592         return "sal{w}\t%0";
9593       else
9594         return "sal{w}\t{%2, %0|%0, %2}";
9595     }
9597   [(set (attr "type")
9598      (cond [(eq_attr "alternative" "1")
9599               (const_string "lea")
9600             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9601                       (match_operand 0 "register_operand"))
9602                  (match_operand 2 "const1_operand"))
9603               (const_string "alu")
9604            ]
9605            (const_string "ishift")))
9606    (set (attr "length_immediate")
9607      (if_then_else
9608        (ior (eq_attr "type" "alu")
9609             (and (eq_attr "type" "ishift")
9610                  (and (match_operand 2 "const1_operand")
9611                       (ior (match_test "TARGET_SHIFT1")
9612                            (match_test "optimize_function_for_size_p (cfun)")))))
9613        (const_string "0")
9614        (const_string "*")))
9615    (set_attr "mode" "HI,SI")])
9617 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9618 (define_insn "*ashlqi3_1"
9619   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9620         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9621                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9622    (clobber (reg:CC FLAGS_REG))]
9623   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9625   switch (get_attr_type (insn))
9626     {
9627     case TYPE_LEA:
9628       return "#";
9630     case TYPE_ALU:
9631       gcc_assert (operands[2] == const1_rtx);
9632       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9633         return "add{l}\t%k0, %k0";
9634       else
9635         return "add{b}\t%0, %0";
9637     default:
9638       if (operands[2] == const1_rtx
9639           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9640         {
9641           if (get_attr_mode (insn) == MODE_SI)
9642             return "sal{l}\t%k0";
9643           else
9644             return "sal{b}\t%0";
9645         }
9646       else
9647         {
9648           if (get_attr_mode (insn) == MODE_SI)
9649             return "sal{l}\t{%2, %k0|%k0, %2}";
9650           else
9651             return "sal{b}\t{%2, %0|%0, %2}";
9652         }
9653     }
9655   [(set (attr "type")
9656      (cond [(eq_attr "alternative" "2")
9657               (const_string "lea")
9658             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9659                       (match_operand 0 "register_operand"))
9660                  (match_operand 2 "const1_operand"))
9661               (const_string "alu")
9662            ]
9663            (const_string "ishift")))
9664    (set (attr "length_immediate")
9665      (if_then_else
9666        (ior (eq_attr "type" "alu")
9667             (and (eq_attr "type" "ishift")
9668                  (and (match_operand 2 "const1_operand")
9669                       (ior (match_test "TARGET_SHIFT1")
9670                            (match_test "optimize_function_for_size_p (cfun)")))))
9671        (const_string "0")
9672        (const_string "*")))
9673    (set_attr "mode" "QI,SI,SI")])
9675 (define_insn "*ashlqi3_1_slp"
9676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9677         (ashift:QI (match_dup 0)
9678                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9679    (clobber (reg:CC FLAGS_REG))]
9680   "(optimize_function_for_size_p (cfun)
9681     || !TARGET_PARTIAL_FLAG_REG_STALL
9682     || (operands[1] == const1_rtx
9683         && (TARGET_SHIFT1
9684             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9686   switch (get_attr_type (insn))
9687     {
9688     case TYPE_ALU:
9689       gcc_assert (operands[1] == const1_rtx);
9690       return "add{b}\t%0, %0";
9692     default:
9693       if (operands[1] == const1_rtx
9694           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9695         return "sal{b}\t%0";
9696       else
9697         return "sal{b}\t{%1, %0|%0, %1}";
9698     }
9700   [(set (attr "type")
9701      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9702                       (match_operand 0 "register_operand"))
9703                  (match_operand 1 "const1_operand"))
9704               (const_string "alu")
9705            ]
9706            (const_string "ishift1")))
9707    (set (attr "length_immediate")
9708      (if_then_else
9709        (ior (eq_attr "type" "alu")
9710             (and (eq_attr "type" "ishift1")
9711                  (and (match_operand 1 "const1_operand")
9712                       (ior (match_test "TARGET_SHIFT1")
9713                            (match_test "optimize_function_for_size_p (cfun)")))))
9714        (const_string "0")
9715        (const_string "*")))
9716    (set_attr "mode" "QI")])
9718 ;; Convert ashift to the lea pattern to avoid flags dependency.
9719 (define_split
9720   [(set (match_operand 0 "register_operand")
9721         (ashift (match_operand 1 "index_register_operand")
9722                 (match_operand:QI 2 "const_int_operand")))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9725    && reload_completed
9726    && true_regnum (operands[0]) != true_regnum (operands[1])"
9727   [(const_int 0)]
9729   machine_mode mode = GET_MODE (operands[0]);
9730   rtx pat;
9732   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9733     { 
9734       mode = SImode; 
9735       operands[0] = gen_lowpart (mode, operands[0]);
9736       operands[1] = gen_lowpart (mode, operands[1]);
9737     }
9739   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9741   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9743   emit_insn (gen_rtx_SET (operands[0], pat));
9744   DONE;
9747 ;; Convert ashift to the lea pattern to avoid flags dependency.
9748 (define_split
9749   [(set (match_operand:DI 0 "register_operand")
9750         (zero_extend:DI
9751           (ashift:SI (match_operand:SI 1 "index_register_operand")
9752                      (match_operand:QI 2 "const_int_operand"))))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "TARGET_64BIT && reload_completed
9755    && true_regnum (operands[0]) != true_regnum (operands[1])"
9756   [(set (match_dup 0)
9757         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9759   operands[1] = gen_lowpart (SImode, operands[1]);
9760   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9763 ;; This pattern can't accept a variable shift count, since shifts by
9764 ;; zero don't affect the flags.  We assume that shifts by constant
9765 ;; zero are optimized away.
9766 (define_insn "*ashl<mode>3_cmp"
9767   [(set (reg FLAGS_REG)
9768         (compare
9769           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9770                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9771           (const_int 0)))
9772    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9773         (ashift:SWI (match_dup 1) (match_dup 2)))]
9774   "(optimize_function_for_size_p (cfun)
9775     || !TARGET_PARTIAL_FLAG_REG_STALL
9776     || (operands[2] == const1_rtx
9777         && (TARGET_SHIFT1
9778             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9779    && ix86_match_ccmode (insn, CCGOCmode)
9780    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9782   switch (get_attr_type (insn))
9783     {
9784     case TYPE_ALU:
9785       gcc_assert (operands[2] == const1_rtx);
9786       return "add{<imodesuffix>}\t%0, %0";
9788     default:
9789       if (operands[2] == const1_rtx
9790           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9791         return "sal{<imodesuffix>}\t%0";
9792       else
9793         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9794     }
9796   [(set (attr "type")
9797      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9798                       (match_operand 0 "register_operand"))
9799                  (match_operand 2 "const1_operand"))
9800               (const_string "alu")
9801            ]
9802            (const_string "ishift")))
9803    (set (attr "length_immediate")
9804      (if_then_else
9805        (ior (eq_attr "type" "alu")
9806             (and (eq_attr "type" "ishift")
9807                  (and (match_operand 2 "const1_operand")
9808                       (ior (match_test "TARGET_SHIFT1")
9809                            (match_test "optimize_function_for_size_p (cfun)")))))
9810        (const_string "0")
9811        (const_string "*")))
9812    (set_attr "mode" "<MODE>")])
9814 (define_insn "*ashlsi3_cmp_zext"
9815   [(set (reg FLAGS_REG)
9816         (compare
9817           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9818                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9819           (const_int 0)))
9820    (set (match_operand:DI 0 "register_operand" "=r")
9821         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9822   "TARGET_64BIT
9823    && (optimize_function_for_size_p (cfun)
9824        || !TARGET_PARTIAL_FLAG_REG_STALL
9825        || (operands[2] == const1_rtx
9826            && (TARGET_SHIFT1
9827                || TARGET_DOUBLE_WITH_ADD)))
9828    && ix86_match_ccmode (insn, CCGOCmode)
9829    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9831   switch (get_attr_type (insn))
9832     {
9833     case TYPE_ALU:
9834       gcc_assert (operands[2] == const1_rtx);
9835       return "add{l}\t%k0, %k0";
9837     default:
9838       if (operands[2] == const1_rtx
9839           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9840         return "sal{l}\t%k0";
9841       else
9842         return "sal{l}\t{%2, %k0|%k0, %2}";
9843     }
9845   [(set (attr "type")
9846      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9847                  (match_operand 2 "const1_operand"))
9848               (const_string "alu")
9849            ]
9850            (const_string "ishift")))
9851    (set (attr "length_immediate")
9852      (if_then_else
9853        (ior (eq_attr "type" "alu")
9854             (and (eq_attr "type" "ishift")
9855                  (and (match_operand 2 "const1_operand")
9856                       (ior (match_test "TARGET_SHIFT1")
9857                            (match_test "optimize_function_for_size_p (cfun)")))))
9858        (const_string "0")
9859        (const_string "*")))
9860    (set_attr "mode" "SI")])
9862 (define_insn "*ashl<mode>3_cconly"
9863   [(set (reg FLAGS_REG)
9864         (compare
9865           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9866                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9867           (const_int 0)))
9868    (clobber (match_scratch:SWI 0 "=<r>"))]
9869   "(optimize_function_for_size_p (cfun)
9870     || !TARGET_PARTIAL_FLAG_REG_STALL
9871     || (operands[2] == const1_rtx
9872         && (TARGET_SHIFT1
9873             || TARGET_DOUBLE_WITH_ADD)))
9874    && ix86_match_ccmode (insn, CCGOCmode)"
9876   switch (get_attr_type (insn))
9877     {
9878     case TYPE_ALU:
9879       gcc_assert (operands[2] == const1_rtx);
9880       return "add{<imodesuffix>}\t%0, %0";
9882     default:
9883       if (operands[2] == const1_rtx
9884           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9885         return "sal{<imodesuffix>}\t%0";
9886       else
9887         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9888     }
9890   [(set (attr "type")
9891      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9892                       (match_operand 0 "register_operand"))
9893                  (match_operand 2 "const1_operand"))
9894               (const_string "alu")
9895            ]
9896            (const_string "ishift")))
9897    (set (attr "length_immediate")
9898      (if_then_else
9899        (ior (eq_attr "type" "alu")
9900             (and (eq_attr "type" "ishift")
9901                  (and (match_operand 2 "const1_operand")
9902                       (ior (match_test "TARGET_SHIFT1")
9903                            (match_test "optimize_function_for_size_p (cfun)")))))
9904        (const_string "0")
9905        (const_string "*")))
9906    (set_attr "mode" "<MODE>")])
9908 ;; See comment above `ashl<mode>3' about how this works.
9910 (define_expand "<shift_insn><mode>3"
9911   [(set (match_operand:SDWIM 0 "<shift_operand>")
9912         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9913                            (match_operand:QI 2 "nonmemory_operand")))]
9914   ""
9915   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9917 ;; Avoid useless masking of count operand.
9918 (define_insn "*<shift_insn><mode>3_mask"
9919   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9920         (any_shiftrt:SWI48
9921           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9922           (subreg:QI
9923             (and:SI
9924               (match_operand:SI 2 "register_operand" "c")
9925               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9926    (clobber (reg:CC FLAGS_REG))]
9927   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9928    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9929       == GET_MODE_BITSIZE (<MODE>mode)-1"
9931   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9933   [(set_attr "type" "ishift")
9934    (set_attr "mode" "<MODE>")])
9936 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9937   [(set (match_operand:DWI 0 "register_operand" "=r")
9938         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9939                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9940    (clobber (reg:CC FLAGS_REG))]
9941   ""
9942   "#"
9943   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9944   [(const_int 0)]
9945   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9946   [(set_attr "type" "multi")])
9948 ;; By default we don't ask for a scratch register, because when DWImode
9949 ;; values are manipulated, registers are already at a premium.  But if
9950 ;; we have one handy, we won't turn it away.
9952 (define_peephole2
9953   [(match_scratch:DWIH 3 "r")
9954    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9955                    (any_shiftrt:<DWI>
9956                      (match_operand:<DWI> 1 "register_operand")
9957                      (match_operand:QI 2 "nonmemory_operand")))
9958               (clobber (reg:CC FLAGS_REG))])
9959    (match_dup 3)]
9960   "TARGET_CMOVE"
9961   [(const_int 0)]
9962   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9964 (define_insn "x86_64_shrd"
9965   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9966         (ior:DI (lshiftrt:DI (match_dup 0)
9967                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9968                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9969                   (minus:QI (const_int 64) (match_dup 2)))))
9970    (clobber (reg:CC FLAGS_REG))]
9971   "TARGET_64BIT"
9972   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9973   [(set_attr "type" "ishift")
9974    (set_attr "prefix_0f" "1")
9975    (set_attr "mode" "DI")
9976    (set_attr "athlon_decode" "vector")
9977    (set_attr "amdfam10_decode" "vector")
9978    (set_attr "bdver1_decode" "vector")])
9980 (define_insn "x86_shrd"
9981   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9982         (ior:SI (lshiftrt:SI (match_dup 0)
9983                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9984                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9985                   (minus:QI (const_int 32) (match_dup 2)))))
9986    (clobber (reg:CC FLAGS_REG))]
9987   ""
9988   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9989   [(set_attr "type" "ishift")
9990    (set_attr "prefix_0f" "1")
9991    (set_attr "mode" "SI")
9992    (set_attr "pent_pair" "np")
9993    (set_attr "athlon_decode" "vector")
9994    (set_attr "amdfam10_decode" "vector")
9995    (set_attr "bdver1_decode" "vector")])
9997 (define_insn "ashrdi3_cvt"
9998   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9999         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10000                      (match_operand:QI 2 "const_int_operand")))
10001    (clobber (reg:CC FLAGS_REG))]
10002   "TARGET_64BIT && INTVAL (operands[2]) == 63
10003    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10004    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10005   "@
10006    {cqto|cqo}
10007    sar{q}\t{%2, %0|%0, %2}"
10008   [(set_attr "type" "imovx,ishift")
10009    (set_attr "prefix_0f" "0,*")
10010    (set_attr "length_immediate" "0,*")
10011    (set_attr "modrm" "0,1")
10012    (set_attr "mode" "DI")])
10014 (define_insn "ashrsi3_cvt"
10015   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10016         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10017                      (match_operand:QI 2 "const_int_operand")))
10018    (clobber (reg:CC FLAGS_REG))]
10019   "INTVAL (operands[2]) == 31
10020    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10022   "@
10023    {cltd|cdq}
10024    sar{l}\t{%2, %0|%0, %2}"
10025   [(set_attr "type" "imovx,ishift")
10026    (set_attr "prefix_0f" "0,*")
10027    (set_attr "length_immediate" "0,*")
10028    (set_attr "modrm" "0,1")
10029    (set_attr "mode" "SI")])
10031 (define_insn "*ashrsi3_cvt_zext"
10032   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10033         (zero_extend:DI
10034           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10035                        (match_operand:QI 2 "const_int_operand"))))
10036    (clobber (reg:CC FLAGS_REG))]
10037   "TARGET_64BIT && INTVAL (operands[2]) == 31
10038    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10039    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10040   "@
10041    {cltd|cdq}
10042    sar{l}\t{%2, %k0|%k0, %2}"
10043   [(set_attr "type" "imovx,ishift")
10044    (set_attr "prefix_0f" "0,*")
10045    (set_attr "length_immediate" "0,*")
10046    (set_attr "modrm" "0,1")
10047    (set_attr "mode" "SI")])
10049 (define_expand "x86_shift<mode>_adj_3"
10050   [(use (match_operand:SWI48 0 "register_operand"))
10051    (use (match_operand:SWI48 1 "register_operand"))
10052    (use (match_operand:QI 2 "register_operand"))]
10053   ""
10055   rtx_code_label *label = gen_label_rtx ();
10056   rtx tmp;
10058   emit_insn (gen_testqi_ccz_1 (operands[2],
10059                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10061   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10062   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10063   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10064                               gen_rtx_LABEL_REF (VOIDmode, label),
10065                               pc_rtx);
10066   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10067   JUMP_LABEL (tmp) = label;
10069   emit_move_insn (operands[0], operands[1]);
10070   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10071                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10072   emit_label (label);
10073   LABEL_NUSES (label) = 1;
10075   DONE;
10078 (define_insn "*bmi2_<shift_insn><mode>3_1"
10079   [(set (match_operand:SWI48 0 "register_operand" "=r")
10080         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10081                            (match_operand:SWI48 2 "register_operand" "r")))]
10082   "TARGET_BMI2"
10083   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10084   [(set_attr "type" "ishiftx")
10085    (set_attr "mode" "<MODE>")])
10087 (define_insn "*<shift_insn><mode>3_1"
10088   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10089         (any_shiftrt:SWI48
10090           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10091           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10092    (clobber (reg:CC FLAGS_REG))]
10093   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10095   switch (get_attr_type (insn))
10096     {
10097     case TYPE_ISHIFTX:
10098       return "#";
10100     default:
10101       if (operands[2] == const1_rtx
10102           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10103         return "<shift>{<imodesuffix>}\t%0";
10104       else
10105         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10106     }
10108   [(set_attr "isa" "*,bmi2")
10109    (set_attr "type" "ishift,ishiftx")
10110    (set (attr "length_immediate")
10111      (if_then_else
10112        (and (match_operand 2 "const1_operand")
10113             (ior (match_test "TARGET_SHIFT1")
10114                  (match_test "optimize_function_for_size_p (cfun)")))
10115        (const_string "0")
10116        (const_string "*")))
10117    (set_attr "mode" "<MODE>")])
10119 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10120 (define_split
10121   [(set (match_operand:SWI48 0 "register_operand")
10122         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10123                            (match_operand:QI 2 "register_operand")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "TARGET_BMI2 && reload_completed"
10126   [(set (match_dup 0)
10127         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10128   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10130 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10131   [(set (match_operand:DI 0 "register_operand" "=r")
10132         (zero_extend:DI
10133           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10134                           (match_operand:SI 2 "register_operand" "r"))))]
10135   "TARGET_64BIT && TARGET_BMI2"
10136   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10137   [(set_attr "type" "ishiftx")
10138    (set_attr "mode" "SI")])
10140 (define_insn "*<shift_insn>si3_1_zext"
10141   [(set (match_operand:DI 0 "register_operand" "=r,r")
10142         (zero_extend:DI
10143           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10144                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10145    (clobber (reg:CC FLAGS_REG))]
10146   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10148   switch (get_attr_type (insn))
10149     {
10150     case TYPE_ISHIFTX:
10151       return "#";
10153     default:
10154       if (operands[2] == const1_rtx
10155           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10156         return "<shift>{l}\t%k0";
10157       else
10158         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10159     }
10161   [(set_attr "isa" "*,bmi2")
10162    (set_attr "type" "ishift,ishiftx")
10163    (set (attr "length_immediate")
10164      (if_then_else
10165        (and (match_operand 2 "const1_operand")
10166             (ior (match_test "TARGET_SHIFT1")
10167                  (match_test "optimize_function_for_size_p (cfun)")))
10168        (const_string "0")
10169        (const_string "*")))
10170    (set_attr "mode" "SI")])
10172 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10173 (define_split
10174   [(set (match_operand:DI 0 "register_operand")
10175         (zero_extend:DI
10176           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10177                           (match_operand:QI 2 "register_operand"))))
10178    (clobber (reg:CC FLAGS_REG))]
10179   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10180   [(set (match_dup 0)
10181         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10182   "operands[2] = gen_lowpart (SImode, operands[2]);")
10184 (define_insn "*<shift_insn><mode>3_1"
10185   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10186         (any_shiftrt:SWI12
10187           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10188           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10189    (clobber (reg:CC FLAGS_REG))]
10190   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10192   if (operands[2] == const1_rtx
10193       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10194     return "<shift>{<imodesuffix>}\t%0";
10195   else
10196     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10198   [(set_attr "type" "ishift")
10199    (set (attr "length_immediate")
10200      (if_then_else
10201        (and (match_operand 2 "const1_operand")
10202             (ior (match_test "TARGET_SHIFT1")
10203                  (match_test "optimize_function_for_size_p (cfun)")))
10204        (const_string "0")
10205        (const_string "*")))
10206    (set_attr "mode" "<MODE>")])
10208 (define_insn "*<shift_insn>qi3_1_slp"
10209   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10210         (any_shiftrt:QI (match_dup 0)
10211                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10212    (clobber (reg:CC FLAGS_REG))]
10213   "(optimize_function_for_size_p (cfun)
10214     || !TARGET_PARTIAL_REG_STALL
10215     || (operands[1] == const1_rtx
10216         && TARGET_SHIFT1))"
10218   if (operands[1] == const1_rtx
10219       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10220     return "<shift>{b}\t%0";
10221   else
10222     return "<shift>{b}\t{%1, %0|%0, %1}";
10224   [(set_attr "type" "ishift1")
10225    (set (attr "length_immediate")
10226      (if_then_else
10227        (and (match_operand 1 "const1_operand")
10228             (ior (match_test "TARGET_SHIFT1")
10229                  (match_test "optimize_function_for_size_p (cfun)")))
10230        (const_string "0")
10231        (const_string "*")))
10232    (set_attr "mode" "QI")])
10234 ;; This pattern can't accept a variable shift count, since shifts by
10235 ;; zero don't affect the flags.  We assume that shifts by constant
10236 ;; zero are optimized away.
10237 (define_insn "*<shift_insn><mode>3_cmp"
10238   [(set (reg FLAGS_REG)
10239         (compare
10240           (any_shiftrt:SWI
10241             (match_operand:SWI 1 "nonimmediate_operand" "0")
10242             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10243           (const_int 0)))
10244    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10245         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10246   "(optimize_function_for_size_p (cfun)
10247     || !TARGET_PARTIAL_FLAG_REG_STALL
10248     || (operands[2] == const1_rtx
10249         && TARGET_SHIFT1))
10250    && ix86_match_ccmode (insn, CCGOCmode)
10251    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10253   if (operands[2] == const1_rtx
10254       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10255     return "<shift>{<imodesuffix>}\t%0";
10256   else
10257     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10259   [(set_attr "type" "ishift")
10260    (set (attr "length_immediate")
10261      (if_then_else
10262        (and (match_operand 2 "const1_operand")
10263             (ior (match_test "TARGET_SHIFT1")
10264                  (match_test "optimize_function_for_size_p (cfun)")))
10265        (const_string "0")
10266        (const_string "*")))
10267    (set_attr "mode" "<MODE>")])
10269 (define_insn "*<shift_insn>si3_cmp_zext"
10270   [(set (reg FLAGS_REG)
10271         (compare
10272           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10273                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10274           (const_int 0)))
10275    (set (match_operand:DI 0 "register_operand" "=r")
10276         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10277   "TARGET_64BIT
10278    && (optimize_function_for_size_p (cfun)
10279        || !TARGET_PARTIAL_FLAG_REG_STALL
10280        || (operands[2] == const1_rtx
10281            && TARGET_SHIFT1))
10282    && ix86_match_ccmode (insn, CCGOCmode)
10283    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10285   if (operands[2] == const1_rtx
10286       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10287     return "<shift>{l}\t%k0";
10288   else
10289     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10291   [(set_attr "type" "ishift")
10292    (set (attr "length_immediate")
10293      (if_then_else
10294        (and (match_operand 2 "const1_operand")
10295             (ior (match_test "TARGET_SHIFT1")
10296                  (match_test "optimize_function_for_size_p (cfun)")))
10297        (const_string "0")
10298        (const_string "*")))
10299    (set_attr "mode" "SI")])
10301 (define_insn "*<shift_insn><mode>3_cconly"
10302   [(set (reg FLAGS_REG)
10303         (compare
10304           (any_shiftrt:SWI
10305             (match_operand:SWI 1 "register_operand" "0")
10306             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10307           (const_int 0)))
10308    (clobber (match_scratch:SWI 0 "=<r>"))]
10309   "(optimize_function_for_size_p (cfun)
10310     || !TARGET_PARTIAL_FLAG_REG_STALL
10311     || (operands[2] == const1_rtx
10312         && TARGET_SHIFT1))
10313    && ix86_match_ccmode (insn, CCGOCmode)"
10315   if (operands[2] == const1_rtx
10316       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10317     return "<shift>{<imodesuffix>}\t%0";
10318   else
10319     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10321   [(set_attr "type" "ishift")
10322    (set (attr "length_immediate")
10323      (if_then_else
10324        (and (match_operand 2 "const1_operand")
10325             (ior (match_test "TARGET_SHIFT1")
10326                  (match_test "optimize_function_for_size_p (cfun)")))
10327        (const_string "0")
10328        (const_string "*")))
10329    (set_attr "mode" "<MODE>")])
10331 ;; Rotate instructions
10333 (define_expand "<rotate_insn>ti3"
10334   [(set (match_operand:TI 0 "register_operand")
10335         (any_rotate:TI (match_operand:TI 1 "register_operand")
10336                        (match_operand:QI 2 "nonmemory_operand")))]
10337   "TARGET_64BIT"
10339   if (const_1_to_63_operand (operands[2], VOIDmode))
10340     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10341                 (operands[0], operands[1], operands[2]));
10342   else
10343     FAIL;
10345   DONE;
10348 (define_expand "<rotate_insn>di3"
10349   [(set (match_operand:DI 0 "shiftdi_operand")
10350         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10351                        (match_operand:QI 2 "nonmemory_operand")))]
10352  ""
10354   if (TARGET_64BIT)
10355     ix86_expand_binary_operator (<CODE>, DImode, operands);
10356   else if (const_1_to_31_operand (operands[2], VOIDmode))
10357     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10358                 (operands[0], operands[1], operands[2]));
10359   else
10360     FAIL;
10362   DONE;
10365 (define_expand "<rotate_insn><mode>3"
10366   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10367         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10368                             (match_operand:QI 2 "nonmemory_operand")))]
10369   ""
10370   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10372 ;; Avoid useless masking of count operand.
10373 (define_insn "*<rotate_insn><mode>3_mask"
10374   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10375         (any_rotate:SWI48
10376           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10377           (subreg:QI
10378             (and:SI
10379               (match_operand:SI 2 "register_operand" "c")
10380               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10381    (clobber (reg:CC FLAGS_REG))]
10382   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10383    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10384       == GET_MODE_BITSIZE (<MODE>mode)-1"
10386   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10388   [(set_attr "type" "rotate")
10389    (set_attr "mode" "<MODE>")])
10391 ;; Implement rotation using two double-precision
10392 ;; shift instructions and a scratch register.
10394 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10395  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10396        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10397                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10398   (clobber (reg:CC FLAGS_REG))
10399   (clobber (match_scratch:DWIH 3 "=&r"))]
10400  ""
10401  "#"
10402  "reload_completed"
10403  [(set (match_dup 3) (match_dup 4))
10404   (parallel
10405    [(set (match_dup 4)
10406          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10407                    (lshiftrt:DWIH (match_dup 5)
10408                                   (minus:QI (match_dup 6) (match_dup 2)))))
10409     (clobber (reg:CC FLAGS_REG))])
10410   (parallel
10411    [(set (match_dup 5)
10412          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10413                    (lshiftrt:DWIH (match_dup 3)
10414                                   (minus:QI (match_dup 6) (match_dup 2)))))
10415     (clobber (reg:CC FLAGS_REG))])]
10417   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10419   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10422 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10423  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10424        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10425                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10426   (clobber (reg:CC FLAGS_REG))
10427   (clobber (match_scratch:DWIH 3 "=&r"))]
10428  ""
10429  "#"
10430  "reload_completed"
10431  [(set (match_dup 3) (match_dup 4))
10432   (parallel
10433    [(set (match_dup 4)
10434          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10435                    (ashift:DWIH (match_dup 5)
10436                                 (minus:QI (match_dup 6) (match_dup 2)))))
10437     (clobber (reg:CC FLAGS_REG))])
10438   (parallel
10439    [(set (match_dup 5)
10440          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10441                    (ashift:DWIH (match_dup 3)
10442                                 (minus:QI (match_dup 6) (match_dup 2)))))
10443     (clobber (reg:CC FLAGS_REG))])]
10445   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10447   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10450 (define_insn "*bmi2_rorx<mode>3_1"
10451   [(set (match_operand:SWI48 0 "register_operand" "=r")
10452         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10453                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10454   "TARGET_BMI2"
10455   "rorx\t{%2, %1, %0|%0, %1, %2}"
10456   [(set_attr "type" "rotatex")
10457    (set_attr "mode" "<MODE>")])
10459 (define_insn "*<rotate_insn><mode>3_1"
10460   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10461         (any_rotate:SWI48
10462           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10463           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10464    (clobber (reg:CC FLAGS_REG))]
10465   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10467   switch (get_attr_type (insn))
10468     {
10469     case TYPE_ROTATEX:
10470       return "#";
10472     default:
10473       if (operands[2] == const1_rtx
10474           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10475         return "<rotate>{<imodesuffix>}\t%0";
10476       else
10477         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10478     }
10480   [(set_attr "isa" "*,bmi2")
10481    (set_attr "type" "rotate,rotatex")
10482    (set (attr "length_immediate")
10483      (if_then_else
10484        (and (eq_attr "type" "rotate")
10485             (and (match_operand 2 "const1_operand")
10486                  (ior (match_test "TARGET_SHIFT1")
10487                       (match_test "optimize_function_for_size_p (cfun)"))))
10488        (const_string "0")
10489        (const_string "*")))
10490    (set_attr "mode" "<MODE>")])
10492 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10493 (define_split
10494   [(set (match_operand:SWI48 0 "register_operand")
10495         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10496                       (match_operand:QI 2 "immediate_operand")))
10497    (clobber (reg:CC FLAGS_REG))]
10498   "TARGET_BMI2 && reload_completed"
10499   [(set (match_dup 0)
10500         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10502   operands[2]
10503     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10506 (define_split
10507   [(set (match_operand:SWI48 0 "register_operand")
10508         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10509                         (match_operand:QI 2 "immediate_operand")))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "TARGET_BMI2 && reload_completed"
10512   [(set (match_dup 0)
10513         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10515 (define_insn "*bmi2_rorxsi3_1_zext"
10516   [(set (match_operand:DI 0 "register_operand" "=r")
10517         (zero_extend:DI
10518           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10519                        (match_operand:QI 2 "immediate_operand" "I"))))]
10520   "TARGET_64BIT && TARGET_BMI2"
10521   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10522   [(set_attr "type" "rotatex")
10523    (set_attr "mode" "SI")])
10525 (define_insn "*<rotate_insn>si3_1_zext"
10526   [(set (match_operand:DI 0 "register_operand" "=r,r")
10527         (zero_extend:DI
10528           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10529                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10530    (clobber (reg:CC FLAGS_REG))]
10531   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10533   switch (get_attr_type (insn))
10534     {
10535     case TYPE_ROTATEX:
10536       return "#";
10538     default:
10539       if (operands[2] == const1_rtx
10540           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10541         return "<rotate>{l}\t%k0";
10542       else
10543         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10544     }
10546   [(set_attr "isa" "*,bmi2")
10547    (set_attr "type" "rotate,rotatex")
10548    (set (attr "length_immediate")
10549      (if_then_else
10550        (and (eq_attr "type" "rotate")
10551             (and (match_operand 2 "const1_operand")
10552                  (ior (match_test "TARGET_SHIFT1")
10553                       (match_test "optimize_function_for_size_p (cfun)"))))
10554        (const_string "0")
10555        (const_string "*")))
10556    (set_attr "mode" "SI")])
10558 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10559 (define_split
10560   [(set (match_operand:DI 0 "register_operand")
10561         (zero_extend:DI
10562           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10563                      (match_operand:QI 2 "immediate_operand"))))
10564    (clobber (reg:CC FLAGS_REG))]
10565   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10566   [(set (match_dup 0)
10567         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10569   operands[2]
10570     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10573 (define_split
10574   [(set (match_operand:DI 0 "register_operand")
10575         (zero_extend:DI
10576           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10577                        (match_operand:QI 2 "immediate_operand"))))
10578    (clobber (reg:CC FLAGS_REG))]
10579   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10580   [(set (match_dup 0)
10581         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10583 (define_insn "*<rotate_insn><mode>3_1"
10584   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10585         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10586                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10587    (clobber (reg:CC FLAGS_REG))]
10588   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10590   if (operands[2] == const1_rtx
10591       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10592     return "<rotate>{<imodesuffix>}\t%0";
10593   else
10594     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10596   [(set_attr "type" "rotate")
10597    (set (attr "length_immediate")
10598      (if_then_else
10599        (and (match_operand 2 "const1_operand")
10600             (ior (match_test "TARGET_SHIFT1")
10601                  (match_test "optimize_function_for_size_p (cfun)")))
10602        (const_string "0")
10603        (const_string "*")))
10604    (set_attr "mode" "<MODE>")])
10606 (define_insn "*<rotate_insn>qi3_1_slp"
10607   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10608         (any_rotate:QI (match_dup 0)
10609                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10610    (clobber (reg:CC FLAGS_REG))]
10611   "(optimize_function_for_size_p (cfun)
10612     || !TARGET_PARTIAL_REG_STALL
10613     || (operands[1] == const1_rtx
10614         && TARGET_SHIFT1))"
10616   if (operands[1] == const1_rtx
10617       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618     return "<rotate>{b}\t%0";
10619   else
10620     return "<rotate>{b}\t{%1, %0|%0, %1}";
10622   [(set_attr "type" "rotate1")
10623    (set (attr "length_immediate")
10624      (if_then_else
10625        (and (match_operand 1 "const1_operand")
10626             (ior (match_test "TARGET_SHIFT1")
10627                  (match_test "optimize_function_for_size_p (cfun)")))
10628        (const_string "0")
10629        (const_string "*")))
10630    (set_attr "mode" "QI")])
10632 (define_split
10633  [(set (match_operand:HI 0 "register_operand")
10634        (any_rotate:HI (match_dup 0) (const_int 8)))
10635   (clobber (reg:CC FLAGS_REG))]
10636  "reload_completed
10637   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10638  [(parallel [(set (strict_low_part (match_dup 0))
10639                   (bswap:HI (match_dup 0)))
10640              (clobber (reg:CC FLAGS_REG))])])
10642 ;; Bit set / bit test instructions
10644 ;; %%% bts, btr, btc, bt.
10645 ;; In general these instructions are *slow* when applied to memory,
10646 ;; since they enforce atomic operation.  When applied to registers,
10647 ;; it depends on the cpu implementation.  They're never faster than
10648 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10649 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10650 ;; within the instruction itself, so operating on bits in the high
10651 ;; 32-bits of a register becomes easier.
10653 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10654 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10655 ;; negdf respectively, so they can never be disabled entirely.
10657 (define_insn "*btsq"
10658   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10659                          (const_int 1)
10660                          (match_operand 1 "const_0_to_63_operand" "J"))
10661         (const_int 1))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10664   "bts{q}\t{%1, %0|%0, %1}"
10665   [(set_attr "type" "alu1")
10666    (set_attr "prefix_0f" "1")
10667    (set_attr "mode" "DI")])
10669 (define_insn "*btrq"
10670   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10671                          (const_int 1)
10672                          (match_operand 1 "const_0_to_63_operand" "J"))
10673         (const_int 0))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10676   "btr{q}\t{%1, %0|%0, %1}"
10677   [(set_attr "type" "alu1")
10678    (set_attr "prefix_0f" "1")
10679    (set_attr "mode" "DI")])
10681 (define_insn "*btcq"
10682   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10683                          (const_int 1)
10684                          (match_operand 1 "const_0_to_63_operand" "J"))
10685         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10686    (clobber (reg:CC FLAGS_REG))]
10687   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10688   "btc{q}\t{%1, %0|%0, %1}"
10689   [(set_attr "type" "alu1")
10690    (set_attr "prefix_0f" "1")
10691    (set_attr "mode" "DI")])
10693 ;; Allow Nocona to avoid these instructions if a register is available.
10695 (define_peephole2
10696   [(match_scratch:DI 2 "r")
10697    (parallel [(set (zero_extract:DI
10698                      (match_operand:DI 0 "register_operand")
10699                      (const_int 1)
10700                      (match_operand 1 "const_0_to_63_operand"))
10701                    (const_int 1))
10702               (clobber (reg:CC FLAGS_REG))])]
10703   "TARGET_64BIT && !TARGET_USE_BT"
10704   [(const_int 0)]
10706   int i = INTVAL (operands[1]);
10708   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10710   if (i >= 31)
10711     {
10712       emit_move_insn (operands[2], op1);
10713       op1 = operands[2];
10714     }
10716   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10717   DONE;
10720 (define_peephole2
10721   [(match_scratch:DI 2 "r")
10722    (parallel [(set (zero_extract:DI
10723                      (match_operand:DI 0 "register_operand")
10724                      (const_int 1)
10725                      (match_operand 1 "const_0_to_63_operand"))
10726                    (const_int 0))
10727               (clobber (reg:CC FLAGS_REG))])]
10728   "TARGET_64BIT && !TARGET_USE_BT"
10729   [(const_int 0)]
10731   int i = INTVAL (operands[1]);
10733   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10735   if (i >= 32)
10736     {
10737       emit_move_insn (operands[2], op1);
10738       op1 = operands[2];
10739     }
10741   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10742   DONE;
10745 (define_peephole2
10746   [(match_scratch:DI 2 "r")
10747    (parallel [(set (zero_extract:DI
10748                      (match_operand:DI 0 "register_operand")
10749                      (const_int 1)
10750                      (match_operand 1 "const_0_to_63_operand"))
10751               (not:DI (zero_extract:DI
10752                         (match_dup 0) (const_int 1) (match_dup 1))))
10753               (clobber (reg:CC FLAGS_REG))])]
10754   "TARGET_64BIT && !TARGET_USE_BT"
10755   [(const_int 0)]
10757   int i = INTVAL (operands[1]);
10759   rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
10761   if (i >= 31)
10762     {
10763       emit_move_insn (operands[2], op1);
10764       op1 = operands[2];
10765     }
10767   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10768   DONE;
10771 (define_insn "*bt<mode>"
10772   [(set (reg:CCC FLAGS_REG)
10773         (compare:CCC
10774           (zero_extract:SWI48
10775             (match_operand:SWI48 0 "register_operand" "r")
10776             (const_int 1)
10777             (match_operand:SI 1 "nonmemory_operand" "rN"))
10778           (const_int 0)))]
10779   ""
10781   switch (get_attr_mode (insn))
10782     {
10783     case MODE_SI:
10784       return "bt{l}\t{%1, %k0|%k0, %1}";
10786     case MODE_DI:
10787       return "bt{q}\t{%q1, %0|%0, %q1}";
10789     default:
10790       gcc_unreachable ();
10791     }
10793   [(set_attr "type" "alu1")
10794    (set_attr "prefix_0f" "1")
10795    (set (attr "mode")
10796         (if_then_else
10797           (and (match_test "CONST_INT_P (operands[1])")
10798                (match_test "INTVAL (operands[1]) < 32"))
10799           (const_string "SI")
10800           (const_string "<MODE>")))])
10802 (define_insn_and_split "*jcc_bt<mode>"
10803   [(set (pc)
10804         (if_then_else (match_operator 0 "bt_comparison_operator"
10805                         [(zero_extract:SWI48
10806                            (match_operand:SWI48 1 "register_operand")
10807                            (const_int 1)
10808                            (match_operand:SI 2 "nonmemory_operand"))
10809                          (const_int 0)])
10810                       (label_ref (match_operand 3))
10811                       (pc)))
10812    (clobber (reg:CC FLAGS_REG))]
10813   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10814    && (CONST_INT_P (operands[2])
10815        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
10816           && INTVAL (operands[2])
10817                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
10818        : register_operand (operands[2], SImode))
10819    && can_create_pseudo_p ()"
10820   "#"
10821   "&& 1"
10822   [(set (reg:CCC FLAGS_REG)
10823         (compare:CCC
10824           (zero_extract:SWI48
10825             (match_dup 1)
10826             (const_int 1)
10827             (match_dup 2))
10828           (const_int 0)))
10829    (set (pc)
10830         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10831                       (label_ref (match_dup 3))
10832                       (pc)))]
10834   operands[0] = shallow_copy_rtx (operands[0]);
10835   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10838 (define_insn_and_split "*jcc_bt<mode>_1"
10839   [(set (pc)
10840         (if_then_else (match_operator 0 "bt_comparison_operator"
10841                         [(zero_extract:SWI48
10842                            (match_operand:SWI48 1 "register_operand")
10843                            (const_int 1)
10844                            (zero_extend:SI
10845                              (match_operand:QI 2 "register_operand")))
10846                          (const_int 0)])
10847                       (label_ref (match_operand 3))
10848                       (pc)))
10849    (clobber (reg:CC FLAGS_REG))]
10850   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10851    && can_create_pseudo_p ()"
10852   "#"
10853   "&& 1"
10854   [(set (reg:CCC FLAGS_REG)
10855         (compare:CCC
10856           (zero_extract:SWI48
10857             (match_dup 1)
10858             (const_int 1)
10859             (match_dup 2))
10860           (const_int 0)))
10861    (set (pc)
10862         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10863                       (label_ref (match_dup 3))
10864                       (pc)))]
10866   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10867   operands[0] = shallow_copy_rtx (operands[0]);
10868   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10871 ;; Avoid useless masking of bit offset operand.
10872 (define_insn_and_split "*jcc_bt<mode>_mask"
10873   [(set (pc)
10874         (if_then_else (match_operator 0 "bt_comparison_operator"
10875                         [(zero_extract:SWI48
10876                            (match_operand:SWI48 1 "register_operand")
10877                            (const_int 1)
10878                            (and:SI
10879                              (match_operand:SI 2 "register_operand")
10880                              (match_operand 3 "const_int_operand")))])
10881                       (label_ref (match_operand 4))
10882                       (pc)))
10883    (clobber (reg:CC FLAGS_REG))]
10884   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10885    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10886       == GET_MODE_BITSIZE (<MODE>mode)-1
10887    && can_create_pseudo_p ()"
10888   "#"
10889   "&& 1"
10890   [(set (reg:CCC FLAGS_REG)
10891         (compare:CCC
10892           (zero_extract:SWI48
10893             (match_dup 1)
10894             (const_int 1)
10895             (match_dup 2))
10896           (const_int 0)))
10897    (set (pc)
10898         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10899                       (label_ref (match_dup 4))
10900                       (pc)))]
10902   operands[0] = shallow_copy_rtx (operands[0]);
10903   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10906 ;; Store-flag instructions.
10908 ;; For all sCOND expanders, also expand the compare or test insn that
10909 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10911 (define_insn_and_split "*setcc_di_1"
10912   [(set (match_operand:DI 0 "register_operand" "=q")
10913         (match_operator:DI 1 "ix86_comparison_operator"
10914           [(reg FLAGS_REG) (const_int 0)]))]
10915   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10916   "#"
10917   "&& reload_completed"
10918   [(set (match_dup 2) (match_dup 1))
10919    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10921   operands[1] = shallow_copy_rtx (operands[1]);
10922   PUT_MODE (operands[1], QImode);
10923   operands[2] = gen_lowpart (QImode, operands[0]);
10926 (define_insn_and_split "*setcc_si_1_and"
10927   [(set (match_operand:SI 0 "register_operand" "=q")
10928         (match_operator:SI 1 "ix86_comparison_operator"
10929           [(reg FLAGS_REG) (const_int 0)]))
10930    (clobber (reg:CC FLAGS_REG))]
10931   "!TARGET_PARTIAL_REG_STALL
10932    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10933   "#"
10934   "&& reload_completed"
10935   [(set (match_dup 2) (match_dup 1))
10936    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10937               (clobber (reg:CC FLAGS_REG))])]
10939   operands[1] = shallow_copy_rtx (operands[1]);
10940   PUT_MODE (operands[1], QImode);
10941   operands[2] = gen_lowpart (QImode, operands[0]);
10944 (define_insn_and_split "*setcc_si_1_movzbl"
10945   [(set (match_operand:SI 0 "register_operand" "=q")
10946         (match_operator:SI 1 "ix86_comparison_operator"
10947           [(reg FLAGS_REG) (const_int 0)]))]
10948   "!TARGET_PARTIAL_REG_STALL
10949    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10950   "#"
10951   "&& reload_completed"
10952   [(set (match_dup 2) (match_dup 1))
10953    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10955   operands[1] = shallow_copy_rtx (operands[1]);
10956   PUT_MODE (operands[1], QImode);
10957   operands[2] = gen_lowpart (QImode, operands[0]);
10960 (define_insn "*setcc_qi"
10961   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10962         (match_operator:QI 1 "ix86_comparison_operator"
10963           [(reg FLAGS_REG) (const_int 0)]))]
10964   ""
10965   "set%C1\t%0"
10966   [(set_attr "type" "setcc")
10967    (set_attr "mode" "QI")])
10969 (define_insn "*setcc_qi_slp"
10970   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10971         (match_operator:QI 1 "ix86_comparison_operator"
10972           [(reg FLAGS_REG) (const_int 0)]))]
10973   ""
10974   "set%C1\t%0"
10975   [(set_attr "type" "setcc")
10976    (set_attr "mode" "QI")])
10978 ;; In general it is not safe to assume too much about CCmode registers,
10979 ;; so simplify-rtx stops when it sees a second one.  Under certain
10980 ;; conditions this is safe on x86, so help combine not create
10982 ;;      seta    %al
10983 ;;      testb   %al, %al
10984 ;;      sete    %al
10986 (define_split
10987   [(set (match_operand:QI 0 "nonimmediate_operand")
10988         (ne:QI (match_operator 1 "ix86_comparison_operator"
10989                  [(reg FLAGS_REG) (const_int 0)])
10990             (const_int 0)))]
10991   ""
10992   [(set (match_dup 0) (match_dup 1))]
10994   operands[1] = shallow_copy_rtx (operands[1]);
10995   PUT_MODE (operands[1], QImode);
10998 (define_split
10999   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11000         (ne:QI (match_operator 1 "ix86_comparison_operator"
11001                  [(reg FLAGS_REG) (const_int 0)])
11002             (const_int 0)))]
11003   ""
11004   [(set (match_dup 0) (match_dup 1))]
11006   operands[1] = shallow_copy_rtx (operands[1]);
11007   PUT_MODE (operands[1], QImode);
11010 (define_split
11011   [(set (match_operand:QI 0 "nonimmediate_operand")
11012         (eq:QI (match_operator 1 "ix86_comparison_operator"
11013                  [(reg FLAGS_REG) (const_int 0)])
11014             (const_int 0)))]
11015   ""
11016   [(set (match_dup 0) (match_dup 1))]
11018   operands[1] = shallow_copy_rtx (operands[1]);
11019   PUT_MODE (operands[1], QImode);
11020   PUT_CODE (operands[1],
11021             ix86_reverse_condition (GET_CODE (operands[1]),
11022                                     GET_MODE (XEXP (operands[1], 0))));
11024   /* Make sure that (a) the CCmode we have for the flags is strong
11025      enough for the reversed compare or (b) we have a valid FP compare.  */
11026   if (! ix86_comparison_operator (operands[1], VOIDmode))
11027     FAIL;
11030 (define_split
11031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11032         (eq:QI (match_operator 1 "ix86_comparison_operator"
11033                  [(reg FLAGS_REG) (const_int 0)])
11034             (const_int 0)))]
11035   ""
11036   [(set (match_dup 0) (match_dup 1))]
11038   operands[1] = shallow_copy_rtx (operands[1]);
11039   PUT_MODE (operands[1], QImode);
11040   PUT_CODE (operands[1],
11041             ix86_reverse_condition (GET_CODE (operands[1]),
11042                                     GET_MODE (XEXP (operands[1], 0))));
11044   /* Make sure that (a) the CCmode we have for the flags is strong
11045      enough for the reversed compare or (b) we have a valid FP compare.  */
11046   if (! ix86_comparison_operator (operands[1], VOIDmode))
11047     FAIL;
11050 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11051 ;; subsequent logical operations are used to imitate conditional moves.
11052 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11053 ;; it directly.
11055 (define_insn "setcc_<mode>_sse"
11056   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11057         (match_operator:MODEF 3 "sse_comparison_operator"
11058           [(match_operand:MODEF 1 "register_operand" "0,x")
11059            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11060   "SSE_FLOAT_MODE_P (<MODE>mode)"
11061   "@
11062    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11063    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11064   [(set_attr "isa" "noavx,avx")
11065    (set_attr "type" "ssecmp")
11066    (set_attr "length_immediate" "1")
11067    (set_attr "prefix" "orig,vex")
11068    (set_attr "mode" "<MODE>")])
11070 ;; Basic conditional jump instructions.
11071 ;; We ignore the overflow flag for signed branch instructions.
11073 (define_insn "*jcc_1"
11074   [(set (pc)
11075         (if_then_else (match_operator 1 "ix86_comparison_operator"
11076                                       [(reg FLAGS_REG) (const_int 0)])
11077                       (label_ref (match_operand 0))
11078                       (pc)))]
11079   ""
11080   "%!%+j%C1\t%l0"
11081   [(set_attr "type" "ibr")
11082    (set_attr "modrm" "0")
11083    (set (attr "length_nobnd")
11084         (if_then_else
11085           (and (ge (minus (match_dup 0) (pc))
11086                    (const_int -126))
11087                (lt (minus (match_dup 0) (pc))
11088                    (const_int 128)))
11089           (const_int 2)
11090           (const_int 6)))])
11092 (define_insn "*jcc_2"
11093   [(set (pc)
11094         (if_then_else (match_operator 1 "ix86_comparison_operator"
11095                                       [(reg FLAGS_REG) (const_int 0)])
11096                       (pc)
11097                       (label_ref (match_operand 0))))]
11098   ""
11099   "%!%+j%c1\t%l0"
11100   [(set_attr "type" "ibr")
11101    (set_attr "modrm" "0")
11102    (set (attr "length_nobnd")
11103         (if_then_else
11104           (and (ge (minus (match_dup 0) (pc))
11105                    (const_int -126))
11106                (lt (minus (match_dup 0) (pc))
11107                    (const_int 128)))
11108           (const_int 2)
11109           (const_int 6)))])
11111 ;; In general it is not safe to assume too much about CCmode registers,
11112 ;; so simplify-rtx stops when it sees a second one.  Under certain
11113 ;; conditions this is safe on x86, so help combine not create
11115 ;;      seta    %al
11116 ;;      testb   %al, %al
11117 ;;      je      Lfoo
11119 (define_split
11120   [(set (pc)
11121         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11122                                       [(reg FLAGS_REG) (const_int 0)])
11123                           (const_int 0))
11124                       (label_ref (match_operand 1))
11125                       (pc)))]
11126   ""
11127   [(set (pc)
11128         (if_then_else (match_dup 0)
11129                       (label_ref (match_dup 1))
11130                       (pc)))]
11132   operands[0] = shallow_copy_rtx (operands[0]);
11133   PUT_MODE (operands[0], VOIDmode);
11136 (define_split
11137   [(set (pc)
11138         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11139                                       [(reg FLAGS_REG) (const_int 0)])
11140                           (const_int 0))
11141                       (label_ref (match_operand 1))
11142                       (pc)))]
11143   ""
11144   [(set (pc)
11145         (if_then_else (match_dup 0)
11146                       (label_ref (match_dup 1))
11147                       (pc)))]
11149   operands[0] = shallow_copy_rtx (operands[0]);
11150   PUT_MODE (operands[0], VOIDmode);
11151   PUT_CODE (operands[0],
11152             ix86_reverse_condition (GET_CODE (operands[0]),
11153                                     GET_MODE (XEXP (operands[0], 0))));
11155   /* Make sure that (a) the CCmode we have for the flags is strong
11156      enough for the reversed compare or (b) we have a valid FP compare.  */
11157   if (! ix86_comparison_operator (operands[0], VOIDmode))
11158     FAIL;
11161 ;; Define combination compare-and-branch fp compare instructions to help
11162 ;; combine.
11164 (define_insn "*jcc<mode>_0_i387"
11165   [(set (pc)
11166         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11167                         [(match_operand:X87MODEF 1 "register_operand" "f")
11168                          (match_operand:X87MODEF 2 "const0_operand")])
11169           (label_ref (match_operand 3))
11170           (pc)))
11171    (clobber (reg:CCFP FPSR_REG))
11172    (clobber (reg:CCFP FLAGS_REG))
11173    (clobber (match_scratch:HI 4 "=a"))]
11174   "TARGET_80387 && !TARGET_CMOVE"
11175   "#")
11177 (define_insn "*jcc<mode>_0_r_i387"
11178   [(set (pc)
11179         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11180                         [(match_operand:X87MODEF 1 "register_operand" "f")
11181                          (match_operand:X87MODEF 2 "const0_operand")])
11182           (pc)
11183           (label_ref (match_operand 3))))
11184    (clobber (reg:CCFP FPSR_REG))
11185    (clobber (reg:CCFP FLAGS_REG))
11186    (clobber (match_scratch:HI 4 "=a"))]
11187   "TARGET_80387 && !TARGET_CMOVE"
11188   "#")
11190 (define_insn "*jccxf_i387"
11191   [(set (pc)
11192         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11193                         [(match_operand:XF 1 "register_operand" "f")
11194                          (match_operand:XF 2 "register_operand" "f")])
11195           (label_ref (match_operand 3))
11196           (pc)))
11197    (clobber (reg:CCFP FPSR_REG))
11198    (clobber (reg:CCFP FLAGS_REG))
11199    (clobber (match_scratch:HI 4 "=a"))]
11200   "TARGET_80387 && !TARGET_CMOVE"
11201   "#")
11203 (define_insn "*jccxf_r_i387"
11204   [(set (pc)
11205         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11206                         [(match_operand:XF 1 "register_operand" "f")
11207                          (match_operand:XF 2 "register_operand" "f")])
11208           (pc)
11209           (label_ref (match_operand 3))))
11210    (clobber (reg:CCFP FPSR_REG))
11211    (clobber (reg:CCFP FLAGS_REG))
11212    (clobber (match_scratch:HI 4 "=a"))]
11213   "TARGET_80387 && !TARGET_CMOVE"
11214   "#")
11216 (define_insn "*jcc<mode>_i387"
11217   [(set (pc)
11218         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11219                         [(match_operand:MODEF 1 "register_operand" "f")
11220                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11221           (label_ref (match_operand 3))
11222           (pc)))
11223    (clobber (reg:CCFP FPSR_REG))
11224    (clobber (reg:CCFP FLAGS_REG))
11225    (clobber (match_scratch:HI 4 "=a"))]
11226   "TARGET_80387 && !TARGET_CMOVE"
11227   "#")
11229 (define_insn "*jcc<mode>_r_i387"
11230   [(set (pc)
11231         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11232                         [(match_operand:MODEF 1 "register_operand" "f")
11233                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11234           (pc)
11235           (label_ref (match_operand 3))))
11236    (clobber (reg:CCFP FPSR_REG))
11237    (clobber (reg:CCFP FLAGS_REG))
11238    (clobber (match_scratch:HI 4 "=a"))]
11239   "TARGET_80387 && !TARGET_CMOVE"
11240   "#")
11242 (define_insn "*jccu<mode>_i387"
11243   [(set (pc)
11244         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11245                         [(match_operand:X87MODEF 1 "register_operand" "f")
11246                          (match_operand:X87MODEF 2 "register_operand" "f")])
11247           (label_ref (match_operand 3))
11248           (pc)))
11249    (clobber (reg:CCFP FPSR_REG))
11250    (clobber (reg:CCFP FLAGS_REG))
11251    (clobber (match_scratch:HI 4 "=a"))]
11252   "TARGET_80387 && !TARGET_CMOVE"
11253   "#")
11255 (define_insn "*jccu<mode>_r_i387"
11256   [(set (pc)
11257         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11258                         [(match_operand:X87MODEF 1 "register_operand" "f")
11259                          (match_operand:X87MODEF 2 "register_operand" "f")])
11260           (pc)
11261           (label_ref (match_operand 3))))
11262    (clobber (reg:CCFP FPSR_REG))
11263    (clobber (reg:CCFP FLAGS_REG))
11264    (clobber (match_scratch:HI 4 "=a"))]
11265   "TARGET_80387 && !TARGET_CMOVE"
11266   "#")
11268 (define_split
11269   [(set (pc)
11270         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11271                         [(match_operand:X87MODEF 1 "register_operand")
11272                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11273           (match_operand 3)
11274           (match_operand 4)))
11275    (clobber (reg:CCFP FPSR_REG))
11276    (clobber (reg:CCFP FLAGS_REG))]
11277   "TARGET_80387 && !TARGET_CMOVE
11278    && reload_completed"
11279   [(const_int 0)]
11281   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11282                         operands[3], operands[4], NULL_RTX);
11283   DONE;
11286 (define_split
11287   [(set (pc)
11288         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11289                         [(match_operand:X87MODEF 1 "register_operand")
11290                          (match_operand:X87MODEF 2 "general_operand")])
11291           (match_operand 3)
11292           (match_operand 4)))
11293    (clobber (reg:CCFP FPSR_REG))
11294    (clobber (reg:CCFP FLAGS_REG))
11295    (clobber (match_scratch:HI 5))]
11296   "TARGET_80387 && !TARGET_CMOVE
11297    && reload_completed"
11298   [(const_int 0)]
11300   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11301                         operands[3], operands[4], operands[5]);
11302   DONE;
11305 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11306 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11307 ;; with a precedence over other operators and is always put in the first
11308 ;; place. Swap condition and operands to match ficom instruction.
11310 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11311   [(set (pc)
11312         (if_then_else
11313           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11314             [(match_operator:X87MODEF 1 "float_operator"
11315               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11316              (match_operand:X87MODEF 3 "register_operand" "f")])
11317           (label_ref (match_operand 4))
11318           (pc)))
11319    (clobber (reg:CCFP FPSR_REG))
11320    (clobber (reg:CCFP FLAGS_REG))
11321    (clobber (match_scratch:HI 5 "=a"))]
11322   "TARGET_80387 && !TARGET_CMOVE
11323    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11324        || optimize_function_for_size_p (cfun))"
11325   "#")
11327 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11328   [(set (pc)
11329         (if_then_else
11330           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11331             [(match_operator:X87MODEF 1 "float_operator"
11332               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11333              (match_operand:X87MODEF 3 "register_operand" "f")])
11334           (pc)
11335           (label_ref (match_operand 4))))
11336    (clobber (reg:CCFP FPSR_REG))
11337    (clobber (reg:CCFP FLAGS_REG))
11338    (clobber (match_scratch:HI 5 "=a"))]
11339   "TARGET_80387 && !TARGET_CMOVE
11340    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11341        || optimize_function_for_size_p (cfun))"
11342   "#")
11344 (define_split
11345   [(set (pc)
11346         (if_then_else
11347           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11348             [(match_operator:X87MODEF 1 "float_operator"
11349               [(match_operand:SWI24 2 "memory_operand")])
11350              (match_operand:X87MODEF 3 "register_operand")])
11351           (match_operand 4)
11352           (match_operand 5)))
11353    (clobber (reg:CCFP FPSR_REG))
11354    (clobber (reg:CCFP FLAGS_REG))
11355    (clobber (match_scratch:HI 6))]
11356   "TARGET_80387 && !TARGET_CMOVE
11357    && reload_completed"
11358   [(const_int 0)]
11360   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11361                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11362                         operands[4], operands[5], operands[6]);
11363   DONE;
11366 ;; Unconditional and other jump instructions
11368 (define_insn "jump"
11369   [(set (pc)
11370         (label_ref (match_operand 0)))]
11371   ""
11372   "%!jmp\t%l0"
11373   [(set_attr "type" "ibr")
11374    (set_attr "modrm" "0")
11375    (set (attr "length_nobnd")
11376         (if_then_else
11377           (and (ge (minus (match_dup 0) (pc))
11378                    (const_int -126))
11379                (lt (minus (match_dup 0) (pc))
11380                    (const_int 128)))
11381           (const_int 2)
11382           (const_int 5)))])
11384 (define_expand "indirect_jump"
11385   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11386   ""
11388   if (TARGET_X32)
11389     operands[0] = convert_memory_address (word_mode, operands[0]);
11392 (define_insn "*indirect_jump"
11393   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11394   ""
11395   "%!jmp\t%A0"
11396   [(set_attr "type" "ibr")
11397    (set_attr "length_immediate" "0")])
11399 (define_expand "tablejump"
11400   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11401               (use (label_ref (match_operand 1)))])]
11402   ""
11404   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11405      relative.  Convert the relative address to an absolute address.  */
11406   if (flag_pic)
11407     {
11408       rtx op0, op1;
11409       enum rtx_code code;
11411       /* We can't use @GOTOFF for text labels on VxWorks;
11412          see gotoff_operand.  */
11413       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11414         {
11415           code = PLUS;
11416           op0 = operands[0];
11417           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11418         }
11419       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11420         {
11421           code = PLUS;
11422           op0 = operands[0];
11423           op1 = pic_offset_table_rtx;
11424         }
11425       else
11426         {
11427           code = MINUS;
11428           op0 = pic_offset_table_rtx;
11429           op1 = operands[0];
11430         }
11432       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11433                                          OPTAB_DIRECT);
11434     }
11436   if (TARGET_X32)
11437     operands[0] = convert_memory_address (word_mode, operands[0]);
11440 (define_insn "*tablejump_1"
11441   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11442    (use (label_ref (match_operand 1)))]
11443   ""
11444   "%!jmp\t%A0"
11445   [(set_attr "type" "ibr")
11446    (set_attr "length_immediate" "0")])
11448 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11450 (define_peephole2
11451   [(set (reg FLAGS_REG) (match_operand 0))
11452    (set (match_operand:QI 1 "register_operand")
11453         (match_operator:QI 2 "ix86_comparison_operator"
11454           [(reg FLAGS_REG) (const_int 0)]))
11455    (set (match_operand 3 "any_QIreg_operand")
11456         (zero_extend (match_dup 1)))]
11457   "(peep2_reg_dead_p (3, operands[1])
11458     || operands_match_p (operands[1], operands[3]))
11459    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11460   [(set (match_dup 4) (match_dup 0))
11461    (set (strict_low_part (match_dup 5))
11462         (match_dup 2))]
11464   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11465   operands[5] = gen_lowpart (QImode, operands[3]);
11466   ix86_expand_clear (operands[3]);
11469 (define_peephole2
11470   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11471               (match_operand 4)])
11472    (set (match_operand:QI 1 "register_operand")
11473         (match_operator:QI 2 "ix86_comparison_operator"
11474           [(reg FLAGS_REG) (const_int 0)]))
11475    (set (match_operand 3 "any_QIreg_operand")
11476         (zero_extend (match_dup 1)))]
11477   "(peep2_reg_dead_p (3, operands[1])
11478     || operands_match_p (operands[1], operands[3]))
11479    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11480    && ! (GET_CODE (operands[4]) == CLOBBER
11481          && reg_mentioned_p (operands[3], operands[4]))"
11482   [(parallel [(set (match_dup 5) (match_dup 0))
11483               (match_dup 4)])
11484    (set (strict_low_part (match_dup 6))
11485         (match_dup 2))]
11487   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11488   operands[6] = gen_lowpart (QImode, operands[3]);
11489   ix86_expand_clear (operands[3]);
11492 ;; Similar, but match zero extend with andsi3.
11494 (define_peephole2
11495   [(set (reg FLAGS_REG) (match_operand 0))
11496    (set (match_operand:QI 1 "register_operand")
11497         (match_operator:QI 2 "ix86_comparison_operator"
11498           [(reg FLAGS_REG) (const_int 0)]))
11499    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11500                    (and:SI (match_dup 3) (const_int 255)))
11501               (clobber (reg:CC FLAGS_REG))])]
11502   "REGNO (operands[1]) == REGNO (operands[3])
11503    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11504   [(set (match_dup 4) (match_dup 0))
11505    (set (strict_low_part (match_dup 5))
11506         (match_dup 2))]
11508   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11509   operands[5] = gen_lowpart (QImode, operands[3]);
11510   ix86_expand_clear (operands[3]);
11513 (define_peephole2
11514   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11515               (match_operand 4)])
11516    (set (match_operand:QI 1 "register_operand")
11517         (match_operator:QI 2 "ix86_comparison_operator"
11518           [(reg FLAGS_REG) (const_int 0)]))
11519    (parallel [(set (match_operand 3 "any_QIreg_operand")
11520                    (zero_extend (match_dup 1)))
11521               (clobber (reg:CC FLAGS_REG))])]
11522   "(peep2_reg_dead_p (3, operands[1])
11523     || operands_match_p (operands[1], operands[3]))
11524    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11525    && ! (GET_CODE (operands[4]) == CLOBBER
11526          && reg_mentioned_p (operands[3], operands[4]))"
11527   [(parallel [(set (match_dup 5) (match_dup 0))
11528               (match_dup 4)])
11529    (set (strict_low_part (match_dup 6))
11530         (match_dup 2))]
11532   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11533   operands[6] = gen_lowpart (QImode, operands[3]);
11534   ix86_expand_clear (operands[3]);
11537 ;; Call instructions.
11539 ;; The predicates normally associated with named expanders are not properly
11540 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11541 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11543 ;; P6 processors will jump to the address after the decrement when %esp
11544 ;; is used as a call operand, so they will execute return address as a code.
11545 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11547 ;; Register constraint for call instruction.
11548 (define_mode_attr c [(SI "l") (DI "r")])
11550 ;; Call subroutine returning no value.
11552 (define_expand "call"
11553   [(call (match_operand:QI 0)
11554          (match_operand 1))
11555    (use (match_operand 2))]
11556   ""
11558   ix86_expand_call (NULL, operands[0], operands[1],
11559                     operands[2], NULL, false);
11560   DONE;
11563 (define_expand "sibcall"
11564   [(call (match_operand:QI 0)
11565          (match_operand 1))
11566    (use (match_operand 2))]
11567   ""
11569   ix86_expand_call (NULL, operands[0], operands[1],
11570                     operands[2], NULL, true);
11571   DONE;
11574 (define_insn "*call"
11575   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11576          (match_operand 1))]
11577   "!SIBLING_CALL_P (insn)"
11578   "* return ix86_output_call_insn (insn, operands[0]);"
11579   [(set_attr "type" "call")])
11581 ;; This covers both call and sibcall since only GOT slot is allowed.
11582 (define_insn "*call_got_x32"
11583   [(call (mem:QI (zero_extend:DI
11584                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11585          (match_operand 1))]
11586   "TARGET_X32"
11587   "* return ix86_output_call_insn (insn, operands[0]);"
11588   [(set_attr "type" "call")])
11590 (define_insn "*sibcall"
11591   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11592          (match_operand 1))]
11593   "SIBLING_CALL_P (insn)"
11594   "* return ix86_output_call_insn (insn, operands[0]);"
11595   [(set_attr "type" "call")])
11597 (define_insn "*sibcall_memory"
11598   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11599          (match_operand 1))
11600    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11601   "!TARGET_X32"
11602   "* return ix86_output_call_insn (insn, operands[0]);"
11603   [(set_attr "type" "call")])
11605 (define_peephole2
11606   [(set (match_operand:W 0 "register_operand")
11607         (match_operand:W 1 "memory_operand"))
11608    (call (mem:QI (match_dup 0))
11609          (match_operand 3))]
11610   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11611    && !reg_mentioned_p (operands[0],
11612                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11613   [(parallel [(call (mem:QI (match_dup 1))
11614                     (match_dup 3))
11615               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11617 (define_peephole2
11618   [(set (match_operand:W 0 "register_operand")
11619         (match_operand:W 1 "memory_operand"))
11620    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11621    (call (mem:QI (match_dup 0))
11622          (match_operand 3))]
11623   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11624    && !reg_mentioned_p (operands[0],
11625                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11626   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11627    (parallel [(call (mem:QI (match_dup 1))
11628                     (match_dup 3))
11629               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11631 (define_expand "call_pop"
11632   [(parallel [(call (match_operand:QI 0)
11633                     (match_operand:SI 1))
11634               (set (reg:SI SP_REG)
11635                    (plus:SI (reg:SI SP_REG)
11636                             (match_operand:SI 3)))])]
11637   "!TARGET_64BIT"
11639   ix86_expand_call (NULL, operands[0], operands[1],
11640                     operands[2], operands[3], false);
11641   DONE;
11644 (define_insn "*call_pop"
11645   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11646          (match_operand 1))
11647    (set (reg:SI SP_REG)
11648         (plus:SI (reg:SI SP_REG)
11649                  (match_operand:SI 2 "immediate_operand" "i")))]
11650   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11651   "* return ix86_output_call_insn (insn, operands[0]);"
11652   [(set_attr "type" "call")])
11654 (define_insn "*sibcall_pop"
11655   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11656          (match_operand 1))
11657    (set (reg:SI SP_REG)
11658         (plus:SI (reg:SI SP_REG)
11659                  (match_operand:SI 2 "immediate_operand" "i")))]
11660   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11661   "* return ix86_output_call_insn (insn, operands[0]);"
11662   [(set_attr "type" "call")])
11664 (define_insn "*sibcall_pop_memory"
11665   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11666          (match_operand 1))
11667    (set (reg:SI SP_REG)
11668         (plus:SI (reg:SI SP_REG)
11669                  (match_operand:SI 2 "immediate_operand" "i")))
11670    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11671   "!TARGET_64BIT"
11672   "* return ix86_output_call_insn (insn, operands[0]);"
11673   [(set_attr "type" "call")])
11675 (define_peephole2
11676   [(set (match_operand:SI 0 "register_operand")
11677         (match_operand:SI 1 "memory_operand"))
11678    (parallel [(call (mem:QI (match_dup 0))
11679                     (match_operand 3))
11680               (set (reg:SI SP_REG)
11681                    (plus:SI (reg:SI SP_REG)
11682                             (match_operand:SI 4 "immediate_operand")))])]
11683   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11684    && !reg_mentioned_p (operands[0],
11685                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11686   [(parallel [(call (mem:QI (match_dup 1))
11687                     (match_dup 3))
11688               (set (reg:SI SP_REG)
11689                    (plus:SI (reg:SI SP_REG)
11690                             (match_dup 4)))
11691               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11693 (define_peephole2
11694   [(set (match_operand:SI 0 "register_operand")
11695         (match_operand:SI 1 "memory_operand"))
11696    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11697    (parallel [(call (mem:QI (match_dup 0))
11698                     (match_operand 3))
11699               (set (reg:SI SP_REG)
11700                    (plus:SI (reg:SI SP_REG)
11701                             (match_operand:SI 4 "immediate_operand")))])]
11702   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11703    && !reg_mentioned_p (operands[0],
11704                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11705   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11706    (parallel [(call (mem:QI (match_dup 1))
11707                     (match_dup 3))
11708               (set (reg:SI SP_REG)
11709                    (plus:SI (reg:SI SP_REG)
11710                             (match_dup 4)))
11711               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11713 ;; Combining simple memory jump instruction
11715 (define_peephole2
11716   [(set (match_operand:W 0 "register_operand")
11717         (match_operand:W 1 "memory_operand"))
11718    (set (pc) (match_dup 0))]
11719   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11720   [(set (pc) (match_dup 1))])
11722 ;; Call subroutine, returning value in operand 0
11724 (define_expand "call_value"
11725   [(set (match_operand 0)
11726         (call (match_operand:QI 1)
11727               (match_operand 2)))
11728    (use (match_operand 3))]
11729   ""
11731   ix86_expand_call (operands[0], operands[1], operands[2],
11732                     operands[3], NULL, false);
11733   DONE;
11736 (define_expand "sibcall_value"
11737   [(set (match_operand 0)
11738         (call (match_operand:QI 1)
11739               (match_operand 2)))
11740    (use (match_operand 3))]
11741   ""
11743   ix86_expand_call (operands[0], operands[1], operands[2],
11744                     operands[3], NULL, true);
11745   DONE;
11748 (define_insn "*call_value"
11749   [(set (match_operand 0)
11750         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11751               (match_operand 2)))]
11752   "!SIBLING_CALL_P (insn)"
11753   "* return ix86_output_call_insn (insn, operands[1]);"
11754   [(set_attr "type" "callv")])
11756 ;; This covers both call and sibcall since only GOT slot is allowed.
11757 (define_insn "*call_value_got_x32"
11758   [(set (match_operand 0)
11759         (call (mem:QI
11760                 (zero_extend:DI
11761                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
11762               (match_operand 2)))]
11763   "TARGET_X32"
11764   "* return ix86_output_call_insn (insn, operands[1]);"
11765   [(set_attr "type" "callv")])
11767 (define_insn "*sibcall_value"
11768   [(set (match_operand 0)
11769         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11770               (match_operand 2)))]
11771   "SIBLING_CALL_P (insn)"
11772   "* return ix86_output_call_insn (insn, operands[1]);"
11773   [(set_attr "type" "callv")])
11775 (define_insn "*sibcall_value_memory"
11776   [(set (match_operand 0)
11777         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11778               (match_operand 2)))
11779    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11780   "!TARGET_X32"
11781   "* return ix86_output_call_insn (insn, operands[1]);"
11782   [(set_attr "type" "callv")])
11784 (define_peephole2
11785   [(set (match_operand:W 0 "register_operand")
11786         (match_operand:W 1 "memory_operand"))
11787    (set (match_operand 2)
11788    (call (mem:QI (match_dup 0))
11789                  (match_operand 3)))]
11790   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11791    && !reg_mentioned_p (operands[0],
11792                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11793   [(parallel [(set (match_dup 2)
11794                    (call (mem:QI (match_dup 1))
11795                          (match_dup 3)))
11796               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11798 (define_peephole2
11799   [(set (match_operand:W 0 "register_operand")
11800         (match_operand:W 1 "memory_operand"))
11801    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11802    (set (match_operand 2)
11803         (call (mem:QI (match_dup 0))
11804               (match_operand 3)))]
11805   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11806    && !reg_mentioned_p (operands[0],
11807                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11808   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11809    (parallel [(set (match_dup 2)
11810                    (call (mem:QI (match_dup 1))
11811                          (match_dup 3)))
11812               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11814 (define_expand "call_value_pop"
11815   [(parallel [(set (match_operand 0)
11816                    (call (match_operand:QI 1)
11817                          (match_operand:SI 2)))
11818               (set (reg:SI SP_REG)
11819                    (plus:SI (reg:SI SP_REG)
11820                             (match_operand:SI 4)))])]
11821   "!TARGET_64BIT"
11823   ix86_expand_call (operands[0], operands[1], operands[2],
11824                     operands[3], operands[4], false);
11825   DONE;
11828 (define_insn "*call_value_pop"
11829   [(set (match_operand 0)
11830         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11831               (match_operand 2)))
11832    (set (reg:SI SP_REG)
11833         (plus:SI (reg:SI SP_REG)
11834                  (match_operand:SI 3 "immediate_operand" "i")))]
11835   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11836   "* return ix86_output_call_insn (insn, operands[1]);"
11837   [(set_attr "type" "callv")])
11839 (define_insn "*sibcall_value_pop"
11840   [(set (match_operand 0)
11841         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11842               (match_operand 2)))
11843    (set (reg:SI SP_REG)
11844         (plus:SI (reg:SI SP_REG)
11845                  (match_operand:SI 3 "immediate_operand" "i")))]
11846   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11847   "* return ix86_output_call_insn (insn, operands[1]);"
11848   [(set_attr "type" "callv")])
11850 (define_insn "*sibcall_value_pop_memory"
11851   [(set (match_operand 0)
11852         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11853               (match_operand 2)))
11854    (set (reg:SI SP_REG)
11855         (plus:SI (reg:SI SP_REG)
11856                  (match_operand:SI 3 "immediate_operand" "i")))
11857    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11858   "!TARGET_64BIT"
11859   "* return ix86_output_call_insn (insn, operands[1]);"
11860   [(set_attr "type" "callv")])
11862 (define_peephole2
11863   [(set (match_operand:SI 0 "register_operand")
11864         (match_operand:SI 1 "memory_operand"))
11865    (parallel [(set (match_operand 2)
11866                    (call (mem:QI (match_dup 0))
11867                          (match_operand 3)))
11868               (set (reg:SI SP_REG)
11869                    (plus:SI (reg:SI SP_REG)
11870                             (match_operand:SI 4 "immediate_operand")))])]
11871   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11872    && !reg_mentioned_p (operands[0],
11873                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
11874   [(parallel [(set (match_dup 2)
11875                    (call (mem:QI (match_dup 1))
11876                          (match_dup 3)))
11877               (set (reg:SI SP_REG)
11878                    (plus:SI (reg:SI SP_REG)
11879                             (match_dup 4)))
11880               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11882 (define_peephole2
11883   [(set (match_operand:SI 0 "register_operand")
11884         (match_operand:SI 1 "memory_operand"))
11885    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11886    (parallel [(set (match_operand 2)
11887                    (call (mem:QI (match_dup 0))
11888                          (match_operand 3)))
11889               (set (reg:SI SP_REG)
11890                    (plus:SI (reg:SI SP_REG)
11891                             (match_operand:SI 4 "immediate_operand")))])]
11892   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11893    && !reg_mentioned_p (operands[0],
11894                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
11895   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11896    (parallel [(set (match_dup 2)
11897                    (call (mem:QI (match_dup 1))
11898                          (match_dup 3)))
11899               (set (reg:SI SP_REG)
11900                    (plus:SI (reg:SI SP_REG)
11901                             (match_dup 4)))
11902               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11904 ;; Call subroutine returning any type.
11906 (define_expand "untyped_call"
11907   [(parallel [(call (match_operand 0)
11908                     (const_int 0))
11909               (match_operand 1)
11910               (match_operand 2)])]
11911   ""
11913   int i;
11915   /* In order to give reg-stack an easier job in validating two
11916      coprocessor registers as containing a possible return value,
11917      simply pretend the untyped call returns a complex long double
11918      value. 
11920      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11921      and should have the default ABI.  */
11923   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11924                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11925                     operands[0], const0_rtx,
11926                     GEN_INT ((TARGET_64BIT
11927                               ? (ix86_abi == SYSV_ABI
11928                                  ? X86_64_SSE_REGPARM_MAX
11929                                  : X86_64_MS_SSE_REGPARM_MAX)
11930                               : X86_32_SSE_REGPARM_MAX)
11931                              - 1),
11932                     NULL, false);
11934   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11935     {
11936       rtx set = XVECEXP (operands[2], 0, i);
11937       emit_move_insn (SET_DEST (set), SET_SRC (set));
11938     }
11940   /* The optimizer does not know that the call sets the function value
11941      registers we stored in the result block.  We avoid problems by
11942      claiming that all hard registers are used and clobbered at this
11943      point.  */
11944   emit_insn (gen_blockage ());
11946   DONE;
11949 ;; Prologue and epilogue instructions
11951 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11952 ;; all of memory.  This blocks insns from being moved across this point.
11954 (define_insn "blockage"
11955   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11956   ""
11957   ""
11958   [(set_attr "length" "0")])
11960 ;; Do not schedule instructions accessing memory across this point.
11962 (define_expand "memory_blockage"
11963   [(set (match_dup 0)
11964         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11965   ""
11967   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11968   MEM_VOLATILE_P (operands[0]) = 1;
11971 (define_insn "*memory_blockage"
11972   [(set (match_operand:BLK 0)
11973         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11974   ""
11975   ""
11976   [(set_attr "length" "0")])
11978 ;; As USE insns aren't meaningful after reload, this is used instead
11979 ;; to prevent deleting instructions setting registers for PIC code
11980 (define_insn "prologue_use"
11981   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11982   ""
11983   ""
11984   [(set_attr "length" "0")])
11986 ;; Insn emitted into the body of a function to return from a function.
11987 ;; This is only done if the function's epilogue is known to be simple.
11988 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11990 (define_expand "return"
11991   [(simple_return)]
11992   "ix86_can_use_return_insn_p ()"
11994   if (crtl->args.pops_args)
11995     {
11996       rtx popc = GEN_INT (crtl->args.pops_args);
11997       emit_jump_insn (gen_simple_return_pop_internal (popc));
11998       DONE;
11999     }
12002 ;; We need to disable this for TARGET_SEH, as otherwise
12003 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12004 ;; the maximum size of prologue in unwind information.
12006 (define_expand "simple_return"
12007   [(simple_return)]
12008   "!TARGET_SEH"
12010   if (crtl->args.pops_args)
12011     {
12012       rtx popc = GEN_INT (crtl->args.pops_args);
12013       emit_jump_insn (gen_simple_return_pop_internal (popc));
12014       DONE;
12015     }
12018 (define_insn "simple_return_internal"
12019   [(simple_return)]
12020   "reload_completed"
12021   "%!ret"
12022   [(set_attr "length_nobnd" "1")
12023    (set_attr "atom_unit" "jeu")
12024    (set_attr "length_immediate" "0")
12025    (set_attr "modrm" "0")])
12027 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12028 ;; instruction Athlon and K8 have.
12030 (define_insn "simple_return_internal_long"
12031   [(simple_return)
12032    (unspec [(const_int 0)] UNSPEC_REP)]
12033   "reload_completed"
12035   if (ix86_bnd_prefixed_insn_p (insn))
12036     return "%!ret";
12038   return "rep%; ret";
12040   [(set_attr "length" "2")
12041    (set_attr "atom_unit" "jeu")
12042    (set_attr "length_immediate" "0")
12043    (set_attr "prefix_rep" "1")
12044    (set_attr "modrm" "0")])
12046 (define_insn "simple_return_pop_internal"
12047   [(simple_return)
12048    (use (match_operand:SI 0 "const_int_operand"))]
12049   "reload_completed"
12050   "%!ret\t%0"
12051   [(set_attr "length_nobnd" "3")
12052    (set_attr "atom_unit" "jeu")
12053    (set_attr "length_immediate" "2")
12054    (set_attr "modrm" "0")])
12056 (define_insn "simple_return_indirect_internal"
12057   [(simple_return)
12058    (use (match_operand:SI 0 "register_operand" "r"))]
12059   "reload_completed"
12060   "%!jmp\t%A0"
12061   [(set_attr "type" "ibr")
12062    (set_attr "length_immediate" "0")])
12064 (define_insn "nop"
12065   [(const_int 0)]
12066   ""
12067   "nop"
12068   [(set_attr "length" "1")
12069    (set_attr "length_immediate" "0")
12070    (set_attr "modrm" "0")])
12072 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12073 (define_insn "nops"
12074   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12075                     UNSPECV_NOPS)]
12076   "reload_completed"
12078   int num = INTVAL (operands[0]);
12080   gcc_assert (IN_RANGE (num, 1, 8));
12082   while (num--)
12083     fputs ("\tnop\n", asm_out_file);
12085   return "";
12087   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12088    (set_attr "length_immediate" "0")
12089    (set_attr "modrm" "0")])
12091 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12092 ;; branch prediction penalty for the third jump in a 16-byte
12093 ;; block on K8.
12095 (define_insn "pad"
12096   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12097   ""
12099 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12100   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12101 #else
12102   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12103      The align insn is used to avoid 3 jump instructions in the row to improve
12104      branch prediction and the benefits hardly outweigh the cost of extra 8
12105      nops on the average inserted by full alignment pseudo operation.  */
12106 #endif
12107   return "";
12109   [(set_attr "length" "16")])
12111 (define_expand "prologue"
12112   [(const_int 0)]
12113   ""
12114   "ix86_expand_prologue (); DONE;")
12116 (define_insn "set_got"
12117   [(set (match_operand:SI 0 "register_operand" "=r")
12118         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "!TARGET_64BIT"
12121   "* return output_set_got (operands[0], NULL_RTX);"
12122   [(set_attr "type" "multi")
12123    (set_attr "length" "12")])
12125 (define_insn "set_got_labelled"
12126   [(set (match_operand:SI 0 "register_operand" "=r")
12127         (unspec:SI [(label_ref (match_operand 1))]
12128          UNSPEC_SET_GOT))
12129    (clobber (reg:CC FLAGS_REG))]
12130   "!TARGET_64BIT"
12131   "* return output_set_got (operands[0], operands[1]);"
12132   [(set_attr "type" "multi")
12133    (set_attr "length" "12")])
12135 (define_insn "set_got_rex64"
12136   [(set (match_operand:DI 0 "register_operand" "=r")
12137         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12138   "TARGET_64BIT"
12139   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12140   [(set_attr "type" "lea")
12141    (set_attr "length_address" "4")
12142    (set_attr "mode" "DI")])
12144 (define_insn "set_rip_rex64"
12145   [(set (match_operand:DI 0 "register_operand" "=r")
12146         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12147   "TARGET_64BIT"
12148   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12149   [(set_attr "type" "lea")
12150    (set_attr "length_address" "4")
12151    (set_attr "mode" "DI")])
12153 (define_insn "set_got_offset_rex64"
12154   [(set (match_operand:DI 0 "register_operand" "=r")
12155         (unspec:DI
12156           [(label_ref (match_operand 1))]
12157           UNSPEC_SET_GOT_OFFSET))]
12158   "TARGET_LP64"
12159   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12160   [(set_attr "type" "imov")
12161    (set_attr "length_immediate" "0")
12162    (set_attr "length_address" "8")
12163    (set_attr "mode" "DI")])
12165 (define_expand "epilogue"
12166   [(const_int 0)]
12167   ""
12168   "ix86_expand_epilogue (1); DONE;")
12170 (define_expand "sibcall_epilogue"
12171   [(const_int 0)]
12172   ""
12173   "ix86_expand_epilogue (0); DONE;")
12175 (define_expand "eh_return"
12176   [(use (match_operand 0 "register_operand"))]
12177   ""
12179   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12181   /* Tricky bit: we write the address of the handler to which we will
12182      be returning into someone else's stack frame, one word below the
12183      stack address we wish to restore.  */
12184   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12185   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12186   tmp = gen_rtx_MEM (Pmode, tmp);
12187   emit_move_insn (tmp, ra);
12189   emit_jump_insn (gen_eh_return_internal ());
12190   emit_barrier ();
12191   DONE;
12194 (define_insn_and_split "eh_return_internal"
12195   [(eh_return)]
12196   ""
12197   "#"
12198   "epilogue_completed"
12199   [(const_int 0)]
12200   "ix86_expand_epilogue (2); DONE;")
12202 (define_insn "leave"
12203   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12204    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12205    (clobber (mem:BLK (scratch)))]
12206   "!TARGET_64BIT"
12207   "leave"
12208   [(set_attr "type" "leave")])
12210 (define_insn "leave_rex64"
12211   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12212    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12213    (clobber (mem:BLK (scratch)))]
12214   "TARGET_64BIT"
12215   "leave"
12216   [(set_attr "type" "leave")])
12218 ;; Handle -fsplit-stack.
12220 (define_expand "split_stack_prologue"
12221   [(const_int 0)]
12222   ""
12224   ix86_expand_split_stack_prologue ();
12225   DONE;
12228 ;; In order to support the call/return predictor, we use a return
12229 ;; instruction which the middle-end doesn't see.
12230 (define_insn "split_stack_return"
12231   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12232                      UNSPECV_SPLIT_STACK_RETURN)]
12233   ""
12235   if (operands[0] == const0_rtx)
12236     return "ret";
12237   else
12238     return "ret\t%0";
12240   [(set_attr "atom_unit" "jeu")
12241    (set_attr "modrm" "0")
12242    (set (attr "length")
12243         (if_then_else (match_operand:SI 0 "const0_operand")
12244                       (const_int 1)
12245                       (const_int 3)))
12246    (set (attr "length_immediate")
12247         (if_then_else (match_operand:SI 0 "const0_operand")
12248                       (const_int 0)
12249                       (const_int 2)))])
12251 ;; If there are operand 0 bytes available on the stack, jump to
12252 ;; operand 1.
12254 (define_expand "split_stack_space_check"
12255   [(set (pc) (if_then_else
12256               (ltu (minus (reg SP_REG)
12257                           (match_operand 0 "register_operand"))
12258                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12259               (label_ref (match_operand 1))
12260               (pc)))]
12261   ""
12263   rtx reg, size, limit;
12265   reg = gen_reg_rtx (Pmode);
12266   size = force_reg (Pmode, operands[0]);
12267   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12268   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12269                           UNSPEC_STACK_CHECK);
12270   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12271   ix86_expand_branch (GEU, reg, limit, operands[1]);
12273   DONE;
12276 ;; Bit manipulation instructions.
12278 (define_expand "ffs<mode>2"
12279   [(set (match_dup 2) (const_int -1))
12280    (parallel [(set (match_dup 3) (match_dup 4))
12281               (set (match_operand:SWI48 0 "register_operand")
12282                    (ctz:SWI48
12283                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12284    (set (match_dup 0) (if_then_else:SWI48
12285                         (eq (match_dup 3) (const_int 0))
12286                         (match_dup 2)
12287                         (match_dup 0)))
12288    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12289               (clobber (reg:CC FLAGS_REG))])]
12290   ""
12292   machine_mode flags_mode;
12294   if (<MODE>mode == SImode && !TARGET_CMOVE)
12295     {
12296       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12297       DONE;
12298     }
12300   flags_mode
12301     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12303   operands[2] = gen_reg_rtx (<MODE>mode);
12304   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12305   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12308 (define_insn_and_split "ffssi2_no_cmove"
12309   [(set (match_operand:SI 0 "register_operand" "=r")
12310         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12311    (clobber (match_scratch:SI 2 "=&q"))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "!TARGET_CMOVE"
12314   "#"
12315   "&& reload_completed"
12316   [(parallel [(set (match_dup 4) (match_dup 5))
12317               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12318    (set (strict_low_part (match_dup 3))
12319         (eq:QI (match_dup 4) (const_int 0)))
12320    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12321               (clobber (reg:CC FLAGS_REG))])
12322    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12323               (clobber (reg:CC FLAGS_REG))])
12324    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12325               (clobber (reg:CC FLAGS_REG))])]
12327   machine_mode flags_mode
12328     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12330   operands[3] = gen_lowpart (QImode, operands[2]);
12331   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12332   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12334   ix86_expand_clear (operands[2]);
12337 (define_insn "*tzcnt<mode>_1"
12338   [(set (reg:CCC FLAGS_REG)
12339         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12340                      (const_int 0)))
12341    (set (match_operand:SWI48 0 "register_operand" "=r")
12342         (ctz:SWI48 (match_dup 1)))]
12343   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12344   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12345   [(set_attr "type" "alu1")
12346    (set_attr "prefix_0f" "1")
12347    (set_attr "prefix_rep" "1")
12348    (set_attr "btver2_decode" "double")
12349    (set_attr "mode" "<MODE>")])
12351 (define_insn "*bsf<mode>_1"
12352   [(set (reg:CCZ FLAGS_REG)
12353         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12354                      (const_int 0)))
12355    (set (match_operand:SWI48 0 "register_operand" "=r")
12356         (ctz:SWI48 (match_dup 1)))]
12357   ""
12358   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12359   [(set_attr "type" "alu1")
12360    (set_attr "prefix_0f" "1")
12361    (set_attr "btver2_decode" "double")
12362    (set_attr "mode" "<MODE>")])
12364 (define_expand "ctz<mode>2"
12365   [(parallel
12366     [(set (match_operand:SWI248 0 "register_operand")
12367           (ctz:SWI248
12368             (match_operand:SWI248 1 "nonimmediate_operand")))
12369      (clobber (reg:CC FLAGS_REG))])])
12371 ; False dependency happens when destination is only updated by tzcnt,
12372 ; lzcnt or popcnt.  There is no false dependency when destination is
12373 ; also used in source.
12374 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12375   [(set (match_operand:SWI48 0 "register_operand" "=r")
12376         (ctz:SWI48
12377           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12378    (clobber (reg:CC FLAGS_REG))]
12379   "(TARGET_BMI || TARGET_GENERIC)
12380    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12381   "#"
12382   "&& reload_completed"
12383   [(parallel
12384     [(set (match_dup 0)
12385           (ctz:SWI48 (match_dup 1)))
12386      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12387      (clobber (reg:CC FLAGS_REG))])]
12389   if (!reg_mentioned_p (operands[0], operands[1]))
12390     ix86_expand_clear (operands[0]);
12393 (define_insn "*ctz<mode>2_falsedep"
12394   [(set (match_operand:SWI48 0 "register_operand" "=r")
12395         (ctz:SWI48
12396           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12397    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12398            UNSPEC_INSN_FALSE_DEP)
12399    (clobber (reg:CC FLAGS_REG))]
12400   ""
12402   if (TARGET_BMI)
12403     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12404   else if (TARGET_GENERIC)
12405     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12406     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12407   else
12408     gcc_unreachable ();
12410   [(set_attr "type" "alu1")
12411    (set_attr "prefix_0f" "1")
12412    (set_attr "prefix_rep" "1")
12413    (set_attr "mode" "<MODE>")])
12415 (define_insn "*ctz<mode>2"
12416   [(set (match_operand:SWI248 0 "register_operand" "=r")
12417         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12418    (clobber (reg:CC FLAGS_REG))]
12419   ""
12421   if (TARGET_BMI)
12422     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12423   else if (optimize_function_for_size_p (cfun))
12424     ;
12425   else if (TARGET_GENERIC)
12426     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12427     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12429   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12431   [(set_attr "type" "alu1")
12432    (set_attr "prefix_0f" "1")
12433    (set (attr "prefix_rep")
12434      (if_then_else
12435        (ior (match_test "TARGET_BMI")
12436             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12437                  (match_test "TARGET_GENERIC")))
12438        (const_string "1")
12439        (const_string "0")))
12440    (set_attr "mode" "<MODE>")])
12442 (define_expand "clz<mode>2"
12443   [(parallel
12444      [(set (match_operand:SWI248 0 "register_operand")
12445            (minus:SWI248
12446              (match_dup 2)
12447              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12448       (clobber (reg:CC FLAGS_REG))])
12449    (parallel
12450      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12451       (clobber (reg:CC FLAGS_REG))])]
12452   ""
12454   if (TARGET_LZCNT)
12455     {
12456       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12457       DONE;
12458     }
12459   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12462 (define_expand "clz<mode>2_lzcnt"
12463   [(parallel
12464     [(set (match_operand:SWI248 0 "register_operand")
12465           (clz:SWI248
12466             (match_operand:SWI248 1 "nonimmediate_operand")))
12467      (clobber (reg:CC FLAGS_REG))])]
12468   "TARGET_LZCNT")
12470 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12471   [(set (match_operand:SWI48 0 "register_operand" "=r")
12472         (clz:SWI48
12473           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12474    (clobber (reg:CC FLAGS_REG))]
12475   "TARGET_LZCNT
12476    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12477   "#"
12478   "&& reload_completed"
12479   [(parallel
12480     [(set (match_dup 0)
12481           (clz:SWI48 (match_dup 1)))
12482      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12483      (clobber (reg:CC FLAGS_REG))])]
12485   if (!reg_mentioned_p (operands[0], operands[1]))
12486     ix86_expand_clear (operands[0]);
12489 (define_insn "*clz<mode>2_lzcnt_falsedep"
12490   [(set (match_operand:SWI48 0 "register_operand" "=r")
12491         (clz:SWI48
12492           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12493    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12494            UNSPEC_INSN_FALSE_DEP)
12495    (clobber (reg:CC FLAGS_REG))]
12496   "TARGET_LZCNT"
12497   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12498   [(set_attr "prefix_rep" "1")
12499    (set_attr "type" "bitmanip")
12500    (set_attr "mode" "<MODE>")])
12502 (define_insn "*clz<mode>2_lzcnt"
12503   [(set (match_operand:SWI248 0 "register_operand" "=r")
12504         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12505    (clobber (reg:CC FLAGS_REG))]
12506   "TARGET_LZCNT"
12507   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12508   [(set_attr "prefix_rep" "1")
12509    (set_attr "type" "bitmanip")
12510    (set_attr "mode" "<MODE>")])
12512 ;; BMI instructions.
12513 (define_insn "*bmi_andn_<mode>"
12514   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12515         (and:SWI48
12516           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12517           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "TARGET_BMI"
12520   "andn\t{%2, %1, %0|%0, %1, %2}"
12521   [(set_attr "type" "bitmanip")
12522    (set_attr "btver2_decode" "direct, double")
12523    (set_attr "mode" "<MODE>")])
12525 (define_insn "*bmi_andn_<mode>_ccno"
12526   [(set (reg FLAGS_REG)
12527         (compare
12528           (and:SWI48
12529             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12530             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12531           (const_int 0)))
12532    (clobber (match_scratch:SWI48 0 "=r,r"))]
12533   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12534   "andn\t{%2, %1, %0|%0, %1, %2}"
12535   [(set_attr "type" "bitmanip")
12536    (set_attr "btver2_decode" "direct, double")
12537    (set_attr "mode" "<MODE>")])
12539 (define_insn "bmi_bextr_<mode>"
12540   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12541         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12542                        (match_operand:SWI48 2 "register_operand" "r,r")]
12543                       UNSPEC_BEXTR))
12544    (clobber (reg:CC FLAGS_REG))]
12545   "TARGET_BMI"
12546   "bextr\t{%2, %1, %0|%0, %1, %2}"
12547   [(set_attr "type" "bitmanip")
12548    (set_attr "btver2_decode" "direct, double")
12549    (set_attr "mode" "<MODE>")])
12551 (define_insn "*bmi_bextr_<mode>_ccz"
12552   [(set (reg:CCZ FLAGS_REG)
12553         (compare:CCZ
12554           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12555                          (match_operand:SWI48 2 "register_operand" "r,r")]
12556                         UNSPEC_BEXTR)
12557           (const_int 0)))
12558    (clobber (match_scratch:SWI48 0 "=r,r"))]
12559   "TARGET_BMI"
12560   "bextr\t{%2, %1, %0|%0, %1, %2}"
12561   [(set_attr "type" "bitmanip")
12562    (set_attr "btver2_decode" "direct, double")
12563    (set_attr "mode" "<MODE>")])
12565 (define_insn "*bmi_blsi_<mode>"
12566   [(set (match_operand:SWI48 0 "register_operand" "=r")
12567         (and:SWI48
12568           (neg:SWI48
12569             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12570           (match_dup 1)))
12571    (clobber (reg:CC FLAGS_REG))]
12572   "TARGET_BMI"
12573   "blsi\t{%1, %0|%0, %1}"
12574   [(set_attr "type" "bitmanip")
12575    (set_attr "btver2_decode" "double")
12576    (set_attr "mode" "<MODE>")])
12578 (define_insn "*bmi_blsmsk_<mode>"
12579   [(set (match_operand:SWI48 0 "register_operand" "=r")
12580         (xor:SWI48
12581           (plus:SWI48
12582             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12583             (const_int -1))
12584           (match_dup 1)))
12585    (clobber (reg:CC FLAGS_REG))]
12586   "TARGET_BMI"
12587   "blsmsk\t{%1, %0|%0, %1}"
12588   [(set_attr "type" "bitmanip")
12589    (set_attr "btver2_decode" "double")
12590    (set_attr "mode" "<MODE>")])
12592 (define_insn "*bmi_blsr_<mode>"
12593   [(set (match_operand:SWI48 0 "register_operand" "=r")
12594         (and:SWI48
12595           (plus:SWI48
12596             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12597             (const_int -1))
12598           (match_dup 1)))
12599    (clobber (reg:CC FLAGS_REG))]
12600    "TARGET_BMI"
12601    "blsr\t{%1, %0|%0, %1}"
12602   [(set_attr "type" "bitmanip")
12603    (set_attr "btver2_decode" "double")
12604    (set_attr "mode" "<MODE>")])
12606 ;; BMI2 instructions.
12607 (define_expand "bmi2_bzhi_<mode>3"
12608   [(parallel
12609     [(set (match_operand:SWI48 0 "register_operand")
12610           (zero_extract:SWI48
12611             (match_operand:SWI48 1 "nonimmediate_operand")
12612             (umin:SWI48
12613               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12614                          (const_int 255))
12615               (match_dup 3))
12616             (const_int 0)))
12617      (clobber (reg:CC FLAGS_REG))])]
12618   "TARGET_BMI2"
12619   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12621 (define_insn "*bmi2_bzhi_<mode>3"
12622   [(set (match_operand:SWI48 0 "register_operand" "=r")
12623         (zero_extract:SWI48
12624           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12625           (umin:SWI48
12626             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12627                        (const_int 255))
12628             (match_operand:SWI48 3 "const_int_operand" "n"))
12629           (const_int 0)))
12630    (clobber (reg:CC FLAGS_REG))]
12631   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12632   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12633   [(set_attr "type" "bitmanip")
12634    (set_attr "prefix" "vex")
12635    (set_attr "mode" "<MODE>")])
12637 (define_mode_attr k [(SI "k") (DI "q")])
12639 (define_insn "*bmi2_bzhi_<mode>3_1"
12640   [(set (match_operand:SWI48 0 "register_operand" "=r")
12641         (zero_extract:SWI48
12642           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12643           (umin:SWI48
12644             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12645             (match_operand:SWI48 3 "const_int_operand" "n"))
12646           (const_int 0)))
12647    (clobber (reg:CC FLAGS_REG))]
12648   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12649   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12650   [(set_attr "type" "bitmanip")
12651    (set_attr "prefix" "vex")
12652    (set_attr "mode" "<MODE>")])
12654 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
12655   [(set (reg:CCZ FLAGS_REG)
12656         (compare:CCZ
12657           (zero_extract:SWI48
12658             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12659             (umin:SWI48
12660               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12661               (match_operand:SWI48 3 "const_int_operand" "n"))
12662             (const_int 0))
12663         (const_int 0)))
12664    (clobber (match_scratch:SWI48 0 "=r"))]
12665   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12666   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12667   [(set_attr "type" "bitmanip")
12668    (set_attr "prefix" "vex")
12669    (set_attr "mode" "<MODE>")])
12671 (define_insn "bmi2_pdep_<mode>3"
12672   [(set (match_operand:SWI48 0 "register_operand" "=r")
12673         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12674                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12675                        UNSPEC_PDEP))]
12676   "TARGET_BMI2"
12677   "pdep\t{%2, %1, %0|%0, %1, %2}"
12678   [(set_attr "type" "bitmanip")
12679    (set_attr "prefix" "vex")
12680    (set_attr "mode" "<MODE>")])
12682 (define_insn "bmi2_pext_<mode>3"
12683   [(set (match_operand:SWI48 0 "register_operand" "=r")
12684         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12685                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12686                        UNSPEC_PEXT))]
12687   "TARGET_BMI2"
12688   "pext\t{%2, %1, %0|%0, %1, %2}"
12689   [(set_attr "type" "bitmanip")
12690    (set_attr "prefix" "vex")
12691    (set_attr "mode" "<MODE>")])
12693 ;; TBM instructions.
12694 (define_insn "tbm_bextri_<mode>"
12695   [(set (match_operand:SWI48 0 "register_operand" "=r")
12696         (zero_extract:SWI48
12697           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12698           (match_operand 2 "const_0_to_255_operand" "N")
12699           (match_operand 3 "const_0_to_255_operand" "N")))
12700    (clobber (reg:CC FLAGS_REG))]
12701    "TARGET_TBM"
12703   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12704   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12706   [(set_attr "type" "bitmanip")
12707    (set_attr "mode" "<MODE>")])
12709 (define_insn "*tbm_blcfill_<mode>"
12710   [(set (match_operand:SWI48 0 "register_operand" "=r")
12711         (and:SWI48
12712           (plus:SWI48
12713             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12714             (const_int 1))
12715           (match_dup 1)))
12716    (clobber (reg:CC FLAGS_REG))]
12717    "TARGET_TBM"
12718    "blcfill\t{%1, %0|%0, %1}"
12719   [(set_attr "type" "bitmanip")
12720    (set_attr "mode" "<MODE>")])
12722 (define_insn "*tbm_blci_<mode>"
12723   [(set (match_operand:SWI48 0 "register_operand" "=r")
12724         (ior:SWI48
12725           (not:SWI48
12726             (plus:SWI48
12727               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12728               (const_int 1)))
12729           (match_dup 1)))
12730    (clobber (reg:CC FLAGS_REG))]
12731    "TARGET_TBM"
12732    "blci\t{%1, %0|%0, %1}"
12733   [(set_attr "type" "bitmanip")
12734    (set_attr "mode" "<MODE>")])
12736 (define_insn "*tbm_blcic_<mode>"
12737   [(set (match_operand:SWI48 0 "register_operand" "=r")
12738         (and:SWI48
12739           (plus:SWI48
12740             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12741             (const_int 1))
12742           (not:SWI48
12743             (match_dup 1))))
12744    (clobber (reg:CC FLAGS_REG))]
12745    "TARGET_TBM"
12746    "blcic\t{%1, %0|%0, %1}"
12747   [(set_attr "type" "bitmanip")
12748    (set_attr "mode" "<MODE>")])
12750 (define_insn "*tbm_blcmsk_<mode>"
12751   [(set (match_operand:SWI48 0 "register_operand" "=r")
12752         (xor:SWI48
12753           (plus:SWI48
12754             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12755             (const_int 1))
12756           (match_dup 1)))
12757    (clobber (reg:CC FLAGS_REG))]
12758    "TARGET_TBM"
12759    "blcmsk\t{%1, %0|%0, %1}"
12760   [(set_attr "type" "bitmanip")
12761    (set_attr "mode" "<MODE>")])
12763 (define_insn "*tbm_blcs_<mode>"
12764   [(set (match_operand:SWI48 0 "register_operand" "=r")
12765         (ior:SWI48
12766           (plus:SWI48
12767             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12768             (const_int 1))
12769           (match_dup 1)))
12770    (clobber (reg:CC FLAGS_REG))]
12771    "TARGET_TBM"
12772    "blcs\t{%1, %0|%0, %1}"
12773   [(set_attr "type" "bitmanip")
12774    (set_attr "mode" "<MODE>")])
12776 (define_insn "*tbm_blsfill_<mode>"
12777   [(set (match_operand:SWI48 0 "register_operand" "=r")
12778         (ior:SWI48
12779           (plus:SWI48
12780             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12781             (const_int -1))
12782           (match_dup 1)))
12783    (clobber (reg:CC FLAGS_REG))]
12784    "TARGET_TBM"
12785    "blsfill\t{%1, %0|%0, %1}"
12786   [(set_attr "type" "bitmanip")
12787    (set_attr "mode" "<MODE>")])
12789 (define_insn "*tbm_blsic_<mode>"
12790   [(set (match_operand:SWI48 0 "register_operand" "=r")
12791         (ior:SWI48
12792           (plus:SWI48
12793             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12794             (const_int -1))
12795           (not:SWI48
12796             (match_dup 1))))
12797    (clobber (reg:CC FLAGS_REG))]
12798    "TARGET_TBM"
12799    "blsic\t{%1, %0|%0, %1}"
12800   [(set_attr "type" "bitmanip")
12801    (set_attr "mode" "<MODE>")])
12803 (define_insn "*tbm_t1mskc_<mode>"
12804   [(set (match_operand:SWI48 0 "register_operand" "=r")
12805         (ior:SWI48
12806           (plus:SWI48
12807             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12808             (const_int 1))
12809           (not:SWI48
12810             (match_dup 1))))
12811    (clobber (reg:CC FLAGS_REG))]
12812    "TARGET_TBM"
12813    "t1mskc\t{%1, %0|%0, %1}"
12814   [(set_attr "type" "bitmanip")
12815    (set_attr "mode" "<MODE>")])
12817 (define_insn "*tbm_tzmsk_<mode>"
12818   [(set (match_operand:SWI48 0 "register_operand" "=r")
12819         (and:SWI48
12820           (plus:SWI48
12821             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12822             (const_int -1))
12823           (not:SWI48
12824             (match_dup 1))))
12825    (clobber (reg:CC FLAGS_REG))]
12826    "TARGET_TBM"
12827    "tzmsk\t{%1, %0|%0, %1}"
12828   [(set_attr "type" "bitmanip")
12829    (set_attr "mode" "<MODE>")])
12831 (define_insn "bsr_rex64"
12832   [(set (match_operand:DI 0 "register_operand" "=r")
12833         (minus:DI (const_int 63)
12834                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12835    (clobber (reg:CC FLAGS_REG))]
12836   "TARGET_64BIT"
12837   "bsr{q}\t{%1, %0|%0, %1}"
12838   [(set_attr "type" "alu1")
12839    (set_attr "prefix_0f" "1")
12840    (set_attr "mode" "DI")])
12842 (define_insn "bsr"
12843   [(set (match_operand:SI 0 "register_operand" "=r")
12844         (minus:SI (const_int 31)
12845                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12846    (clobber (reg:CC FLAGS_REG))]
12847   ""
12848   "bsr{l}\t{%1, %0|%0, %1}"
12849   [(set_attr "type" "alu1")
12850    (set_attr "prefix_0f" "1")
12851    (set_attr "mode" "SI")])
12853 (define_insn "*bsrhi"
12854   [(set (match_operand:HI 0 "register_operand" "=r")
12855         (minus:HI (const_int 15)
12856                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12857    (clobber (reg:CC FLAGS_REG))]
12858   ""
12859   "bsr{w}\t{%1, %0|%0, %1}"
12860   [(set_attr "type" "alu1")
12861    (set_attr "prefix_0f" "1")
12862    (set_attr "mode" "HI")])
12864 (define_expand "popcount<mode>2"
12865   [(parallel
12866     [(set (match_operand:SWI248 0 "register_operand")
12867           (popcount:SWI248
12868             (match_operand:SWI248 1 "nonimmediate_operand")))
12869      (clobber (reg:CC FLAGS_REG))])]
12870   "TARGET_POPCNT")
12872 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12873   [(set (match_operand:SWI48 0 "register_operand" "=r")
12874         (popcount:SWI48
12875           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12876    (clobber (reg:CC FLAGS_REG))]
12877   "TARGET_POPCNT
12878    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12879   "#"
12880   "&& reload_completed"
12881   [(parallel
12882     [(set (match_dup 0)
12883           (popcount:SWI48 (match_dup 1)))
12884      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12885      (clobber (reg:CC FLAGS_REG))])]
12887   if (!reg_mentioned_p (operands[0], operands[1]))
12888     ix86_expand_clear (operands[0]);
12891 (define_insn "*popcount<mode>2_falsedep"
12892   [(set (match_operand:SWI48 0 "register_operand" "=r")
12893         (popcount:SWI48
12894           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12895    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12896            UNSPEC_INSN_FALSE_DEP)
12897    (clobber (reg:CC FLAGS_REG))]
12898   "TARGET_POPCNT"
12900 #if TARGET_MACHO
12901   return "popcnt\t{%1, %0|%0, %1}";
12902 #else
12903   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12904 #endif
12906   [(set_attr "prefix_rep" "1")
12907    (set_attr "type" "bitmanip")
12908    (set_attr "mode" "<MODE>")])
12910 (define_insn "*popcount<mode>2"
12911   [(set (match_operand:SWI248 0 "register_operand" "=r")
12912         (popcount:SWI248
12913           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12914    (clobber (reg:CC FLAGS_REG))]
12915   "TARGET_POPCNT"
12917 #if TARGET_MACHO
12918   return "popcnt\t{%1, %0|%0, %1}";
12919 #else
12920   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12921 #endif
12923   [(set_attr "prefix_rep" "1")
12924    (set_attr "type" "bitmanip")
12925    (set_attr "mode" "<MODE>")])
12927 (define_expand "bswapdi2"
12928   [(set (match_operand:DI 0 "register_operand")
12929         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12930   "TARGET_64BIT"
12932   if (!TARGET_MOVBE)
12933     operands[1] = force_reg (DImode, operands[1]);
12936 (define_expand "bswapsi2"
12937   [(set (match_operand:SI 0 "register_operand")
12938         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12939   ""
12941   if (TARGET_MOVBE)
12942     ;
12943   else if (TARGET_BSWAP)
12944     operands[1] = force_reg (SImode, operands[1]);
12945   else
12946     {
12947       rtx x = operands[0];
12949       emit_move_insn (x, operands[1]);
12950       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12951       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12952       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12953       DONE;
12954     }
12957 (define_insn "*bswap<mode>2_movbe"
12958   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12959         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12960   "TARGET_MOVBE
12961    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12962   "@
12963     bswap\t%0
12964     movbe\t{%1, %0|%0, %1}
12965     movbe\t{%1, %0|%0, %1}"
12966   [(set_attr "type" "bitmanip,imov,imov")
12967    (set_attr "modrm" "0,1,1")
12968    (set_attr "prefix_0f" "*,1,1")
12969    (set_attr "prefix_extra" "*,1,1")
12970    (set_attr "mode" "<MODE>")])
12972 (define_insn "*bswap<mode>2"
12973   [(set (match_operand:SWI48 0 "register_operand" "=r")
12974         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12975   "TARGET_BSWAP"
12976   "bswap\t%0"
12977   [(set_attr "type" "bitmanip")
12978    (set_attr "modrm" "0")
12979    (set_attr "mode" "<MODE>")])
12981 (define_insn "*bswaphi_lowpart_1"
12982   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12983         (bswap:HI (match_dup 0)))
12984    (clobber (reg:CC FLAGS_REG))]
12985   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12986   "@
12987     xchg{b}\t{%h0, %b0|%b0, %h0}
12988     rol{w}\t{$8, %0|%0, 8}"
12989   [(set_attr "length" "2,4")
12990    (set_attr "mode" "QI,HI")])
12992 (define_insn "bswaphi_lowpart"
12993   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12994         (bswap:HI (match_dup 0)))
12995    (clobber (reg:CC FLAGS_REG))]
12996   ""
12997   "rol{w}\t{$8, %0|%0, 8}"
12998   [(set_attr "length" "4")
12999    (set_attr "mode" "HI")])
13001 (define_expand "paritydi2"
13002   [(set (match_operand:DI 0 "register_operand")
13003         (parity:DI (match_operand:DI 1 "register_operand")))]
13004   "! TARGET_POPCNT"
13006   rtx scratch = gen_reg_rtx (QImode);
13007   rtx cond;
13009   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13010                                 NULL_RTX, operands[1]));
13012   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13013                          gen_rtx_REG (CCmode, FLAGS_REG),
13014                          const0_rtx);
13015   emit_insn (gen_rtx_SET (scratch, cond));
13017   if (TARGET_64BIT)
13018     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13019   else
13020     {
13021       rtx tmp = gen_reg_rtx (SImode);
13023       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13024       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13025     }
13026   DONE;
13029 (define_expand "paritysi2"
13030   [(set (match_operand:SI 0 "register_operand")
13031         (parity:SI (match_operand:SI 1 "register_operand")))]
13032   "! TARGET_POPCNT"
13034   rtx scratch = gen_reg_rtx (QImode);
13035   rtx cond;
13037   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13039   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13040                          gen_rtx_REG (CCmode, FLAGS_REG),
13041                          const0_rtx);
13042   emit_insn (gen_rtx_SET (scratch, cond));
13044   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13045   DONE;
13048 (define_insn_and_split "paritydi2_cmp"
13049   [(set (reg:CC FLAGS_REG)
13050         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13051                    UNSPEC_PARITY))
13052    (clobber (match_scratch:DI 0 "=r"))
13053    (clobber (match_scratch:SI 1 "=&r"))
13054    (clobber (match_scratch:HI 2 "=Q"))]
13055   "! TARGET_POPCNT"
13056   "#"
13057   "&& reload_completed"
13058   [(parallel
13059      [(set (match_dup 1)
13060            (xor:SI (match_dup 1) (match_dup 4)))
13061       (clobber (reg:CC FLAGS_REG))])
13062    (parallel
13063      [(set (reg:CC FLAGS_REG)
13064            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13065       (clobber (match_dup 1))
13066       (clobber (match_dup 2))])]
13068   operands[4] = gen_lowpart (SImode, operands[3]);
13070   if (TARGET_64BIT)
13071     {
13072       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13073       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13074     }
13075   else
13076     operands[1] = gen_highpart (SImode, operands[3]);
13079 (define_insn_and_split "paritysi2_cmp"
13080   [(set (reg:CC FLAGS_REG)
13081         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13082                    UNSPEC_PARITY))
13083    (clobber (match_scratch:SI 0 "=r"))
13084    (clobber (match_scratch:HI 1 "=&Q"))]
13085   "! TARGET_POPCNT"
13086   "#"
13087   "&& reload_completed"
13088   [(parallel
13089      [(set (match_dup 1)
13090            (xor:HI (match_dup 1) (match_dup 3)))
13091       (clobber (reg:CC FLAGS_REG))])
13092    (parallel
13093      [(set (reg:CC FLAGS_REG)
13094            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13095       (clobber (match_dup 1))])]
13097   operands[3] = gen_lowpart (HImode, operands[2]);
13099   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13100   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13103 (define_insn "*parityhi2_cmp"
13104   [(set (reg:CC FLAGS_REG)
13105         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13106                    UNSPEC_PARITY))
13107    (clobber (match_scratch:HI 0 "=Q"))]
13108   "! TARGET_POPCNT"
13109   "xor{b}\t{%h0, %b0|%b0, %h0}"
13110   [(set_attr "length" "2")
13111    (set_attr "mode" "HI")])
13114 ;; Thread-local storage patterns for ELF.
13116 ;; Note that these code sequences must appear exactly as shown
13117 ;; in order to allow linker relaxation.
13119 (define_insn "*tls_global_dynamic_32_gnu"
13120   [(set (match_operand:SI 0 "register_operand" "=a")
13121         (unspec:SI
13122          [(match_operand:SI 1 "register_operand" "b")
13123           (match_operand 2 "tls_symbolic_operand")
13124           (match_operand 3 "constant_call_address_operand" "Bz")
13125           (reg:SI SP_REG)]
13126          UNSPEC_TLS_GD))
13127    (clobber (match_scratch:SI 4 "=d"))
13128    (clobber (match_scratch:SI 5 "=c"))
13129    (clobber (reg:CC FLAGS_REG))]
13130   "!TARGET_64BIT && TARGET_GNU_TLS"
13132   output_asm_insn
13133     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13134   if (TARGET_SUN_TLS)
13135 #ifdef HAVE_AS_IX86_TLSGDPLT
13136     return "call\t%a2@tlsgdplt";
13137 #else
13138     return "call\t%p3@plt";
13139 #endif
13140   return "call\t%P3";
13142   [(set_attr "type" "multi")
13143    (set_attr "length" "12")])
13145 (define_expand "tls_global_dynamic_32"
13146   [(parallel
13147     [(set (match_operand:SI 0 "register_operand")
13148           (unspec:SI [(match_operand:SI 2 "register_operand")
13149                       (match_operand 1 "tls_symbolic_operand")
13150                       (match_operand 3 "constant_call_address_operand")
13151                       (reg:SI SP_REG)]
13152                      UNSPEC_TLS_GD))
13153      (clobber (match_scratch:SI 4))
13154      (clobber (match_scratch:SI 5))
13155      (clobber (reg:CC FLAGS_REG))])]
13156   ""
13157   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13159 (define_insn "*tls_global_dynamic_64_<mode>"
13160   [(set (match_operand:P 0 "register_operand" "=a")
13161         (call:P
13162          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13163          (match_operand 3)))
13164    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13165               (reg:P SP_REG)]
13166              UNSPEC_TLS_GD)]
13167   "TARGET_64BIT"
13169   if (!TARGET_X32)
13170     fputs (ASM_BYTE "0x66\n", asm_out_file);
13171   output_asm_insn
13172     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13173   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13174   fputs ("\trex64\n", asm_out_file);
13175   if (TARGET_SUN_TLS)
13176     return "call\t%p2@plt";
13177   return "call\t%P2";
13179   [(set_attr "type" "multi")
13180    (set (attr "length")
13181         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13183 (define_insn "*tls_global_dynamic_64_largepic"
13184   [(set (match_operand:DI 0 "register_operand" "=a")
13185         (call:DI
13186          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13187                           (match_operand:DI 3 "immediate_operand" "i")))
13188          (match_operand 4)))
13189    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13190                (reg:DI SP_REG)]
13191               UNSPEC_TLS_GD)]
13192   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13193    && GET_CODE (operands[3]) == CONST
13194    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13195    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13197   output_asm_insn
13198     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13199   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13200   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13201   return "call\t{*%%rax|rax}";
13203   [(set_attr "type" "multi")
13204    (set_attr "length" "22")])
13206 (define_expand "tls_global_dynamic_64_<mode>"
13207   [(parallel
13208     [(set (match_operand:P 0 "register_operand")
13209           (call:P
13210            (mem:QI (match_operand 2))
13211            (const_int 0)))
13212      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13213                 (reg:P SP_REG)]
13214                UNSPEC_TLS_GD)])]
13215   "TARGET_64BIT"
13216   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13218 (define_insn "*tls_local_dynamic_base_32_gnu"
13219   [(set (match_operand:SI 0 "register_operand" "=a")
13220         (unspec:SI
13221          [(match_operand:SI 1 "register_operand" "b")
13222           (match_operand 2 "constant_call_address_operand" "Bz")
13223           (reg:SI SP_REG)]
13224          UNSPEC_TLS_LD_BASE))
13225    (clobber (match_scratch:SI 3 "=d"))
13226    (clobber (match_scratch:SI 4 "=c"))
13227    (clobber (reg:CC FLAGS_REG))]
13228   "!TARGET_64BIT && TARGET_GNU_TLS"
13230   output_asm_insn
13231     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13232   if (TARGET_SUN_TLS)
13233     {
13234       if (HAVE_AS_IX86_TLSLDMPLT)
13235         return "call\t%&@tlsldmplt";
13236       else
13237         return "call\t%p2@plt";
13238     }
13239   return "call\t%P2";
13241   [(set_attr "type" "multi")
13242    (set_attr "length" "11")])
13244 (define_expand "tls_local_dynamic_base_32"
13245   [(parallel
13246      [(set (match_operand:SI 0 "register_operand")
13247            (unspec:SI
13248             [(match_operand:SI 1 "register_operand")
13249              (match_operand 2 "constant_call_address_operand")
13250              (reg:SI SP_REG)]
13251             UNSPEC_TLS_LD_BASE))
13252       (clobber (match_scratch:SI 3))
13253       (clobber (match_scratch:SI 4))
13254       (clobber (reg:CC FLAGS_REG))])]
13255   ""
13256   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13258 (define_insn "*tls_local_dynamic_base_64_<mode>"
13259   [(set (match_operand:P 0 "register_operand" "=a")
13260         (call:P
13261          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13262          (match_operand 2)))
13263    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13264   "TARGET_64BIT"
13266   output_asm_insn
13267     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13268   if (TARGET_SUN_TLS)
13269     return "call\t%p1@plt";
13270   return "call\t%P1";
13272   [(set_attr "type" "multi")
13273    (set_attr "length" "12")])
13275 (define_insn "*tls_local_dynamic_base_64_largepic"
13276   [(set (match_operand:DI 0 "register_operand" "=a")
13277         (call:DI
13278          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13279                           (match_operand:DI 2 "immediate_operand" "i")))
13280          (match_operand 3)))
13281    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13282   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13283    && GET_CODE (operands[2]) == CONST
13284    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13285    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13287   output_asm_insn
13288     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13289   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13290   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13291   return "call\t{*%%rax|rax}";
13293   [(set_attr "type" "multi")
13294    (set_attr "length" "22")])
13296 (define_expand "tls_local_dynamic_base_64_<mode>"
13297   [(parallel
13298      [(set (match_operand:P 0 "register_operand")
13299            (call:P
13300             (mem:QI (match_operand 1))
13301             (const_int 0)))
13302       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13303   "TARGET_64BIT"
13304   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13306 ;; Local dynamic of a single variable is a lose.  Show combine how
13307 ;; to convert that back to global dynamic.
13309 (define_insn_and_split "*tls_local_dynamic_32_once"
13310   [(set (match_operand:SI 0 "register_operand" "=a")
13311         (plus:SI
13312          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13313                      (match_operand 2 "constant_call_address_operand" "Bz")
13314                      (reg:SI SP_REG)]
13315                     UNSPEC_TLS_LD_BASE)
13316          (const:SI (unspec:SI
13317                     [(match_operand 3 "tls_symbolic_operand")]
13318                     UNSPEC_DTPOFF))))
13319    (clobber (match_scratch:SI 4 "=d"))
13320    (clobber (match_scratch:SI 5 "=c"))
13321    (clobber (reg:CC FLAGS_REG))]
13322   ""
13323   "#"
13324   ""
13325   [(parallel
13326      [(set (match_dup 0)
13327            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13328                        (reg:SI SP_REG)]
13329                       UNSPEC_TLS_GD))
13330       (clobber (match_dup 4))
13331       (clobber (match_dup 5))
13332       (clobber (reg:CC FLAGS_REG))])])
13334 ;; Segment register for the thread base ptr load
13335 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13337 ;; Load and add the thread base pointer from %<tp_seg>:0.
13338 (define_insn "*load_tp_x32"
13339   [(set (match_operand:SI 0 "register_operand" "=r")
13340         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13341   "TARGET_X32"
13342   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13343   [(set_attr "type" "imov")
13344    (set_attr "modrm" "0")
13345    (set_attr "length" "7")
13346    (set_attr "memory" "load")
13347    (set_attr "imm_disp" "false")])
13349 (define_insn "*load_tp_x32_zext"
13350   [(set (match_operand:DI 0 "register_operand" "=r")
13351         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13352   "TARGET_X32"
13353   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13354   [(set_attr "type" "imov")
13355    (set_attr "modrm" "0")
13356    (set_attr "length" "7")
13357    (set_attr "memory" "load")
13358    (set_attr "imm_disp" "false")])
13360 (define_insn "*load_tp_<mode>"
13361   [(set (match_operand:P 0 "register_operand" "=r")
13362         (unspec:P [(const_int 0)] UNSPEC_TP))]
13363   "!TARGET_X32"
13364   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13365   [(set_attr "type" "imov")
13366    (set_attr "modrm" "0")
13367    (set_attr "length" "7")
13368    (set_attr "memory" "load")
13369    (set_attr "imm_disp" "false")])
13371 (define_insn "*add_tp_x32"
13372   [(set (match_operand:SI 0 "register_operand" "=r")
13373         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13374                  (match_operand:SI 1 "register_operand" "0")))
13375    (clobber (reg:CC FLAGS_REG))]
13376   "TARGET_X32"
13377   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13378   [(set_attr "type" "alu")
13379    (set_attr "modrm" "0")
13380    (set_attr "length" "7")
13381    (set_attr "memory" "load")
13382    (set_attr "imm_disp" "false")])
13384 (define_insn "*add_tp_x32_zext"
13385   [(set (match_operand:DI 0 "register_operand" "=r")
13386         (zero_extend:DI
13387           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13388                    (match_operand:SI 1 "register_operand" "0"))))
13389    (clobber (reg:CC FLAGS_REG))]
13390   "TARGET_X32"
13391   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13392   [(set_attr "type" "alu")
13393    (set_attr "modrm" "0")
13394    (set_attr "length" "7")
13395    (set_attr "memory" "load")
13396    (set_attr "imm_disp" "false")])
13398 (define_insn "*add_tp_<mode>"
13399   [(set (match_operand:P 0 "register_operand" "=r")
13400         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13401                 (match_operand:P 1 "register_operand" "0")))
13402    (clobber (reg:CC FLAGS_REG))]
13403   "!TARGET_X32"
13404   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13405   [(set_attr "type" "alu")
13406    (set_attr "modrm" "0")
13407    (set_attr "length" "7")
13408    (set_attr "memory" "load")
13409    (set_attr "imm_disp" "false")])
13411 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13412 ;; %rax as destination of the initial executable code sequence.
13413 (define_insn "tls_initial_exec_64_sun"
13414   [(set (match_operand:DI 0 "register_operand" "=a")
13415         (unspec:DI
13416          [(match_operand 1 "tls_symbolic_operand")]
13417          UNSPEC_TLS_IE_SUN))
13418    (clobber (reg:CC FLAGS_REG))]
13419   "TARGET_64BIT && TARGET_SUN_TLS"
13421   output_asm_insn
13422     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13423   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13425   [(set_attr "type" "multi")])
13427 ;; GNU2 TLS patterns can be split.
13429 (define_expand "tls_dynamic_gnu2_32"
13430   [(set (match_dup 3)
13431         (plus:SI (match_operand:SI 2 "register_operand")
13432                  (const:SI
13433                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13434                              UNSPEC_TLSDESC))))
13435    (parallel
13436     [(set (match_operand:SI 0 "register_operand")
13437           (unspec:SI [(match_dup 1) (match_dup 3)
13438                       (match_dup 2) (reg:SI SP_REG)]
13439                       UNSPEC_TLSDESC))
13440      (clobber (reg:CC FLAGS_REG))])]
13441   "!TARGET_64BIT && TARGET_GNU2_TLS"
13443   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13444   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13447 (define_insn "*tls_dynamic_gnu2_lea_32"
13448   [(set (match_operand:SI 0 "register_operand" "=r")
13449         (plus:SI (match_operand:SI 1 "register_operand" "b")
13450                  (const:SI
13451                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13452                               UNSPEC_TLSDESC))))]
13453   "!TARGET_64BIT && TARGET_GNU2_TLS"
13454   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13455   [(set_attr "type" "lea")
13456    (set_attr "mode" "SI")
13457    (set_attr "length" "6")
13458    (set_attr "length_address" "4")])
13460 (define_insn "*tls_dynamic_gnu2_call_32"
13461   [(set (match_operand:SI 0 "register_operand" "=a")
13462         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13463                     (match_operand:SI 2 "register_operand" "0")
13464                     ;; we have to make sure %ebx still points to the GOT
13465                     (match_operand:SI 3 "register_operand" "b")
13466                     (reg:SI SP_REG)]
13467                    UNSPEC_TLSDESC))
13468    (clobber (reg:CC FLAGS_REG))]
13469   "!TARGET_64BIT && TARGET_GNU2_TLS"
13470   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13471   [(set_attr "type" "call")
13472    (set_attr "length" "2")
13473    (set_attr "length_address" "0")])
13475 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13476   [(set (match_operand:SI 0 "register_operand" "=&a")
13477         (plus:SI
13478          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13479                      (match_operand:SI 4)
13480                      (match_operand:SI 2 "register_operand" "b")
13481                      (reg:SI SP_REG)]
13482                     UNSPEC_TLSDESC)
13483          (const:SI (unspec:SI
13484                     [(match_operand 1 "tls_symbolic_operand")]
13485                     UNSPEC_DTPOFF))))
13486    (clobber (reg:CC FLAGS_REG))]
13487   "!TARGET_64BIT && TARGET_GNU2_TLS"
13488   "#"
13489   ""
13490   [(set (match_dup 0) (match_dup 5))]
13492   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13493   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13496 (define_expand "tls_dynamic_gnu2_64"
13497   [(set (match_dup 2)
13498         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13499                    UNSPEC_TLSDESC))
13500    (parallel
13501     [(set (match_operand:DI 0 "register_operand")
13502           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13503                      UNSPEC_TLSDESC))
13504      (clobber (reg:CC FLAGS_REG))])]
13505   "TARGET_64BIT && TARGET_GNU2_TLS"
13507   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13508   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13511 (define_insn "*tls_dynamic_gnu2_lea_64"
13512   [(set (match_operand:DI 0 "register_operand" "=r")
13513         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13514                    UNSPEC_TLSDESC))]
13515   "TARGET_64BIT && TARGET_GNU2_TLS"
13516   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13517   [(set_attr "type" "lea")
13518    (set_attr "mode" "DI")
13519    (set_attr "length" "7")
13520    (set_attr "length_address" "4")])
13522 (define_insn "*tls_dynamic_gnu2_call_64"
13523   [(set (match_operand:DI 0 "register_operand" "=a")
13524         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13525                     (match_operand:DI 2 "register_operand" "0")
13526                     (reg:DI SP_REG)]
13527                    UNSPEC_TLSDESC))
13528    (clobber (reg:CC FLAGS_REG))]
13529   "TARGET_64BIT && TARGET_GNU2_TLS"
13530   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13531   [(set_attr "type" "call")
13532    (set_attr "length" "2")
13533    (set_attr "length_address" "0")])
13535 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13536   [(set (match_operand:DI 0 "register_operand" "=&a")
13537         (plus:DI
13538          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13539                      (match_operand:DI 3)
13540                      (reg:DI SP_REG)]
13541                     UNSPEC_TLSDESC)
13542          (const:DI (unspec:DI
13543                     [(match_operand 1 "tls_symbolic_operand")]
13544                     UNSPEC_DTPOFF))))
13545    (clobber (reg:CC FLAGS_REG))]
13546   "TARGET_64BIT && TARGET_GNU2_TLS"
13547   "#"
13548   ""
13549   [(set (match_dup 0) (match_dup 4))]
13551   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13552   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13555 ;; These patterns match the binary 387 instructions for addM3, subM3,
13556 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13557 ;; SFmode.  The first is the normal insn, the second the same insn but
13558 ;; with one operand a conversion, and the third the same insn but with
13559 ;; the other operand a conversion.  The conversion may be SFmode or
13560 ;; SImode if the target mode DFmode, but only SImode if the target mode
13561 ;; is SFmode.
13563 ;; Gcc is slightly more smart about handling normal two address instructions
13564 ;; so use special patterns for add and mull.
13566 (define_insn "*fop_<mode>_comm_mixed"
13567   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
13568         (match_operator:MODEF 3 "binary_fp_operator"
13569           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
13570            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
13571   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13572    && COMMUTATIVE_ARITH_P (operands[3])
13573    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13574   "* return output_387_binary_op (insn, operands);"
13575   [(set (attr "type")
13576         (if_then_else (eq_attr "alternative" "1,2")
13577            (if_then_else (match_operand:MODEF 3 "mult_operator")
13578               (const_string "ssemul")
13579               (const_string "sseadd"))
13580            (if_then_else (match_operand:MODEF 3 "mult_operator")
13581               (const_string "fmul")
13582               (const_string "fop"))))
13583    (set_attr "isa" "*,noavx,avx")
13584    (set_attr "prefix" "orig,orig,vex")
13585    (set_attr "mode" "<MODE>")
13586    (set (attr "enabled")
13587      (cond [(eq_attr "alternative" "0")
13588               (symbol_ref "TARGET_MIX_SSE_I387")
13589            ]
13590            (const_string "*")))])
13592 (define_insn "*fop_<mode>_comm_i387"
13593   [(set (match_operand:MODEF 0 "register_operand" "=f")
13594         (match_operator:MODEF 3 "binary_fp_operator"
13595           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13596            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13597   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13598    && COMMUTATIVE_ARITH_P (operands[3])
13599    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13600   "* return output_387_binary_op (insn, operands);"
13601   [(set (attr "type")
13602         (if_then_else (match_operand:MODEF 3 "mult_operator")
13603            (const_string "fmul")
13604            (const_string "fop")))
13605    (set_attr "mode" "<MODE>")])
13607 (define_insn "*rcpsf2_sse"
13608   [(set (match_operand:SF 0 "register_operand" "=x")
13609         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13610                    UNSPEC_RCP))]
13611   "TARGET_SSE_MATH"
13612   "%vrcpss\t{%1, %d0|%d0, %1}"
13613   [(set_attr "type" "sse")
13614    (set_attr "atom_sse_attr" "rcp")
13615    (set_attr "btver2_sse_attr" "rcp")
13616    (set_attr "prefix" "maybe_vex")
13617    (set_attr "mode" "SF")])
13619 (define_insn "*fop_<mode>_1_mixed"
13620   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
13621         (match_operator:MODEF 3 "binary_fp_operator"
13622           [(match_operand:MODEF 1
13623              "register_mixssei387nonimm_operand" "0,fm,0,v")
13624            (match_operand:MODEF 2
13625              "nonimmediate_operand"              "fm,0,xm,vm")]))]
13626   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13627    && !COMMUTATIVE_ARITH_P (operands[3])
13628    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13629   "* return output_387_binary_op (insn, operands);"
13630   [(set (attr "type")
13631         (cond [(and (eq_attr "alternative" "2,3")
13632                     (match_operand:MODEF 3 "mult_operator"))
13633                  (const_string "ssemul")
13634                (and (eq_attr "alternative" "2,3")
13635                     (match_operand:MODEF 3 "div_operator"))
13636                  (const_string "ssediv")
13637                (eq_attr "alternative" "2,3")
13638                  (const_string "sseadd")
13639                (match_operand:MODEF 3 "mult_operator")
13640                  (const_string "fmul")
13641                (match_operand:MODEF 3 "div_operator")
13642                  (const_string "fdiv")
13643               ]
13644               (const_string "fop")))
13645    (set_attr "isa" "*,*,noavx,avx")
13646    (set_attr "prefix" "orig,orig,orig,vex")
13647    (set_attr "mode" "<MODE>")
13648    (set (attr "enabled")
13649      (cond [(eq_attr "alternative" "0,1")
13650               (symbol_ref "TARGET_MIX_SSE_I387")
13651            ]
13652            (const_string "*")))])
13654 ;; This pattern is not fully shadowed by the pattern above.
13655 (define_insn "*fop_<mode>_1_i387"
13656   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13657         (match_operator:MODEF 3 "binary_fp_operator"
13658           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13659            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13660   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13661    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662    && !COMMUTATIVE_ARITH_P (operands[3])
13663    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13664   "* return output_387_binary_op (insn, operands);"
13665   [(set (attr "type")
13666         (cond [(match_operand:MODEF 3 "mult_operator")
13667                  (const_string "fmul")
13668                (match_operand:MODEF 3 "div_operator")
13669                  (const_string "fdiv")
13670               ]
13671               (const_string "fop")))
13672    (set_attr "mode" "<MODE>")])
13674 ;; ??? Add SSE splitters for these!
13675 (define_insn "*fop_<MODEF:mode>_2_i387"
13676   [(set (match_operand:MODEF 0 "register_operand" "=f")
13677         (match_operator:MODEF 3 "binary_fp_operator"
13678           [(float:MODEF
13679              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13680            (match_operand:MODEF 2 "register_operand" "0")]))]
13681   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13682    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13683    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13684        || optimize_function_for_size_p (cfun))"
13685   { return output_387_binary_op (insn, operands); }
13686   [(set (attr "type")
13687         (cond [(match_operand:MODEF 3 "mult_operator")
13688                  (const_string "fmul")
13689                (match_operand:MODEF 3 "div_operator")
13690                  (const_string "fdiv")
13691               ]
13692               (const_string "fop")))
13693    (set_attr "fp_int_src" "true")
13694    (set_attr "mode" "<SWI24:MODE>")])
13696 (define_insn "*fop_<MODEF:mode>_3_i387"
13697   [(set (match_operand:MODEF 0 "register_operand" "=f")
13698         (match_operator:MODEF 3 "binary_fp_operator"
13699           [(match_operand:MODEF 1 "register_operand" "0")
13700            (float:MODEF
13701              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13702   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13703    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13704    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13705        || optimize_function_for_size_p (cfun))"
13706   { return output_387_binary_op (insn, operands); }
13707   [(set (attr "type")
13708         (cond [(match_operand:MODEF 3 "mult_operator")
13709                  (const_string "fmul")
13710                (match_operand:MODEF 3 "div_operator")
13711                  (const_string "fdiv")
13712               ]
13713               (const_string "fop")))
13714    (set_attr "fp_int_src" "true")
13715    (set_attr "mode" "<MODE>")])
13717 (define_insn "*fop_df_4_i387"
13718   [(set (match_operand:DF 0 "register_operand" "=f,f")
13719         (match_operator:DF 3 "binary_fp_operator"
13720            [(float_extend:DF
13721              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13722             (match_operand:DF 2 "register_operand" "0,f")]))]
13723   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13724    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13725    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13726   "* return output_387_binary_op (insn, operands);"
13727   [(set (attr "type")
13728         (cond [(match_operand:DF 3 "mult_operator")
13729                  (const_string "fmul")
13730                (match_operand:DF 3 "div_operator")
13731                  (const_string "fdiv")
13732               ]
13733               (const_string "fop")))
13734    (set_attr "mode" "SF")])
13736 (define_insn "*fop_df_5_i387"
13737   [(set (match_operand:DF 0 "register_operand" "=f,f")
13738         (match_operator:DF 3 "binary_fp_operator"
13739           [(match_operand:DF 1 "register_operand" "0,f")
13740            (float_extend:DF
13741             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13742   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13743    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13744   "* return output_387_binary_op (insn, operands);"
13745   [(set (attr "type")
13746         (cond [(match_operand:DF 3 "mult_operator")
13747                  (const_string "fmul")
13748                (match_operand:DF 3 "div_operator")
13749                  (const_string "fdiv")
13750               ]
13751               (const_string "fop")))
13752    (set_attr "mode" "SF")])
13754 (define_insn "*fop_df_6_i387"
13755   [(set (match_operand:DF 0 "register_operand" "=f,f")
13756         (match_operator:DF 3 "binary_fp_operator"
13757           [(float_extend:DF
13758             (match_operand:SF 1 "register_operand" "0,f"))
13759            (float_extend:DF
13760             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13761   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13762    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13763   "* return output_387_binary_op (insn, operands);"
13764   [(set (attr "type")
13765         (cond [(match_operand:DF 3 "mult_operator")
13766                  (const_string "fmul")
13767                (match_operand:DF 3 "div_operator")
13768                  (const_string "fdiv")
13769               ]
13770               (const_string "fop")))
13771    (set_attr "mode" "SF")])
13773 (define_insn "*fop_xf_comm_i387"
13774   [(set (match_operand:XF 0 "register_operand" "=f")
13775         (match_operator:XF 3 "binary_fp_operator"
13776                         [(match_operand:XF 1 "register_operand" "%0")
13777                          (match_operand:XF 2 "register_operand" "f")]))]
13778   "TARGET_80387
13779    && COMMUTATIVE_ARITH_P (operands[3])"
13780   "* return output_387_binary_op (insn, operands);"
13781   [(set (attr "type")
13782         (if_then_else (match_operand:XF 3 "mult_operator")
13783            (const_string "fmul")
13784            (const_string "fop")))
13785    (set_attr "mode" "XF")])
13787 (define_insn "*fop_xf_1_i387"
13788   [(set (match_operand:XF 0 "register_operand" "=f,f")
13789         (match_operator:XF 3 "binary_fp_operator"
13790                         [(match_operand:XF 1 "register_operand" "0,f")
13791                          (match_operand:XF 2 "register_operand" "f,0")]))]
13792   "TARGET_80387
13793    && !COMMUTATIVE_ARITH_P (operands[3])"
13794   "* return output_387_binary_op (insn, operands);"
13795   [(set (attr "type")
13796         (cond [(match_operand:XF 3 "mult_operator")
13797                  (const_string "fmul")
13798                (match_operand:XF 3 "div_operator")
13799                  (const_string "fdiv")
13800               ]
13801               (const_string "fop")))
13802    (set_attr "mode" "XF")])
13804 (define_insn "*fop_xf_2_i387"
13805   [(set (match_operand:XF 0 "register_operand" "=f")
13806         (match_operator:XF 3 "binary_fp_operator"
13807           [(float:XF
13808              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13809            (match_operand:XF 2 "register_operand" "0")]))]
13810   "TARGET_80387
13811    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13812   { return output_387_binary_op (insn, operands); }
13813   [(set (attr "type")
13814         (cond [(match_operand:XF 3 "mult_operator")
13815                  (const_string "fmul")
13816                (match_operand:XF 3 "div_operator")
13817                  (const_string "fdiv")
13818               ]
13819               (const_string "fop")))
13820    (set_attr "fp_int_src" "true")
13821    (set_attr "mode" "<MODE>")])
13823 (define_insn "*fop_xf_3_i387"
13824   [(set (match_operand:XF 0 "register_operand" "=f")
13825         (match_operator:XF 3 "binary_fp_operator"
13826           [(match_operand:XF 1 "register_operand" "0")
13827            (float:XF
13828              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13829   "TARGET_80387
13830    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13831   { return output_387_binary_op (insn, operands); }
13832   [(set (attr "type")
13833         (cond [(match_operand:XF 3 "mult_operator")
13834                  (const_string "fmul")
13835                (match_operand:XF 3 "div_operator")
13836                  (const_string "fdiv")
13837               ]
13838               (const_string "fop")))
13839    (set_attr "fp_int_src" "true")
13840    (set_attr "mode" "<MODE>")])
13842 (define_insn "*fop_xf_4_i387"
13843   [(set (match_operand:XF 0 "register_operand" "=f,f")
13844         (match_operator:XF 3 "binary_fp_operator"
13845            [(float_extend:XF
13846               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13847             (match_operand:XF 2 "register_operand" "0,f")]))]
13848   "TARGET_80387"
13849   "* return output_387_binary_op (insn, operands);"
13850   [(set (attr "type")
13851         (cond [(match_operand:XF 3 "mult_operator")
13852                  (const_string "fmul")
13853                (match_operand:XF 3 "div_operator")
13854                  (const_string "fdiv")
13855               ]
13856               (const_string "fop")))
13857    (set_attr "mode" "<MODE>")])
13859 (define_insn "*fop_xf_5_i387"
13860   [(set (match_operand:XF 0 "register_operand" "=f,f")
13861         (match_operator:XF 3 "binary_fp_operator"
13862           [(match_operand:XF 1 "register_operand" "0,f")
13863            (float_extend:XF
13864              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13865   "TARGET_80387"
13866   "* return output_387_binary_op (insn, operands);"
13867   [(set (attr "type")
13868         (cond [(match_operand:XF 3 "mult_operator")
13869                  (const_string "fmul")
13870                (match_operand:XF 3 "div_operator")
13871                  (const_string "fdiv")
13872               ]
13873               (const_string "fop")))
13874    (set_attr "mode" "<MODE>")])
13876 (define_insn "*fop_xf_6_i387"
13877   [(set (match_operand:XF 0 "register_operand" "=f,f")
13878         (match_operator:XF 3 "binary_fp_operator"
13879           [(float_extend:XF
13880              (match_operand:MODEF 1 "register_operand" "0,f"))
13881            (float_extend:XF
13882              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13883   "TARGET_80387"
13884   "* return output_387_binary_op (insn, operands);"
13885   [(set (attr "type")
13886         (cond [(match_operand:XF 3 "mult_operator")
13887                  (const_string "fmul")
13888                (match_operand:XF 3 "div_operator")
13889                  (const_string "fdiv")
13890               ]
13891               (const_string "fop")))
13892    (set_attr "mode" "<MODE>")])
13894 ;; FPU special functions.
13896 ;; This pattern implements a no-op XFmode truncation for
13897 ;; all fancy i386 XFmode math functions.
13899 (define_insn "truncxf<mode>2_i387_noop_unspec"
13900   [(set (match_operand:MODEF 0 "register_operand" "=f")
13901         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13902         UNSPEC_TRUNC_NOOP))]
13903   "TARGET_USE_FANCY_MATH_387"
13904   "* return output_387_reg_move (insn, operands);"
13905   [(set_attr "type" "fmov")
13906    (set_attr "mode" "<MODE>")])
13908 (define_insn "sqrtxf2"
13909   [(set (match_operand:XF 0 "register_operand" "=f")
13910         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13911   "TARGET_USE_FANCY_MATH_387"
13912   "fsqrt"
13913   [(set_attr "type" "fpspc")
13914    (set_attr "mode" "XF")
13915    (set_attr "athlon_decode" "direct")
13916    (set_attr "amdfam10_decode" "direct")
13917    (set_attr "bdver1_decode" "direct")])
13919 (define_insn "sqrt_extend<mode>xf2_i387"
13920   [(set (match_operand:XF 0 "register_operand" "=f")
13921         (sqrt:XF
13922           (float_extend:XF
13923             (match_operand:MODEF 1 "register_operand" "0"))))]
13924   "TARGET_USE_FANCY_MATH_387"
13925   "fsqrt"
13926   [(set_attr "type" "fpspc")
13927    (set_attr "mode" "XF")
13928    (set_attr "athlon_decode" "direct")
13929    (set_attr "amdfam10_decode" "direct")
13930    (set_attr "bdver1_decode" "direct")])
13932 (define_insn "*rsqrtsf2_sse"
13933   [(set (match_operand:SF 0 "register_operand" "=x")
13934         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13935                    UNSPEC_RSQRT))]
13936   "TARGET_SSE_MATH"
13937   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13938   [(set_attr "type" "sse")
13939    (set_attr "atom_sse_attr" "rcp")
13940    (set_attr "btver2_sse_attr" "rcp")
13941    (set_attr "prefix" "maybe_vex")
13942    (set_attr "mode" "SF")])
13944 (define_expand "rsqrtsf2"
13945   [(set (match_operand:SF 0 "register_operand")
13946         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13947                    UNSPEC_RSQRT))]
13948   "TARGET_SSE_MATH"
13950   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13951   DONE;
13954 (define_insn "*sqrt<mode>2_sse"
13955   [(set (match_operand:MODEF 0 "register_operand" "=v")
13956         (sqrt:MODEF
13957           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
13958   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13959   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13960   [(set_attr "type" "sse")
13961    (set_attr "atom_sse_attr" "sqrt")
13962    (set_attr "btver2_sse_attr" "sqrt")
13963    (set_attr "prefix" "maybe_vex")
13964    (set_attr "mode" "<MODE>")
13965    (set_attr "athlon_decode" "*")
13966    (set_attr "amdfam10_decode" "*")
13967    (set_attr "bdver1_decode" "*")])
13969 (define_expand "sqrt<mode>2"
13970   [(set (match_operand:MODEF 0 "register_operand")
13971         (sqrt:MODEF
13972           (match_operand:MODEF 1 "nonimmediate_operand")))]
13973   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13974    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13976   if (<MODE>mode == SFmode
13977       && TARGET_SSE_MATH
13978       && TARGET_RECIP_SQRT
13979       && !optimize_function_for_size_p (cfun)
13980       && flag_finite_math_only && !flag_trapping_math
13981       && flag_unsafe_math_optimizations)
13982     {
13983       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13984       DONE;
13985     }
13987   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13988     {
13989       rtx op0 = gen_reg_rtx (XFmode);
13990       rtx op1 = force_reg (<MODE>mode, operands[1]);
13992       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13993       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13994       DONE;
13995    }
13998 (define_insn "fpremxf4_i387"
13999   [(set (match_operand:XF 0 "register_operand" "=f")
14000         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14001                     (match_operand:XF 3 "register_operand" "1")]
14002                    UNSPEC_FPREM_F))
14003    (set (match_operand:XF 1 "register_operand" "=u")
14004         (unspec:XF [(match_dup 2) (match_dup 3)]
14005                    UNSPEC_FPREM_U))
14006    (set (reg:CCFP FPSR_REG)
14007         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14008                      UNSPEC_C2_FLAG))]
14009   "TARGET_USE_FANCY_MATH_387
14010    && flag_finite_math_only"
14011   "fprem"
14012   [(set_attr "type" "fpspc")
14013    (set_attr "mode" "XF")])
14015 (define_expand "fmodxf3"
14016   [(use (match_operand:XF 0 "register_operand"))
14017    (use (match_operand:XF 1 "general_operand"))
14018    (use (match_operand:XF 2 "general_operand"))]
14019   "TARGET_USE_FANCY_MATH_387
14020    && flag_finite_math_only"
14022   rtx_code_label *label = gen_label_rtx ();
14024   rtx op1 = gen_reg_rtx (XFmode);
14025   rtx op2 = gen_reg_rtx (XFmode);
14027   emit_move_insn (op2, operands[2]);
14028   emit_move_insn (op1, operands[1]);
14030   emit_label (label);
14031   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14032   ix86_emit_fp_unordered_jump (label);
14033   LABEL_NUSES (label) = 1;
14035   emit_move_insn (operands[0], op1);
14036   DONE;
14039 (define_expand "fmod<mode>3"
14040   [(use (match_operand:MODEF 0 "register_operand"))
14041    (use (match_operand:MODEF 1 "general_operand"))
14042    (use (match_operand:MODEF 2 "general_operand"))]
14043   "TARGET_USE_FANCY_MATH_387
14044    && flag_finite_math_only"
14046   rtx (*gen_truncxf) (rtx, rtx);
14048   rtx_code_label *label = gen_label_rtx ();
14050   rtx op1 = gen_reg_rtx (XFmode);
14051   rtx op2 = gen_reg_rtx (XFmode);
14053   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14054   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14056   emit_label (label);
14057   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14058   ix86_emit_fp_unordered_jump (label);
14059   LABEL_NUSES (label) = 1;
14061   /* Truncate the result properly for strict SSE math.  */
14062   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14063       && !TARGET_MIX_SSE_I387)
14064     gen_truncxf = gen_truncxf<mode>2;
14065   else
14066     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14068   emit_insn (gen_truncxf (operands[0], op1));
14069   DONE;
14072 (define_insn "fprem1xf4_i387"
14073   [(set (match_operand:XF 0 "register_operand" "=f")
14074         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14075                     (match_operand:XF 3 "register_operand" "1")]
14076                    UNSPEC_FPREM1_F))
14077    (set (match_operand:XF 1 "register_operand" "=u")
14078         (unspec:XF [(match_dup 2) (match_dup 3)]
14079                    UNSPEC_FPREM1_U))
14080    (set (reg:CCFP FPSR_REG)
14081         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14082                      UNSPEC_C2_FLAG))]
14083   "TARGET_USE_FANCY_MATH_387
14084    && flag_finite_math_only"
14085   "fprem1"
14086   [(set_attr "type" "fpspc")
14087    (set_attr "mode" "XF")])
14089 (define_expand "remainderxf3"
14090   [(use (match_operand:XF 0 "register_operand"))
14091    (use (match_operand:XF 1 "general_operand"))
14092    (use (match_operand:XF 2 "general_operand"))]
14093   "TARGET_USE_FANCY_MATH_387
14094    && flag_finite_math_only"
14096   rtx_code_label *label = gen_label_rtx ();
14098   rtx op1 = gen_reg_rtx (XFmode);
14099   rtx op2 = gen_reg_rtx (XFmode);
14101   emit_move_insn (op2, operands[2]);
14102   emit_move_insn (op1, operands[1]);
14104   emit_label (label);
14105   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14106   ix86_emit_fp_unordered_jump (label);
14107   LABEL_NUSES (label) = 1;
14109   emit_move_insn (operands[0], op1);
14110   DONE;
14113 (define_expand "remainder<mode>3"
14114   [(use (match_operand:MODEF 0 "register_operand"))
14115    (use (match_operand:MODEF 1 "general_operand"))
14116    (use (match_operand:MODEF 2 "general_operand"))]
14117   "TARGET_USE_FANCY_MATH_387
14118    && flag_finite_math_only"
14120   rtx (*gen_truncxf) (rtx, rtx);
14122   rtx_code_label *label = gen_label_rtx ();
14124   rtx op1 = gen_reg_rtx (XFmode);
14125   rtx op2 = gen_reg_rtx (XFmode);
14127   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14128   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14130   emit_label (label);
14132   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14133   ix86_emit_fp_unordered_jump (label);
14134   LABEL_NUSES (label) = 1;
14136   /* Truncate the result properly for strict SSE math.  */
14137   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14138       && !TARGET_MIX_SSE_I387)
14139     gen_truncxf = gen_truncxf<mode>2;
14140   else
14141     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14143   emit_insn (gen_truncxf (operands[0], op1));
14144   DONE;
14147 (define_int_iterator SINCOS
14148         [UNSPEC_SIN
14149          UNSPEC_COS])
14151 (define_int_attr sincos
14152         [(UNSPEC_SIN "sin")
14153          (UNSPEC_COS "cos")])
14155 (define_insn "*<sincos>xf2_i387"
14156   [(set (match_operand:XF 0 "register_operand" "=f")
14157         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14158                    SINCOS))]
14159   "TARGET_USE_FANCY_MATH_387
14160    && flag_unsafe_math_optimizations"
14161   "f<sincos>"
14162   [(set_attr "type" "fpspc")
14163    (set_attr "mode" "XF")])
14165 (define_insn "*<sincos>_extend<mode>xf2_i387"
14166   [(set (match_operand:XF 0 "register_operand" "=f")
14167         (unspec:XF [(float_extend:XF
14168                       (match_operand:MODEF 1 "register_operand" "0"))]
14169                    SINCOS))]
14170   "TARGET_USE_FANCY_MATH_387
14171    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14172        || TARGET_MIX_SSE_I387)
14173    && flag_unsafe_math_optimizations"
14174   "f<sincos>"
14175   [(set_attr "type" "fpspc")
14176    (set_attr "mode" "XF")])
14178 ;; When sincos pattern is defined, sin and cos builtin functions will be
14179 ;; expanded to sincos pattern with one of its outputs left unused.
14180 ;; CSE pass will figure out if two sincos patterns can be combined,
14181 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14182 ;; depending on the unused output.
14184 (define_insn "sincosxf3"
14185   [(set (match_operand:XF 0 "register_operand" "=f")
14186         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14187                    UNSPEC_SINCOS_COS))
14188    (set (match_operand:XF 1 "register_operand" "=u")
14189         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14190   "TARGET_USE_FANCY_MATH_387
14191    && flag_unsafe_math_optimizations"
14192   "fsincos"
14193   [(set_attr "type" "fpspc")
14194    (set_attr "mode" "XF")])
14196 (define_split
14197   [(set (match_operand:XF 0 "register_operand")
14198         (unspec:XF [(match_operand:XF 2 "register_operand")]
14199                    UNSPEC_SINCOS_COS))
14200    (set (match_operand:XF 1 "register_operand")
14201         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14202   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14203    && can_create_pseudo_p ()"
14204   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14206 (define_split
14207   [(set (match_operand:XF 0 "register_operand")
14208         (unspec:XF [(match_operand:XF 2 "register_operand")]
14209                    UNSPEC_SINCOS_COS))
14210    (set (match_operand:XF 1 "register_operand")
14211         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14212   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14213    && can_create_pseudo_p ()"
14214   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14216 (define_insn "sincos_extend<mode>xf3_i387"
14217   [(set (match_operand:XF 0 "register_operand" "=f")
14218         (unspec:XF [(float_extend:XF
14219                       (match_operand:MODEF 2 "register_operand" "0"))]
14220                    UNSPEC_SINCOS_COS))
14221    (set (match_operand:XF 1 "register_operand" "=u")
14222         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14223   "TARGET_USE_FANCY_MATH_387
14224    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14225        || TARGET_MIX_SSE_I387)
14226    && flag_unsafe_math_optimizations"
14227   "fsincos"
14228   [(set_attr "type" "fpspc")
14229    (set_attr "mode" "XF")])
14231 (define_split
14232   [(set (match_operand:XF 0 "register_operand")
14233         (unspec:XF [(float_extend:XF
14234                       (match_operand:MODEF 2 "register_operand"))]
14235                    UNSPEC_SINCOS_COS))
14236    (set (match_operand:XF 1 "register_operand")
14237         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14238   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14239    && can_create_pseudo_p ()"
14240   [(set (match_dup 1)
14241         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14243 (define_split
14244   [(set (match_operand:XF 0 "register_operand")
14245         (unspec:XF [(float_extend:XF
14246                       (match_operand:MODEF 2 "register_operand"))]
14247                    UNSPEC_SINCOS_COS))
14248    (set (match_operand:XF 1 "register_operand")
14249         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14250   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14251    && can_create_pseudo_p ()"
14252   [(set (match_dup 0)
14253         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14255 (define_expand "sincos<mode>3"
14256   [(use (match_operand:MODEF 0 "register_operand"))
14257    (use (match_operand:MODEF 1 "register_operand"))
14258    (use (match_operand:MODEF 2 "register_operand"))]
14259   "TARGET_USE_FANCY_MATH_387
14260    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14261        || TARGET_MIX_SSE_I387)
14262    && flag_unsafe_math_optimizations"
14264   rtx op0 = gen_reg_rtx (XFmode);
14265   rtx op1 = gen_reg_rtx (XFmode);
14267   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14268   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14269   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14270   DONE;
14273 (define_insn "fptanxf4_i387"
14274   [(set (match_operand:XF 0 "register_operand" "=f")
14275         (match_operand:XF 3 "const_double_operand" "F"))
14276    (set (match_operand:XF 1 "register_operand" "=u")
14277         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14278                    UNSPEC_TAN))]
14279   "TARGET_USE_FANCY_MATH_387
14280    && flag_unsafe_math_optimizations
14281    && standard_80387_constant_p (operands[3]) == 2"
14282   "fptan"
14283   [(set_attr "type" "fpspc")
14284    (set_attr "mode" "XF")])
14286 (define_insn "fptan_extend<mode>xf4_i387"
14287   [(set (match_operand:MODEF 0 "register_operand" "=f")
14288         (match_operand:MODEF 3 "const_double_operand" "F"))
14289    (set (match_operand:XF 1 "register_operand" "=u")
14290         (unspec:XF [(float_extend:XF
14291                       (match_operand:MODEF 2 "register_operand" "0"))]
14292                    UNSPEC_TAN))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295        || TARGET_MIX_SSE_I387)
14296    && flag_unsafe_math_optimizations
14297    && standard_80387_constant_p (operands[3]) == 2"
14298   "fptan"
14299   [(set_attr "type" "fpspc")
14300    (set_attr "mode" "XF")])
14302 (define_expand "tanxf2"
14303   [(use (match_operand:XF 0 "register_operand"))
14304    (use (match_operand:XF 1 "register_operand"))]
14305   "TARGET_USE_FANCY_MATH_387
14306    && flag_unsafe_math_optimizations"
14308   rtx one = gen_reg_rtx (XFmode);
14309   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14311   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14312   DONE;
14315 (define_expand "tan<mode>2"
14316   [(use (match_operand:MODEF 0 "register_operand"))
14317    (use (match_operand:MODEF 1 "register_operand"))]
14318   "TARGET_USE_FANCY_MATH_387
14319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14320        || TARGET_MIX_SSE_I387)
14321    && flag_unsafe_math_optimizations"
14323   rtx op0 = gen_reg_rtx (XFmode);
14325   rtx one = gen_reg_rtx (<MODE>mode);
14326   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14328   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14329                                              operands[1], op2));
14330   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14331   DONE;
14334 (define_insn "*fpatanxf3_i387"
14335   [(set (match_operand:XF 0 "register_operand" "=f")
14336         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14337                     (match_operand:XF 2 "register_operand" "u")]
14338                    UNSPEC_FPATAN))
14339    (clobber (match_scratch:XF 3 "=2"))]
14340   "TARGET_USE_FANCY_MATH_387
14341    && flag_unsafe_math_optimizations"
14342   "fpatan"
14343   [(set_attr "type" "fpspc")
14344    (set_attr "mode" "XF")])
14346 (define_insn "fpatan_extend<mode>xf3_i387"
14347   [(set (match_operand:XF 0 "register_operand" "=f")
14348         (unspec:XF [(float_extend:XF
14349                       (match_operand:MODEF 1 "register_operand" "0"))
14350                     (float_extend:XF
14351                       (match_operand:MODEF 2 "register_operand" "u"))]
14352                    UNSPEC_FPATAN))
14353    (clobber (match_scratch:XF 3 "=2"))]
14354   "TARGET_USE_FANCY_MATH_387
14355    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14356        || TARGET_MIX_SSE_I387)
14357    && flag_unsafe_math_optimizations"
14358   "fpatan"
14359   [(set_attr "type" "fpspc")
14360    (set_attr "mode" "XF")])
14362 (define_expand "atan2xf3"
14363   [(parallel [(set (match_operand:XF 0 "register_operand")
14364                    (unspec:XF [(match_operand:XF 2 "register_operand")
14365                                (match_operand:XF 1 "register_operand")]
14366                               UNSPEC_FPATAN))
14367               (clobber (match_scratch:XF 3))])]
14368   "TARGET_USE_FANCY_MATH_387
14369    && flag_unsafe_math_optimizations")
14371 (define_expand "atan2<mode>3"
14372   [(use (match_operand:MODEF 0 "register_operand"))
14373    (use (match_operand:MODEF 1 "register_operand"))
14374    (use (match_operand:MODEF 2 "register_operand"))]
14375   "TARGET_USE_FANCY_MATH_387
14376    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14377        || TARGET_MIX_SSE_I387)
14378    && flag_unsafe_math_optimizations"
14380   rtx op0 = gen_reg_rtx (XFmode);
14382   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14383   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14384   DONE;
14387 (define_expand "atanxf2"
14388   [(parallel [(set (match_operand:XF 0 "register_operand")
14389                    (unspec:XF [(match_dup 2)
14390                                (match_operand:XF 1 "register_operand")]
14391                               UNSPEC_FPATAN))
14392               (clobber (match_scratch:XF 3))])]
14393   "TARGET_USE_FANCY_MATH_387
14394    && flag_unsafe_math_optimizations"
14396   operands[2] = gen_reg_rtx (XFmode);
14397   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14400 (define_expand "atan<mode>2"
14401   [(use (match_operand:MODEF 0 "register_operand"))
14402    (use (match_operand:MODEF 1 "register_operand"))]
14403   "TARGET_USE_FANCY_MATH_387
14404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14405        || TARGET_MIX_SSE_I387)
14406    && flag_unsafe_math_optimizations"
14408   rtx op0 = gen_reg_rtx (XFmode);
14410   rtx op2 = gen_reg_rtx (<MODE>mode);
14411   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14413   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14414   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14415   DONE;
14418 (define_expand "asinxf2"
14419   [(set (match_dup 2)
14420         (mult:XF (match_operand:XF 1 "register_operand")
14421                  (match_dup 1)))
14422    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14423    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14424    (parallel [(set (match_operand:XF 0 "register_operand")
14425                    (unspec:XF [(match_dup 5) (match_dup 1)]
14426                               UNSPEC_FPATAN))
14427               (clobber (match_scratch:XF 6))])]
14428   "TARGET_USE_FANCY_MATH_387
14429    && flag_unsafe_math_optimizations"
14431   int i;
14433   if (optimize_insn_for_size_p ())
14434     FAIL;
14436   for (i = 2; i < 6; i++)
14437     operands[i] = gen_reg_rtx (XFmode);
14439   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14442 (define_expand "asin<mode>2"
14443   [(use (match_operand:MODEF 0 "register_operand"))
14444    (use (match_operand:MODEF 1 "general_operand"))]
14445  "TARGET_USE_FANCY_MATH_387
14446    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447        || TARGET_MIX_SSE_I387)
14448    && flag_unsafe_math_optimizations"
14450   rtx op0 = gen_reg_rtx (XFmode);
14451   rtx op1 = gen_reg_rtx (XFmode);
14453   if (optimize_insn_for_size_p ())
14454     FAIL;
14456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14457   emit_insn (gen_asinxf2 (op0, op1));
14458   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14459   DONE;
14462 (define_expand "acosxf2"
14463   [(set (match_dup 2)
14464         (mult:XF (match_operand:XF 1 "register_operand")
14465                  (match_dup 1)))
14466    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14467    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14468    (parallel [(set (match_operand:XF 0 "register_operand")
14469                    (unspec:XF [(match_dup 1) (match_dup 5)]
14470                               UNSPEC_FPATAN))
14471               (clobber (match_scratch:XF 6))])]
14472   "TARGET_USE_FANCY_MATH_387
14473    && flag_unsafe_math_optimizations"
14475   int i;
14477   if (optimize_insn_for_size_p ())
14478     FAIL;
14480   for (i = 2; i < 6; i++)
14481     operands[i] = gen_reg_rtx (XFmode);
14483   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14486 (define_expand "acos<mode>2"
14487   [(use (match_operand:MODEF 0 "register_operand"))
14488    (use (match_operand:MODEF 1 "general_operand"))]
14489  "TARGET_USE_FANCY_MATH_387
14490    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491        || TARGET_MIX_SSE_I387)
14492    && flag_unsafe_math_optimizations"
14494   rtx op0 = gen_reg_rtx (XFmode);
14495   rtx op1 = gen_reg_rtx (XFmode);
14497   if (optimize_insn_for_size_p ())
14498     FAIL;
14500   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14501   emit_insn (gen_acosxf2 (op0, op1));
14502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14503   DONE;
14506 (define_insn "fyl2xxf3_i387"
14507   [(set (match_operand:XF 0 "register_operand" "=f")
14508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14509                     (match_operand:XF 2 "register_operand" "u")]
14510                    UNSPEC_FYL2X))
14511    (clobber (match_scratch:XF 3 "=2"))]
14512   "TARGET_USE_FANCY_MATH_387
14513    && flag_unsafe_math_optimizations"
14514   "fyl2x"
14515   [(set_attr "type" "fpspc")
14516    (set_attr "mode" "XF")])
14518 (define_insn "fyl2x_extend<mode>xf3_i387"
14519   [(set (match_operand:XF 0 "register_operand" "=f")
14520         (unspec:XF [(float_extend:XF
14521                       (match_operand:MODEF 1 "register_operand" "0"))
14522                     (match_operand:XF 2 "register_operand" "u")]
14523                    UNSPEC_FYL2X))
14524    (clobber (match_scratch:XF 3 "=2"))]
14525   "TARGET_USE_FANCY_MATH_387
14526    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527        || TARGET_MIX_SSE_I387)
14528    && flag_unsafe_math_optimizations"
14529   "fyl2x"
14530   [(set_attr "type" "fpspc")
14531    (set_attr "mode" "XF")])
14533 (define_expand "logxf2"
14534   [(parallel [(set (match_operand:XF 0 "register_operand")
14535                    (unspec:XF [(match_operand:XF 1 "register_operand")
14536                                (match_dup 2)] UNSPEC_FYL2X))
14537               (clobber (match_scratch:XF 3))])]
14538   "TARGET_USE_FANCY_MATH_387
14539    && flag_unsafe_math_optimizations"
14541   operands[2] = gen_reg_rtx (XFmode);
14542   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14545 (define_expand "log<mode>2"
14546   [(use (match_operand:MODEF 0 "register_operand"))
14547    (use (match_operand:MODEF 1 "register_operand"))]
14548   "TARGET_USE_FANCY_MATH_387
14549    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14550        || TARGET_MIX_SSE_I387)
14551    && flag_unsafe_math_optimizations"
14553   rtx op0 = gen_reg_rtx (XFmode);
14555   rtx op2 = gen_reg_rtx (XFmode);
14556   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14558   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14559   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14560   DONE;
14563 (define_expand "log10xf2"
14564   [(parallel [(set (match_operand:XF 0 "register_operand")
14565                    (unspec:XF [(match_operand:XF 1 "register_operand")
14566                                (match_dup 2)] UNSPEC_FYL2X))
14567               (clobber (match_scratch:XF 3))])]
14568   "TARGET_USE_FANCY_MATH_387
14569    && flag_unsafe_math_optimizations"
14571   operands[2] = gen_reg_rtx (XFmode);
14572   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14575 (define_expand "log10<mode>2"
14576   [(use (match_operand:MODEF 0 "register_operand"))
14577    (use (match_operand:MODEF 1 "register_operand"))]
14578   "TARGET_USE_FANCY_MATH_387
14579    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14580        || TARGET_MIX_SSE_I387)
14581    && flag_unsafe_math_optimizations"
14583   rtx op0 = gen_reg_rtx (XFmode);
14585   rtx op2 = gen_reg_rtx (XFmode);
14586   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14588   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14589   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14590   DONE;
14593 (define_expand "log2xf2"
14594   [(parallel [(set (match_operand:XF 0 "register_operand")
14595                    (unspec:XF [(match_operand:XF 1 "register_operand")
14596                                (match_dup 2)] UNSPEC_FYL2X))
14597               (clobber (match_scratch:XF 3))])]
14598   "TARGET_USE_FANCY_MATH_387
14599    && flag_unsafe_math_optimizations"
14601   operands[2] = gen_reg_rtx (XFmode);
14602   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14605 (define_expand "log2<mode>2"
14606   [(use (match_operand:MODEF 0 "register_operand"))
14607    (use (match_operand:MODEF 1 "register_operand"))]
14608   "TARGET_USE_FANCY_MATH_387
14609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14610        || TARGET_MIX_SSE_I387)
14611    && flag_unsafe_math_optimizations"
14613   rtx op0 = gen_reg_rtx (XFmode);
14615   rtx op2 = gen_reg_rtx (XFmode);
14616   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14618   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14619   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14620   DONE;
14623 (define_insn "fyl2xp1xf3_i387"
14624   [(set (match_operand:XF 0 "register_operand" "=f")
14625         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14626                     (match_operand:XF 2 "register_operand" "u")]
14627                    UNSPEC_FYL2XP1))
14628    (clobber (match_scratch:XF 3 "=2"))]
14629   "TARGET_USE_FANCY_MATH_387
14630    && flag_unsafe_math_optimizations"
14631   "fyl2xp1"
14632   [(set_attr "type" "fpspc")
14633    (set_attr "mode" "XF")])
14635 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14636   [(set (match_operand:XF 0 "register_operand" "=f")
14637         (unspec:XF [(float_extend:XF
14638                       (match_operand:MODEF 1 "register_operand" "0"))
14639                     (match_operand:XF 2 "register_operand" "u")]
14640                    UNSPEC_FYL2XP1))
14641    (clobber (match_scratch:XF 3 "=2"))]
14642   "TARGET_USE_FANCY_MATH_387
14643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14644        || TARGET_MIX_SSE_I387)
14645    && flag_unsafe_math_optimizations"
14646   "fyl2xp1"
14647   [(set_attr "type" "fpspc")
14648    (set_attr "mode" "XF")])
14650 (define_expand "log1pxf2"
14651   [(use (match_operand:XF 0 "register_operand"))
14652    (use (match_operand:XF 1 "register_operand"))]
14653   "TARGET_USE_FANCY_MATH_387
14654    && flag_unsafe_math_optimizations"
14656   if (optimize_insn_for_size_p ())
14657     FAIL;
14659   ix86_emit_i387_log1p (operands[0], operands[1]);
14660   DONE;
14663 (define_expand "log1p<mode>2"
14664   [(use (match_operand:MODEF 0 "register_operand"))
14665    (use (match_operand:MODEF 1 "register_operand"))]
14666   "TARGET_USE_FANCY_MATH_387
14667    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14668        || TARGET_MIX_SSE_I387)
14669    && flag_unsafe_math_optimizations"
14671   rtx op0;
14673   if (optimize_insn_for_size_p ())
14674     FAIL;
14676   op0 = gen_reg_rtx (XFmode);
14678   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14680   ix86_emit_i387_log1p (op0, operands[1]);
14681   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14682   DONE;
14685 (define_insn "fxtractxf3_i387"
14686   [(set (match_operand:XF 0 "register_operand" "=f")
14687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14688                    UNSPEC_XTRACT_FRACT))
14689    (set (match_operand:XF 1 "register_operand" "=u")
14690         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14691   "TARGET_USE_FANCY_MATH_387
14692    && flag_unsafe_math_optimizations"
14693   "fxtract"
14694   [(set_attr "type" "fpspc")
14695    (set_attr "mode" "XF")])
14697 (define_insn "fxtract_extend<mode>xf3_i387"
14698   [(set (match_operand:XF 0 "register_operand" "=f")
14699         (unspec:XF [(float_extend:XF
14700                       (match_operand:MODEF 2 "register_operand" "0"))]
14701                    UNSPEC_XTRACT_FRACT))
14702    (set (match_operand:XF 1 "register_operand" "=u")
14703         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14704   "TARGET_USE_FANCY_MATH_387
14705    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14706        || TARGET_MIX_SSE_I387)
14707    && flag_unsafe_math_optimizations"
14708   "fxtract"
14709   [(set_attr "type" "fpspc")
14710    (set_attr "mode" "XF")])
14712 (define_expand "logbxf2"
14713   [(parallel [(set (match_dup 2)
14714                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14715                               UNSPEC_XTRACT_FRACT))
14716               (set (match_operand:XF 0 "register_operand")
14717                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14718   "TARGET_USE_FANCY_MATH_387
14719    && flag_unsafe_math_optimizations"
14720   "operands[2] = gen_reg_rtx (XFmode);")
14722 (define_expand "logb<mode>2"
14723   [(use (match_operand:MODEF 0 "register_operand"))
14724    (use (match_operand:MODEF 1 "register_operand"))]
14725   "TARGET_USE_FANCY_MATH_387
14726    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14727        || TARGET_MIX_SSE_I387)
14728    && flag_unsafe_math_optimizations"
14730   rtx op0 = gen_reg_rtx (XFmode);
14731   rtx op1 = gen_reg_rtx (XFmode);
14733   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14734   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14735   DONE;
14738 (define_expand "ilogbxf2"
14739   [(use (match_operand:SI 0 "register_operand"))
14740    (use (match_operand:XF 1 "register_operand"))]
14741   "TARGET_USE_FANCY_MATH_387
14742    && flag_unsafe_math_optimizations"
14744   rtx op0, op1;
14746   if (optimize_insn_for_size_p ())
14747     FAIL;
14749   op0 = gen_reg_rtx (XFmode);
14750   op1 = gen_reg_rtx (XFmode);
14752   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14753   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14754   DONE;
14757 (define_expand "ilogb<mode>2"
14758   [(use (match_operand:SI 0 "register_operand"))
14759    (use (match_operand:MODEF 1 "register_operand"))]
14760   "TARGET_USE_FANCY_MATH_387
14761    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14762        || TARGET_MIX_SSE_I387)
14763    && flag_unsafe_math_optimizations"
14765   rtx op0, op1;
14767   if (optimize_insn_for_size_p ())
14768     FAIL;
14770   op0 = gen_reg_rtx (XFmode);
14771   op1 = gen_reg_rtx (XFmode);
14773   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14774   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14775   DONE;
14778 (define_insn "*f2xm1xf2_i387"
14779   [(set (match_operand:XF 0 "register_operand" "=f")
14780         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14781                    UNSPEC_F2XM1))]
14782   "TARGET_USE_FANCY_MATH_387
14783    && flag_unsafe_math_optimizations"
14784   "f2xm1"
14785   [(set_attr "type" "fpspc")
14786    (set_attr "mode" "XF")])
14788 (define_insn "fscalexf4_i387"
14789   [(set (match_operand:XF 0 "register_operand" "=f")
14790         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14791                     (match_operand:XF 3 "register_operand" "1")]
14792                    UNSPEC_FSCALE_FRACT))
14793    (set (match_operand:XF 1 "register_operand" "=u")
14794         (unspec:XF [(match_dup 2) (match_dup 3)]
14795                    UNSPEC_FSCALE_EXP))]
14796   "TARGET_USE_FANCY_MATH_387
14797    && flag_unsafe_math_optimizations"
14798   "fscale"
14799   [(set_attr "type" "fpspc")
14800    (set_attr "mode" "XF")])
14802 (define_expand "expNcorexf3"
14803   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14804                                (match_operand:XF 2 "register_operand")))
14805    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14806    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14807    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14808    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14809    (parallel [(set (match_operand:XF 0 "register_operand")
14810                    (unspec:XF [(match_dup 8) (match_dup 4)]
14811                               UNSPEC_FSCALE_FRACT))
14812               (set (match_dup 9)
14813                    (unspec:XF [(match_dup 8) (match_dup 4)]
14814                               UNSPEC_FSCALE_EXP))])]
14815   "TARGET_USE_FANCY_MATH_387
14816    && flag_unsafe_math_optimizations"
14818   int i;
14820   if (optimize_insn_for_size_p ())
14821     FAIL;
14823   for (i = 3; i < 10; i++)
14824     operands[i] = gen_reg_rtx (XFmode);
14826   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14829 (define_expand "expxf2"
14830   [(use (match_operand:XF 0 "register_operand"))
14831    (use (match_operand:XF 1 "register_operand"))]
14832   "TARGET_USE_FANCY_MATH_387
14833    && flag_unsafe_math_optimizations"
14835   rtx op2;
14837   if (optimize_insn_for_size_p ())
14838     FAIL;
14840   op2 = gen_reg_rtx (XFmode);
14841   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14843   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14844   DONE;
14847 (define_expand "exp<mode>2"
14848   [(use (match_operand:MODEF 0 "register_operand"))
14849    (use (match_operand:MODEF 1 "general_operand"))]
14850  "TARGET_USE_FANCY_MATH_387
14851    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14852        || TARGET_MIX_SSE_I387)
14853    && flag_unsafe_math_optimizations"
14855   rtx op0, op1;
14857   if (optimize_insn_for_size_p ())
14858     FAIL;
14860   op0 = gen_reg_rtx (XFmode);
14861   op1 = gen_reg_rtx (XFmode);
14863   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14864   emit_insn (gen_expxf2 (op0, op1));
14865   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14866   DONE;
14869 (define_expand "exp10xf2"
14870   [(use (match_operand:XF 0 "register_operand"))
14871    (use (match_operand:XF 1 "register_operand"))]
14872   "TARGET_USE_FANCY_MATH_387
14873    && flag_unsafe_math_optimizations"
14875   rtx op2;
14877   if (optimize_insn_for_size_p ())
14878     FAIL;
14880   op2 = gen_reg_rtx (XFmode);
14881   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14883   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14884   DONE;
14887 (define_expand "exp10<mode>2"
14888   [(use (match_operand:MODEF 0 "register_operand"))
14889    (use (match_operand:MODEF 1 "general_operand"))]
14890  "TARGET_USE_FANCY_MATH_387
14891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14892        || TARGET_MIX_SSE_I387)
14893    && flag_unsafe_math_optimizations"
14895   rtx op0, op1;
14897   if (optimize_insn_for_size_p ())
14898     FAIL;
14900   op0 = gen_reg_rtx (XFmode);
14901   op1 = gen_reg_rtx (XFmode);
14903   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14904   emit_insn (gen_exp10xf2 (op0, op1));
14905   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14906   DONE;
14909 (define_expand "exp2xf2"
14910   [(use (match_operand:XF 0 "register_operand"))
14911    (use (match_operand:XF 1 "register_operand"))]
14912   "TARGET_USE_FANCY_MATH_387
14913    && flag_unsafe_math_optimizations"
14915   rtx op2;
14917   if (optimize_insn_for_size_p ())
14918     FAIL;
14920   op2 = gen_reg_rtx (XFmode);
14921   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14923   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14924   DONE;
14927 (define_expand "exp2<mode>2"
14928   [(use (match_operand:MODEF 0 "register_operand"))
14929    (use (match_operand:MODEF 1 "general_operand"))]
14930  "TARGET_USE_FANCY_MATH_387
14931    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14932        || TARGET_MIX_SSE_I387)
14933    && flag_unsafe_math_optimizations"
14935   rtx op0, op1;
14937   if (optimize_insn_for_size_p ())
14938     FAIL;
14940   op0 = gen_reg_rtx (XFmode);
14941   op1 = gen_reg_rtx (XFmode);
14943   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14944   emit_insn (gen_exp2xf2 (op0, op1));
14945   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14946   DONE;
14949 (define_expand "expm1xf2"
14950   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14951                                (match_dup 2)))
14952    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14953    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14954    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14955    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14956    (parallel [(set (match_dup 7)
14957                    (unspec:XF [(match_dup 6) (match_dup 4)]
14958                               UNSPEC_FSCALE_FRACT))
14959               (set (match_dup 8)
14960                    (unspec:XF [(match_dup 6) (match_dup 4)]
14961                               UNSPEC_FSCALE_EXP))])
14962    (parallel [(set (match_dup 10)
14963                    (unspec:XF [(match_dup 9) (match_dup 8)]
14964                               UNSPEC_FSCALE_FRACT))
14965               (set (match_dup 11)
14966                    (unspec:XF [(match_dup 9) (match_dup 8)]
14967                               UNSPEC_FSCALE_EXP))])
14968    (set (match_dup 12) (minus:XF (match_dup 10)
14969                                  (float_extend:XF (match_dup 13))))
14970    (set (match_operand:XF 0 "register_operand")
14971         (plus:XF (match_dup 12) (match_dup 7)))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && flag_unsafe_math_optimizations"
14975   int i;
14977   if (optimize_insn_for_size_p ())
14978     FAIL;
14980   for (i = 2; i < 13; i++)
14981     operands[i] = gen_reg_rtx (XFmode);
14983   operands[13]
14984     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14986   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14989 (define_expand "expm1<mode>2"
14990   [(use (match_operand:MODEF 0 "register_operand"))
14991    (use (match_operand:MODEF 1 "general_operand"))]
14992  "TARGET_USE_FANCY_MATH_387
14993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14994        || TARGET_MIX_SSE_I387)
14995    && flag_unsafe_math_optimizations"
14997   rtx op0, op1;
14999   if (optimize_insn_for_size_p ())
15000     FAIL;
15002   op0 = gen_reg_rtx (XFmode);
15003   op1 = gen_reg_rtx (XFmode);
15005   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15006   emit_insn (gen_expm1xf2 (op0, op1));
15007   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15008   DONE;
15011 (define_expand "ldexpxf3"
15012   [(match_operand:XF 0 "register_operand")
15013    (match_operand:XF 1 "register_operand")
15014    (match_operand:SI 2 "register_operand")]
15015   "TARGET_USE_FANCY_MATH_387
15016    && flag_unsafe_math_optimizations"
15018   rtx tmp1, tmp2;
15019   if (optimize_insn_for_size_p ())
15020     FAIL;
15022   tmp1 = gen_reg_rtx (XFmode);
15023   tmp2 = gen_reg_rtx (XFmode);
15025   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15026   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15027                                  operands[1], tmp1));
15028   DONE;
15031 (define_expand "ldexp<mode>3"
15032   [(use (match_operand:MODEF 0 "register_operand"))
15033    (use (match_operand:MODEF 1 "general_operand"))
15034    (use (match_operand:SI 2 "register_operand"))]
15035  "TARGET_USE_FANCY_MATH_387
15036    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15037        || TARGET_MIX_SSE_I387)
15038    && flag_unsafe_math_optimizations"
15040   rtx op0, op1;
15042   if (optimize_insn_for_size_p ())
15043     FAIL;
15045   op0 = gen_reg_rtx (XFmode);
15046   op1 = gen_reg_rtx (XFmode);
15048   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15049   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15051   DONE;
15054 (define_expand "scalbxf3"
15055   [(parallel [(set (match_operand:XF 0 " register_operand")
15056                    (unspec:XF [(match_operand:XF 1 "register_operand")
15057                                (match_operand:XF 2 "register_operand")]
15058                               UNSPEC_FSCALE_FRACT))
15059               (set (match_dup 3)
15060                    (unspec:XF [(match_dup 1) (match_dup 2)]
15061                               UNSPEC_FSCALE_EXP))])]
15062   "TARGET_USE_FANCY_MATH_387
15063    && flag_unsafe_math_optimizations"
15065   if (optimize_insn_for_size_p ())
15066     FAIL;
15068   operands[3] = gen_reg_rtx (XFmode);
15071 (define_expand "scalb<mode>3"
15072   [(use (match_operand:MODEF 0 "register_operand"))
15073    (use (match_operand:MODEF 1 "general_operand"))
15074    (use (match_operand:MODEF 2 "general_operand"))]
15075  "TARGET_USE_FANCY_MATH_387
15076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15077        || TARGET_MIX_SSE_I387)
15078    && flag_unsafe_math_optimizations"
15080   rtx op0, op1, op2;
15082   if (optimize_insn_for_size_p ())
15083     FAIL;
15085   op0 = gen_reg_rtx (XFmode);
15086   op1 = gen_reg_rtx (XFmode);
15087   op2 = gen_reg_rtx (XFmode);
15089   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15090   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15091   emit_insn (gen_scalbxf3 (op0, op1, op2));
15092   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15093   DONE;
15096 (define_expand "significandxf2"
15097   [(parallel [(set (match_operand:XF 0 "register_operand")
15098                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15099                               UNSPEC_XTRACT_FRACT))
15100               (set (match_dup 2)
15101                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15102   "TARGET_USE_FANCY_MATH_387
15103    && flag_unsafe_math_optimizations"
15104   "operands[2] = gen_reg_rtx (XFmode);")
15106 (define_expand "significand<mode>2"
15107   [(use (match_operand:MODEF 0 "register_operand"))
15108    (use (match_operand:MODEF 1 "register_operand"))]
15109   "TARGET_USE_FANCY_MATH_387
15110    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15111        || TARGET_MIX_SSE_I387)
15112    && flag_unsafe_math_optimizations"
15114   rtx op0 = gen_reg_rtx (XFmode);
15115   rtx op1 = gen_reg_rtx (XFmode);
15117   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15118   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15119   DONE;
15123 (define_insn "sse4_1_round<mode>2"
15124   [(set (match_operand:MODEF 0 "register_operand" "=x")
15125         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15126                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15127                       UNSPEC_ROUND))]
15128   "TARGET_ROUND"
15129   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15130   [(set_attr "type" "ssecvt")
15131    (set_attr "prefix_extra" "1")
15132    (set_attr "prefix" "maybe_vex")
15133    (set_attr "mode" "<MODE>")])
15135 (define_insn "rintxf2"
15136   [(set (match_operand:XF 0 "register_operand" "=f")
15137         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15138                    UNSPEC_FRNDINT))]
15139   "TARGET_USE_FANCY_MATH_387
15140    && flag_unsafe_math_optimizations"
15141   "frndint"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "XF")])
15145 (define_expand "rint<mode>2"
15146   [(use (match_operand:MODEF 0 "register_operand"))
15147    (use (match_operand:MODEF 1 "register_operand"))]
15148   "(TARGET_USE_FANCY_MATH_387
15149     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15150         || TARGET_MIX_SSE_I387)
15151     && flag_unsafe_math_optimizations)
15152    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15153        && !flag_trapping_math)"
15155   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15156       && !flag_trapping_math)
15157     {
15158       if (TARGET_ROUND)
15159         emit_insn (gen_sse4_1_round<mode>2
15160                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15161       else if (optimize_insn_for_size_p ())
15162         FAIL;
15163       else
15164         ix86_expand_rint (operands[0], operands[1]);
15165     }
15166   else
15167     {
15168       rtx op0 = gen_reg_rtx (XFmode);
15169       rtx op1 = gen_reg_rtx (XFmode);
15171       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15172       emit_insn (gen_rintxf2 (op0, op1));
15174       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15175     }
15176   DONE;
15179 (define_expand "round<mode>2"
15180   [(match_operand:X87MODEF 0 "register_operand")
15181    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15182   "(TARGET_USE_FANCY_MATH_387
15183     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184         || TARGET_MIX_SSE_I387)
15185     && flag_unsafe_math_optimizations)
15186    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15187        && !flag_trapping_math && !flag_rounding_math)"
15189   if (optimize_insn_for_size_p ())
15190     FAIL;
15192   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15193       && !flag_trapping_math && !flag_rounding_math)
15194     {
15195       if (TARGET_ROUND)
15196         {
15197           operands[1] = force_reg (<MODE>mode, operands[1]);
15198           ix86_expand_round_sse4 (operands[0], operands[1]);
15199         }
15200       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15201         ix86_expand_round (operands[0], operands[1]);
15202       else
15203         ix86_expand_rounddf_32 (operands[0], operands[1]);
15204     }
15205   else
15206     {
15207       operands[1] = force_reg (<MODE>mode, operands[1]);
15208       ix86_emit_i387_round (operands[0], operands[1]);
15209     }
15210   DONE;
15213 (define_insn_and_split "*fistdi2_1"
15214   [(set (match_operand:DI 0 "nonimmediate_operand")
15215         (unspec:DI [(match_operand:XF 1 "register_operand")]
15216                    UNSPEC_FIST))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && can_create_pseudo_p ()"
15219   "#"
15220   "&& 1"
15221   [(const_int 0)]
15223   if (memory_operand (operands[0], VOIDmode))
15224     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15225   else
15226     {
15227       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15228       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15229                                          operands[2]));
15230     }
15231   DONE;
15233   [(set_attr "type" "fpspc")
15234    (set_attr "mode" "DI")])
15236 (define_insn "fistdi2"
15237   [(set (match_operand:DI 0 "memory_operand" "=m")
15238         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15239                    UNSPEC_FIST))
15240    (clobber (match_scratch:XF 2 "=&1f"))]
15241   "TARGET_USE_FANCY_MATH_387"
15242   "* return output_fix_trunc (insn, operands, false);"
15243   [(set_attr "type" "fpspc")
15244    (set_attr "mode" "DI")])
15246 (define_insn "fistdi2_with_temp"
15247   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15248         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15249                    UNSPEC_FIST))
15250    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15251    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15252   "TARGET_USE_FANCY_MATH_387"
15253   "#"
15254   [(set_attr "type" "fpspc")
15255    (set_attr "mode" "DI")])
15257 (define_split
15258   [(set (match_operand:DI 0 "register_operand")
15259         (unspec:DI [(match_operand:XF 1 "register_operand")]
15260                    UNSPEC_FIST))
15261    (clobber (match_operand:DI 2 "memory_operand"))
15262    (clobber (match_scratch 3))]
15263   "reload_completed"
15264   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15265               (clobber (match_dup 3))])
15266    (set (match_dup 0) (match_dup 2))])
15268 (define_split
15269   [(set (match_operand:DI 0 "memory_operand")
15270         (unspec:DI [(match_operand:XF 1 "register_operand")]
15271                    UNSPEC_FIST))
15272    (clobber (match_operand:DI 2 "memory_operand"))
15273    (clobber (match_scratch 3))]
15274   "reload_completed"
15275   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15276               (clobber (match_dup 3))])])
15278 (define_insn_and_split "*fist<mode>2_1"
15279   [(set (match_operand:SWI24 0 "register_operand")
15280         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15281                       UNSPEC_FIST))]
15282   "TARGET_USE_FANCY_MATH_387
15283    && can_create_pseudo_p ()"
15284   "#"
15285   "&& 1"
15286   [(const_int 0)]
15288   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15289   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15290                                         operands[2]));
15291   DONE;
15293   [(set_attr "type" "fpspc")
15294    (set_attr "mode" "<MODE>")])
15296 (define_insn "fist<mode>2"
15297   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15298         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15299                       UNSPEC_FIST))]
15300   "TARGET_USE_FANCY_MATH_387"
15301   "* return output_fix_trunc (insn, operands, false);"
15302   [(set_attr "type" "fpspc")
15303    (set_attr "mode" "<MODE>")])
15305 (define_insn "fist<mode>2_with_temp"
15306   [(set (match_operand:SWI24 0 "register_operand" "=r")
15307         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15308                       UNSPEC_FIST))
15309    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15310   "TARGET_USE_FANCY_MATH_387"
15311   "#"
15312   [(set_attr "type" "fpspc")
15313    (set_attr "mode" "<MODE>")])
15315 (define_split
15316   [(set (match_operand:SWI24 0 "register_operand")
15317         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15318                       UNSPEC_FIST))
15319    (clobber (match_operand:SWI24 2 "memory_operand"))]
15320   "reload_completed"
15321   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15322    (set (match_dup 0) (match_dup 2))])
15324 (define_split
15325   [(set (match_operand:SWI24 0 "memory_operand")
15326         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15327                       UNSPEC_FIST))
15328    (clobber (match_operand:SWI24 2 "memory_operand"))]
15329   "reload_completed"
15330   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15332 (define_expand "lrintxf<mode>2"
15333   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15334      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15335                      UNSPEC_FIST))]
15336   "TARGET_USE_FANCY_MATH_387")
15338 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15339   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15340      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15341                    UNSPEC_FIX_NOTRUNC))]
15342   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15344 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15345   [(match_operand:SWI248x 0 "nonimmediate_operand")
15346    (match_operand:X87MODEF 1 "register_operand")]
15347   "(TARGET_USE_FANCY_MATH_387
15348     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15349         || TARGET_MIX_SSE_I387)
15350     && flag_unsafe_math_optimizations)
15351    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15352        && <SWI248x:MODE>mode != HImode 
15353        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15354        && !flag_trapping_math && !flag_rounding_math)"
15356   if (optimize_insn_for_size_p ())
15357     FAIL;
15359   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15360       && <SWI248x:MODE>mode != HImode
15361       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15362       && !flag_trapping_math && !flag_rounding_math)
15363     ix86_expand_lround (operands[0], operands[1]);
15364   else
15365     ix86_emit_i387_round (operands[0], operands[1]);
15366   DONE;
15369 (define_int_iterator FRNDINT_ROUNDING
15370         [UNSPEC_FRNDINT_FLOOR
15371          UNSPEC_FRNDINT_CEIL
15372          UNSPEC_FRNDINT_TRUNC])
15374 (define_int_iterator FIST_ROUNDING
15375         [UNSPEC_FIST_FLOOR
15376          UNSPEC_FIST_CEIL])
15378 ;; Base name for define_insn
15379 (define_int_attr rounding_insn
15380         [(UNSPEC_FRNDINT_FLOOR "floor")
15381          (UNSPEC_FRNDINT_CEIL "ceil")
15382          (UNSPEC_FRNDINT_TRUNC "btrunc")
15383          (UNSPEC_FIST_FLOOR "floor")
15384          (UNSPEC_FIST_CEIL "ceil")])
15386 (define_int_attr rounding
15387         [(UNSPEC_FRNDINT_FLOOR "floor")
15388          (UNSPEC_FRNDINT_CEIL "ceil")
15389          (UNSPEC_FRNDINT_TRUNC "trunc")
15390          (UNSPEC_FIST_FLOOR "floor")
15391          (UNSPEC_FIST_CEIL "ceil")])
15393 (define_int_attr ROUNDING
15394         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15395          (UNSPEC_FRNDINT_CEIL "CEIL")
15396          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15397          (UNSPEC_FIST_FLOOR "FLOOR")
15398          (UNSPEC_FIST_CEIL "CEIL")])
15400 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15401 (define_insn_and_split "frndintxf2_<rounding>"
15402   [(set (match_operand:XF 0 "register_operand")
15403         (unspec:XF [(match_operand:XF 1 "register_operand")]
15404                    FRNDINT_ROUNDING))
15405    (clobber (reg:CC FLAGS_REG))]
15406   "TARGET_USE_FANCY_MATH_387
15407    && flag_unsafe_math_optimizations
15408    && can_create_pseudo_p ()"
15409   "#"
15410   "&& 1"
15411   [(const_int 0)]
15413   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15415   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15416   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15418   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15419                                              operands[2], operands[3]));
15420   DONE;
15422   [(set_attr "type" "frndint")
15423    (set_attr "i387_cw" "<rounding>")
15424    (set_attr "mode" "XF")])
15426 (define_insn "frndintxf2_<rounding>_i387"
15427   [(set (match_operand:XF 0 "register_operand" "=f")
15428         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15429                    FRNDINT_ROUNDING))
15430    (use (match_operand:HI 2 "memory_operand" "m"))
15431    (use (match_operand:HI 3 "memory_operand" "m"))]
15432   "TARGET_USE_FANCY_MATH_387
15433    && flag_unsafe_math_optimizations"
15434   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15435   [(set_attr "type" "frndint")
15436    (set_attr "i387_cw" "<rounding>")
15437    (set_attr "mode" "XF")])
15439 (define_expand "<rounding_insn>xf2"
15440   [(parallel [(set (match_operand:XF 0 "register_operand")
15441                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15442                               FRNDINT_ROUNDING))
15443               (clobber (reg:CC FLAGS_REG))])]
15444   "TARGET_USE_FANCY_MATH_387
15445    && flag_unsafe_math_optimizations
15446    && !optimize_insn_for_size_p ()")
15448 (define_expand "<rounding_insn><mode>2"
15449   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15450                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15451                                  FRNDINT_ROUNDING))
15452               (clobber (reg:CC FLAGS_REG))])]
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_<ROUNDING>)));
15466       else if (optimize_insn_for_size_p ())
15467         FAIL;
15468       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15469         {
15470           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15471             ix86_expand_floorceil (operands[0], operands[1], true);
15472           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15473             ix86_expand_floorceil (operands[0], operands[1], false);
15474           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15475             ix86_expand_trunc (operands[0], operands[1]);
15476           else
15477             gcc_unreachable ();
15478         }
15479       else
15480         {
15481           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15482             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15483           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15484             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15485           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15486             ix86_expand_truncdf_32 (operands[0], operands[1]);
15487           else
15488             gcc_unreachable ();
15489         }
15490     }
15491   else
15492     {
15493       rtx op0, op1;
15495       if (optimize_insn_for_size_p ())
15496         FAIL;
15498       op0 = gen_reg_rtx (XFmode);
15499       op1 = gen_reg_rtx (XFmode);
15500       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15503       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15504     }
15505   DONE;
15508 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15509 (define_insn_and_split "frndintxf2_mask_pm"
15510   [(set (match_operand:XF 0 "register_operand")
15511         (unspec:XF [(match_operand:XF 1 "register_operand")]
15512                    UNSPEC_FRNDINT_MASK_PM))
15513    (clobber (reg:CC FLAGS_REG))]
15514   "TARGET_USE_FANCY_MATH_387
15515    && flag_unsafe_math_optimizations
15516    && can_create_pseudo_p ()"
15517   "#"
15518   "&& 1"
15519   [(const_int 0)]
15521   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15523   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15524   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15526   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15527                                           operands[2], operands[3]));
15528   DONE;
15530   [(set_attr "type" "frndint")
15531    (set_attr "i387_cw" "mask_pm")
15532    (set_attr "mode" "XF")])
15534 (define_insn "frndintxf2_mask_pm_i387"
15535   [(set (match_operand:XF 0 "register_operand" "=f")
15536         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15537                    UNSPEC_FRNDINT_MASK_PM))
15538    (use (match_operand:HI 2 "memory_operand" "m"))
15539    (use (match_operand:HI 3 "memory_operand" "m"))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && flag_unsafe_math_optimizations"
15542   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15543   [(set_attr "type" "frndint")
15544    (set_attr "i387_cw" "mask_pm")
15545    (set_attr "mode" "XF")])
15547 (define_expand "nearbyintxf2"
15548   [(parallel [(set (match_operand:XF 0 "register_operand")
15549                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15550                               UNSPEC_FRNDINT_MASK_PM))
15551               (clobber (reg:CC FLAGS_REG))])]
15552   "TARGET_USE_FANCY_MATH_387
15553    && flag_unsafe_math_optimizations")
15555 (define_expand "nearbyint<mode>2"
15556   [(use (match_operand:MODEF 0 "register_operand"))
15557    (use (match_operand:MODEF 1 "register_operand"))]
15558   "TARGET_USE_FANCY_MATH_387
15559    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15560        || TARGET_MIX_SSE_I387)
15561    && flag_unsafe_math_optimizations"
15563   rtx op0 = gen_reg_rtx (XFmode);
15564   rtx op1 = gen_reg_rtx (XFmode);
15566   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15567   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15570   DONE;
15573 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15574 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15575   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15576         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15577                         FIST_ROUNDING))
15578    (clobber (reg:CC FLAGS_REG))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && flag_unsafe_math_optimizations
15581    && can_create_pseudo_p ()"
15582   "#"
15583   "&& 1"
15584   [(const_int 0)]
15586   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15588   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15589   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15590   if (memory_operand (operands[0], VOIDmode))
15591     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15592                                            operands[2], operands[3]));
15593   else
15594     {
15595       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15596       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15597                   (operands[0], operands[1], operands[2],
15598                    operands[3], operands[4]));
15599     }
15600   DONE;
15602   [(set_attr "type" "fistp")
15603    (set_attr "i387_cw" "<rounding>")
15604    (set_attr "mode" "<MODE>")])
15606 (define_insn "fistdi2_<rounding>"
15607   [(set (match_operand:DI 0 "memory_operand" "=m")
15608         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15609                    FIST_ROUNDING))
15610    (use (match_operand:HI 2 "memory_operand" "m"))
15611    (use (match_operand:HI 3 "memory_operand" "m"))
15612    (clobber (match_scratch:XF 4 "=&1f"))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && flag_unsafe_math_optimizations"
15615   "* return output_fix_trunc (insn, operands, false);"
15616   [(set_attr "type" "fistp")
15617    (set_attr "i387_cw" "<rounding>")
15618    (set_attr "mode" "DI")])
15620 (define_insn "fistdi2_<rounding>_with_temp"
15621   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15622         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15623                    FIST_ROUNDING))
15624    (use (match_operand:HI 2 "memory_operand" "m,m"))
15625    (use (match_operand:HI 3 "memory_operand" "m,m"))
15626    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15627    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15628   "TARGET_USE_FANCY_MATH_387
15629    && flag_unsafe_math_optimizations"
15630   "#"
15631   [(set_attr "type" "fistp")
15632    (set_attr "i387_cw" "<rounding>")
15633    (set_attr "mode" "DI")])
15635 (define_split
15636   [(set (match_operand:DI 0 "register_operand")
15637         (unspec:DI [(match_operand:XF 1 "register_operand")]
15638                    FIST_ROUNDING))
15639    (use (match_operand:HI 2 "memory_operand"))
15640    (use (match_operand:HI 3 "memory_operand"))
15641    (clobber (match_operand:DI 4 "memory_operand"))
15642    (clobber (match_scratch 5))]
15643   "reload_completed"
15644   [(parallel [(set (match_dup 4)
15645                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15646               (use (match_dup 2))
15647               (use (match_dup 3))
15648               (clobber (match_dup 5))])
15649    (set (match_dup 0) (match_dup 4))])
15651 (define_split
15652   [(set (match_operand:DI 0 "memory_operand")
15653         (unspec:DI [(match_operand:XF 1 "register_operand")]
15654                    FIST_ROUNDING))
15655    (use (match_operand:HI 2 "memory_operand"))
15656    (use (match_operand:HI 3 "memory_operand"))
15657    (clobber (match_operand:DI 4 "memory_operand"))
15658    (clobber (match_scratch 5))]
15659   "reload_completed"
15660   [(parallel [(set (match_dup 0)
15661                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15662               (use (match_dup 2))
15663               (use (match_dup 3))
15664               (clobber (match_dup 5))])])
15666 (define_insn "fist<mode>2_<rounding>"
15667   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15668         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15669                       FIST_ROUNDING))
15670    (use (match_operand:HI 2 "memory_operand" "m"))
15671    (use (match_operand:HI 3 "memory_operand" "m"))]
15672   "TARGET_USE_FANCY_MATH_387
15673    && flag_unsafe_math_optimizations"
15674   "* return output_fix_trunc (insn, operands, false);"
15675   [(set_attr "type" "fistp")
15676    (set_attr "i387_cw" "<rounding>")
15677    (set_attr "mode" "<MODE>")])
15679 (define_insn "fist<mode>2_<rounding>_with_temp"
15680   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15681         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15682                       FIST_ROUNDING))
15683    (use (match_operand:HI 2 "memory_operand" "m,m"))
15684    (use (match_operand:HI 3 "memory_operand" "m,m"))
15685    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15686   "TARGET_USE_FANCY_MATH_387
15687    && flag_unsafe_math_optimizations"
15688   "#"
15689   [(set_attr "type" "fistp")
15690    (set_attr "i387_cw" "<rounding>")
15691    (set_attr "mode" "<MODE>")])
15693 (define_split
15694   [(set (match_operand:SWI24 0 "register_operand")
15695         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15696                       FIST_ROUNDING))
15697    (use (match_operand:HI 2 "memory_operand"))
15698    (use (match_operand:HI 3 "memory_operand"))
15699    (clobber (match_operand:SWI24 4 "memory_operand"))]
15700   "reload_completed"
15701   [(parallel [(set (match_dup 4)
15702                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15703               (use (match_dup 2))
15704               (use (match_dup 3))])
15705    (set (match_dup 0) (match_dup 4))])
15707 (define_split
15708   [(set (match_operand:SWI24 0 "memory_operand")
15709         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15710                       FIST_ROUNDING))
15711    (use (match_operand:HI 2 "memory_operand"))
15712    (use (match_operand:HI 3 "memory_operand"))
15713    (clobber (match_operand:SWI24 4 "memory_operand"))]
15714   "reload_completed"
15715   [(parallel [(set (match_dup 0)
15716                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15717               (use (match_dup 2))
15718               (use (match_dup 3))])])
15720 (define_expand "l<rounding_insn>xf<mode>2"
15721   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15722                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15723                                    FIST_ROUNDING))
15724               (clobber (reg:CC FLAGS_REG))])]
15725   "TARGET_USE_FANCY_MATH_387
15726    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15727    && flag_unsafe_math_optimizations")
15729 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15730   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15731                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15732                                  FIST_ROUNDING))
15733               (clobber (reg:CC FLAGS_REG))])]
15734   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15735    && !flag_trapping_math"
15737   if (TARGET_64BIT && optimize_insn_for_size_p ())
15738     FAIL;
15740   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15741     ix86_expand_lfloorceil (operands[0], operands[1], true);
15742   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15743     ix86_expand_lfloorceil (operands[0], operands[1], false);
15744   else
15745     gcc_unreachable ();
15747   DONE;
15750 (define_insn "fxam<mode>2_i387"
15751   [(set (match_operand:HI 0 "register_operand" "=a")
15752         (unspec:HI
15753           [(match_operand:X87MODEF 1 "register_operand" "f")]
15754           UNSPEC_FXAM))]
15755   "TARGET_USE_FANCY_MATH_387"
15756   "fxam\n\tfnstsw\t%0"
15757   [(set_attr "type" "multi")
15758    (set_attr "length" "4")
15759    (set_attr "unit" "i387")
15760    (set_attr "mode" "<MODE>")])
15762 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15763   [(set (match_operand:HI 0 "register_operand")
15764         (unspec:HI
15765           [(match_operand:MODEF 1 "memory_operand")]
15766           UNSPEC_FXAM_MEM))]
15767   "TARGET_USE_FANCY_MATH_387
15768    && can_create_pseudo_p ()"
15769   "#"
15770   "&& 1"
15771   [(set (match_dup 2)(match_dup 1))
15772    (set (match_dup 0)
15773         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15775   operands[2] = gen_reg_rtx (<MODE>mode);
15777   MEM_VOLATILE_P (operands[1]) = 1;
15779   [(set_attr "type" "multi")
15780    (set_attr "unit" "i387")
15781    (set_attr "mode" "<MODE>")])
15783 (define_expand "isinfxf2"
15784   [(use (match_operand:SI 0 "register_operand"))
15785    (use (match_operand:XF 1 "register_operand"))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && ix86_libc_has_function (function_c99_misc)"
15789   rtx mask = GEN_INT (0x45);
15790   rtx val = GEN_INT (0x05);
15792   rtx cond;
15794   rtx scratch = gen_reg_rtx (HImode);
15795   rtx res = gen_reg_rtx (QImode);
15797   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15799   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15800   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15801   cond = gen_rtx_fmt_ee (EQ, QImode,
15802                          gen_rtx_REG (CCmode, FLAGS_REG),
15803                          const0_rtx);
15804   emit_insn (gen_rtx_SET (res, cond));
15805   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15806   DONE;
15809 (define_expand "isinf<mode>2"
15810   [(use (match_operand:SI 0 "register_operand"))
15811    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15812   "TARGET_USE_FANCY_MATH_387
15813    && ix86_libc_has_function (function_c99_misc)
15814    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15816   rtx mask = GEN_INT (0x45);
15817   rtx val = GEN_INT (0x05);
15819   rtx cond;
15821   rtx scratch = gen_reg_rtx (HImode);
15822   rtx res = gen_reg_rtx (QImode);
15824   /* Remove excess precision by forcing value through memory. */
15825   if (memory_operand (operands[1], VOIDmode))
15826     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15827   else
15828     {
15829       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15831       emit_move_insn (temp, operands[1]);
15832       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15833     }
15835   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15836   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15837   cond = gen_rtx_fmt_ee (EQ, QImode,
15838                          gen_rtx_REG (CCmode, FLAGS_REG),
15839                          const0_rtx);
15840   emit_insn (gen_rtx_SET (res, cond));
15841   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15842   DONE;
15845 (define_expand "signbitxf2"
15846   [(use (match_operand:SI 0 "register_operand"))
15847    (use (match_operand:XF 1 "register_operand"))]
15848   "TARGET_USE_FANCY_MATH_387"
15850   rtx scratch = gen_reg_rtx (HImode);
15852   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15853   emit_insn (gen_andsi3 (operands[0],
15854              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15855   DONE;
15858 (define_insn "movmsk_df"
15859   [(set (match_operand:SI 0 "register_operand" "=r")
15860         (unspec:SI
15861           [(match_operand:DF 1 "register_operand" "x")]
15862           UNSPEC_MOVMSK))]
15863   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15864   "%vmovmskpd\t{%1, %0|%0, %1}"
15865   [(set_attr "type" "ssemov")
15866    (set_attr "prefix" "maybe_vex")
15867    (set_attr "mode" "DF")])
15869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15871 (define_expand "signbitdf2"
15872   [(use (match_operand:SI 0 "register_operand"))
15873    (use (match_operand:DF 1 "register_operand"))]
15874   "TARGET_USE_FANCY_MATH_387
15875    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15877   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15878     {
15879       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15880       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15881     }
15882   else
15883     {
15884       rtx scratch = gen_reg_rtx (HImode);
15886       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15887       emit_insn (gen_andsi3 (operands[0],
15888                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15889     }
15890   DONE;
15893 (define_expand "signbitsf2"
15894   [(use (match_operand:SI 0 "register_operand"))
15895    (use (match_operand:SF 1 "register_operand"))]
15896   "TARGET_USE_FANCY_MATH_387
15897    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15899   rtx scratch = gen_reg_rtx (HImode);
15901   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15902   emit_insn (gen_andsi3 (operands[0],
15903              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15904   DONE;
15907 ;; Block operation instructions
15909 (define_insn "cld"
15910   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15911   ""
15912   "cld"
15913   [(set_attr "length" "1")
15914    (set_attr "length_immediate" "0")
15915    (set_attr "modrm" "0")])
15917 (define_expand "movmem<mode>"
15918   [(use (match_operand:BLK 0 "memory_operand"))
15919    (use (match_operand:BLK 1 "memory_operand"))
15920    (use (match_operand:SWI48 2 "nonmemory_operand"))
15921    (use (match_operand:SWI48 3 "const_int_operand"))
15922    (use (match_operand:SI 4 "const_int_operand"))
15923    (use (match_operand:SI 5 "const_int_operand"))
15924    (use (match_operand:SI 6 ""))
15925    (use (match_operand:SI 7 ""))
15926    (use (match_operand:SI 8 ""))]
15927   ""
15929  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15930                                 operands[2], NULL, operands[3],
15931                                 operands[4], operands[5],
15932                                 operands[6], operands[7],
15933                                 operands[8], false))
15934    DONE;
15935  else
15936    FAIL;
15939 ;; Most CPUs don't like single string operations
15940 ;; Handle this case here to simplify previous expander.
15942 (define_expand "strmov"
15943   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15944    (set (match_operand 1 "memory_operand") (match_dup 4))
15945    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15946               (clobber (reg:CC FLAGS_REG))])
15947    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15948               (clobber (reg:CC FLAGS_REG))])]
15949   ""
15951   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15953   /* If .md ever supports :P for Pmode, these can be directly
15954      in the pattern above.  */
15955   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15956   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15958   /* Can't use this if the user has appropriated esi or edi.  */
15959   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15960       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15961     {
15962       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15963                                       operands[2], operands[3],
15964                                       operands[5], operands[6]));
15965       DONE;
15966     }
15968   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15971 (define_expand "strmov_singleop"
15972   [(parallel [(set (match_operand 1 "memory_operand")
15973                    (match_operand 3 "memory_operand"))
15974               (set (match_operand 0 "register_operand")
15975                    (match_operand 4))
15976               (set (match_operand 2 "register_operand")
15977                    (match_operand 5))])]
15978   ""
15979   "ix86_current_function_needs_cld = 1;")
15981 (define_insn "*strmovdi_rex_1"
15982   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15983         (mem:DI (match_operand:P 3 "register_operand" "1")))
15984    (set (match_operand:P 0 "register_operand" "=D")
15985         (plus:P (match_dup 2)
15986                 (const_int 8)))
15987    (set (match_operand:P 1 "register_operand" "=S")
15988         (plus:P (match_dup 3)
15989                 (const_int 8)))]
15990   "TARGET_64BIT
15991    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15992   "%^movsq"
15993   [(set_attr "type" "str")
15994    (set_attr "memory" "both")
15995    (set_attr "mode" "DI")])
15997 (define_insn "*strmovsi_1"
15998   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15999         (mem:SI (match_operand:P 3 "register_operand" "1")))
16000    (set (match_operand:P 0 "register_operand" "=D")
16001         (plus:P (match_dup 2)
16002                 (const_int 4)))
16003    (set (match_operand:P 1 "register_operand" "=S")
16004         (plus:P (match_dup 3)
16005                 (const_int 4)))]
16006   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16007   "%^movs{l|d}"
16008   [(set_attr "type" "str")
16009    (set_attr "memory" "both")
16010    (set_attr "mode" "SI")])
16012 (define_insn "*strmovhi_1"
16013   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16014         (mem:HI (match_operand:P 3 "register_operand" "1")))
16015    (set (match_operand:P 0 "register_operand" "=D")
16016         (plus:P (match_dup 2)
16017                 (const_int 2)))
16018    (set (match_operand:P 1 "register_operand" "=S")
16019         (plus:P (match_dup 3)
16020                 (const_int 2)))]
16021   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16022   "%^movsw"
16023   [(set_attr "type" "str")
16024    (set_attr "memory" "both")
16025    (set_attr "mode" "HI")])
16027 (define_insn "*strmovqi_1"
16028   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16029         (mem:QI (match_operand:P 3 "register_operand" "1")))
16030    (set (match_operand:P 0 "register_operand" "=D")
16031         (plus:P (match_dup 2)
16032                 (const_int 1)))
16033    (set (match_operand:P 1 "register_operand" "=S")
16034         (plus:P (match_dup 3)
16035                 (const_int 1)))]
16036   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16037   "%^movsb"
16038   [(set_attr "type" "str")
16039    (set_attr "memory" "both")
16040    (set (attr "prefix_rex")
16041         (if_then_else
16042           (match_test "<P:MODE>mode == DImode")
16043           (const_string "0")
16044           (const_string "*")))
16045    (set_attr "mode" "QI")])
16047 (define_expand "rep_mov"
16048   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16049               (set (match_operand 0 "register_operand")
16050                    (match_operand 5))
16051               (set (match_operand 2 "register_operand")
16052                    (match_operand 6))
16053               (set (match_operand 1 "memory_operand")
16054                    (match_operand 3 "memory_operand"))
16055               (use (match_dup 4))])]
16056   ""
16057   "ix86_current_function_needs_cld = 1;")
16059 (define_insn "*rep_movdi_rex64"
16060   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16061    (set (match_operand:P 0 "register_operand" "=D")
16062         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16063                           (const_int 3))
16064                 (match_operand:P 3 "register_operand" "0")))
16065    (set (match_operand:P 1 "register_operand" "=S")
16066         (plus:P (ashift:P (match_dup 5) (const_int 3))
16067                 (match_operand:P 4 "register_operand" "1")))
16068    (set (mem:BLK (match_dup 3))
16069         (mem:BLK (match_dup 4)))
16070    (use (match_dup 5))]
16071   "TARGET_64BIT
16072    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16073   "%^rep{%;} movsq"
16074   [(set_attr "type" "str")
16075    (set_attr "prefix_rep" "1")
16076    (set_attr "memory" "both")
16077    (set_attr "mode" "DI")])
16079 (define_insn "*rep_movsi"
16080   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16081    (set (match_operand:P 0 "register_operand" "=D")
16082         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16083                           (const_int 2))
16084                  (match_operand:P 3 "register_operand" "0")))
16085    (set (match_operand:P 1 "register_operand" "=S")
16086         (plus:P (ashift:P (match_dup 5) (const_int 2))
16087                 (match_operand:P 4 "register_operand" "1")))
16088    (set (mem:BLK (match_dup 3))
16089         (mem:BLK (match_dup 4)))
16090    (use (match_dup 5))]
16091   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16092   "%^rep{%;} movs{l|d}"
16093   [(set_attr "type" "str")
16094    (set_attr "prefix_rep" "1")
16095    (set_attr "memory" "both")
16096    (set_attr "mode" "SI")])
16098 (define_insn "*rep_movqi"
16099   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16100    (set (match_operand:P 0 "register_operand" "=D")
16101         (plus:P (match_operand:P 3 "register_operand" "0")
16102                 (match_operand:P 5 "register_operand" "2")))
16103    (set (match_operand:P 1 "register_operand" "=S")
16104         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16105    (set (mem:BLK (match_dup 3))
16106         (mem:BLK (match_dup 4)))
16107    (use (match_dup 5))]
16108   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16109   "%^rep{%;} movsb"
16110   [(set_attr "type" "str")
16111    (set_attr "prefix_rep" "1")
16112    (set_attr "memory" "both")
16113    (set_attr "mode" "QI")])
16115 (define_expand "setmem<mode>"
16116    [(use (match_operand:BLK 0 "memory_operand"))
16117     (use (match_operand:SWI48 1 "nonmemory_operand"))
16118     (use (match_operand:QI 2 "nonmemory_operand"))
16119     (use (match_operand 3 "const_int_operand"))
16120     (use (match_operand:SI 4 "const_int_operand"))
16121     (use (match_operand:SI 5 "const_int_operand"))
16122     (use (match_operand:SI 6 ""))
16123     (use (match_operand:SI 7 ""))
16124     (use (match_operand:SI 8 ""))]
16125   ""
16127  if (ix86_expand_set_or_movmem (operands[0], NULL,
16128                                 operands[1], operands[2],
16129                                 operands[3], operands[4],
16130                                 operands[5], operands[6],
16131                                 operands[7], operands[8], true))
16132    DONE;
16133  else
16134    FAIL;
16137 ;; Most CPUs don't like single string operations
16138 ;; Handle this case here to simplify previous expander.
16140 (define_expand "strset"
16141   [(set (match_operand 1 "memory_operand")
16142         (match_operand 2 "register_operand"))
16143    (parallel [(set (match_operand 0 "register_operand")
16144                    (match_dup 3))
16145               (clobber (reg:CC FLAGS_REG))])]
16146   ""
16148   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16149     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16151   /* If .md ever supports :P for Pmode, this can be directly
16152      in the pattern above.  */
16153   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16154                               GEN_INT (GET_MODE_SIZE (GET_MODE
16155                                                       (operands[2]))));
16156   /* Can't use this if the user has appropriated eax or edi.  */
16157   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16158       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16159     {
16160       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16161                                       operands[3]));
16162       DONE;
16163     }
16166 (define_expand "strset_singleop"
16167   [(parallel [(set (match_operand 1 "memory_operand")
16168                    (match_operand 2 "register_operand"))
16169               (set (match_operand 0 "register_operand")
16170                    (match_operand 3))
16171               (unspec [(const_int 0)] UNSPEC_STOS)])]
16172   ""
16173   "ix86_current_function_needs_cld = 1;")
16175 (define_insn "*strsetdi_rex_1"
16176   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16177         (match_operand:DI 2 "register_operand" "a"))
16178    (set (match_operand:P 0 "register_operand" "=D")
16179         (plus:P (match_dup 1)
16180                 (const_int 8)))
16181    (unspec [(const_int 0)] UNSPEC_STOS)]
16182   "TARGET_64BIT
16183    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16184   "%^stosq"
16185   [(set_attr "type" "str")
16186    (set_attr "memory" "store")
16187    (set_attr "mode" "DI")])
16189 (define_insn "*strsetsi_1"
16190   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16191         (match_operand:SI 2 "register_operand" "a"))
16192    (set (match_operand:P 0 "register_operand" "=D")
16193         (plus:P (match_dup 1)
16194                 (const_int 4)))
16195    (unspec [(const_int 0)] UNSPEC_STOS)]
16196   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16197   "%^stos{l|d}"
16198   [(set_attr "type" "str")
16199    (set_attr "memory" "store")
16200    (set_attr "mode" "SI")])
16202 (define_insn "*strsethi_1"
16203   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16204         (match_operand:HI 2 "register_operand" "a"))
16205    (set (match_operand:P 0 "register_operand" "=D")
16206         (plus:P (match_dup 1)
16207                 (const_int 2)))
16208    (unspec [(const_int 0)] UNSPEC_STOS)]
16209   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16210   "%^stosw"
16211   [(set_attr "type" "str")
16212    (set_attr "memory" "store")
16213    (set_attr "mode" "HI")])
16215 (define_insn "*strsetqi_1"
16216   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16217         (match_operand:QI 2 "register_operand" "a"))
16218    (set (match_operand:P 0 "register_operand" "=D")
16219         (plus:P (match_dup 1)
16220                 (const_int 1)))
16221    (unspec [(const_int 0)] UNSPEC_STOS)]
16222   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16223   "%^stosb"
16224   [(set_attr "type" "str")
16225    (set_attr "memory" "store")
16226    (set (attr "prefix_rex")
16227         (if_then_else
16228           (match_test "<P:MODE>mode == DImode")
16229           (const_string "0")
16230           (const_string "*")))
16231    (set_attr "mode" "QI")])
16233 (define_expand "rep_stos"
16234   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16235               (set (match_operand 0 "register_operand")
16236                    (match_operand 4))
16237               (set (match_operand 2 "memory_operand") (const_int 0))
16238               (use (match_operand 3 "register_operand"))
16239               (use (match_dup 1))])]
16240   ""
16241   "ix86_current_function_needs_cld = 1;")
16243 (define_insn "*rep_stosdi_rex64"
16244   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16245    (set (match_operand:P 0 "register_operand" "=D")
16246         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16247                           (const_int 3))
16248                  (match_operand:P 3 "register_operand" "0")))
16249    (set (mem:BLK (match_dup 3))
16250         (const_int 0))
16251    (use (match_operand:DI 2 "register_operand" "a"))
16252    (use (match_dup 4))]
16253   "TARGET_64BIT
16254    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16255   "%^rep{%;} stosq"
16256   [(set_attr "type" "str")
16257    (set_attr "prefix_rep" "1")
16258    (set_attr "memory" "store")
16259    (set_attr "mode" "DI")])
16261 (define_insn "*rep_stossi"
16262   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16263    (set (match_operand:P 0 "register_operand" "=D")
16264         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16265                           (const_int 2))
16266                  (match_operand:P 3 "register_operand" "0")))
16267    (set (mem:BLK (match_dup 3))
16268         (const_int 0))
16269    (use (match_operand:SI 2 "register_operand" "a"))
16270    (use (match_dup 4))]
16271   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16272   "%^rep{%;} stos{l|d}"
16273   [(set_attr "type" "str")
16274    (set_attr "prefix_rep" "1")
16275    (set_attr "memory" "store")
16276    (set_attr "mode" "SI")])
16278 (define_insn "*rep_stosqi"
16279   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16280    (set (match_operand:P 0 "register_operand" "=D")
16281         (plus:P (match_operand:P 3 "register_operand" "0")
16282                 (match_operand:P 4 "register_operand" "1")))
16283    (set (mem:BLK (match_dup 3))
16284         (const_int 0))
16285    (use (match_operand:QI 2 "register_operand" "a"))
16286    (use (match_dup 4))]
16287   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16288   "%^rep{%;} stosb"
16289   [(set_attr "type" "str")
16290    (set_attr "prefix_rep" "1")
16291    (set_attr "memory" "store")
16292    (set (attr "prefix_rex")
16293         (if_then_else
16294           (match_test "<P:MODE>mode == DImode")
16295           (const_string "0")
16296           (const_string "*")))
16297    (set_attr "mode" "QI")])
16299 (define_expand "cmpstrnsi"
16300   [(set (match_operand:SI 0 "register_operand")
16301         (compare:SI (match_operand:BLK 1 "general_operand")
16302                     (match_operand:BLK 2 "general_operand")))
16303    (use (match_operand 3 "general_operand"))
16304    (use (match_operand 4 "immediate_operand"))]
16305   ""
16307   rtx addr1, addr2, out, outlow, count, countreg, align;
16309   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16310     FAIL;
16312   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16313   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16314     FAIL;
16316   out = operands[0];
16317   if (!REG_P (out))
16318     out = gen_reg_rtx (SImode);
16320   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16321   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16322   if (addr1 != XEXP (operands[1], 0))
16323     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16324   if (addr2 != XEXP (operands[2], 0))
16325     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16327   count = operands[3];
16328   countreg = ix86_zero_extend_to_Pmode (count);
16330   /* %%% Iff we are testing strict equality, we can use known alignment
16331      to good advantage.  This may be possible with combine, particularly
16332      once cc0 is dead.  */
16333   align = operands[4];
16335   if (CONST_INT_P (count))
16336     {
16337       if (INTVAL (count) == 0)
16338         {
16339           emit_move_insn (operands[0], const0_rtx);
16340           DONE;
16341         }
16342       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16343                                      operands[1], operands[2]));
16344     }
16345   else
16346     {
16347       rtx (*gen_cmp) (rtx, rtx);
16349       gen_cmp = (TARGET_64BIT
16350                  ? gen_cmpdi_1 : gen_cmpsi_1);
16352       emit_insn (gen_cmp (countreg, countreg));
16353       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16354                                   operands[1], operands[2]));
16355     }
16357   outlow = gen_lowpart (QImode, out);
16358   emit_insn (gen_cmpintqi (outlow));
16359   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16361   if (operands[0] != out)
16362     emit_move_insn (operands[0], out);
16364   DONE;
16367 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16369 (define_expand "cmpintqi"
16370   [(set (match_dup 1)
16371         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16372    (set (match_dup 2)
16373         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16374    (parallel [(set (match_operand:QI 0 "register_operand")
16375                    (minus:QI (match_dup 1)
16376                              (match_dup 2)))
16377               (clobber (reg:CC FLAGS_REG))])]
16378   ""
16380   operands[1] = gen_reg_rtx (QImode);
16381   operands[2] = gen_reg_rtx (QImode);
16384 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16385 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16387 (define_expand "cmpstrnqi_nz_1"
16388   [(parallel [(set (reg:CC FLAGS_REG)
16389                    (compare:CC (match_operand 4 "memory_operand")
16390                                (match_operand 5 "memory_operand")))
16391               (use (match_operand 2 "register_operand"))
16392               (use (match_operand:SI 3 "immediate_operand"))
16393               (clobber (match_operand 0 "register_operand"))
16394               (clobber (match_operand 1 "register_operand"))
16395               (clobber (match_dup 2))])]
16396   ""
16397   "ix86_current_function_needs_cld = 1;")
16399 (define_insn "*cmpstrnqi_nz_1"
16400   [(set (reg:CC FLAGS_REG)
16401         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16402                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16403    (use (match_operand:P 6 "register_operand" "2"))
16404    (use (match_operand:SI 3 "immediate_operand" "i"))
16405    (clobber (match_operand:P 0 "register_operand" "=S"))
16406    (clobber (match_operand:P 1 "register_operand" "=D"))
16407    (clobber (match_operand:P 2 "register_operand" "=c"))]
16408   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16409   "%^repz{%;} cmpsb"
16410   [(set_attr "type" "str")
16411    (set_attr "mode" "QI")
16412    (set (attr "prefix_rex")
16413         (if_then_else
16414           (match_test "<P:MODE>mode == DImode")
16415           (const_string "0")
16416           (const_string "*")))
16417    (set_attr "prefix_rep" "1")])
16419 ;; The same, but the count is not known to not be zero.
16421 (define_expand "cmpstrnqi_1"
16422   [(parallel [(set (reg:CC FLAGS_REG)
16423                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16424                                      (const_int 0))
16425                   (compare:CC (match_operand 4 "memory_operand")
16426                               (match_operand 5 "memory_operand"))
16427                   (const_int 0)))
16428               (use (match_operand:SI 3 "immediate_operand"))
16429               (use (reg:CC FLAGS_REG))
16430               (clobber (match_operand 0 "register_operand"))
16431               (clobber (match_operand 1 "register_operand"))
16432               (clobber (match_dup 2))])]
16433   ""
16434   "ix86_current_function_needs_cld = 1;")
16436 (define_insn "*cmpstrnqi_1"
16437   [(set (reg:CC FLAGS_REG)
16438         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16439                              (const_int 0))
16440           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16441                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16442           (const_int 0)))
16443    (use (match_operand:SI 3 "immediate_operand" "i"))
16444    (use (reg:CC FLAGS_REG))
16445    (clobber (match_operand:P 0 "register_operand" "=S"))
16446    (clobber (match_operand:P 1 "register_operand" "=D"))
16447    (clobber (match_operand:P 2 "register_operand" "=c"))]
16448   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16449   "%^repz{%;} cmpsb"
16450   [(set_attr "type" "str")
16451    (set_attr "mode" "QI")
16452    (set (attr "prefix_rex")
16453         (if_then_else
16454           (match_test "<P:MODE>mode == DImode")
16455           (const_string "0")
16456           (const_string "*")))
16457    (set_attr "prefix_rep" "1")])
16459 (define_expand "strlen<mode>"
16460   [(set (match_operand:P 0 "register_operand")
16461         (unspec:P [(match_operand:BLK 1 "general_operand")
16462                    (match_operand:QI 2 "immediate_operand")
16463                    (match_operand 3 "immediate_operand")]
16464                   UNSPEC_SCAS))]
16465   ""
16467  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16468    DONE;
16469  else
16470    FAIL;
16473 (define_expand "strlenqi_1"
16474   [(parallel [(set (match_operand 0 "register_operand")
16475                    (match_operand 2))
16476               (clobber (match_operand 1 "register_operand"))
16477               (clobber (reg:CC FLAGS_REG))])]
16478   ""
16479   "ix86_current_function_needs_cld = 1;")
16481 (define_insn "*strlenqi_1"
16482   [(set (match_operand:P 0 "register_operand" "=&c")
16483         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16484                    (match_operand:QI 2 "register_operand" "a")
16485                    (match_operand:P 3 "immediate_operand" "i")
16486                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16487    (clobber (match_operand:P 1 "register_operand" "=D"))
16488    (clobber (reg:CC FLAGS_REG))]
16489   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16490   "%^repnz{%;} scasb"
16491   [(set_attr "type" "str")
16492    (set_attr "mode" "QI")
16493    (set (attr "prefix_rex")
16494         (if_then_else
16495           (match_test "<P:MODE>mode == DImode")
16496           (const_string "0")
16497           (const_string "*")))
16498    (set_attr "prefix_rep" "1")])
16500 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16501 ;; handled in combine, but it is not currently up to the task.
16502 ;; When used for their truth value, the cmpstrn* expanders generate
16503 ;; code like this:
16505 ;;   repz cmpsb
16506 ;;   seta       %al
16507 ;;   setb       %dl
16508 ;;   cmpb       %al, %dl
16509 ;;   jcc        label
16511 ;; The intermediate three instructions are unnecessary.
16513 ;; This one handles cmpstrn*_nz_1...
16514 (define_peephole2
16515   [(parallel[
16516      (set (reg:CC FLAGS_REG)
16517           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16518                       (mem:BLK (match_operand 5 "register_operand"))))
16519      (use (match_operand 6 "register_operand"))
16520      (use (match_operand:SI 3 "immediate_operand"))
16521      (clobber (match_operand 0 "register_operand"))
16522      (clobber (match_operand 1 "register_operand"))
16523      (clobber (match_operand 2 "register_operand"))])
16524    (set (match_operand:QI 7 "register_operand")
16525         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16526    (set (match_operand:QI 8 "register_operand")
16527         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16528    (set (reg FLAGS_REG)
16529         (compare (match_dup 7) (match_dup 8)))
16530   ]
16531   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16532   [(parallel[
16533      (set (reg:CC FLAGS_REG)
16534           (compare:CC (mem:BLK (match_dup 4))
16535                       (mem:BLK (match_dup 5))))
16536      (use (match_dup 6))
16537      (use (match_dup 3))
16538      (clobber (match_dup 0))
16539      (clobber (match_dup 1))
16540      (clobber (match_dup 2))])])
16542 ;; ...and this one handles cmpstrn*_1.
16543 (define_peephole2
16544   [(parallel[
16545      (set (reg:CC FLAGS_REG)
16546           (if_then_else:CC (ne (match_operand 6 "register_operand")
16547                                (const_int 0))
16548             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16549                         (mem:BLK (match_operand 5 "register_operand")))
16550             (const_int 0)))
16551      (use (match_operand:SI 3 "immediate_operand"))
16552      (use (reg:CC FLAGS_REG))
16553      (clobber (match_operand 0 "register_operand"))
16554      (clobber (match_operand 1 "register_operand"))
16555      (clobber (match_operand 2 "register_operand"))])
16556    (set (match_operand:QI 7 "register_operand")
16557         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16558    (set (match_operand:QI 8 "register_operand")
16559         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16560    (set (reg FLAGS_REG)
16561         (compare (match_dup 7) (match_dup 8)))
16562   ]
16563   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16564   [(parallel[
16565      (set (reg:CC FLAGS_REG)
16566           (if_then_else:CC (ne (match_dup 6)
16567                                (const_int 0))
16568             (compare:CC (mem:BLK (match_dup 4))
16569                         (mem:BLK (match_dup 5)))
16570             (const_int 0)))
16571      (use (match_dup 3))
16572      (use (reg:CC FLAGS_REG))
16573      (clobber (match_dup 0))
16574      (clobber (match_dup 1))
16575      (clobber (match_dup 2))])])
16577 ;; Conditional move instructions.
16579 (define_expand "mov<mode>cc"
16580   [(set (match_operand:SWIM 0 "register_operand")
16581         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16582                            (match_operand:SWIM 2 "<general_operand>")
16583                            (match_operand:SWIM 3 "<general_operand>")))]
16584   ""
16585   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16587 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16588 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16589 ;; So just document what we're doing explicitly.
16591 (define_expand "x86_mov<mode>cc_0_m1"
16592   [(parallel
16593     [(set (match_operand:SWI48 0 "register_operand")
16594           (if_then_else:SWI48
16595             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16596              [(match_operand 1 "flags_reg_operand")
16597               (const_int 0)])
16598             (const_int -1)
16599             (const_int 0)))
16600      (clobber (reg:CC FLAGS_REG))])])
16602 (define_insn "*x86_mov<mode>cc_0_m1"
16603   [(set (match_operand:SWI48 0 "register_operand" "=r")
16604         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16605                              [(reg FLAGS_REG) (const_int 0)])
16606           (const_int -1)
16607           (const_int 0)))
16608    (clobber (reg:CC FLAGS_REG))]
16609   ""
16610   "sbb{<imodesuffix>}\t%0, %0"
16611   ; Since we don't have the proper number of operands for an alu insn,
16612   ; fill in all the blanks.
16613   [(set_attr "type" "alu")
16614    (set_attr "use_carry" "1")
16615    (set_attr "pent_pair" "pu")
16616    (set_attr "memory" "none")
16617    (set_attr "imm_disp" "false")
16618    (set_attr "mode" "<MODE>")
16619    (set_attr "length_immediate" "0")])
16621 (define_insn "*x86_mov<mode>cc_0_m1_se"
16622   [(set (match_operand:SWI48 0 "register_operand" "=r")
16623         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16624                              [(reg FLAGS_REG) (const_int 0)])
16625                             (const_int 1)
16626                             (const_int 0)))
16627    (clobber (reg:CC FLAGS_REG))]
16628   ""
16629   "sbb{<imodesuffix>}\t%0, %0"
16630   [(set_attr "type" "alu")
16631    (set_attr "use_carry" "1")
16632    (set_attr "pent_pair" "pu")
16633    (set_attr "memory" "none")
16634    (set_attr "imm_disp" "false")
16635    (set_attr "mode" "<MODE>")
16636    (set_attr "length_immediate" "0")])
16638 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16639   [(set (match_operand:SWI48 0 "register_operand" "=r")
16640         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16641                     [(reg FLAGS_REG) (const_int 0)])))
16642    (clobber (reg:CC FLAGS_REG))]
16643   ""
16644   "sbb{<imodesuffix>}\t%0, %0"
16645   [(set_attr "type" "alu")
16646    (set_attr "use_carry" "1")
16647    (set_attr "pent_pair" "pu")
16648    (set_attr "memory" "none")
16649    (set_attr "imm_disp" "false")
16650    (set_attr "mode" "<MODE>")
16651    (set_attr "length_immediate" "0")])
16653 (define_insn "*mov<mode>cc_noc"
16654   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16655         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16656                                [(reg FLAGS_REG) (const_int 0)])
16657           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16658           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16659   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16660   "@
16661    cmov%O2%C1\t{%2, %0|%0, %2}
16662    cmov%O2%c1\t{%3, %0|%0, %3}"
16663   [(set_attr "type" "icmov")
16664    (set_attr "mode" "<MODE>")])
16666 (define_insn "*movsicc_noc_zext"
16667   [(set (match_operand:DI 0 "register_operand" "=r,r")
16668         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16669                            [(reg FLAGS_REG) (const_int 0)])
16670           (zero_extend:DI
16671             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
16672           (zero_extend:DI
16673             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
16674   "TARGET_64BIT
16675    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16676   "@
16677    cmov%O2%C1\t{%2, %k0|%k0, %2}
16678    cmov%O2%c1\t{%3, %k0|%k0, %3}"
16679   [(set_attr "type" "icmov")
16680    (set_attr "mode" "SI")])
16682 ;; Don't do conditional moves with memory inputs.  This splitter helps
16683 ;; register starved x86_32 by forcing inputs into registers before reload.
16684 (define_split
16685   [(set (match_operand:SWI248 0 "register_operand")
16686         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16687                                [(reg FLAGS_REG) (const_int 0)])
16688           (match_operand:SWI248 2 "nonimmediate_operand")
16689           (match_operand:SWI248 3 "nonimmediate_operand")))]
16690   "!TARGET_64BIT && TARGET_CMOVE
16691    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16692    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16693    && can_create_pseudo_p ()
16694    && optimize_insn_for_speed_p ()"
16695   [(set (match_dup 0)
16696         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16698   if (MEM_P (operands[2]))
16699     operands[2] = force_reg (<MODE>mode, operands[2]);
16700   if (MEM_P (operands[3]))
16701     operands[3] = force_reg (<MODE>mode, operands[3]);
16704 (define_insn "*movqicc_noc"
16705   [(set (match_operand:QI 0 "register_operand" "=r,r")
16706         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16707                            [(reg FLAGS_REG) (const_int 0)])
16708                       (match_operand:QI 2 "register_operand" "r,0")
16709                       (match_operand:QI 3 "register_operand" "0,r")))]
16710   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16711   "#"
16712   [(set_attr "type" "icmov")
16713    (set_attr "mode" "QI")])
16715 (define_split
16716   [(set (match_operand:SWI12 0 "register_operand")
16717         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16718                               [(reg FLAGS_REG) (const_int 0)])
16719                       (match_operand:SWI12 2 "register_operand")
16720                       (match_operand:SWI12 3 "register_operand")))]
16721   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16722    && reload_completed"
16723   [(set (match_dup 0)
16724         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16726   operands[0] = gen_lowpart (SImode, operands[0]);
16727   operands[2] = gen_lowpart (SImode, operands[2]);
16728   operands[3] = gen_lowpart (SImode, operands[3]);
16731 ;; Don't do conditional moves with memory inputs
16732 (define_peephole2
16733   [(match_scratch:SWI248 4 "r")
16734    (set (match_operand:SWI248 0 "register_operand")
16735         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16736                                [(reg FLAGS_REG) (const_int 0)])
16737           (match_operand:SWI248 2 "nonimmediate_operand")
16738           (match_operand:SWI248 3 "nonimmediate_operand")))]
16739   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16740    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16741    && optimize_insn_for_speed_p ()"
16742   [(set (match_dup 4) (match_dup 5))
16743    (set (match_dup 0)
16744         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16746   if (MEM_P (operands[2]))
16747     {
16748       operands[5] = operands[2];
16749       operands[2] = operands[4];
16750     }
16751   else if (MEM_P (operands[3]))
16752     {
16753       operands[5] = operands[3];
16754       operands[3] = operands[4];
16755     }
16756   else
16757     gcc_unreachable ();
16760 (define_peephole2
16761   [(match_scratch:SI 4 "r")
16762    (set (match_operand:DI 0 "register_operand")
16763         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
16764                            [(reg FLAGS_REG) (const_int 0)])
16765           (zero_extend:DI
16766             (match_operand:SI 2 "nonimmediate_operand"))
16767           (zero_extend:DI
16768             (match_operand:SI 3 "nonimmediate_operand"))))]
16769   "TARGET_64BIT
16770    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16771    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16772    && optimize_insn_for_speed_p ()"
16773   [(set (match_dup 4) (match_dup 5))
16774    (set (match_dup 0)
16775         (if_then_else:DI (match_dup 1)
16776           (zero_extend:DI (match_dup 2))
16777           (zero_extend:DI (match_dup 3))))]
16779   if (MEM_P (operands[2]))
16780     {
16781       operands[5] = operands[2];
16782       operands[2] = operands[4];
16783     }
16784   else if (MEM_P (operands[3]))
16785     {
16786       operands[5] = operands[3];
16787       operands[3] = operands[4];
16788     }
16789   else
16790     gcc_unreachable ();
16793 (define_expand "mov<mode>cc"
16794   [(set (match_operand:X87MODEF 0 "register_operand")
16795         (if_then_else:X87MODEF
16796           (match_operand 1 "comparison_operator")
16797           (match_operand:X87MODEF 2 "register_operand")
16798           (match_operand:X87MODEF 3 "register_operand")))]
16799   "(TARGET_80387 && TARGET_CMOVE)
16800    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16801   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16803 (define_insn "*movxfcc_1"
16804   [(set (match_operand:XF 0 "register_operand" "=f,f")
16805         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16806                                 [(reg FLAGS_REG) (const_int 0)])
16807                       (match_operand:XF 2 "register_operand" "f,0")
16808                       (match_operand:XF 3 "register_operand" "0,f")))]
16809   "TARGET_80387 && TARGET_CMOVE"
16810   "@
16811    fcmov%F1\t{%2, %0|%0, %2}
16812    fcmov%f1\t{%3, %0|%0, %3}"
16813   [(set_attr "type" "fcmov")
16814    (set_attr "mode" "XF")])
16816 (define_insn "*movdfcc_1"
16817   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16818         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16819                                 [(reg FLAGS_REG) (const_int 0)])
16820                       (match_operand:DF 2 "nonimmediate_operand"
16821                                                "f ,0,rm,0 ,rm,0")
16822                       (match_operand:DF 3 "nonimmediate_operand"
16823                                                "0 ,f,0 ,rm,0, rm")))]
16824   "TARGET_80387 && TARGET_CMOVE
16825    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16826   "@
16827    fcmov%F1\t{%2, %0|%0, %2}
16828    fcmov%f1\t{%3, %0|%0, %3}
16829    #
16830    #
16831    cmov%O2%C1\t{%2, %0|%0, %2}
16832    cmov%O2%c1\t{%3, %0|%0, %3}"
16833   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16834    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16835    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16837 (define_split
16838   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16839         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16840                                 [(reg FLAGS_REG) (const_int 0)])
16841                       (match_operand:DF 2 "nonimmediate_operand")
16842                       (match_operand:DF 3 "nonimmediate_operand")))]
16843   "!TARGET_64BIT && reload_completed"
16844   [(set (match_dup 2)
16845         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16846    (set (match_dup 3)
16847         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16849   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16850   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16853 (define_insn "*movsfcc_1_387"
16854   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16855         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16856                                 [(reg FLAGS_REG) (const_int 0)])
16857                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16858                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16859   "TARGET_80387 && TARGET_CMOVE
16860    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16861   "@
16862    fcmov%F1\t{%2, %0|%0, %2}
16863    fcmov%f1\t{%3, %0|%0, %3}
16864    cmov%O2%C1\t{%2, %0|%0, %2}
16865    cmov%O2%c1\t{%3, %0|%0, %3}"
16866   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16867    (set_attr "mode" "SF,SF,SI,SI")])
16869 ;; Don't do conditional moves with memory inputs.  This splitter helps
16870 ;; register starved x86_32 by forcing inputs into registers before reload.
16871 (define_split
16872   [(set (match_operand:MODEF 0 "register_operand")
16873         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16874                               [(reg FLAGS_REG) (const_int 0)])
16875           (match_operand:MODEF 2 "nonimmediate_operand")
16876           (match_operand:MODEF 3 "nonimmediate_operand")))]
16877   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16878    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16879    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16880    && can_create_pseudo_p ()
16881    && optimize_insn_for_speed_p ()"
16882   [(set (match_dup 0)
16883         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16885   if (MEM_P (operands[2]))
16886     operands[2] = force_reg (<MODE>mode, operands[2]);
16887   if (MEM_P (operands[3]))
16888     operands[3] = force_reg (<MODE>mode, operands[3]);
16891 ;; Don't do conditional moves with memory inputs
16892 (define_peephole2
16893   [(match_scratch:MODEF 4 "r")
16894    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16895         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16896                               [(reg FLAGS_REG) (const_int 0)])
16897           (match_operand:MODEF 2 "nonimmediate_operand")
16898           (match_operand:MODEF 3 "nonimmediate_operand")))]
16899   "(<MODE>mode != DFmode || TARGET_64BIT)
16900    && TARGET_80387 && TARGET_CMOVE
16901    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16902    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16903    && optimize_insn_for_speed_p ()"
16904   [(set (match_dup 4) (match_dup 5))
16905    (set (match_dup 0)
16906         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16908   if (MEM_P (operands[2]))
16909     {
16910       operands[5] = operands[2];
16911       operands[2] = operands[4];
16912     }
16913   else if (MEM_P (operands[3]))
16914     {
16915       operands[5] = operands[3];
16916       operands[3] = operands[4];
16917     }
16918   else
16919     gcc_unreachable ();
16922 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16923 ;; the scalar versions to have only XMM registers as operands.
16925 ;; XOP conditional move
16926 (define_insn "*xop_pcmov_<mode>"
16927   [(set (match_operand:MODEF 0 "register_operand" "=x")
16928         (if_then_else:MODEF
16929           (match_operand:MODEF 1 "register_operand" "x")
16930           (match_operand:MODEF 2 "register_operand" "x")
16931           (match_operand:MODEF 3 "register_operand" "x")))]
16932   "TARGET_XOP"
16933   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16934   [(set_attr "type" "sse4arg")])
16936 ;; These versions of the min/max patterns are intentionally ignorant of
16937 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16938 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16939 ;; are undefined in this condition, we're certain this is correct.
16941 (define_insn "<code><mode>3"
16942   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16943         (smaxmin:MODEF
16944           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16945           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16946   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16947   "@
16948    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16949    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16950   [(set_attr "isa" "noavx,avx")
16951    (set_attr "prefix" "orig,vex")
16952    (set_attr "type" "sseadd")
16953    (set_attr "mode" "<MODE>")])
16955 ;; These versions of the min/max patterns implement exactly the operations
16956 ;;   min = (op1 < op2 ? op1 : op2)
16957 ;;   max = (!(op1 < op2) ? op1 : op2)
16958 ;; Their operands are not commutative, and thus they may be used in the
16959 ;; presence of -0.0 and NaN.
16961 (define_int_iterator IEEE_MAXMIN
16962         [UNSPEC_IEEE_MAX
16963          UNSPEC_IEEE_MIN])
16965 (define_int_attr ieee_maxmin
16966         [(UNSPEC_IEEE_MAX "max")
16967          (UNSPEC_IEEE_MIN "min")])
16969 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16970   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16971         (unspec:MODEF
16972           [(match_operand:MODEF 1 "register_operand" "0,v")
16973            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
16974           IEEE_MAXMIN))]
16975   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16976   "@
16977    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16978    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16979   [(set_attr "isa" "noavx,avx")
16980    (set_attr "prefix" "orig,maybe_evex")
16981    (set_attr "type" "sseadd")
16982    (set_attr "mode" "<MODE>")])
16984 ;; Make two stack loads independent:
16985 ;;   fld aa              fld aa
16986 ;;   fld %st(0)     ->   fld bb
16987 ;;   fmul bb             fmul %st(1), %st
16989 ;; Actually we only match the last two instructions for simplicity.
16990 (define_peephole2
16991   [(set (match_operand 0 "fp_register_operand")
16992         (match_operand 1 "fp_register_operand"))
16993    (set (match_dup 0)
16994         (match_operator 2 "binary_fp_operator"
16995            [(match_dup 0)
16996             (match_operand 3 "memory_operand")]))]
16997   "REGNO (operands[0]) != REGNO (operands[1])"
16998   [(set (match_dup 0) (match_dup 3))
16999    (set (match_dup 0) (match_dup 4))]
17001   ;; The % modifier is not operational anymore in peephole2's, so we have to
17002   ;; swap the operands manually in the case of addition and multiplication.
17004   rtx op0, op1;
17006   if (COMMUTATIVE_ARITH_P (operands[2]))
17007     op0 = operands[0], op1 = operands[1];
17008   else
17009     op0 = operands[1], op1 = operands[0];
17011   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17012                                 GET_MODE (operands[2]),
17013                                 op0, op1);
17016 ;; Conditional addition patterns
17017 (define_expand "add<mode>cc"
17018   [(match_operand:SWI 0 "register_operand")
17019    (match_operand 1 "ordered_comparison_operator")
17020    (match_operand:SWI 2 "register_operand")
17021    (match_operand:SWI 3 "const_int_operand")]
17022   ""
17023   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17025 ;; Misc patterns (?)
17027 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17028 ;; Otherwise there will be nothing to keep
17030 ;; [(set (reg ebp) (reg esp))]
17031 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17032 ;;  (clobber (eflags)]
17033 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17035 ;; in proper program order.
17037 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17038   [(set (match_operand:P 0 "register_operand" "=r,r")
17039         (plus:P (match_operand:P 1 "register_operand" "0,r")
17040                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17041    (clobber (reg:CC FLAGS_REG))
17042    (clobber (mem:BLK (scratch)))]
17043   ""
17045   switch (get_attr_type (insn))
17046     {
17047     case TYPE_IMOV:
17048       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17050     case TYPE_ALU:
17051       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17052       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17053         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17055       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17057     default:
17058       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17059       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17060     }
17062   [(set (attr "type")
17063         (cond [(and (eq_attr "alternative" "0")
17064                     (not (match_test "TARGET_OPT_AGU")))
17065                  (const_string "alu")
17066                (match_operand:<MODE> 2 "const0_operand")
17067                  (const_string "imov")
17068               ]
17069               (const_string "lea")))
17070    (set (attr "length_immediate")
17071         (cond [(eq_attr "type" "imov")
17072                  (const_string "0")
17073                (and (eq_attr "type" "alu")
17074                     (match_operand 2 "const128_operand"))
17075                  (const_string "1")
17076               ]
17077               (const_string "*")))
17078    (set_attr "mode" "<MODE>")])
17080 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17081   [(set (match_operand:P 0 "register_operand" "=r")
17082         (minus:P (match_operand:P 1 "register_operand" "0")
17083                  (match_operand:P 2 "register_operand" "r")))
17084    (clobber (reg:CC FLAGS_REG))
17085    (clobber (mem:BLK (scratch)))]
17086   ""
17087   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17088   [(set_attr "type" "alu")
17089    (set_attr "mode" "<MODE>")])
17091 (define_insn "allocate_stack_worker_probe_<mode>"
17092   [(set (match_operand:P 0 "register_operand" "=a")
17093         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17094                             UNSPECV_STACK_PROBE))
17095    (clobber (reg:CC FLAGS_REG))]
17096   "ix86_target_stack_probe ()"
17097   "call\t___chkstk_ms"
17098   [(set_attr "type" "multi")
17099    (set_attr "length" "5")])
17101 (define_expand "allocate_stack"
17102   [(match_operand 0 "register_operand")
17103    (match_operand 1 "general_operand")]
17104   "ix86_target_stack_probe ()"
17106   rtx x;
17108 #ifndef CHECK_STACK_LIMIT
17109 #define CHECK_STACK_LIMIT 0
17110 #endif
17112   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17113       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17114     x = operands[1];
17115   else
17116     {
17117       rtx (*insn) (rtx, rtx);
17119       x = copy_to_mode_reg (Pmode, operands[1]);
17121       insn = (TARGET_64BIT
17122               ? gen_allocate_stack_worker_probe_di
17123               : gen_allocate_stack_worker_probe_si);
17125       emit_insn (insn (x, x));
17126     }
17128   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17129                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17131   if (x != stack_pointer_rtx)
17132     emit_move_insn (stack_pointer_rtx, x);
17134   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17135   DONE;
17138 ;; Use IOR for stack probes, this is shorter.
17139 (define_expand "probe_stack"
17140   [(match_operand 0 "memory_operand")]
17141   ""
17143   rtx (*gen_ior3) (rtx, rtx, rtx);
17145   gen_ior3 = (GET_MODE (operands[0]) == DImode
17146               ? gen_iordi3 : gen_iorsi3);
17148   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17149   DONE;
17152 (define_insn "adjust_stack_and_probe<mode>"
17153   [(set (match_operand:P 0 "register_operand" "=r")
17154         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17155                             UNSPECV_PROBE_STACK_RANGE))
17156    (set (reg:P SP_REG)
17157         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17158    (clobber (reg:CC FLAGS_REG))
17159    (clobber (mem:BLK (scratch)))]
17160   ""
17161   "* return output_adjust_stack_and_probe (operands[0]);"
17162   [(set_attr "type" "multi")])
17164 (define_insn "probe_stack_range<mode>"
17165   [(set (match_operand:P 0 "register_operand" "=r")
17166         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17167                             (match_operand:P 2 "const_int_operand" "n")]
17168                             UNSPECV_PROBE_STACK_RANGE))
17169    (clobber (reg:CC FLAGS_REG))]
17170   ""
17171   "* return output_probe_stack_range (operands[0], operands[2]);"
17172   [(set_attr "type" "multi")])
17174 (define_expand "builtin_setjmp_receiver"
17175   [(label_ref (match_operand 0))]
17176   "!TARGET_64BIT && flag_pic"
17178 #if TARGET_MACHO
17179   if (TARGET_MACHO)
17180     {
17181       rtx xops[3];
17182       rtx_code_label *label_rtx = gen_label_rtx ();
17183       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17184       xops[0] = xops[1] = pic_offset_table_rtx;
17185       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17186       ix86_expand_binary_operator (MINUS, SImode, xops);
17187     }
17188   else
17189 #endif
17190     emit_insn (gen_set_got (pic_offset_table_rtx));
17191   DONE;
17194 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17195 ;; Do not split instructions with mask registers.
17196 (define_split
17197   [(set (match_operand 0 "general_reg_operand")
17198         (match_operator 3 "promotable_binary_operator"
17199            [(match_operand 1 "general_reg_operand")
17200             (match_operand 2 "aligned_operand")]))
17201    (clobber (reg:CC FLAGS_REG))]
17202   "! TARGET_PARTIAL_REG_STALL && reload_completed
17203    && ((GET_MODE (operands[0]) == HImode
17204         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17205             /* ??? next two lines just !satisfies_constraint_K (...) */
17206             || !CONST_INT_P (operands[2])
17207             || satisfies_constraint_K (operands[2])))
17208        || (GET_MODE (operands[0]) == QImode
17209            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17210   [(parallel [(set (match_dup 0)
17211                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17212               (clobber (reg:CC FLAGS_REG))])]
17214   operands[0] = gen_lowpart (SImode, operands[0]);
17215   operands[1] = gen_lowpart (SImode, operands[1]);
17216   if (GET_CODE (operands[3]) != ASHIFT)
17217     operands[2] = gen_lowpart (SImode, operands[2]);
17218   operands[3] = shallow_copy_rtx (operands[3]);
17219   PUT_MODE (operands[3], SImode);
17222 ; Promote the QImode tests, as i386 has encoding of the AND
17223 ; instruction with 32-bit sign-extended immediate and thus the
17224 ; instruction size is unchanged, except in the %eax case for
17225 ; which it is increased by one byte, hence the ! optimize_size.
17226 (define_split
17227   [(set (match_operand 0 "flags_reg_operand")
17228         (match_operator 2 "compare_operator"
17229           [(and (match_operand 3 "aligned_operand")
17230                 (match_operand 4 "const_int_operand"))
17231            (const_int 0)]))
17232    (set (match_operand 1 "register_operand")
17233         (and (match_dup 3) (match_dup 4)))]
17234   "! TARGET_PARTIAL_REG_STALL && reload_completed
17235    && optimize_insn_for_speed_p ()
17236    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17237        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17238    /* Ensure that the operand will remain sign-extended immediate.  */
17239    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17240   [(parallel [(set (match_dup 0)
17241                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17242                                     (const_int 0)]))
17243               (set (match_dup 1)
17244                    (and:SI (match_dup 3) (match_dup 4)))])]
17246   operands[4]
17247     = gen_int_mode (INTVAL (operands[4])
17248                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17249   operands[1] = gen_lowpart (SImode, operands[1]);
17250   operands[3] = gen_lowpart (SImode, operands[3]);
17253 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17254 ; the TEST instruction with 32-bit sign-extended immediate and thus
17255 ; the instruction size would at least double, which is not what we
17256 ; want even with ! optimize_size.
17257 (define_split
17258   [(set (match_operand 0 "flags_reg_operand")
17259         (match_operator 1 "compare_operator"
17260           [(and (match_operand:HI 2 "aligned_operand")
17261                 (match_operand:HI 3 "const_int_operand"))
17262            (const_int 0)]))]
17263   "! TARGET_PARTIAL_REG_STALL && reload_completed
17264    && ! TARGET_FAST_PREFIX
17265    && optimize_insn_for_speed_p ()
17266    /* Ensure that the operand will remain sign-extended immediate.  */
17267    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17268   [(set (match_dup 0)
17269         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17270                          (const_int 0)]))]
17272   operands[3]
17273     = gen_int_mode (INTVAL (operands[3])
17274                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17275   operands[2] = gen_lowpart (SImode, operands[2]);
17278 (define_split
17279   [(set (match_operand 0 "register_operand")
17280         (neg (match_operand 1 "register_operand")))
17281    (clobber (reg:CC FLAGS_REG))]
17282   "! TARGET_PARTIAL_REG_STALL && reload_completed
17283    && (GET_MODE (operands[0]) == HImode
17284        || (GET_MODE (operands[0]) == QImode
17285            && (TARGET_PROMOTE_QImode
17286                || optimize_insn_for_size_p ())))"
17287   [(parallel [(set (match_dup 0)
17288                    (neg:SI (match_dup 1)))
17289               (clobber (reg:CC FLAGS_REG))])]
17291   operands[0] = gen_lowpart (SImode, operands[0]);
17292   operands[1] = gen_lowpart (SImode, operands[1]);
17295 ;; Do not split instructions with mask regs.
17296 (define_split
17297   [(set (match_operand 0 "general_reg_operand")
17298         (not (match_operand 1 "general_reg_operand")))]
17299   "! TARGET_PARTIAL_REG_STALL && reload_completed
17300    && (GET_MODE (operands[0]) == HImode
17301        || (GET_MODE (operands[0]) == QImode
17302            && (TARGET_PROMOTE_QImode
17303                || optimize_insn_for_size_p ())))"
17304   [(set (match_dup 0)
17305         (not:SI (match_dup 1)))]
17307   operands[0] = gen_lowpart (SImode, operands[0]);
17308   operands[1] = gen_lowpart (SImode, operands[1]);
17311 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17312 ;; transform a complex memory operation into two memory to register operations.
17314 ;; Don't push memory operands
17315 (define_peephole2
17316   [(set (match_operand:SWI 0 "push_operand")
17317         (match_operand:SWI 1 "memory_operand"))
17318    (match_scratch:SWI 2 "<r>")]
17319   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17320    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17321   [(set (match_dup 2) (match_dup 1))
17322    (set (match_dup 0) (match_dup 2))])
17324 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17325 ;; SImode pushes.
17326 (define_peephole2
17327   [(set (match_operand:SF 0 "push_operand")
17328         (match_operand:SF 1 "memory_operand"))
17329    (match_scratch:SF 2 "r")]
17330   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17331    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17332   [(set (match_dup 2) (match_dup 1))
17333    (set (match_dup 0) (match_dup 2))])
17335 ;; Don't move an immediate directly to memory when the instruction
17336 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17337 (define_peephole2
17338   [(match_scratch:SWI124 1 "<r>")
17339    (set (match_operand:SWI124 0 "memory_operand")
17340         (const_int 0))]
17341   "optimize_insn_for_speed_p ()
17342    && ((<MODE>mode == HImode
17343        && TARGET_LCP_STALL)
17344        || (!TARGET_USE_MOV0
17345           && TARGET_SPLIT_LONG_MOVES
17346           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17347    && peep2_regno_dead_p (0, FLAGS_REG)"
17348   [(parallel [(set (match_dup 2) (const_int 0))
17349               (clobber (reg:CC FLAGS_REG))])
17350    (set (match_dup 0) (match_dup 1))]
17351   "operands[2] = gen_lowpart (SImode, operands[1]);")
17353 (define_peephole2
17354   [(match_scratch:SWI124 2 "<r>")
17355    (set (match_operand:SWI124 0 "memory_operand")
17356         (match_operand:SWI124 1 "immediate_operand"))]
17357   "optimize_insn_for_speed_p ()
17358    && ((<MODE>mode == HImode
17359        && TARGET_LCP_STALL)
17360        || (TARGET_SPLIT_LONG_MOVES
17361           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17362   [(set (match_dup 2) (match_dup 1))
17363    (set (match_dup 0) (match_dup 2))])
17365 ;; Don't compare memory with zero, load and use a test instead.
17366 (define_peephole2
17367   [(set (match_operand 0 "flags_reg_operand")
17368         (match_operator 1 "compare_operator"
17369           [(match_operand:SI 2 "memory_operand")
17370            (const_int 0)]))
17371    (match_scratch:SI 3 "r")]
17372   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17373   [(set (match_dup 3) (match_dup 2))
17374    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17376 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17377 ;; Don't split NOTs with a displacement operand, because resulting XOR
17378 ;; will not be pairable anyway.
17380 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17381 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17382 ;; so this split helps here as well.
17384 ;; Note: Can't do this as a regular split because we can't get proper
17385 ;; lifetime information then.
17387 (define_peephole2
17388   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17389         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17390   "optimize_insn_for_speed_p ()
17391    && ((TARGET_NOT_UNPAIRABLE
17392         && (!MEM_P (operands[0])
17393             || !memory_displacement_operand (operands[0], <MODE>mode)))
17394        || (TARGET_NOT_VECTORMODE
17395            && long_memory_operand (operands[0], <MODE>mode)))
17396    && peep2_regno_dead_p (0, FLAGS_REG)"
17397   [(parallel [(set (match_dup 0)
17398                    (xor:SWI124 (match_dup 1) (const_int -1)))
17399               (clobber (reg:CC FLAGS_REG))])])
17401 ;; Non pairable "test imm, reg" instructions can be translated to
17402 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17403 ;; byte opcode instead of two, have a short form for byte operands),
17404 ;; so do it for other CPUs as well.  Given that the value was dead,
17405 ;; this should not create any new dependencies.  Pass on the sub-word
17406 ;; versions if we're concerned about partial register stalls.
17408 (define_peephole2
17409   [(set (match_operand 0 "flags_reg_operand")
17410         (match_operator 1 "compare_operator"
17411           [(and:SI (match_operand:SI 2 "register_operand")
17412                    (match_operand:SI 3 "immediate_operand"))
17413            (const_int 0)]))]
17414   "ix86_match_ccmode (insn, CCNOmode)
17415    && (true_regnum (operands[2]) != AX_REG
17416        || satisfies_constraint_K (operands[3]))
17417    && peep2_reg_dead_p (1, operands[2])"
17418   [(parallel
17419      [(set (match_dup 0)
17420            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17421                             (const_int 0)]))
17422       (set (match_dup 2)
17423            (and:SI (match_dup 2) (match_dup 3)))])])
17425 ;; We don't need to handle HImode case, because it will be promoted to SImode
17426 ;; on ! TARGET_PARTIAL_REG_STALL
17428 (define_peephole2
17429   [(set (match_operand 0 "flags_reg_operand")
17430         (match_operator 1 "compare_operator"
17431           [(and:QI (match_operand:QI 2 "register_operand")
17432                    (match_operand:QI 3 "immediate_operand"))
17433            (const_int 0)]))]
17434   "! TARGET_PARTIAL_REG_STALL
17435    && ix86_match_ccmode (insn, CCNOmode)
17436    && true_regnum (operands[2]) != AX_REG
17437    && peep2_reg_dead_p (1, operands[2])"
17438   [(parallel
17439      [(set (match_dup 0)
17440            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17441                             (const_int 0)]))
17442       (set (match_dup 2)
17443            (and:QI (match_dup 2) (match_dup 3)))])])
17445 (define_peephole2
17446   [(set (match_operand 0 "flags_reg_operand")
17447         (match_operator 1 "compare_operator"
17448           [(and:SI
17449              (zero_extract:SI
17450                (match_operand 2 "QIreg_operand")
17451                (const_int 8)
17452                (const_int 8))
17453              (match_operand 3 "const_int_operand"))
17454            (const_int 0)]))]
17455   "! TARGET_PARTIAL_REG_STALL
17456    && ix86_match_ccmode (insn, CCNOmode)
17457    && true_regnum (operands[2]) != AX_REG
17458    && peep2_reg_dead_p (1, operands[2])"
17459   [(parallel [(set (match_dup 0)
17460                    (match_op_dup 1
17461                      [(and:SI
17462                         (zero_extract:SI
17463                           (match_dup 2)
17464                           (const_int 8)
17465                           (const_int 8))
17466                         (match_dup 3))
17467                       (const_int 0)]))
17468               (set (zero_extract:SI (match_dup 2)
17469                                     (const_int 8)
17470                                     (const_int 8))
17471                    (and:SI
17472                      (zero_extract:SI
17473                        (match_dup 2)
17474                        (const_int 8)
17475                        (const_int 8))
17476                      (match_dup 3)))])])
17478 ;; Don't do logical operations with memory inputs.
17479 (define_peephole2
17480   [(match_scratch:SI 2 "r")
17481    (parallel [(set (match_operand:SI 0 "register_operand")
17482                    (match_operator:SI 3 "arith_or_logical_operator"
17483                      [(match_dup 0)
17484                       (match_operand:SI 1 "memory_operand")]))
17485               (clobber (reg:CC FLAGS_REG))])]
17486   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17487   [(set (match_dup 2) (match_dup 1))
17488    (parallel [(set (match_dup 0)
17489                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17490               (clobber (reg:CC FLAGS_REG))])])
17492 (define_peephole2
17493   [(match_scratch:SI 2 "r")
17494    (parallel [(set (match_operand:SI 0 "register_operand")
17495                    (match_operator:SI 3 "arith_or_logical_operator"
17496                      [(match_operand:SI 1 "memory_operand")
17497                       (match_dup 0)]))
17498               (clobber (reg:CC FLAGS_REG))])]
17499   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17500   [(set (match_dup 2) (match_dup 1))
17501    (parallel [(set (match_dup 0)
17502                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17503               (clobber (reg:CC FLAGS_REG))])])
17505 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17506 ;; refers to the destination of the load!
17508 (define_peephole2
17509   [(set (match_operand:SI 0 "register_operand")
17510         (match_operand:SI 1 "register_operand"))
17511    (parallel [(set (match_dup 0)
17512                    (match_operator:SI 3 "commutative_operator"
17513                      [(match_dup 0)
17514                       (match_operand:SI 2 "memory_operand")]))
17515               (clobber (reg:CC FLAGS_REG))])]
17516   "REGNO (operands[0]) != REGNO (operands[1])
17517    && GENERAL_REGNO_P (REGNO (operands[0]))
17518    && GENERAL_REGNO_P (REGNO (operands[1]))"
17519   [(set (match_dup 0) (match_dup 4))
17520    (parallel [(set (match_dup 0)
17521                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17522               (clobber (reg:CC FLAGS_REG))])]
17523   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17525 (define_peephole2
17526   [(set (match_operand 0 "register_operand")
17527         (match_operand 1 "register_operand"))
17528    (set (match_dup 0)
17529                    (match_operator 3 "commutative_operator"
17530                      [(match_dup 0)
17531                       (match_operand 2 "memory_operand")]))]
17532   "REGNO (operands[0]) != REGNO (operands[1])
17533    && ((MMX_REGNO_P (REGNO (operands[0]))
17534         && MMX_REGNO_P (REGNO (operands[1]))) 
17535        || (SSE_REGNO_P (REGNO (operands[0]))
17536            && SSE_REGNO_P (REGNO (operands[1]))))"
17537   [(set (match_dup 0) (match_dup 2))
17538    (set (match_dup 0)
17539         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17541 ; Don't do logical operations with memory outputs
17543 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17544 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17545 ; the same decoder scheduling characteristics as the original.
17547 (define_peephole2
17548   [(match_scratch:SI 2 "r")
17549    (parallel [(set (match_operand:SI 0 "memory_operand")
17550                    (match_operator:SI 3 "arith_or_logical_operator"
17551                      [(match_dup 0)
17552                       (match_operand:SI 1 "nonmemory_operand")]))
17553               (clobber (reg:CC FLAGS_REG))])]
17554   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17555    /* Do not split stack checking probes.  */
17556    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17557   [(set (match_dup 2) (match_dup 0))
17558    (parallel [(set (match_dup 2)
17559                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17560               (clobber (reg:CC FLAGS_REG))])
17561    (set (match_dup 0) (match_dup 2))])
17563 (define_peephole2
17564   [(match_scratch:SI 2 "r")
17565    (parallel [(set (match_operand:SI 0 "memory_operand")
17566                    (match_operator:SI 3 "arith_or_logical_operator"
17567                      [(match_operand:SI 1 "nonmemory_operand")
17568                       (match_dup 0)]))
17569               (clobber (reg:CC FLAGS_REG))])]
17570   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17571    /* Do not split stack checking probes.  */
17572    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17573   [(set (match_dup 2) (match_dup 0))
17574    (parallel [(set (match_dup 2)
17575                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17576               (clobber (reg:CC FLAGS_REG))])
17577    (set (match_dup 0) (match_dup 2))])
17579 ;; Attempt to use arith or logical operations with memory outputs with
17580 ;; setting of flags.
17581 (define_peephole2
17582   [(set (match_operand:SWI 0 "register_operand")
17583         (match_operand:SWI 1 "memory_operand"))
17584    (parallel [(set (match_dup 0)
17585                    (match_operator:SWI 3 "plusminuslogic_operator"
17586                      [(match_dup 0)
17587                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17588               (clobber (reg:CC FLAGS_REG))])
17589    (set (match_dup 1) (match_dup 0))
17590    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17591   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17592    && peep2_reg_dead_p (4, operands[0])
17593    && !reg_overlap_mentioned_p (operands[0], operands[1])
17594    && !reg_overlap_mentioned_p (operands[0], operands[2])
17595    && (<MODE>mode != QImode
17596        || immediate_operand (operands[2], QImode)
17597        || any_QIreg_operand (operands[2], QImode))
17598    && ix86_match_ccmode (peep2_next_insn (3),
17599                          (GET_CODE (operands[3]) == PLUS
17600                           || GET_CODE (operands[3]) == MINUS)
17601                          ? CCGOCmode : CCNOmode)"
17602   [(parallel [(set (match_dup 4) (match_dup 5))
17603               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17604                                                   (match_dup 2)]))])]
17606   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17607   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17608                                 copy_rtx (operands[1]),
17609                                 copy_rtx (operands[2]));
17610   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17611                                  operands[5], const0_rtx);
17614 (define_peephole2
17615   [(parallel [(set (match_operand:SWI 0 "register_operand")
17616                    (match_operator:SWI 2 "plusminuslogic_operator"
17617                      [(match_dup 0)
17618                       (match_operand:SWI 1 "memory_operand")]))
17619               (clobber (reg:CC FLAGS_REG))])
17620    (set (match_dup 1) (match_dup 0))
17621    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17622   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17623    && GET_CODE (operands[2]) != MINUS
17624    && peep2_reg_dead_p (3, operands[0])
17625    && !reg_overlap_mentioned_p (operands[0], operands[1])
17626    && ix86_match_ccmode (peep2_next_insn (2),
17627                          GET_CODE (operands[2]) == PLUS
17628                          ? CCGOCmode : CCNOmode)"
17629   [(parallel [(set (match_dup 3) (match_dup 4))
17630               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17631                                                   (match_dup 0)]))])]
17633   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17634   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17635                                 copy_rtx (operands[1]),
17636                                 copy_rtx (operands[0]));
17637   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17638                                  operands[4], const0_rtx);
17641 (define_peephole2
17642   [(set (match_operand:SWI12 0 "register_operand")
17643         (match_operand:SWI12 1 "memory_operand"))
17644    (parallel [(set (match_operand:SI 4 "register_operand")
17645                    (match_operator:SI 3 "plusminuslogic_operator"
17646                      [(match_dup 4)
17647                       (match_operand:SI 2 "nonmemory_operand")]))
17648               (clobber (reg:CC FLAGS_REG))])
17649    (set (match_dup 1) (match_dup 0))
17650    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17651   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17652    && REG_P (operands[0]) && REG_P (operands[4])
17653    && REGNO (operands[0]) == REGNO (operands[4])
17654    && peep2_reg_dead_p (4, operands[0])
17655    && (<MODE>mode != QImode
17656        || immediate_operand (operands[2], SImode)
17657        || any_QIreg_operand (operands[2], SImode))
17658    && !reg_overlap_mentioned_p (operands[0], operands[1])
17659    && !reg_overlap_mentioned_p (operands[0], operands[2])
17660    && ix86_match_ccmode (peep2_next_insn (3),
17661                          (GET_CODE (operands[3]) == PLUS
17662                           || GET_CODE (operands[3]) == MINUS)
17663                          ? CCGOCmode : CCNOmode)"
17664   [(parallel [(set (match_dup 4) (match_dup 5))
17665               (set (match_dup 1) (match_dup 6))])]
17667   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17668   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17669   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17670                                 copy_rtx (operands[1]), operands[2]);
17671   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17672                                  operands[5], const0_rtx);
17673   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17674                                 copy_rtx (operands[1]),
17675                                 copy_rtx (operands[2]));
17678 ;; Attempt to always use XOR for zeroing registers.
17679 (define_peephole2
17680   [(set (match_operand 0 "register_operand")
17681         (match_operand 1 "const0_operand"))]
17682   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17683    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17684    && GENERAL_REGNO_P (REGNO (operands[0]))
17685    && peep2_regno_dead_p (0, FLAGS_REG)"
17686   [(parallel [(set (match_dup 0) (const_int 0))
17687               (clobber (reg:CC FLAGS_REG))])]
17688   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17690 (define_peephole2
17691   [(set (strict_low_part (match_operand 0 "register_operand"))
17692         (const_int 0))]
17693   "(GET_MODE (operands[0]) == QImode
17694     || GET_MODE (operands[0]) == HImode)
17695    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17696    && peep2_regno_dead_p (0, FLAGS_REG)"
17697   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17698               (clobber (reg:CC FLAGS_REG))])])
17700 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17701 (define_peephole2
17702   [(set (match_operand:SWI248 0 "register_operand")
17703         (const_int -1))]
17704   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17705    && GENERAL_REGNO_P (REGNO (operands[0]))
17706    && peep2_regno_dead_p (0, FLAGS_REG)"
17707   [(parallel [(set (match_dup 0) (const_int -1))
17708               (clobber (reg:CC FLAGS_REG))])]
17710   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17711     operands[0] = gen_lowpart (SImode, operands[0]);
17714 ;; Attempt to convert simple lea to add/shift.
17715 ;; These can be created by move expanders.
17716 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17717 ;; relevant lea instructions were already split.
17719 (define_peephole2
17720   [(set (match_operand:SWI48 0 "register_operand")
17721         (plus:SWI48 (match_dup 0)
17722                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17723   "!TARGET_OPT_AGU
17724    && peep2_regno_dead_p (0, FLAGS_REG)"
17725   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17726               (clobber (reg:CC FLAGS_REG))])])
17728 (define_peephole2
17729   [(set (match_operand:SWI48 0 "register_operand")
17730         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17731                     (match_dup 0)))]
17732   "!TARGET_OPT_AGU
17733    && peep2_regno_dead_p (0, FLAGS_REG)"
17734   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17735               (clobber (reg:CC FLAGS_REG))])])
17737 (define_peephole2
17738   [(set (match_operand:DI 0 "register_operand")
17739         (zero_extend:DI
17740           (plus:SI (match_operand:SI 1 "register_operand")
17741                    (match_operand:SI 2 "nonmemory_operand"))))]
17742   "TARGET_64BIT && !TARGET_OPT_AGU
17743    && REGNO (operands[0]) == REGNO (operands[1])
17744    && peep2_regno_dead_p (0, FLAGS_REG)"
17745   [(parallel [(set (match_dup 0)
17746                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17747               (clobber (reg:CC FLAGS_REG))])])
17749 (define_peephole2
17750   [(set (match_operand:DI 0 "register_operand")
17751         (zero_extend:DI
17752           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17753                    (match_operand:SI 2 "register_operand"))))]
17754   "TARGET_64BIT && !TARGET_OPT_AGU
17755    && REGNO (operands[0]) == REGNO (operands[2])
17756    && peep2_regno_dead_p (0, FLAGS_REG)"
17757   [(parallel [(set (match_dup 0)
17758                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17759               (clobber (reg:CC FLAGS_REG))])])
17761 (define_peephole2
17762   [(set (match_operand:SWI48 0 "register_operand")
17763         (mult:SWI48 (match_dup 0)
17764                     (match_operand:SWI48 1 "const_int_operand")))]
17765   "exact_log2 (INTVAL (operands[1])) >= 0
17766    && peep2_regno_dead_p (0, FLAGS_REG)"
17767   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17768               (clobber (reg:CC FLAGS_REG))])]
17769   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17771 (define_peephole2
17772   [(set (match_operand:DI 0 "register_operand")
17773         (zero_extend:DI
17774           (mult:SI (match_operand:SI 1 "register_operand")
17775                    (match_operand:SI 2 "const_int_operand"))))]
17776   "TARGET_64BIT
17777    && exact_log2 (INTVAL (operands[2])) >= 0
17778    && REGNO (operands[0]) == REGNO (operands[1])
17779    && peep2_regno_dead_p (0, FLAGS_REG)"
17780   [(parallel [(set (match_dup 0)
17781                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17782               (clobber (reg:CC FLAGS_REG))])]
17783   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17785 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17786 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17787 ;; On many CPUs it is also faster, since special hardware to avoid esp
17788 ;; dependencies is present.
17790 ;; While some of these conversions may be done using splitters, we use
17791 ;; peepholes in order to allow combine_stack_adjustments pass to see
17792 ;; nonobfuscated RTL.
17794 ;; Convert prologue esp subtractions to push.
17795 ;; We need register to push.  In order to keep verify_flow_info happy we have
17796 ;; two choices
17797 ;; - use scratch and clobber it in order to avoid dependencies
17798 ;; - use already live register
17799 ;; We can't use the second way right now, since there is no reliable way how to
17800 ;; verify that given register is live.  First choice will also most likely in
17801 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17802 ;; call clobbered registers are dead.  We may want to use base pointer as an
17803 ;; alternative when no register is available later.
17805 (define_peephole2
17806   [(match_scratch:W 1 "r")
17807    (parallel [(set (reg:P SP_REG)
17808                    (plus:P (reg:P SP_REG)
17809                            (match_operand:P 0 "const_int_operand")))
17810               (clobber (reg:CC FLAGS_REG))
17811               (clobber (mem:BLK (scratch)))])]
17812   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17813    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17814   [(clobber (match_dup 1))
17815    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17816               (clobber (mem:BLK (scratch)))])])
17818 (define_peephole2
17819   [(match_scratch:W 1 "r")
17820    (parallel [(set (reg:P SP_REG)
17821                    (plus:P (reg:P SP_REG)
17822                            (match_operand:P 0 "const_int_operand")))
17823               (clobber (reg:CC FLAGS_REG))
17824               (clobber (mem:BLK (scratch)))])]
17825   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17826    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17827   [(clobber (match_dup 1))
17828    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17829    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17830               (clobber (mem:BLK (scratch)))])])
17832 ;; Convert esp subtractions to push.
17833 (define_peephole2
17834   [(match_scratch:W 1 "r")
17835    (parallel [(set (reg:P SP_REG)
17836                    (plus:P (reg:P SP_REG)
17837                            (match_operand:P 0 "const_int_operand")))
17838               (clobber (reg:CC FLAGS_REG))])]
17839   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17840    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17841   [(clobber (match_dup 1))
17842    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17844 (define_peephole2
17845   [(match_scratch:W 1 "r")
17846    (parallel [(set (reg:P SP_REG)
17847                    (plus:P (reg:P SP_REG)
17848                            (match_operand:P 0 "const_int_operand")))
17849               (clobber (reg:CC FLAGS_REG))])]
17850   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17851    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17852   [(clobber (match_dup 1))
17853    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17854    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17856 ;; Convert epilogue deallocator to pop.
17857 (define_peephole2
17858   [(match_scratch:W 1 "r")
17859    (parallel [(set (reg:P SP_REG)
17860                    (plus:P (reg:P SP_REG)
17861                            (match_operand:P 0 "const_int_operand")))
17862               (clobber (reg:CC FLAGS_REG))
17863               (clobber (mem:BLK (scratch)))])]
17864   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17865    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17866   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17867               (clobber (mem:BLK (scratch)))])])
17869 ;; Two pops case is tricky, since pop causes dependency
17870 ;; on destination register.  We use two registers if available.
17871 (define_peephole2
17872   [(match_scratch:W 1 "r")
17873    (match_scratch:W 2 "r")
17874    (parallel [(set (reg:P SP_REG)
17875                    (plus:P (reg:P SP_REG)
17876                            (match_operand:P 0 "const_int_operand")))
17877               (clobber (reg:CC FLAGS_REG))
17878               (clobber (mem:BLK (scratch)))])]
17879   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17880    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17881   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17882               (clobber (mem:BLK (scratch)))])
17883    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17885 (define_peephole2
17886   [(match_scratch:W 1 "r")
17887    (parallel [(set (reg:P SP_REG)
17888                    (plus:P (reg:P SP_REG)
17889                            (match_operand:P 0 "const_int_operand")))
17890               (clobber (reg:CC FLAGS_REG))
17891               (clobber (mem:BLK (scratch)))])]
17892   "optimize_insn_for_size_p ()
17893    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17894   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17895               (clobber (mem:BLK (scratch)))])
17896    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17898 ;; Convert esp additions to pop.
17899 (define_peephole2
17900   [(match_scratch:W 1 "r")
17901    (parallel [(set (reg:P SP_REG)
17902                    (plus:P (reg:P SP_REG)
17903                            (match_operand:P 0 "const_int_operand")))
17904               (clobber (reg:CC FLAGS_REG))])]
17905   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17906   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17908 ;; Two pops case is tricky, since pop causes dependency
17909 ;; on destination register.  We use two registers if available.
17910 (define_peephole2
17911   [(match_scratch:W 1 "r")
17912    (match_scratch:W 2 "r")
17913    (parallel [(set (reg:P SP_REG)
17914                    (plus:P (reg:P SP_REG)
17915                            (match_operand:P 0 "const_int_operand")))
17916               (clobber (reg:CC FLAGS_REG))])]
17917   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17918   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17919    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17921 (define_peephole2
17922   [(match_scratch:W 1 "r")
17923    (parallel [(set (reg:P SP_REG)
17924                    (plus:P (reg:P SP_REG)
17925                            (match_operand:P 0 "const_int_operand")))
17926               (clobber (reg:CC FLAGS_REG))])]
17927   "optimize_insn_for_size_p ()
17928    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17929   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17930    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17932 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17933 ;; required and register dies.  Similarly for 128 to -128.
17934 (define_peephole2
17935   [(set (match_operand 0 "flags_reg_operand")
17936         (match_operator 1 "compare_operator"
17937           [(match_operand 2 "register_operand")
17938            (match_operand 3 "const_int_operand")]))]
17939   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17940      && incdec_operand (operands[3], GET_MODE (operands[3])))
17941     || (!TARGET_FUSE_CMP_AND_BRANCH
17942         && INTVAL (operands[3]) == 128))
17943    && ix86_match_ccmode (insn, CCGCmode)
17944    && peep2_reg_dead_p (1, operands[2])"
17945   [(parallel [(set (match_dup 0)
17946                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17947               (clobber (match_dup 2))])])
17949 ;; Convert imul by three, five and nine into lea
17950 (define_peephole2
17951   [(parallel
17952     [(set (match_operand:SWI48 0 "register_operand")
17953           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17954                       (match_operand:SWI48 2 "const359_operand")))
17955      (clobber (reg:CC FLAGS_REG))])]
17956   "!TARGET_PARTIAL_REG_STALL
17957    || <MODE>mode == SImode
17958    || optimize_function_for_size_p (cfun)"
17959   [(set (match_dup 0)
17960         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17961                     (match_dup 1)))]
17962   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17964 (define_peephole2
17965   [(parallel
17966     [(set (match_operand:SWI48 0 "register_operand")
17967           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17968                       (match_operand:SWI48 2 "const359_operand")))
17969      (clobber (reg:CC FLAGS_REG))])]
17970   "optimize_insn_for_speed_p ()
17971    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17972   [(set (match_dup 0) (match_dup 1))
17973    (set (match_dup 0)
17974         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17975                     (match_dup 0)))]
17976   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17978 ;; imul $32bit_imm, mem, reg is vector decoded, while
17979 ;; imul $32bit_imm, reg, reg is direct decoded.
17980 (define_peephole2
17981   [(match_scratch:SWI48 3 "r")
17982    (parallel [(set (match_operand:SWI48 0 "register_operand")
17983                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17984                                (match_operand:SWI48 2 "immediate_operand")))
17985               (clobber (reg:CC FLAGS_REG))])]
17986   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17987    && !satisfies_constraint_K (operands[2])"
17988   [(set (match_dup 3) (match_dup 1))
17989    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17990               (clobber (reg:CC FLAGS_REG))])])
17992 (define_peephole2
17993   [(match_scratch:SI 3 "r")
17994    (parallel [(set (match_operand:DI 0 "register_operand")
17995                    (zero_extend:DI
17996                      (mult:SI (match_operand:SI 1 "memory_operand")
17997                               (match_operand:SI 2 "immediate_operand"))))
17998               (clobber (reg:CC FLAGS_REG))])]
17999   "TARGET_64BIT
18000    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18001    && !satisfies_constraint_K (operands[2])"
18002   [(set (match_dup 3) (match_dup 1))
18003    (parallel [(set (match_dup 0)
18004                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18005               (clobber (reg:CC FLAGS_REG))])])
18007 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18008 ;; Convert it into imul reg, reg
18009 ;; It would be better to force assembler to encode instruction using long
18010 ;; immediate, but there is apparently no way to do so.
18011 (define_peephole2
18012   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18013                    (mult:SWI248
18014                     (match_operand:SWI248 1 "nonimmediate_operand")
18015                     (match_operand:SWI248 2 "const_int_operand")))
18016               (clobber (reg:CC FLAGS_REG))])
18017    (match_scratch:SWI248 3 "r")]
18018   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18019    && satisfies_constraint_K (operands[2])"
18020   [(set (match_dup 3) (match_dup 2))
18021    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18022               (clobber (reg:CC FLAGS_REG))])]
18024   if (!rtx_equal_p (operands[0], operands[1]))
18025     emit_move_insn (operands[0], operands[1]);
18028 ;; After splitting up read-modify operations, array accesses with memory
18029 ;; operands might end up in form:
18030 ;;  sall    $2, %eax
18031 ;;  movl    4(%esp), %edx
18032 ;;  addl    %edx, %eax
18033 ;; instead of pre-splitting:
18034 ;;  sall    $2, %eax
18035 ;;  addl    4(%esp), %eax
18036 ;; Turn it into:
18037 ;;  movl    4(%esp), %edx
18038 ;;  leal    (%edx,%eax,4), %eax
18040 (define_peephole2
18041   [(match_scratch:W 5 "r")
18042    (parallel [(set (match_operand 0 "register_operand")
18043                    (ashift (match_operand 1 "register_operand")
18044                            (match_operand 2 "const_int_operand")))
18045                (clobber (reg:CC FLAGS_REG))])
18046    (parallel [(set (match_operand 3 "register_operand")
18047                    (plus (match_dup 0)
18048                          (match_operand 4 "x86_64_general_operand")))
18049                    (clobber (reg:CC FLAGS_REG))])]
18050   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18051    /* Validate MODE for lea.  */
18052    && ((!TARGET_PARTIAL_REG_STALL
18053         && (GET_MODE (operands[0]) == QImode
18054             || GET_MODE (operands[0]) == HImode))
18055        || GET_MODE (operands[0]) == SImode
18056        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18057    && (rtx_equal_p (operands[0], operands[3])
18058        || peep2_reg_dead_p (2, operands[0]))
18059    /* We reorder load and the shift.  */
18060    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18061   [(set (match_dup 5) (match_dup 4))
18062    (set (match_dup 0) (match_dup 1))]
18064   machine_mode op1mode = GET_MODE (operands[1]);
18065   machine_mode mode = op1mode == DImode ? DImode : SImode;
18066   int scale = 1 << INTVAL (operands[2]);
18067   rtx index = gen_lowpart (word_mode, operands[1]);
18068   rtx base = gen_lowpart (word_mode, operands[5]);
18069   rtx dest = gen_lowpart (mode, operands[3]);
18071   operands[1] = gen_rtx_PLUS (word_mode, base,
18072                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18073   if (mode != word_mode)
18074     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18076   operands[5] = base;
18077   if (op1mode != word_mode)
18078     operands[5] = gen_lowpart (op1mode, operands[5]);
18080   operands[0] = dest;
18083 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18084 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18085 ;; caught for use by garbage collectors and the like.  Using an insn that
18086 ;; maps to SIGILL makes it more likely the program will rightfully die.
18087 ;; Keeping with tradition, "6" is in honor of #UD.
18088 (define_insn "trap"
18089   [(trap_if (const_int 1) (const_int 6))]
18090   ""
18092 #ifdef HAVE_AS_IX86_UD2
18093   return "ud2";
18094 #else
18095   return ASM_SHORT "0x0b0f";
18096 #endif
18098   [(set_attr "length" "2")])
18100 (define_expand "prefetch"
18101   [(prefetch (match_operand 0 "address_operand")
18102              (match_operand:SI 1 "const_int_operand")
18103              (match_operand:SI 2 "const_int_operand"))]
18104   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18106   bool write = INTVAL (operands[1]) != 0;
18107   int locality = INTVAL (operands[2]);
18109   gcc_assert (IN_RANGE (locality, 0, 3));
18111   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18112      supported by SSE counterpart or the SSE prefetch is not available
18113      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18114      of locality.  */
18115   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18116     operands[2] = const2_rtx;
18117   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18118     operands[2] = GEN_INT (3);
18119   else
18120     operands[1] = const0_rtx;
18123 (define_insn "*prefetch_sse"
18124   [(prefetch (match_operand 0 "address_operand" "p")
18125              (const_int 0)
18126              (match_operand:SI 1 "const_int_operand"))]
18127   "TARGET_PREFETCH_SSE"
18129   static const char * const patterns[4] = {
18130    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18131   };
18133   int locality = INTVAL (operands[1]);
18134   gcc_assert (IN_RANGE (locality, 0, 3));
18136   return patterns[locality];
18138   [(set_attr "type" "sse")
18139    (set_attr "atom_sse_attr" "prefetch")
18140    (set (attr "length_address")
18141         (symbol_ref "memory_address_length (operands[0], false)"))
18142    (set_attr "memory" "none")])
18144 (define_insn "*prefetch_3dnow"
18145   [(prefetch (match_operand 0 "address_operand" "p")
18146              (match_operand:SI 1 "const_int_operand" "n")
18147              (const_int 3))]
18148   "TARGET_PRFCHW"
18150   if (INTVAL (operands[1]) == 0)
18151     return "prefetch\t%a0";
18152   else
18153     return "prefetchw\t%a0";
18155   [(set_attr "type" "mmx")
18156    (set (attr "length_address")
18157         (symbol_ref "memory_address_length (operands[0], false)"))
18158    (set_attr "memory" "none")])
18160 (define_insn "*prefetch_prefetchwt1"
18161   [(prefetch (match_operand 0 "address_operand" "p")
18162              (const_int 1)
18163              (const_int 2))]
18164   "TARGET_PREFETCHWT1"
18165   "prefetchwt1\t%a0";
18166   [(set_attr "type" "sse")
18167    (set (attr "length_address")
18168         (symbol_ref "memory_address_length (operands[0], false)"))
18169    (set_attr "memory" "none")])
18171 (define_expand "stack_protect_set"
18172   [(match_operand 0 "memory_operand")
18173    (match_operand 1 "memory_operand")]
18174   "TARGET_SSP_TLS_GUARD"
18176   rtx (*insn)(rtx, rtx);
18178 #ifdef TARGET_THREAD_SSP_OFFSET
18179   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18180   insn = (TARGET_LP64
18181           ? gen_stack_tls_protect_set_di
18182           : gen_stack_tls_protect_set_si);
18183 #else
18184   insn = (TARGET_LP64
18185           ? gen_stack_protect_set_di
18186           : gen_stack_protect_set_si);
18187 #endif
18189   emit_insn (insn (operands[0], operands[1]));
18190   DONE;
18193 (define_insn "stack_protect_set_<mode>"
18194   [(set (match_operand:PTR 0 "memory_operand" "=m")
18195         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18196                     UNSPEC_SP_SET))
18197    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18198    (clobber (reg:CC FLAGS_REG))]
18199   "TARGET_SSP_TLS_GUARD"
18200   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18201   [(set_attr "type" "multi")])
18203 (define_insn "stack_tls_protect_set_<mode>"
18204   [(set (match_operand:PTR 0 "memory_operand" "=m")
18205         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18206                     UNSPEC_SP_TLS_SET))
18207    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18208    (clobber (reg:CC FLAGS_REG))]
18209   ""
18210   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18211   [(set_attr "type" "multi")])
18213 (define_expand "stack_protect_test"
18214   [(match_operand 0 "memory_operand")
18215    (match_operand 1 "memory_operand")
18216    (match_operand 2)]
18217   "TARGET_SSP_TLS_GUARD"
18219   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18221   rtx (*insn)(rtx, rtx, rtx);
18223 #ifdef TARGET_THREAD_SSP_OFFSET
18224   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18225   insn = (TARGET_LP64
18226           ? gen_stack_tls_protect_test_di
18227           : gen_stack_tls_protect_test_si);
18228 #else
18229   insn = (TARGET_LP64
18230           ? gen_stack_protect_test_di
18231           : gen_stack_protect_test_si);
18232 #endif
18234   emit_insn (insn (flags, operands[0], operands[1]));
18236   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18237                                   flags, const0_rtx, operands[2]));
18238   DONE;
18241 (define_insn "stack_protect_test_<mode>"
18242   [(set (match_operand:CCZ 0 "flags_reg_operand")
18243         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18244                      (match_operand:PTR 2 "memory_operand" "m")]
18245                     UNSPEC_SP_TEST))
18246    (clobber (match_scratch:PTR 3 "=&r"))]
18247   "TARGET_SSP_TLS_GUARD"
18248   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18249   [(set_attr "type" "multi")])
18251 (define_insn "stack_tls_protect_test_<mode>"
18252   [(set (match_operand:CCZ 0 "flags_reg_operand")
18253         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18254                      (match_operand:PTR 2 "const_int_operand" "i")]
18255                     UNSPEC_SP_TLS_TEST))
18256    (clobber (match_scratch:PTR 3 "=r"))]
18257   ""
18258   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18259   [(set_attr "type" "multi")])
18261 (define_insn "sse4_2_crc32<mode>"
18262   [(set (match_operand:SI 0 "register_operand" "=r")
18263         (unspec:SI
18264           [(match_operand:SI 1 "register_operand" "0")
18265            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18266           UNSPEC_CRC32))]
18267   "TARGET_SSE4_2 || TARGET_CRC32"
18268   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18269   [(set_attr "type" "sselog1")
18270    (set_attr "prefix_rep" "1")
18271    (set_attr "prefix_extra" "1")
18272    (set (attr "prefix_data16")
18273      (if_then_else (match_operand:HI 2)
18274        (const_string "1")
18275        (const_string "*")))
18276    (set (attr "prefix_rex")
18277      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18278        (const_string "1")
18279        (const_string "*")))
18280    (set_attr "mode" "SI")])
18282 (define_insn "sse4_2_crc32di"
18283   [(set (match_operand:DI 0 "register_operand" "=r")
18284         (unspec:DI
18285           [(match_operand:DI 1 "register_operand" "0")
18286            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18287           UNSPEC_CRC32))]
18288   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18289   "crc32{q}\t{%2, %0|%0, %2}"
18290   [(set_attr "type" "sselog1")
18291    (set_attr "prefix_rep" "1")
18292    (set_attr "prefix_extra" "1")
18293    (set_attr "mode" "DI")])
18295 (define_insn "rdpmc"
18296   [(set (match_operand:DI 0 "register_operand" "=A")
18297         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18298                             UNSPECV_RDPMC))]
18299   "!TARGET_64BIT"
18300   "rdpmc"
18301   [(set_attr "type" "other")
18302    (set_attr "length" "2")])
18304 (define_insn "rdpmc_rex64"
18305   [(set (match_operand:DI 0 "register_operand" "=a")
18306         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18307                             UNSPECV_RDPMC))
18308    (set (match_operand:DI 1 "register_operand" "=d")
18309         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18310   "TARGET_64BIT"
18311   "rdpmc"
18312   [(set_attr "type" "other")
18313    (set_attr "length" "2")])
18315 (define_insn "rdtsc"
18316   [(set (match_operand:DI 0 "register_operand" "=A")
18317         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18318   "!TARGET_64BIT"
18319   "rdtsc"
18320   [(set_attr "type" "other")
18321    (set_attr "length" "2")])
18323 (define_insn "rdtsc_rex64"
18324   [(set (match_operand:DI 0 "register_operand" "=a")
18325         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18326    (set (match_operand:DI 1 "register_operand" "=d")
18327         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18328   "TARGET_64BIT"
18329   "rdtsc"
18330   [(set_attr "type" "other")
18331    (set_attr "length" "2")])
18333 (define_insn "rdtscp"
18334   [(set (match_operand:DI 0 "register_operand" "=A")
18335         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18336    (set (match_operand:SI 1 "register_operand" "=c")
18337         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18338   "!TARGET_64BIT"
18339   "rdtscp"
18340   [(set_attr "type" "other")
18341    (set_attr "length" "3")])
18343 (define_insn "rdtscp_rex64"
18344   [(set (match_operand:DI 0 "register_operand" "=a")
18345         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18346    (set (match_operand:DI 1 "register_operand" "=d")
18347         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18348    (set (match_operand:SI 2 "register_operand" "=c")
18349         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18350   "TARGET_64BIT"
18351   "rdtscp"
18352   [(set_attr "type" "other")
18353    (set_attr "length" "3")])
18355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18357 ;; FXSR, XSAVE and XSAVEOPT instructions
18359 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18361 (define_insn "fxsave"
18362   [(set (match_operand:BLK 0 "memory_operand" "=m")
18363         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18364   "TARGET_FXSR"
18365   "fxsave\t%0"
18366   [(set_attr "type" "other")
18367    (set_attr "memory" "store")
18368    (set (attr "length")
18369         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18371 (define_insn "fxsave64"
18372   [(set (match_operand:BLK 0 "memory_operand" "=m")
18373         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18374   "TARGET_64BIT && TARGET_FXSR"
18375   "fxsave64\t%0"
18376   [(set_attr "type" "other")
18377    (set_attr "memory" "store")
18378    (set (attr "length")
18379         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18381 (define_insn "fxrstor"
18382   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18383                     UNSPECV_FXRSTOR)]
18384   "TARGET_FXSR"
18385   "fxrstor\t%0"
18386   [(set_attr "type" "other")
18387    (set_attr "memory" "load")
18388    (set (attr "length")
18389         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18391 (define_insn "fxrstor64"
18392   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18393                     UNSPECV_FXRSTOR64)]
18394   "TARGET_64BIT && TARGET_FXSR"
18395   "fxrstor64\t%0"
18396   [(set_attr "type" "other")
18397    (set_attr "memory" "load")
18398    (set (attr "length")
18399         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18401 (define_int_iterator ANY_XSAVE
18402         [UNSPECV_XSAVE
18403          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18404          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18405          (UNSPECV_XSAVES "TARGET_XSAVES")])
18407 (define_int_iterator ANY_XSAVE64
18408         [UNSPECV_XSAVE64
18409          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18410          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18411          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18413 (define_int_attr xsave
18414         [(UNSPECV_XSAVE "xsave")
18415          (UNSPECV_XSAVE64 "xsave64")
18416          (UNSPECV_XSAVEOPT "xsaveopt")
18417          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18418          (UNSPECV_XSAVEC "xsavec")
18419          (UNSPECV_XSAVEC64 "xsavec64")
18420          (UNSPECV_XSAVES "xsaves")
18421          (UNSPECV_XSAVES64 "xsaves64")])
18423 (define_int_iterator ANY_XRSTOR
18424         [UNSPECV_XRSTOR
18425          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18427 (define_int_iterator ANY_XRSTOR64
18428         [UNSPECV_XRSTOR64
18429          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18431 (define_int_attr xrstor
18432         [(UNSPECV_XRSTOR "xrstor")
18433          (UNSPECV_XRSTOR64 "xrstor")
18434          (UNSPECV_XRSTORS "xrstors")
18435          (UNSPECV_XRSTORS64 "xrstors")])
18437 (define_insn "<xsave>"
18438   [(set (match_operand:BLK 0 "memory_operand" "=m")
18439         (unspec_volatile:BLK
18440          [(match_operand:DI 1 "register_operand" "A")]
18441          ANY_XSAVE))]
18442   "!TARGET_64BIT && TARGET_XSAVE"
18443   "<xsave>\t%0"
18444   [(set_attr "type" "other")
18445    (set_attr "memory" "store")
18446    (set (attr "length")
18447         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18449 (define_insn "<xsave>_rex64"
18450   [(set (match_operand:BLK 0 "memory_operand" "=m")
18451         (unspec_volatile:BLK
18452          [(match_operand:SI 1 "register_operand" "a")
18453           (match_operand:SI 2 "register_operand" "d")]
18454          ANY_XSAVE))]
18455   "TARGET_64BIT && TARGET_XSAVE"
18456   "<xsave>\t%0"
18457   [(set_attr "type" "other")
18458    (set_attr "memory" "store")
18459    (set (attr "length")
18460         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18462 (define_insn "<xsave>"
18463   [(set (match_operand:BLK 0 "memory_operand" "=m")
18464         (unspec_volatile:BLK
18465          [(match_operand:SI 1 "register_operand" "a")
18466           (match_operand:SI 2 "register_operand" "d")]
18467          ANY_XSAVE64))]
18468   "TARGET_64BIT && TARGET_XSAVE"
18469   "<xsave>\t%0"
18470   [(set_attr "type" "other")
18471    (set_attr "memory" "store")
18472    (set (attr "length")
18473         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18475 (define_insn "<xrstor>"
18476    [(unspec_volatile:BLK
18477      [(match_operand:BLK 0 "memory_operand" "m")
18478       (match_operand:DI 1 "register_operand" "A")]
18479      ANY_XRSTOR)]
18480   "!TARGET_64BIT && TARGET_XSAVE"
18481   "<xrstor>\t%0"
18482   [(set_attr "type" "other")
18483    (set_attr "memory" "load")
18484    (set (attr "length")
18485         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18487 (define_insn "<xrstor>_rex64"
18488    [(unspec_volatile:BLK
18489      [(match_operand:BLK 0 "memory_operand" "m")
18490       (match_operand:SI 1 "register_operand" "a")
18491       (match_operand:SI 2 "register_operand" "d")]
18492      ANY_XRSTOR)]
18493   "TARGET_64BIT && TARGET_XSAVE"
18494   "<xrstor>\t%0"
18495   [(set_attr "type" "other")
18496    (set_attr "memory" "load")
18497    (set (attr "length")
18498         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18500 (define_insn "<xrstor>64"
18501    [(unspec_volatile:BLK
18502      [(match_operand:BLK 0 "memory_operand" "m")
18503       (match_operand:SI 1 "register_operand" "a")
18504       (match_operand:SI 2 "register_operand" "d")]
18505      ANY_XRSTOR64)]
18506   "TARGET_64BIT && TARGET_XSAVE"
18507   "<xrstor>64\t%0"
18508   [(set_attr "type" "other")
18509    (set_attr "memory" "load")
18510    (set (attr "length")
18511         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18513 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18515 ;; Floating-point instructions for atomic compound assignments
18517 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18519 ; Clobber all floating-point registers on environment save and restore
18520 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18521 (define_insn "fnstenv"
18522   [(set (match_operand:BLK 0 "memory_operand" "=m")
18523         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18524    (clobber (reg:HI FPCR_REG))
18525    (clobber (reg:XF ST0_REG))
18526    (clobber (reg:XF ST1_REG))
18527    (clobber (reg:XF ST2_REG))
18528    (clobber (reg:XF ST3_REG))
18529    (clobber (reg:XF ST4_REG))
18530    (clobber (reg:XF ST5_REG))
18531    (clobber (reg:XF ST6_REG))
18532    (clobber (reg:XF ST7_REG))]
18533   "TARGET_80387"
18534   "fnstenv\t%0"
18535   [(set_attr "type" "other")
18536    (set_attr "memory" "store")
18537    (set (attr "length")
18538         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18540 (define_insn "fldenv"
18541   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18542                     UNSPECV_FLDENV)
18543    (clobber (reg:CCFP FPSR_REG))
18544    (clobber (reg:HI FPCR_REG))
18545    (clobber (reg:XF ST0_REG))
18546    (clobber (reg:XF ST1_REG))
18547    (clobber (reg:XF ST2_REG))
18548    (clobber (reg:XF ST3_REG))
18549    (clobber (reg:XF ST4_REG))
18550    (clobber (reg:XF ST5_REG))
18551    (clobber (reg:XF ST6_REG))
18552    (clobber (reg:XF ST7_REG))]
18553   "TARGET_80387"
18554   "fldenv\t%0"
18555   [(set_attr "type" "other")
18556    (set_attr "memory" "load")
18557    (set (attr "length")
18558         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18560 (define_insn "fnstsw"
18561   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18562         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18563   "TARGET_80387"
18564   "fnstsw\t%0"
18565   [(set_attr "type" "other,other")
18566    (set_attr "memory" "none,store")
18567    (set (attr "length")
18568         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18570 (define_insn "fnclex"
18571   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18572   "TARGET_80387"
18573   "fnclex"
18574   [(set_attr "type" "other")
18575    (set_attr "memory" "none")
18576    (set_attr "length" "2")])
18578 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18580 ;; LWP instructions
18582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18584 (define_expand "lwp_llwpcb"
18585   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18586                     UNSPECV_LLWP_INTRINSIC)]
18587   "TARGET_LWP")
18589 (define_insn "*lwp_llwpcb<mode>1"
18590   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18591                     UNSPECV_LLWP_INTRINSIC)]
18592   "TARGET_LWP"
18593   "llwpcb\t%0"
18594   [(set_attr "type" "lwp")
18595    (set_attr "mode" "<MODE>")
18596    (set_attr "length" "5")])
18598 (define_expand "lwp_slwpcb"
18599   [(set (match_operand 0 "register_operand" "=r")
18600         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18601   "TARGET_LWP"
18603   rtx (*insn)(rtx);
18605   insn = (Pmode == DImode
18606           ? gen_lwp_slwpcbdi
18607           : gen_lwp_slwpcbsi);
18609   emit_insn (insn (operands[0]));
18610   DONE;
18613 (define_insn "lwp_slwpcb<mode>"
18614   [(set (match_operand:P 0 "register_operand" "=r")
18615         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18616   "TARGET_LWP"
18617   "slwpcb\t%0"
18618   [(set_attr "type" "lwp")
18619    (set_attr "mode" "<MODE>")
18620    (set_attr "length" "5")])
18622 (define_expand "lwp_lwpval<mode>3"
18623   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18624                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18625                      (match_operand:SI 3 "const_int_operand" "i")]
18626                     UNSPECV_LWPVAL_INTRINSIC)]
18627   "TARGET_LWP"
18628   ;; Avoid unused variable warning.
18629   "(void) operands[0];")
18631 (define_insn "*lwp_lwpval<mode>3_1"
18632   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18633                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18634                      (match_operand:SI 2 "const_int_operand" "i")]
18635                     UNSPECV_LWPVAL_INTRINSIC)]
18636   "TARGET_LWP"
18637   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18638   [(set_attr "type" "lwp")
18639    (set_attr "mode" "<MODE>")
18640    (set (attr "length")
18641         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18643 (define_expand "lwp_lwpins<mode>3"
18644   [(set (reg:CCC FLAGS_REG)
18645         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18646                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18647                               (match_operand:SI 3 "const_int_operand" "i")]
18648                              UNSPECV_LWPINS_INTRINSIC))
18649    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18650         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18651   "TARGET_LWP")
18653 (define_insn "*lwp_lwpins<mode>3_1"
18654   [(set (reg:CCC FLAGS_REG)
18655         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18656                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18657                               (match_operand:SI 2 "const_int_operand" "i")]
18658                              UNSPECV_LWPINS_INTRINSIC))]
18659   "TARGET_LWP"
18660   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18661   [(set_attr "type" "lwp")
18662    (set_attr "mode" "<MODE>")
18663    (set (attr "length")
18664         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18666 (define_int_iterator RDFSGSBASE
18667         [UNSPECV_RDFSBASE
18668          UNSPECV_RDGSBASE])
18670 (define_int_iterator WRFSGSBASE
18671         [UNSPECV_WRFSBASE
18672          UNSPECV_WRGSBASE])
18674 (define_int_attr fsgs
18675         [(UNSPECV_RDFSBASE "fs")
18676          (UNSPECV_RDGSBASE "gs")
18677          (UNSPECV_WRFSBASE "fs")
18678          (UNSPECV_WRGSBASE "gs")])
18680 (define_insn "rd<fsgs>base<mode>"
18681   [(set (match_operand:SWI48 0 "register_operand" "=r")
18682         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18683   "TARGET_64BIT && TARGET_FSGSBASE"
18684   "rd<fsgs>base\t%0"
18685   [(set_attr "type" "other")
18686    (set_attr "prefix_extra" "2")])
18688 (define_insn "wr<fsgs>base<mode>"
18689   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18690                     WRFSGSBASE)]
18691   "TARGET_64BIT && TARGET_FSGSBASE"
18692   "wr<fsgs>base\t%0"
18693   [(set_attr "type" "other")
18694    (set_attr "prefix_extra" "2")])
18696 (define_insn "rdrand<mode>_1"
18697   [(set (match_operand:SWI248 0 "register_operand" "=r")
18698         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18699    (set (reg:CCC FLAGS_REG)
18700         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18701   "TARGET_RDRND"
18702   "rdrand\t%0"
18703   [(set_attr "type" "other")
18704    (set_attr "prefix_extra" "1")])
18706 (define_insn "rdseed<mode>_1"
18707   [(set (match_operand:SWI248 0 "register_operand" "=r")
18708         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18709    (set (reg:CCC FLAGS_REG)
18710         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18711   "TARGET_RDSEED"
18712   "rdseed\t%0"
18713   [(set_attr "type" "other")
18714    (set_attr "prefix_extra" "1")])
18716 (define_expand "pause"
18717   [(set (match_dup 0)
18718         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18719   ""
18721   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18722   MEM_VOLATILE_P (operands[0]) = 1;
18725 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18726 ;; They have the same encoding.
18727 (define_insn "*pause"
18728   [(set (match_operand:BLK 0)
18729         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18730   ""
18731   "rep%; nop"
18732   [(set_attr "length" "2")
18733    (set_attr "memory" "unknown")])
18735 (define_expand "xbegin"
18736   [(set (match_operand:SI 0 "register_operand")
18737         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18738   "TARGET_RTM"
18740   rtx_code_label *label = gen_label_rtx ();
18742   /* xbegin is emitted as jump_insn, so reload won't be able
18743      to reload its operand.  Force the value into AX hard register.  */
18744   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18745   emit_move_insn (ax_reg, constm1_rtx);
18747   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18749   emit_label (label);
18750   LABEL_NUSES (label) = 1;
18752   emit_move_insn (operands[0], ax_reg);
18754   DONE;
18757 (define_insn "xbegin_1"
18758   [(set (pc)
18759         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18760                           (const_int 0))
18761                       (label_ref (match_operand 1))
18762                       (pc)))
18763    (set (match_operand:SI 0 "register_operand" "+a")
18764         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18765   "TARGET_RTM"
18766   "xbegin\t%l1"
18767   [(set_attr "type" "other")
18768    (set_attr "length" "6")])
18770 (define_insn "xend"
18771   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18772   "TARGET_RTM"
18773   "xend"
18774   [(set_attr "type" "other")
18775    (set_attr "length" "3")])
18777 (define_insn "xabort"
18778   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18779                     UNSPECV_XABORT)]
18780   "TARGET_RTM"
18781   "xabort\t%0"
18782   [(set_attr "type" "other")
18783    (set_attr "length" "3")])
18785 (define_expand "xtest"
18786   [(set (match_operand:QI 0 "register_operand")
18787         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18788   "TARGET_RTM"
18790   emit_insn (gen_xtest_1 ());
18792   ix86_expand_setcc (operands[0], NE,
18793                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18794   DONE;
18797 (define_insn "xtest_1"
18798   [(set (reg:CCZ FLAGS_REG)
18799         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18800   "TARGET_RTM"
18801   "xtest"
18802   [(set_attr "type" "other")
18803    (set_attr "length" "3")])
18805 (define_insn "pcommit"
18806   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18807   "TARGET_PCOMMIT"
18808   "pcommit"
18809   [(set_attr "type" "other")
18810    (set_attr "length" "4")])
18812 (define_insn "clwb"
18813   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18814                    UNSPECV_CLWB)]
18815   "TARGET_CLWB"
18816   "clwb\t%a0"
18817   [(set_attr "type" "sse")
18818    (set_attr "atom_sse_attr" "fence")
18819    (set_attr "memory" "unknown")])
18821 (define_insn "clflushopt"
18822   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18823                    UNSPECV_CLFLUSHOPT)]
18824   "TARGET_CLFLUSHOPT"
18825   "clflushopt\t%a0"
18826   [(set_attr "type" "sse")
18827    (set_attr "atom_sse_attr" "fence")
18828    (set_attr "memory" "unknown")])
18830 ;; MONITORX and MWAITX
18831 (define_insn "mwaitx"
18832   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18833                      (match_operand:SI 1 "register_operand" "a")
18834                      (match_operand:SI 2 "register_operand" "b")]
18835                    UNSPECV_MWAITX)]
18836   "TARGET_MWAITX"
18837 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18838 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18839 ;; we only need to set up 32bit registers.
18840   "mwaitx"
18841   [(set_attr "length" "3")])
18843 (define_insn "monitorx_<mode>"
18844   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18845                      (match_operand:SI 1 "register_operand" "c")
18846                      (match_operand:SI 2 "register_operand" "d")]
18847                    UNSPECV_MONITORX)]
18848   "TARGET_MWAITX"
18849 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18850 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
18851 ;; zero extended to 64bit, we only need to set up 32bit registers.
18852   "%^monitorx"
18853   [(set (attr "length")
18854      (symbol_ref ("(Pmode != word_mode) + 3")))])
18856 ;; MPX instructions
18858 (define_expand "<mode>_mk"
18859   [(set (match_operand:BND 0 "register_operand")
18860         (unspec:BND
18861           [(mem:<bnd_ptr>
18862            (match_par_dup 3
18863              [(match_operand:<bnd_ptr> 1 "register_operand")
18864               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18865           UNSPEC_BNDMK))]
18866   "TARGET_MPX"
18868   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18869                                                   operands[2]),
18870                                 UNSPEC_BNDMK_ADDR);
18873 (define_insn "*<mode>_mk"
18874   [(set (match_operand:BND 0 "register_operand" "=w")
18875         (unspec:BND
18876           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18877              [(unspec:<bnd_ptr>
18878                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18879                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18880                 UNSPEC_BNDMK_ADDR)])]
18881           UNSPEC_BNDMK))]
18882   "TARGET_MPX"
18883   "bndmk\t{%3, %0|%0, %3}"
18884   [(set_attr "type" "mpxmk")])
18886 (define_expand "mov<mode>"
18887   [(set (match_operand:BND 0 "general_operand")
18888         (match_operand:BND 1 "general_operand"))]
18889   "TARGET_MPX"
18890   "ix86_expand_move (<MODE>mode, operands); DONE;")
18892 (define_insn "*mov<mode>_internal_mpx"
18893   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18894         (match_operand:BND 1 "general_operand" "wm,w"))]
18895   "TARGET_MPX"
18896   "bndmov\t{%1, %0|%0, %1}"
18897   [(set_attr "type" "mpxmov")])
18899 (define_expand "<mode>_<bndcheck>"
18900   [(parallel
18901      [(unspec
18902         [(match_operand:BND 0 "register_operand")
18903          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18904       (set (match_dup 2)
18905            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18906   "TARGET_MPX"
18908   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18909   MEM_VOLATILE_P (operands[2]) = 1;
18912 (define_insn "*<mode>_<bndcheck>"
18913   [(unspec
18914      [(match_operand:BND 0 "register_operand" "w")
18915       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18916    (set (match_operand:BLK 2 "bnd_mem_operator")
18917         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
18918   "TARGET_MPX"
18919   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18920   [(set_attr "type" "mpxchk")])
18922 (define_expand "<mode>_ldx"
18923   [(parallel
18924      [(set (match_operand:BND 0 "register_operand")
18925            (unspec:BND
18926              [(mem:<bnd_ptr>
18927                 (match_par_dup 3
18928                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18929                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
18930              UNSPEC_BNDLDX))
18931       (use (mem:BLK (match_dup 1)))])]
18932   "TARGET_MPX"
18934   /* Avoid registers which cannot be used as index.  */
18935   if (!index_register_operand (operands[2], Pmode))
18936     operands[2] = copy_addr_to_reg (operands[2]);
18938   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18939                                                   operands[2]),
18940                                 UNSPEC_BNDLDX_ADDR);
18943 (define_insn "*<mode>_ldx"
18944   [(set (match_operand:BND 0 "register_operand" "=w")
18945         (unspec:BND
18946           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18947              [(unspec:<bnd_ptr>
18948                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18949                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18950                 UNSPEC_BNDLDX_ADDR)])]
18951           UNSPEC_BNDLDX))
18952    (use (mem:BLK (match_dup 1)))]
18953   "TARGET_MPX"
18954   "bndldx\t{%3, %0|%0, %3}"
18955   [(set_attr "type" "mpxld")])
18957 (define_expand "<mode>_stx"
18958   [(parallel
18959      [(unspec
18960         [(mem:<bnd_ptr>
18961            (match_par_dup 3
18962              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18963               (match_operand:<bnd_ptr> 1 "register_operand")]))
18964          (match_operand:BND 2 "register_operand")]
18965         UNSPEC_BNDSTX)
18966       (set (match_dup 4)
18967            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18968   "TARGET_MPX"
18970   /* Avoid registers which cannot be used as index.  */
18971   if (!index_register_operand (operands[1], Pmode))
18972     operands[1] = copy_addr_to_reg (operands[1]);
18974   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18975                                                   operands[1]),
18976                                 UNSPEC_BNDLDX_ADDR);
18977   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18978   MEM_VOLATILE_P (operands[4]) = 1;
18981 (define_insn "*<mode>_stx"
18982   [(unspec
18983      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18984         [(unspec:<bnd_ptr>
18985            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18986             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18987            UNSPEC_BNDLDX_ADDR)])
18988          (match_operand:BND 2 "register_operand" "w")]
18989         UNSPEC_BNDSTX)
18990    (set (match_operand:BLK 4 "bnd_mem_operator")
18991         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
18992   "TARGET_MPX"
18993   "bndstx\t{%2, %3|%3, %2}"
18994   [(set_attr "type" "mpxst")])
18996 (define_insn "move_size_reloc_<mode>"
18997   [(set (match_operand:SWI48 0 "register_operand" "=r")
18998         (unspec:SWI48
18999           [(match_operand:SWI48 1 "symbol_operand")]
19000         UNSPEC_SIZEOF))]
19001   "TARGET_MPX"
19003   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19004     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19005   else
19006     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19008   [(set_attr "type" "imov")
19009    (set_attr "mode" "<MODE>")])
19011 (include "mmx.md")
19012 (include "sse.md")
19013 (include "sync.md")