Update gcc-50 to SVN version 231263 (gcc-5-branch)
[dragonfly.git] / contrib / gcc-5.0 / gcc / config / i386 / i386.md
blob8b1d372c586cd4f17baed6246629ccbf66cb4353
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_FLDCW
106   UNSPEC_REP
107   UNSPEC_LD_MPIC        ; load_macho_picbase
108   UNSPEC_TRUNC_NOOP
109   UNSPEC_DIV_ALREADY_SPLIT
110   UNSPEC_PAUSE
111   UNSPEC_LEA_ADDR
112   UNSPEC_XBEGIN_ABORT
113   UNSPEC_STOS
114   UNSPEC_PEEPSIB
115   UNSPEC_INSN_FALSE_DEP
117   ;; For SSE/MMX support:
118   UNSPEC_FIX_NOTRUNC
119   UNSPEC_MASKMOV
120   UNSPEC_MOVMSK
121   UNSPEC_RCP
122   UNSPEC_RSQRT
123   UNSPEC_PSADBW
125   ;; Generic math support
126   UNSPEC_COPYSIGN
127   UNSPEC_IEEE_MIN       ; not commutative
128   UNSPEC_IEEE_MAX       ; not commutative
130   ;; x87 Floating point
131   UNSPEC_SIN
132   UNSPEC_COS
133   UNSPEC_FPATAN
134   UNSPEC_FYL2X
135   UNSPEC_FYL2XP1
136   UNSPEC_FRNDINT
137   UNSPEC_FIST
138   UNSPEC_F2XM1
139   UNSPEC_TAN
140   UNSPEC_FXAM
142   ;; x87 Rounding
143   UNSPEC_FRNDINT_FLOOR
144   UNSPEC_FRNDINT_CEIL
145   UNSPEC_FRNDINT_TRUNC
146   UNSPEC_FRNDINT_MASK_PM
147   UNSPEC_FIST_FLOOR
148   UNSPEC_FIST_CEIL
150   ;; x87 Double output FP
151   UNSPEC_SINCOS_COS
152   UNSPEC_SINCOS_SIN
153   UNSPEC_XTRACT_FRACT
154   UNSPEC_XTRACT_EXP
155   UNSPEC_FSCALE_FRACT
156   UNSPEC_FSCALE_EXP
157   UNSPEC_FPREM_F
158   UNSPEC_FPREM_U
159   UNSPEC_FPREM1_F
160   UNSPEC_FPREM1_U
162   UNSPEC_C2_FLAG
163   UNSPEC_FXAM_MEM
165   ;; SSP patterns
166   UNSPEC_SP_SET
167   UNSPEC_SP_TEST
168   UNSPEC_SP_TLS_SET
169   UNSPEC_SP_TLS_TEST
171   ;; For ROUND support
172   UNSPEC_ROUND
174   ;; For CRC32 support
175   UNSPEC_CRC32
177   ;; For BMI support
178   UNSPEC_BEXTR
180   ;; For BMI2 support
181   UNSPEC_PDEP
182   UNSPEC_PEXT
184   ;; For AVX512F support
185   UNSPEC_KMOV
187   UNSPEC_BNDMK
188   UNSPEC_BNDMK_ADDR
189   UNSPEC_BNDSTX
190   UNSPEC_BNDLDX
191   UNSPEC_BNDLDX_ADDR
192   UNSPEC_BNDCL
193   UNSPEC_BNDCU
194   UNSPEC_BNDCN
195   UNSPEC_MPX_FENCE
198 (define_c_enum "unspecv" [
199   UNSPECV_BLOCKAGE
200   UNSPECV_STACK_PROBE
201   UNSPECV_PROBE_STACK_RANGE
202   UNSPECV_ALIGN
203   UNSPECV_PROLOGUE_USE
204   UNSPECV_SPLIT_STACK_RETURN
205   UNSPECV_CLD
206   UNSPECV_NOPS
207   UNSPECV_RDTSC
208   UNSPECV_RDTSCP
209   UNSPECV_RDPMC
210   UNSPECV_LLWP_INTRINSIC
211   UNSPECV_SLWP_INTRINSIC
212   UNSPECV_LWPVAL_INTRINSIC
213   UNSPECV_LWPINS_INTRINSIC
214   UNSPECV_RDFSBASE
215   UNSPECV_RDGSBASE
216   UNSPECV_WRFSBASE
217   UNSPECV_WRGSBASE
218   UNSPECV_FXSAVE
219   UNSPECV_FXRSTOR
220   UNSPECV_FXSAVE64
221   UNSPECV_FXRSTOR64
222   UNSPECV_XSAVE
223   UNSPECV_XRSTOR
224   UNSPECV_XSAVE64
225   UNSPECV_XRSTOR64
226   UNSPECV_XSAVEOPT
227   UNSPECV_XSAVEOPT64
228   UNSPECV_XSAVES
229   UNSPECV_XRSTORS
230   UNSPECV_XSAVES64
231   UNSPECV_XRSTORS64
232   UNSPECV_XSAVEC
233   UNSPECV_XSAVEC64
235   ;; For atomic compound assignments.
236   UNSPECV_FNSTENV
237   UNSPECV_FLDENV
238   UNSPECV_FNSTSW
239   UNSPECV_FNCLEX
241   ;; For RDRAND support
242   UNSPECV_RDRAND
244   ;; For RDSEED support
245   UNSPECV_RDSEED
247   ;; For RTM support
248   UNSPECV_XBEGIN
249   UNSPECV_XEND
250   UNSPECV_XABORT
251   UNSPECV_XTEST
253   UNSPECV_NLGR
255   ;; For CLWB support
256   UNSPECV_CLWB
258   ;; For PCOMMIT support
259   UNSPECV_PCOMMIT
261   ;; For CLFLUSHOPT support
262   UNSPECV_CLFLUSHOPT
264   ;; For MONITORX and MWAITX support 
265   UNSPECV_MONITORX
266   UNSPECV_MWAITX
270 ;; Constants to represent rounding modes in the ROUND instruction
271 (define_constants
272   [(ROUND_FLOOR                 0x1)
273    (ROUND_CEIL                  0x2)
274    (ROUND_TRUNC                 0x3)
275    (ROUND_MXCSR                 0x4)
276    (ROUND_NO_EXC                0x8)
277   ])
279 ;; Constants to represent AVX512F embeded rounding
280 (define_constants
281   [(ROUND_NEAREST_INT                   0)
282    (ROUND_NEG_INF                       1)
283    (ROUND_POS_INF                       2)
284    (ROUND_ZERO                          3)
285    (NO_ROUND                            4)
286    (ROUND_SAE                           8)
287   ])
289 ;; Constants to represent pcomtrue/pcomfalse variants
290 (define_constants
291   [(PCOM_FALSE                  0)
292    (PCOM_TRUE                   1)
293    (COM_FALSE_S                 2)
294    (COM_FALSE_P                 3)
295    (COM_TRUE_S                  4)
296    (COM_TRUE_P                  5)
297   ])
299 ;; Constants used in the XOP pperm instruction
300 (define_constants
301   [(PPERM_SRC                   0x00)   /* copy source */
302    (PPERM_INVERT                0x20)   /* invert source */
303    (PPERM_REVERSE               0x40)   /* bit reverse source */
304    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
305    (PPERM_ZERO                  0x80)   /* all 0's */
306    (PPERM_ONES                  0xa0)   /* all 1's */
307    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
308    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
309    (PPERM_SRC1                  0x00)   /* use first source byte */
310    (PPERM_SRC2                  0x10)   /* use second source byte */
311    ])
313 ;; Registers by name.
314 (define_constants
315   [(AX_REG                       0)
316    (DX_REG                       1)
317    (CX_REG                       2)
318    (BX_REG                       3)
319    (SI_REG                       4)
320    (DI_REG                       5)
321    (BP_REG                       6)
322    (SP_REG                       7)
323    (ST0_REG                      8)
324    (ST1_REG                      9)
325    (ST2_REG                     10)
326    (ST3_REG                     11)
327    (ST4_REG                     12)
328    (ST5_REG                     13)
329    (ST6_REG                     14)
330    (ST7_REG                     15)
331    (FLAGS_REG                   17)
332    (FPSR_REG                    18)
333    (FPCR_REG                    19)
334    (XMM0_REG                    21)
335    (XMM1_REG                    22)
336    (XMM2_REG                    23)
337    (XMM3_REG                    24)
338    (XMM4_REG                    25)
339    (XMM5_REG                    26)
340    (XMM6_REG                    27)
341    (XMM7_REG                    28)
342    (MM0_REG                     29)
343    (MM1_REG                     30)
344    (MM2_REG                     31)
345    (MM3_REG                     32)
346    (MM4_REG                     33)
347    (MM5_REG                     34)
348    (MM6_REG                     35)
349    (MM7_REG                     36)
350    (R8_REG                      37)
351    (R9_REG                      38)
352    (R10_REG                     39)
353    (R11_REG                     40)
354    (R12_REG                     41)
355    (R13_REG                     42)
356    (R14_REG                     43)
357    (R15_REG                     44)
358    (XMM8_REG                    45)
359    (XMM9_REG                    46)
360    (XMM10_REG                   47)
361    (XMM11_REG                   48)
362    (XMM12_REG                   49)
363    (XMM13_REG                   50)
364    (XMM14_REG                   51)
365    (XMM15_REG                   52)
366    (XMM16_REG                   53)
367    (XMM17_REG                   54)
368    (XMM18_REG                   55)
369    (XMM19_REG                   56)
370    (XMM20_REG                   57)
371    (XMM21_REG                   58)
372    (XMM22_REG                   59)
373    (XMM23_REG                   60)
374    (XMM24_REG                   61)
375    (XMM25_REG                   62)
376    (XMM26_REG                   63)
377    (XMM27_REG                   64)
378    (XMM28_REG                   65)
379    (XMM29_REG                   66)
380    (XMM30_REG                   67)
381    (XMM31_REG                   68)
382    (MASK0_REG                   69)
383    (MASK1_REG                   70)
384    (MASK2_REG                   71)
385    (MASK3_REG                   72)
386    (MASK4_REG                   73)
387    (MASK5_REG                   74)
388    (MASK6_REG                   75)
389    (MASK7_REG                   76)
390    (BND0_REG                    77)
391    (BND1_REG                    78)
392   ])
394 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
395 ;; from i386.c.
397 ;; In C guard expressions, put expressions which may be compile-time
398 ;; constants first.  This allows for better optimization.  For
399 ;; example, write "TARGET_64BIT && reload_completed", not
400 ;; "reload_completed && TARGET_64BIT".
403 ;; Processor type.
404 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
405                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
406                     btver2,knl"
407   (const (symbol_ref "ix86_schedule")))
409 ;; A basic instruction type.  Refinements due to arguments to be
410 ;; provided in other attributes.
411 (define_attr "type"
412   "other,multi,
413    alu,alu1,negnot,imov,imovx,lea,
414    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
415    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
416    push,pop,call,callv,leave,
417    str,bitmanip,
418    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
419    fxch,fistp,fisttp,frndint,
420    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
421    ssemul,sseimul,ssediv,sselog,sselog1,
422    sseishft,sseishft1,ssecmp,ssecomi,
423    ssecvt,ssecvt1,sseicvt,sseins,
424    sseshuf,sseshuf1,ssemuladd,sse4arg,
425    lwp,mskmov,msklog,
426    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
427    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
428   (const_string "other"))
430 ;; Main data type used by the insn
431 (define_attr "mode"
432   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
433   V2DF,V2SF,V1DF,V8DF"
434   (const_string "unknown"))
436 ;; The CPU unit operations uses.
437 (define_attr "unit" "integer,i387,sse,mmx,unknown"
438   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
439                           fxch,fistp,fisttp,frndint")
440            (const_string "i387")
441          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
442                           ssemul,sseimul,ssediv,sselog,sselog1,
443                           sseishft,sseishft1,ssecmp,ssecomi,
444                           ssecvt,ssecvt1,sseicvt,sseins,
445                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
446            (const_string "sse")
447          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
448            (const_string "mmx")
449          (eq_attr "type" "other")
450            (const_string "unknown")]
451          (const_string "integer")))
453 ;; The minimum required alignment of vector mode memory operands of the SSE
454 ;; (non-VEX/EVEX) instruction in bits, if it is different from
455 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
456 ;; multiple alternatives, this should be conservative maximum of those minimum
457 ;; required alignments.
458 (define_attr "ssememalign" "" (const_int 0))
460 ;; The (bounding maximum) length of an instruction immediate.
461 (define_attr "length_immediate" ""
462   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
463                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
464                           mpxld,mpxst")
465            (const_int 0)
466          (eq_attr "unit" "i387,sse,mmx")
467            (const_int 0)
468          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
469                           rotate,rotatex,rotate1,imul,icmp,push,pop")
470            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
471          (eq_attr "type" "imov,test")
472            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
473          (eq_attr "type" "call")
474            (if_then_else (match_operand 0 "constant_call_address_operand")
475              (const_int 4)
476              (const_int 0))
477          (eq_attr "type" "callv")
478            (if_then_else (match_operand 1 "constant_call_address_operand")
479              (const_int 4)
480              (const_int 0))
481          ;; We don't know the size before shorten_branches.  Expect
482          ;; the instruction to fit for better scheduling.
483          (eq_attr "type" "ibr")
484            (const_int 1)
485          ]
486          (symbol_ref "/* Update immediate_length and other attributes! */
487                       gcc_unreachable (),1")))
489 ;; The (bounding maximum) length of an instruction address.
490 (define_attr "length_address" ""
491   (cond [(eq_attr "type" "str,other,multi,fxch")
492            (const_int 0)
493          (and (eq_attr "type" "call")
494               (match_operand 0 "constant_call_address_operand"))
495              (const_int 0)
496          (and (eq_attr "type" "callv")
497               (match_operand 1 "constant_call_address_operand"))
498              (const_int 0)
499          ]
500          (symbol_ref "ix86_attr_length_address_default (insn)")))
502 ;; Set when length prefix is used.
503 (define_attr "prefix_data16" ""
504   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
505            (const_int 0)
506          (eq_attr "mode" "HI")
507            (const_int 1)
508          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
509            (const_int 1)
510         ]
511         (const_int 0)))
513 ;; Set when string REP prefix is used.
514 (define_attr "prefix_rep" ""
515   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
516            (const_int 0)
517          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
518            (const_int 1)
519          (and (eq_attr "type" "ibr,call,callv")
520               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
521            (const_int 1)
522         ]
523         (const_int 0)))
525 ;; Set when 0f opcode prefix is used.
526 (define_attr "prefix_0f" ""
527   (if_then_else
528     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
529                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
530          (eq_attr "unit" "sse,mmx"))
531     (const_int 1)
532     (const_int 0)))
534 ;; Set when REX opcode prefix is used.
535 (define_attr "prefix_rex" ""
536   (cond [(not (match_test "TARGET_64BIT"))
537            (const_int 0)
538          (and (eq_attr "mode" "DI")
539               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
540                    (eq_attr "unit" "!mmx")))
541            (const_int 1)
542          (and (eq_attr "mode" "QI")
543               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
544            (const_int 1)
545          (match_test "x86_extended_reg_mentioned_p (insn)")
546            (const_int 1)
547          (and (eq_attr "type" "imovx")
548               (match_operand:QI 1 "ext_QIreg_operand"))
549            (const_int 1)
550         ]
551         (const_int 0)))
553 ;; There are also additional prefixes in 3DNOW, SSSE3.
554 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
555 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
556 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
557 (define_attr "prefix_extra" ""
558   (cond [(eq_attr "type" "ssemuladd,sse4arg")
559            (const_int 2)
560          (eq_attr "type" "sseiadd1,ssecvt1")
561            (const_int 1)
562         ]
563         (const_int 0)))
565 ;; Prefix used: original, VEX or maybe VEX.
566 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
567   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
568            (const_string "vex")
569          (eq_attr "mode" "XI,V16SF,V8DF")
570            (const_string "evex")
571         ]
572         (const_string "orig")))
574 ;; VEX W bit is used.
575 (define_attr "prefix_vex_w" "" (const_int 0))
577 ;; The length of VEX prefix
578 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
579 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
580 ;; still prefix_0f 1, with prefix_extra 1.
581 (define_attr "length_vex" ""
582   (if_then_else (and (eq_attr "prefix_0f" "1")
583                      (eq_attr "prefix_extra" "0"))
584     (if_then_else (eq_attr "prefix_vex_w" "1")
585       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
586       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
587     (if_then_else (eq_attr "prefix_vex_w" "1")
588       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
589       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
591 ;; 4-bytes evex prefix and 1 byte opcode.
592 (define_attr "length_evex" "" (const_int 5))
594 ;; Set when modrm byte is used.
595 (define_attr "modrm" ""
596   (cond [(eq_attr "type" "str,leave")
597            (const_int 0)
598          (eq_attr "unit" "i387")
599            (const_int 0)
600          (and (eq_attr "type" "incdec")
601               (and (not (match_test "TARGET_64BIT"))
602                    (ior (match_operand:SI 1 "register_operand")
603                         (match_operand:HI 1 "register_operand"))))
604            (const_int 0)
605          (and (eq_attr "type" "push")
606               (not (match_operand 1 "memory_operand")))
607            (const_int 0)
608          (and (eq_attr "type" "pop")
609               (not (match_operand 0 "memory_operand")))
610            (const_int 0)
611          (and (eq_attr "type" "imov")
612               (and (not (eq_attr "mode" "DI"))
613                    (ior (and (match_operand 0 "register_operand")
614                              (match_operand 1 "immediate_operand"))
615                         (ior (and (match_operand 0 "ax_reg_operand")
616                                   (match_operand 1 "memory_displacement_only_operand"))
617                              (and (match_operand 0 "memory_displacement_only_operand")
618                                   (match_operand 1 "ax_reg_operand"))))))
619            (const_int 0)
620          (and (eq_attr "type" "call")
621               (match_operand 0 "constant_call_address_operand"))
622              (const_int 0)
623          (and (eq_attr "type" "callv")
624               (match_operand 1 "constant_call_address_operand"))
625              (const_int 0)
626          (and (eq_attr "type" "alu,alu1,icmp,test")
627               (match_operand 0 "ax_reg_operand"))
628              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
629          ]
630          (const_int 1)))
632 ;; When this attribute is set, calculate total insn length from
633 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
634 (define_attr "length_nobnd" "" (const_int 0))
636 ;; The (bounding maximum) length of an instruction in bytes.
637 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
638 ;; Later we may want to split them and compute proper length as for
639 ;; other insns.
640 (define_attr "length" ""
641   (cond [(eq_attr "length_nobnd" "!0")
642            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
643                  (attr "length_nobnd"))
644          (eq_attr "type" "other,multi,fistp,frndint")
645            (const_int 16)
646          (eq_attr "type" "fcmp")
647            (const_int 4)
648          (eq_attr "unit" "i387")
649            (plus (const_int 2)
650                  (plus (attr "prefix_data16")
651                        (attr "length_address")))
652          (ior (eq_attr "prefix" "evex")
653               (and (ior (eq_attr "prefix" "maybe_evex")
654                         (eq_attr "prefix" "maybe_vex"))
655                    (match_test "TARGET_AVX512F")))
656            (plus (attr "length_evex")
657                  (plus (attr "length_immediate")
658                        (plus (attr "modrm")
659                              (attr "length_address"))))
660          (ior (eq_attr "prefix" "vex")
661               (and (ior (eq_attr "prefix" "maybe_vex")
662                         (eq_attr "prefix" "maybe_evex"))
663                    (match_test "TARGET_AVX")))
664            (plus (attr "length_vex")
665                  (plus (attr "length_immediate")
666                        (plus (attr "modrm")
667                              (attr "length_address"))))]
668          (plus (plus (attr "modrm")
669                      (plus (attr "prefix_0f")
670                            (plus (attr "prefix_rex")
671                                  (plus (attr "prefix_extra")
672                                        (const_int 1)))))
673                (plus (attr "prefix_rep")
674                      (plus (attr "prefix_data16")
675                            (plus (attr "length_immediate")
676                                  (attr "length_address")))))))
678 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
679 ;; `store' if there is a simple memory reference therein, or `unknown'
680 ;; if the instruction is complex.
682 (define_attr "memory" "none,load,store,both,unknown"
683   (cond [(eq_attr "type" "other,multi,str,lwp")
684            (const_string "unknown")
685          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
686            (const_string "none")
687          (eq_attr "type" "fistp,leave")
688            (const_string "both")
689          (eq_attr "type" "frndint")
690            (const_string "load")
691          (eq_attr "type" "mpxld")
692            (const_string "load")
693          (eq_attr "type" "mpxst")
694            (const_string "store")
695          (eq_attr "type" "push")
696            (if_then_else (match_operand 1 "memory_operand")
697              (const_string "both")
698              (const_string "store"))
699          (eq_attr "type" "pop")
700            (if_then_else (match_operand 0 "memory_operand")
701              (const_string "both")
702              (const_string "load"))
703          (eq_attr "type" "setcc")
704            (if_then_else (match_operand 0 "memory_operand")
705              (const_string "store")
706              (const_string "none"))
707          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
708            (if_then_else (ior (match_operand 0 "memory_operand")
709                               (match_operand 1 "memory_operand"))
710              (const_string "load")
711              (const_string "none"))
712          (eq_attr "type" "ibr")
713            (if_then_else (match_operand 0 "memory_operand")
714              (const_string "load")
715              (const_string "none"))
716          (eq_attr "type" "call")
717            (if_then_else (match_operand 0 "constant_call_address_operand")
718              (const_string "none")
719              (const_string "load"))
720          (eq_attr "type" "callv")
721            (if_then_else (match_operand 1 "constant_call_address_operand")
722              (const_string "none")
723              (const_string "load"))
724          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
725               (match_operand 1 "memory_operand"))
726            (const_string "both")
727          (and (match_operand 0 "memory_operand")
728               (match_operand 1 "memory_operand"))
729            (const_string "both")
730          (match_operand 0 "memory_operand")
731            (const_string "store")
732          (match_operand 1 "memory_operand")
733            (const_string "load")
734          (and (eq_attr "type"
735                  "!alu1,negnot,ishift1,
736                    imov,imovx,icmp,test,bitmanip,
737                    fmov,fcmp,fsgn,
738                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
739                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
740                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
741               (match_operand 2 "memory_operand"))
742            (const_string "load")
743          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
744               (match_operand 3 "memory_operand"))
745            (const_string "load")
746         ]
747         (const_string "none")))
749 ;; Indicates if an instruction has both an immediate and a displacement.
751 (define_attr "imm_disp" "false,true,unknown"
752   (cond [(eq_attr "type" "other,multi")
753            (const_string "unknown")
754          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
755               (and (match_operand 0 "memory_displacement_operand")
756                    (match_operand 1 "immediate_operand")))
757            (const_string "true")
758          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
759               (and (match_operand 0 "memory_displacement_operand")
760                    (match_operand 2 "immediate_operand")))
761            (const_string "true")
762         ]
763         (const_string "false")))
765 ;; Indicates if an FP operation has an integer source.
767 (define_attr "fp_int_src" "false,true"
768   (const_string "false"))
770 ;; Defines rounding mode of an FP operation.
772 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
773   (const_string "any"))
775 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
776 (define_attr "use_carry" "0,1" (const_string "0"))
778 ;; Define attribute to indicate unaligned ssemov insns
779 (define_attr "movu" "0,1" (const_string "0"))
781 ;; Used to control the "enabled" attribute on a per-instruction basis.
782 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
783                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
784                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
785                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
786                     avx512vl,noavx512vl"
787   (const_string "base"))
789 (define_attr "enabled" ""
790   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
791          (eq_attr "isa" "x64_sse4")
792            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
793          (eq_attr "isa" "x64_sse4_noavx")
794            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
795          (eq_attr "isa" "x64_avx")
796            (symbol_ref "TARGET_64BIT && TARGET_AVX")
797          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
798          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
799          (eq_attr "isa" "sse2_noavx")
800            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
801          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
802          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
803          (eq_attr "isa" "sse4_noavx")
804            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
805          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
806          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
807          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
808          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
809          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
810          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
811          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
812          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
813          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
814          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
815          (eq_attr "isa" "fma_avx512f")
816            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
817          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
818          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
819          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
820          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
821          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
822          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
823         ]
824         (const_int 1)))
826 (define_attr "preferred_for_size" "" (const_int 1))
827 (define_attr "preferred_for_speed" "" (const_int 1))
829 ;; Describe a user's asm statement.
830 (define_asm_attributes
831   [(set_attr "length" "128")
832    (set_attr "type" "multi")])
834 (define_code_iterator plusminus [plus minus])
836 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
838 (define_code_iterator multdiv [mult div])
840 ;; Base name for define_insn
841 (define_code_attr plusminus_insn
842   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
843    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
845 ;; Base name for insn mnemonic.
846 (define_code_attr plusminus_mnemonic
847   [(plus "add") (ss_plus "adds") (us_plus "addus")
848    (minus "sub") (ss_minus "subs") (us_minus "subus")])
849 (define_code_attr multdiv_mnemonic
850   [(mult "mul") (div "div")])
852 ;; Mark commutative operators as such in constraints.
853 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
854                         (minus "") (ss_minus "") (us_minus "")])
856 ;; Mapping of max and min
857 (define_code_iterator maxmin [smax smin umax umin])
859 ;; Mapping of signed max and min
860 (define_code_iterator smaxmin [smax smin])
862 ;; Mapping of unsigned max and min
863 (define_code_iterator umaxmin [umax umin])
865 ;; Base name for integer and FP insn mnemonic
866 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
867                               (umax "maxu") (umin "minu")])
868 (define_code_attr maxmin_float [(smax "max") (smin "min")])
870 ;; Mapping of logic operators
871 (define_code_iterator any_logic [and ior xor])
872 (define_code_iterator any_or [ior xor])
873 (define_code_iterator fpint_logic [and xor])
875 ;; Base name for insn mnemonic.
876 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
878 ;; Mapping of logic-shift operators
879 (define_code_iterator any_lshift [ashift lshiftrt])
881 ;; Mapping of shift-right operators
882 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
884 ;; Mapping of all shift operators
885 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
887 ;; Base name for define_insn
888 (define_code_attr shift_insn
889   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
891 ;; Base name for insn mnemonic.
892 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
893 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
895 ;; Mapping of rotate operators
896 (define_code_iterator any_rotate [rotate rotatert])
898 ;; Base name for define_insn
899 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
901 ;; Base name for insn mnemonic.
902 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
904 ;; Mapping of abs neg operators
905 (define_code_iterator absneg [abs neg])
907 ;; Base name for x87 insn mnemonic.
908 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
910 ;; Used in signed and unsigned widening multiplications.
911 (define_code_iterator any_extend [sign_extend zero_extend])
913 ;; Prefix for insn menmonic.
914 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
916 ;; Prefix for define_insn
917 (define_code_attr u [(sign_extend "") (zero_extend "u")])
918 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
919 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
921 ;; Used in signed and unsigned truncations.
922 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
923 ;; Instruction suffix for truncations.
924 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
926 ;; Used in signed and unsigned fix.
927 (define_code_iterator any_fix [fix unsigned_fix])
928 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
930 ;; Used in signed and unsigned float.
931 (define_code_iterator any_float [float unsigned_float])
932 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
934 ;; All integer modes.
935 (define_mode_iterator SWI1248x [QI HI SI DI])
937 ;; All integer modes with AVX512BW.
938 (define_mode_iterator SWI1248_AVX512BW
939   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
941 ;; All integer modes without QImode.
942 (define_mode_iterator SWI248x [HI SI DI])
944 ;; All integer modes without QImode and HImode.
945 (define_mode_iterator SWI48x [SI DI])
947 ;; All integer modes without SImode and DImode.
948 (define_mode_iterator SWI12 [QI HI])
950 ;; All integer modes without DImode.
951 (define_mode_iterator SWI124 [QI HI SI])
953 ;; All integer modes without QImode and DImode.
954 (define_mode_iterator SWI24 [HI SI])
956 ;; Single word integer modes.
957 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
959 ;; Single word integer modes without QImode.
960 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
962 ;; Single word integer modes without QImode and HImode.
963 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
965 ;; All math-dependant single and double word integer modes.
966 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
967                              (HI "TARGET_HIMODE_MATH")
968                              SI DI (TI "TARGET_64BIT")])
970 ;; Math-dependant single word integer modes.
971 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
972                             (HI "TARGET_HIMODE_MATH")
973                             SI (DI "TARGET_64BIT")])
975 ;; Math-dependant integer modes without DImode.
976 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
977                                (HI "TARGET_HIMODE_MATH")
978                                SI])
980 ;; Math-dependant single word integer modes without QImode.
981 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
982                                SI (DI "TARGET_64BIT")])
984 ;; Double word integer modes.
985 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
986                            (TI "TARGET_64BIT")])
988 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
989 ;; compile time constant, it is faster to use <MODE_SIZE> than
990 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
991 ;; command line options just use GET_MODE_SIZE macro.
992 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
993                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
994                              (V16QI "16") (V32QI "32") (V64QI "64")
995                              (V8HI "16") (V16HI "32") (V32HI "64")
996                              (V4SI "16") (V8SI "32") (V16SI "64")
997                              (V2DI "16") (V4DI "32") (V8DI "64")
998                              (V1TI "16") (V2TI "32") (V4TI "64")
999                              (V2DF "16") (V4DF "32") (V8DF "64")
1000                              (V4SF "16") (V8SF "32") (V16SF "64")])
1002 ;; Double word integer modes as mode attribute.
1003 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1004 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1006 ;; Half mode for double word integer modes.
1007 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1008                             (DI "TARGET_64BIT")])
1010 ;; Bound modes.
1011 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1012                            (BND64 "TARGET_LP64")])
1014 ;; Pointer mode corresponding to bound mode.
1015 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1017 ;; MPX check types
1018 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1020 ;; Check name
1021 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1022                            (UNSPEC_BNDCU "cu")
1023                            (UNSPEC_BNDCN "cn")])
1025 ;; Instruction suffix for integer modes.
1026 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1028 ;; Instruction suffix for masks.
1029 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1031 ;; Pointer size prefix for integer modes (Intel asm dialect)
1032 (define_mode_attr iptrsize [(QI "BYTE")
1033                             (HI "WORD")
1034                             (SI "DWORD")
1035                             (DI "QWORD")])
1037 ;; Register class for integer modes.
1038 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1040 ;; Immediate operand constraint for integer modes.
1041 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1043 ;; General operand constraint for word modes.
1044 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1046 ;; Immediate operand constraint for double integer modes.
1047 (define_mode_attr di [(SI "nF") (DI "e")])
1049 ;; Immediate operand constraint for shifts.
1050 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1052 ;; General operand predicate for integer modes.
1053 (define_mode_attr general_operand
1054         [(QI "general_operand")
1055          (HI "general_operand")
1056          (SI "x86_64_general_operand")
1057          (DI "x86_64_general_operand")
1058          (TI "x86_64_general_operand")])
1060 ;; General sign extend operand predicate for integer modes,
1061 ;; which disallows VOIDmode operands and thus it is suitable
1062 ;; for use inside sign_extend.
1063 (define_mode_attr general_sext_operand
1064         [(QI "sext_operand")
1065          (HI "sext_operand")
1066          (SI "x86_64_sext_operand")
1067          (DI "x86_64_sext_operand")])
1069 ;; General sign/zero extend operand predicate for integer modes.
1070 (define_mode_attr general_szext_operand
1071         [(QI "general_operand")
1072          (HI "general_operand")
1073          (SI "x86_64_szext_general_operand")
1074          (DI "x86_64_szext_general_operand")])
1076 ;; Immediate operand predicate for integer modes.
1077 (define_mode_attr immediate_operand
1078         [(QI "immediate_operand")
1079          (HI "immediate_operand")
1080          (SI "x86_64_immediate_operand")
1081          (DI "x86_64_immediate_operand")])
1083 ;; Nonmemory operand predicate for integer modes.
1084 (define_mode_attr nonmemory_operand
1085         [(QI "nonmemory_operand")
1086          (HI "nonmemory_operand")
1087          (SI "x86_64_nonmemory_operand")
1088          (DI "x86_64_nonmemory_operand")])
1090 ;; Operand predicate for shifts.
1091 (define_mode_attr shift_operand
1092         [(QI "nonimmediate_operand")
1093          (HI "nonimmediate_operand")
1094          (SI "nonimmediate_operand")
1095          (DI "shiftdi_operand")
1096          (TI "register_operand")])
1098 ;; Operand predicate for shift argument.
1099 (define_mode_attr shift_immediate_operand
1100         [(QI "const_1_to_31_operand")
1101          (HI "const_1_to_31_operand")
1102          (SI "const_1_to_31_operand")
1103          (DI "const_1_to_63_operand")])
1105 ;; Input operand predicate for arithmetic left shifts.
1106 (define_mode_attr ashl_input_operand
1107         [(QI "nonimmediate_operand")
1108          (HI "nonimmediate_operand")
1109          (SI "nonimmediate_operand")
1110          (DI "ashldi_input_operand")
1111          (TI "reg_or_pm1_operand")])
1113 ;; SSE and x87 SFmode and DFmode floating point modes
1114 (define_mode_iterator MODEF [SF DF])
1116 ;; All x87 floating point modes
1117 (define_mode_iterator X87MODEF [SF DF XF])
1119 ;; SSE instruction suffix for various modes
1120 (define_mode_attr ssemodesuffix
1121   [(SF "ss") (DF "sd")
1122    (V16SF "ps") (V8DF "pd")
1123    (V8SF "ps") (V4DF "pd")
1124    (V4SF "ps") (V2DF "pd")
1125    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1126    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1127    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1129 ;; SSE vector suffix for floating point modes
1130 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1132 ;; SSE vector mode corresponding to a scalar mode
1133 (define_mode_attr ssevecmode
1134   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1135 (define_mode_attr ssevecmodelower
1136   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1138 ;; Instruction suffix for REX 64bit operators.
1139 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1141 ;; This mode iterator allows :P to be used for patterns that operate on
1142 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1143 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1145 ;; This mode iterator allows :W to be used for patterns that operate on
1146 ;; word_mode sized quantities.
1147 (define_mode_iterator W
1148   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1150 ;; This mode iterator allows :PTR to be used for patterns that operate on
1151 ;; ptr_mode sized quantities.
1152 (define_mode_iterator PTR
1153   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1155 ;; Scheduling descriptions
1157 (include "pentium.md")
1158 (include "ppro.md")
1159 (include "k6.md")
1160 (include "athlon.md")
1161 (include "bdver1.md")
1162 (include "bdver3.md")
1163 (include "btver2.md")
1164 (include "geode.md")
1165 (include "atom.md")
1166 (include "slm.md")
1167 (include "core2.md")
1170 ;; Operand and operator predicates and constraints
1172 (include "predicates.md")
1173 (include "constraints.md")
1176 ;; Compare and branch/compare and store instructions.
1178 (define_expand "cbranch<mode>4"
1179   [(set (reg:CC FLAGS_REG)
1180         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1181                     (match_operand:SDWIM 2 "<general_operand>")))
1182    (set (pc) (if_then_else
1183                (match_operator 0 "ordered_comparison_operator"
1184                 [(reg:CC FLAGS_REG) (const_int 0)])
1185                (label_ref (match_operand 3))
1186                (pc)))]
1187   ""
1189   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1190     operands[1] = force_reg (<MODE>mode, operands[1]);
1191   ix86_expand_branch (GET_CODE (operands[0]),
1192                       operands[1], operands[2], operands[3]);
1193   DONE;
1196 (define_expand "cstore<mode>4"
1197   [(set (reg:CC FLAGS_REG)
1198         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1199                     (match_operand:SWIM 3 "<general_operand>")))
1200    (set (match_operand:QI 0 "register_operand")
1201         (match_operator 1 "ordered_comparison_operator"
1202           [(reg:CC FLAGS_REG) (const_int 0)]))]
1203   ""
1205   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1206     operands[2] = force_reg (<MODE>mode, operands[2]);
1207   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208                      operands[2], operands[3]);
1209   DONE;
1212 (define_expand "cmp<mode>_1"
1213   [(set (reg:CC FLAGS_REG)
1214         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1215                     (match_operand:SWI48 1 "<general_operand>")))])
1217 (define_insn "*cmp<mode>_ccno_1"
1218   [(set (reg FLAGS_REG)
1219         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1220                  (match_operand:SWI 1 "const0_operand")))]
1221   "ix86_match_ccmode (insn, CCNOmode)"
1222   "@
1223    test{<imodesuffix>}\t%0, %0
1224    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1225   [(set_attr "type" "test,icmp")
1226    (set_attr "length_immediate" "0,1")
1227    (set_attr "mode" "<MODE>")])
1229 (define_insn "*cmp<mode>_1"
1230   [(set (reg FLAGS_REG)
1231         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1232                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1233   "ix86_match_ccmode (insn, CCmode)"
1234   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1235   [(set_attr "type" "icmp")
1236    (set_attr "mode" "<MODE>")])
1238 (define_insn "*cmp<mode>_minus_1"
1239   [(set (reg FLAGS_REG)
1240         (compare
1241           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1242                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1243           (const_int 0)))]
1244   "ix86_match_ccmode (insn, CCGOCmode)"
1245   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1246   [(set_attr "type" "icmp")
1247    (set_attr "mode" "<MODE>")])
1249 (define_insn "*cmpqi_ext_1"
1250   [(set (reg FLAGS_REG)
1251         (compare
1252           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1253           (subreg:QI
1254             (zero_extract:SI
1255               (match_operand 1 "ext_register_operand" "Q,Q")
1256               (const_int 8)
1257               (const_int 8)) 0)))]
1258   "ix86_match_ccmode (insn, CCmode)"
1259   "cmp{b}\t{%h1, %0|%0, %h1}"
1260   [(set_attr "isa" "*,nox64")
1261    (set_attr "type" "icmp")
1262    (set_attr "mode" "QI")])
1264 (define_insn "*cmpqi_ext_2"
1265   [(set (reg FLAGS_REG)
1266         (compare
1267           (subreg:QI
1268             (zero_extract:SI
1269               (match_operand 0 "ext_register_operand" "Q")
1270               (const_int 8)
1271               (const_int 8)) 0)
1272           (match_operand:QI 1 "const0_operand")))]
1273   "ix86_match_ccmode (insn, CCNOmode)"
1274   "test{b}\t%h0, %h0"
1275   [(set_attr "type" "test")
1276    (set_attr "length_immediate" "0")
1277    (set_attr "mode" "QI")])
1279 (define_expand "cmpqi_ext_3"
1280   [(set (reg:CC FLAGS_REG)
1281         (compare:CC
1282           (subreg:QI
1283             (zero_extract:SI
1284               (match_operand 0 "ext_register_operand")
1285               (const_int 8)
1286               (const_int 8)) 0)
1287           (match_operand:QI 1 "const_int_operand")))])
1289 (define_insn "*cmpqi_ext_3"
1290   [(set (reg FLAGS_REG)
1291         (compare
1292           (subreg:QI
1293             (zero_extract:SI
1294               (match_operand 0 "ext_register_operand" "Q,Q")
1295               (const_int 8)
1296               (const_int 8)) 0)
1297           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1298   "ix86_match_ccmode (insn, CCmode)"
1299   "cmp{b}\t{%1, %h0|%h0, %1}"
1300   [(set_attr "isa" "*,nox64")
1301    (set_attr "type" "icmp")
1302    (set_attr "modrm" "1")
1303    (set_attr "mode" "QI")])
1305 (define_insn "*cmpqi_ext_4"
1306   [(set (reg FLAGS_REG)
1307         (compare
1308           (subreg:QI
1309             (zero_extract:SI
1310               (match_operand 0 "ext_register_operand" "Q")
1311               (const_int 8)
1312               (const_int 8)) 0)
1313           (subreg:QI
1314             (zero_extract:SI
1315               (match_operand 1 "ext_register_operand" "Q")
1316               (const_int 8)
1317               (const_int 8)) 0)))]
1318   "ix86_match_ccmode (insn, CCmode)"
1319   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1320   [(set_attr "type" "icmp")
1321    (set_attr "mode" "QI")])
1323 ;; These implement float point compares.
1324 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1325 ;; which would allow mix and match FP modes on the compares.  Which is what
1326 ;; the old patterns did, but with many more of them.
1328 (define_expand "cbranchxf4"
1329   [(set (reg:CC FLAGS_REG)
1330         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1331                     (match_operand:XF 2 "nonmemory_operand")))
1332    (set (pc) (if_then_else
1333               (match_operator 0 "ix86_fp_comparison_operator"
1334                [(reg:CC FLAGS_REG)
1335                 (const_int 0)])
1336               (label_ref (match_operand 3))
1337               (pc)))]
1338   "TARGET_80387"
1340   ix86_expand_branch (GET_CODE (operands[0]),
1341                       operands[1], operands[2], operands[3]);
1342   DONE;
1345 (define_expand "cstorexf4"
1346   [(set (reg:CC FLAGS_REG)
1347         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1348                     (match_operand:XF 3 "nonmemory_operand")))
1349    (set (match_operand:QI 0 "register_operand")
1350               (match_operator 1 "ix86_fp_comparison_operator"
1351                [(reg:CC FLAGS_REG)
1352                 (const_int 0)]))]
1353   "TARGET_80387"
1355   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356                      operands[2], operands[3]);
1357   DONE;
1360 (define_expand "cbranch<mode>4"
1361   [(set (reg:CC FLAGS_REG)
1362         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1363                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1364    (set (pc) (if_then_else
1365               (match_operator 0 "ix86_fp_comparison_operator"
1366                [(reg:CC FLAGS_REG)
1367                 (const_int 0)])
1368               (label_ref (match_operand 3))
1369               (pc)))]
1370   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1372   ix86_expand_branch (GET_CODE (operands[0]),
1373                       operands[1], operands[2], operands[3]);
1374   DONE;
1377 (define_expand "cstore<mode>4"
1378   [(set (reg:CC FLAGS_REG)
1379         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1380                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1381    (set (match_operand:QI 0 "register_operand")
1382               (match_operator 1 "ix86_fp_comparison_operator"
1383                [(reg:CC FLAGS_REG)
1384                 (const_int 0)]))]
1385   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1387   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1388                      operands[2], operands[3]);
1389   DONE;
1392 (define_expand "cbranchcc4"
1393   [(set (pc) (if_then_else
1394               (match_operator 0 "comparison_operator"
1395                [(match_operand 1 "flags_reg_operand")
1396                 (match_operand 2 "const0_operand")])
1397               (label_ref (match_operand 3))
1398               (pc)))]
1399   ""
1401   ix86_expand_branch (GET_CODE (operands[0]),
1402                       operands[1], operands[2], operands[3]);
1403   DONE;
1406 (define_expand "cstorecc4"
1407   [(set (match_operand:QI 0 "register_operand")
1408               (match_operator 1 "comparison_operator"
1409                [(match_operand 2 "flags_reg_operand")
1410                 (match_operand 3 "const0_operand")]))]
1411   ""
1413   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1414                      operands[2], operands[3]);
1415   DONE;
1419 ;; FP compares, step 1:
1420 ;; Set the FP condition codes.
1422 ;; CCFPmode     compare with exceptions
1423 ;; CCFPUmode    compare with no exceptions
1425 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1426 ;; used to manage the reg stack popping would not be preserved.
1428 (define_insn "*cmp<mode>_0_i387"
1429   [(set (match_operand:HI 0 "register_operand" "=a")
1430         (unspec:HI
1431           [(compare:CCFP
1432              (match_operand:X87MODEF 1 "register_operand" "f")
1433              (match_operand:X87MODEF 2 "const0_operand"))]
1434         UNSPEC_FNSTSW))]
1435   "TARGET_80387"
1436   "* return output_fp_compare (insn, operands, false, false);"
1437   [(set_attr "type" "multi")
1438    (set_attr "unit" "i387")
1439    (set_attr "mode" "<MODE>")])
1441 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1442   [(set (reg:CCFP FLAGS_REG)
1443         (compare:CCFP
1444           (match_operand:X87MODEF 1 "register_operand" "f")
1445           (match_operand:X87MODEF 2 "const0_operand")))
1446    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1447   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1448   "#"
1449   "&& reload_completed"
1450   [(set (match_dup 0)
1451         (unspec:HI
1452           [(compare:CCFP (match_dup 1)(match_dup 2))]
1453         UNSPEC_FNSTSW))
1454    (set (reg:CC FLAGS_REG)
1455         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1456   ""
1457   [(set_attr "type" "multi")
1458    (set_attr "unit" "i387")
1459    (set_attr "mode" "<MODE>")])
1461 (define_insn "*cmpxf_i387"
1462   [(set (match_operand:HI 0 "register_operand" "=a")
1463         (unspec:HI
1464           [(compare:CCFP
1465              (match_operand:XF 1 "register_operand" "f")
1466              (match_operand:XF 2 "register_operand" "f"))]
1467           UNSPEC_FNSTSW))]
1468   "TARGET_80387"
1469   "* return output_fp_compare (insn, operands, false, false);"
1470   [(set_attr "type" "multi")
1471    (set_attr "unit" "i387")
1472    (set_attr "mode" "XF")])
1474 (define_insn_and_split "*cmpxf_cc_i387"
1475   [(set (reg:CCFP FLAGS_REG)
1476         (compare:CCFP
1477           (match_operand:XF 1 "register_operand" "f")
1478           (match_operand:XF 2 "register_operand" "f")))
1479    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1480   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1481   "#"
1482   "&& reload_completed"
1483   [(set (match_dup 0)
1484         (unspec:HI
1485           [(compare:CCFP (match_dup 1)(match_dup 2))]
1486         UNSPEC_FNSTSW))
1487    (set (reg:CC FLAGS_REG)
1488         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1489   ""
1490   [(set_attr "type" "multi")
1491    (set_attr "unit" "i387")
1492    (set_attr "mode" "XF")])
1494 (define_insn "*cmp<mode>_i387"
1495   [(set (match_operand:HI 0 "register_operand" "=a")
1496         (unspec:HI
1497           [(compare:CCFP
1498              (match_operand:MODEF 1 "register_operand" "f")
1499              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1500           UNSPEC_FNSTSW))]
1501   "TARGET_80387"
1502   "* return output_fp_compare (insn, operands, false, false);"
1503   [(set_attr "type" "multi")
1504    (set_attr "unit" "i387")
1505    (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmp<mode>_cc_i387"
1508   [(set (reg:CCFP FLAGS_REG)
1509         (compare:CCFP
1510           (match_operand:MODEF 1 "register_operand" "f")
1511           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1512    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1513   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1514   "#"
1515   "&& reload_completed"
1516   [(set (match_dup 0)
1517         (unspec:HI
1518           [(compare:CCFP (match_dup 1)(match_dup 2))]
1519         UNSPEC_FNSTSW))
1520    (set (reg:CC FLAGS_REG)
1521         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1522   ""
1523   [(set_attr "type" "multi")
1524    (set_attr "unit" "i387")
1525    (set_attr "mode" "<MODE>")])
1527 (define_insn "*cmpu<mode>_i387"
1528   [(set (match_operand:HI 0 "register_operand" "=a")
1529         (unspec:HI
1530           [(compare:CCFPU
1531              (match_operand:X87MODEF 1 "register_operand" "f")
1532              (match_operand:X87MODEF 2 "register_operand" "f"))]
1533           UNSPEC_FNSTSW))]
1534   "TARGET_80387"
1535   "* return output_fp_compare (insn, operands, false, true);"
1536   [(set_attr "type" "multi")
1537    (set_attr "unit" "i387")
1538    (set_attr "mode" "<MODE>")])
1540 (define_insn_and_split "*cmpu<mode>_cc_i387"
1541   [(set (reg:CCFPU FLAGS_REG)
1542         (compare:CCFPU
1543           (match_operand:X87MODEF 1 "register_operand" "f")
1544           (match_operand:X87MODEF 2 "register_operand" "f")))
1545    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1546   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1547   "#"
1548   "&& reload_completed"
1549   [(set (match_dup 0)
1550         (unspec:HI
1551           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1552         UNSPEC_FNSTSW))
1553    (set (reg:CC FLAGS_REG)
1554         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1555   ""
1556   [(set_attr "type" "multi")
1557    (set_attr "unit" "i387")
1558    (set_attr "mode" "<MODE>")])
1560 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1561   [(set (match_operand:HI 0 "register_operand" "=a")
1562         (unspec:HI
1563           [(compare:CCFP
1564              (match_operand:X87MODEF 1 "register_operand" "f")
1565              (match_operator:X87MODEF 3 "float_operator"
1566                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1567           UNSPEC_FNSTSW))]
1568   "TARGET_80387
1569    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1570        || optimize_function_for_size_p (cfun))"
1571   "* return output_fp_compare (insn, operands, false, false);"
1572   [(set_attr "type" "multi")
1573    (set_attr "unit" "i387")
1574    (set_attr "fp_int_src" "true")
1575    (set_attr "mode" "<SWI24:MODE>")])
1577 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1578   [(set (reg:CCFP FLAGS_REG)
1579         (compare:CCFP
1580           (match_operand:X87MODEF 1 "register_operand" "f")
1581           (match_operator:X87MODEF 3 "float_operator"
1582             [(match_operand:SWI24 2 "memory_operand" "m")])))
1583    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1584   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1585    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1586        || optimize_function_for_size_p (cfun))"
1587   "#"
1588   "&& reload_completed"
1589   [(set (match_dup 0)
1590         (unspec:HI
1591           [(compare:CCFP
1592              (match_dup 1)
1593              (match_op_dup 3 [(match_dup 2)]))]
1594         UNSPEC_FNSTSW))
1595    (set (reg:CC FLAGS_REG)
1596         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1597   ""
1598   [(set_attr "type" "multi")
1599    (set_attr "unit" "i387")
1600    (set_attr "fp_int_src" "true")
1601    (set_attr "mode" "<SWI24:MODE>")])
1603 ;; FP compares, step 2
1604 ;; Move the fpsw to ax.
1606 (define_insn "x86_fnstsw_1"
1607   [(set (match_operand:HI 0 "register_operand" "=a")
1608         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1609   "TARGET_80387"
1610   "fnstsw\t%0"
1611   [(set_attr "length" "2")
1612    (set_attr "mode" "SI")
1613    (set_attr "unit" "i387")])
1615 ;; FP compares, step 3
1616 ;; Get ax into flags, general case.
1618 (define_insn "x86_sahf_1"
1619   [(set (reg:CC FLAGS_REG)
1620         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1621                    UNSPEC_SAHF))]
1622   "TARGET_SAHF"
1624 #ifndef HAVE_AS_IX86_SAHF
1625   if (TARGET_64BIT)
1626     return ASM_BYTE "0x9e";
1627   else
1628 #endif
1629   return "sahf";
1631   [(set_attr "length" "1")
1632    (set_attr "athlon_decode" "vector")
1633    (set_attr "amdfam10_decode" "direct")
1634    (set_attr "bdver1_decode" "direct")
1635    (set_attr "mode" "SI")])
1637 ;; Pentium Pro can do steps 1 through 3 in one go.
1638 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1639 ;; (these i387 instructions set flags directly)
1641 (define_mode_iterator FPCMP [CCFP CCFPU])
1642 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1644 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1645   [(set (reg:FPCMP FLAGS_REG)
1646         (compare:FPCMP
1647           (match_operand:MODEF 0 "register_operand" "f,x")
1648           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1649   "TARGET_MIX_SSE_I387
1650    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1651   "* return output_fp_compare (insn, operands, true,
1652                                <FPCMP:MODE>mode == CCFPUmode);"
1653   [(set_attr "type" "fcmp,ssecomi")
1654    (set_attr "prefix" "orig,maybe_vex")
1655    (set_attr "mode" "<MODEF:MODE>")
1656    (set (attr "prefix_rep")
1657         (if_then_else (eq_attr "type" "ssecomi")
1658                       (const_string "0")
1659                       (const_string "*")))
1660    (set (attr "prefix_data16")
1661         (cond [(eq_attr "type" "fcmp")
1662                  (const_string "*")
1663                (eq_attr "mode" "DF")
1664                  (const_string "1")
1665               ]
1666               (const_string "0")))
1667    (set_attr "athlon_decode" "vector")
1668    (set_attr "amdfam10_decode" "direct")
1669    (set_attr "bdver1_decode" "double")])
1671 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1672   [(set (reg:FPCMP FLAGS_REG)
1673         (compare:FPCMP
1674           (match_operand:MODEF 0 "register_operand" "x")
1675           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1676   "TARGET_SSE_MATH
1677    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1678   "* return output_fp_compare (insn, operands, true,
1679                                <FPCMP:MODE>mode == CCFPUmode);"
1680   [(set_attr "type" "ssecomi")
1681    (set_attr "prefix" "maybe_vex")
1682    (set_attr "mode" "<MODEF:MODE>")
1683    (set_attr "prefix_rep" "0")
1684    (set (attr "prefix_data16")
1685         (if_then_else (eq_attr "mode" "DF")
1686                       (const_string "1")
1687                       (const_string "0")))
1688    (set_attr "athlon_decode" "vector")
1689    (set_attr "amdfam10_decode" "direct")
1690    (set_attr "bdver1_decode" "double")])
1692 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1693   [(set (reg:FPCMP FLAGS_REG)
1694         (compare:FPCMP
1695           (match_operand:X87MODEF 0 "register_operand" "f")
1696           (match_operand:X87MODEF 1 "register_operand" "f")))]
1697   "TARGET_80387 && TARGET_CMOVE
1698    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1699   "* return output_fp_compare (insn, operands, true,
1700                                <FPCMP:MODE>mode == CCFPUmode);"
1701   [(set_attr "type" "fcmp")
1702    (set_attr "mode" "<X87MODEF:MODE>")
1703    (set_attr "athlon_decode" "vector")
1704    (set_attr "amdfam10_decode" "direct")
1705    (set_attr "bdver1_decode" "double")])
1707 ;; Push/pop instructions.
1709 (define_insn "*push<mode>2"
1710   [(set (match_operand:DWI 0 "push_operand" "=<")
1711         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1712   ""
1713   "#"
1714   [(set_attr "type" "multi")
1715    (set_attr "mode" "<MODE>")])
1717 (define_split
1718   [(set (match_operand:TI 0 "push_operand")
1719         (match_operand:TI 1 "general_operand"))]
1720   "TARGET_64BIT && reload_completed
1721    && !SSE_REG_P (operands[1])"
1722   [(const_int 0)]
1723   "ix86_split_long_move (operands); DONE;")
1725 (define_insn "*pushdi2_rex64"
1726   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1727         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1728   "TARGET_64BIT"
1729   "@
1730    push{q}\t%1
1731    #"
1732   [(set_attr "type" "push,multi")
1733    (set_attr "mode" "DI")])
1735 ;; Convert impossible pushes of immediate to existing instructions.
1736 ;; First try to get scratch register and go through it.  In case this
1737 ;; fails, push sign extended lower part first and then overwrite
1738 ;; upper part by 32bit move.
1739 (define_peephole2
1740   [(match_scratch:DI 2 "r")
1741    (set (match_operand:DI 0 "push_operand")
1742         (match_operand:DI 1 "immediate_operand"))]
1743   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1744    && !x86_64_immediate_operand (operands[1], DImode)"
1745   [(set (match_dup 2) (match_dup 1))
1746    (set (match_dup 0) (match_dup 2))])
1748 ;; We need to define this as both peepholer and splitter for case
1749 ;; peephole2 pass is not run.
1750 ;; "&& 1" is needed to keep it from matching the previous pattern.
1751 (define_peephole2
1752   [(set (match_operand:DI 0 "push_operand")
1753         (match_operand:DI 1 "immediate_operand"))]
1754   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1755    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1756   [(set (match_dup 0) (match_dup 1))
1757    (set (match_dup 2) (match_dup 3))]
1759   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1761   operands[1] = gen_lowpart (DImode, operands[2]);
1762   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1763                                                    GEN_INT (4)));
1766 (define_split
1767   [(set (match_operand:DI 0 "push_operand")
1768         (match_operand:DI 1 "immediate_operand"))]
1769   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1770                     ? epilogue_completed : reload_completed)
1771    && !symbolic_operand (operands[1], DImode)
1772    && !x86_64_immediate_operand (operands[1], DImode)"
1773   [(set (match_dup 0) (match_dup 1))
1774    (set (match_dup 2) (match_dup 3))]
1776   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1778   operands[1] = gen_lowpart (DImode, operands[2]);
1779   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1780                                                    GEN_INT (4)));
1783 (define_split
1784   [(set (match_operand:DI 0 "push_operand")
1785         (match_operand:DI 1 "general_operand"))]
1786   "!TARGET_64BIT && reload_completed
1787    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1788   [(const_int 0)]
1789   "ix86_split_long_move (operands); DONE;")
1791 (define_insn "*pushsi2"
1792   [(set (match_operand:SI 0 "push_operand" "=<")
1793         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1794   "!TARGET_64BIT"
1795   "push{l}\t%1"
1796   [(set_attr "type" "push")
1797    (set_attr "mode" "SI")])
1799 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1800 ;; "push a byte/word".  But actually we use pushl, which has the effect
1801 ;; of rounding the amount pushed up to a word.
1803 ;; For TARGET_64BIT we always round up to 8 bytes.
1804 (define_insn "*push<mode>2_rex64"
1805   [(set (match_operand:SWI124 0 "push_operand" "=X")
1806         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1807   "TARGET_64BIT"
1808   "push{q}\t%q1"
1809   [(set_attr "type" "push")
1810    (set_attr "mode" "DI")])
1812 (define_insn "*push<mode>2"
1813   [(set (match_operand:SWI12 0 "push_operand" "=X")
1814         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1815   "!TARGET_64BIT"
1816   "push{l}\t%k1"
1817   [(set_attr "type" "push")
1818    (set_attr "mode" "SI")])
1820 (define_insn "*push<mode>2_prologue"
1821   [(set (match_operand:W 0 "push_operand" "=<")
1822         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1823    (clobber (mem:BLK (scratch)))]
1824   ""
1825   "push{<imodesuffix>}\t%1"
1826   [(set_attr "type" "push")
1827    (set_attr "mode" "<MODE>")])
1829 (define_insn "*pop<mode>1"
1830   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831         (match_operand:W 1 "pop_operand" ">"))]
1832   ""
1833   "pop{<imodesuffix>}\t%0"
1834   [(set_attr "type" "pop")
1835    (set_attr "mode" "<MODE>")])
1837 (define_insn "*pop<mode>1_epilogue"
1838   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1839         (match_operand:W 1 "pop_operand" ">"))
1840    (clobber (mem:BLK (scratch)))]
1841   ""
1842   "pop{<imodesuffix>}\t%0"
1843   [(set_attr "type" "pop")
1844    (set_attr "mode" "<MODE>")])
1846 (define_insn "*pushfl<mode>2"
1847   [(set (match_operand:W 0 "push_operand" "=<")
1848         (match_operand:W 1 "flags_reg_operand"))]
1849   ""
1850   "pushf{<imodesuffix>}"
1851   [(set_attr "type" "push")
1852    (set_attr "mode" "<MODE>")])
1854 (define_insn "*popfl<mode>1"
1855   [(set (match_operand:W 0 "flags_reg_operand")
1856         (match_operand:W 1 "pop_operand" ">"))]
1857   ""
1858   "popf{<imodesuffix>}"
1859   [(set_attr "type" "pop")
1860    (set_attr "mode" "<MODE>")])
1863 ;; Move instructions.
1865 (define_expand "movxi"
1866   [(set (match_operand:XI 0 "nonimmediate_operand")
1867         (match_operand:XI 1 "general_operand"))]
1868   "TARGET_AVX512F"
1869   "ix86_expand_move (XImode, operands); DONE;")
1871 ;; Reload patterns to support multi-word load/store
1872 ;; with non-offsetable address.
1873 (define_expand "reload_noff_store"
1874   [(parallel [(match_operand 0 "memory_operand" "=m")
1875               (match_operand 1 "register_operand" "r")
1876               (match_operand:DI 2 "register_operand" "=&r")])]
1877   "TARGET_64BIT"
1879   rtx mem = operands[0];
1880   rtx addr = XEXP (mem, 0);
1882   emit_move_insn (operands[2], addr);
1883   mem = replace_equiv_address_nv (mem, operands[2]);
1885   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1886   DONE;
1889 (define_expand "reload_noff_load"
1890   [(parallel [(match_operand 0 "register_operand" "=r")
1891               (match_operand 1 "memory_operand" "m")
1892               (match_operand:DI 2 "register_operand" "=r")])]
1893   "TARGET_64BIT"
1895   rtx mem = operands[1];
1896   rtx addr = XEXP (mem, 0);
1898   emit_move_insn (operands[2], addr);
1899   mem = replace_equiv_address_nv (mem, operands[2]);
1901   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1902   DONE;
1905 (define_expand "movoi"
1906   [(set (match_operand:OI 0 "nonimmediate_operand")
1907         (match_operand:OI 1 "general_operand"))]
1908   "TARGET_AVX"
1909   "ix86_expand_move (OImode, operands); DONE;")
1911 (define_expand "movti"
1912   [(set (match_operand:TI 0 "nonimmediate_operand")
1913         (match_operand:TI 1 "nonimmediate_operand"))]
1914   "TARGET_64BIT || TARGET_SSE"
1916   if (TARGET_64BIT)
1917     ix86_expand_move (TImode, operands);
1918   else
1919     ix86_expand_vector_move (TImode, operands);
1920   DONE;
1923 ;; This expands to what emit_move_complex would generate if we didn't
1924 ;; have a movti pattern.  Having this avoids problems with reload on
1925 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1926 ;; to have around all the time.
1927 (define_expand "movcdi"
1928   [(set (match_operand:CDI 0 "nonimmediate_operand")
1929         (match_operand:CDI 1 "general_operand"))]
1930   ""
1932   if (push_operand (operands[0], CDImode))
1933     emit_move_complex_push (CDImode, operands[0], operands[1]);
1934   else
1935     emit_move_complex_parts (operands[0], operands[1]);
1936   DONE;
1939 (define_expand "mov<mode>"
1940   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1941         (match_operand:SWI1248x 1 "general_operand"))]
1942   ""
1943   "ix86_expand_move (<MODE>mode, operands); DONE;")
1945 (define_insn "*mov<mode>_xor"
1946   [(set (match_operand:SWI48 0 "register_operand" "=r")
1947         (match_operand:SWI48 1 "const0_operand"))
1948    (clobber (reg:CC FLAGS_REG))]
1949   "reload_completed"
1950   "xor{l}\t%k0, %k0"
1951   [(set_attr "type" "alu1")
1952    (set_attr "mode" "SI")
1953    (set_attr "length_immediate" "0")])
1955 (define_insn "*mov<mode>_or"
1956   [(set (match_operand:SWI48 0 "register_operand" "=r")
1957         (match_operand:SWI48 1 "const_int_operand"))
1958    (clobber (reg:CC FLAGS_REG))]
1959   "reload_completed
1960    && operands[1] == constm1_rtx"
1961   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1962   [(set_attr "type" "alu1")
1963    (set_attr "mode" "<MODE>")
1964    (set_attr "length_immediate" "1")])
1966 (define_insn "*movxi_internal_avx512f"
1967   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1968         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1969   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971   switch (which_alternative)
1972     {
1973     case 0:
1974       return standard_sse_constant_opcode (insn, operands[1]);
1975     case 1:
1976     case 2:
1977       if (misaligned_operand (operands[0], XImode)
1978           || misaligned_operand (operands[1], XImode))
1979         return "vmovdqu32\t{%1, %0|%0, %1}";
1980       else
1981         return "vmovdqa32\t{%1, %0|%0, %1}";
1982     default:
1983       gcc_unreachable ();
1984     }
1986   [(set_attr "type" "sselog1,ssemov,ssemov")
1987    (set_attr "prefix" "evex")
1988    (set_attr "mode" "XI")])
1990 (define_insn "*movoi_internal_avx"
1991   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1992         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1993   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1995   switch (get_attr_type (insn))
1996     {
1997     case TYPE_SSELOG1:
1998       return standard_sse_constant_opcode (insn, operands[1]);
2000     case TYPE_SSEMOV:
2001       if (misaligned_operand (operands[0], OImode)
2002           || misaligned_operand (operands[1], OImode))
2003         {
2004           if (get_attr_mode (insn) == MODE_V8SF)
2005             return "vmovups\t{%1, %0|%0, %1}";
2006           else if (get_attr_mode (insn) == MODE_XI)
2007             return "vmovdqu32\t{%1, %0|%0, %1}";
2008           else
2009             return "vmovdqu\t{%1, %0|%0, %1}";
2010         }
2011       else
2012         {
2013           if (get_attr_mode (insn) == MODE_V8SF)
2014             return "vmovaps\t{%1, %0|%0, %1}";
2015           else if (get_attr_mode (insn) == MODE_XI)
2016             return "vmovdqa32\t{%1, %0|%0, %1}";
2017           else
2018             return "vmovdqa\t{%1, %0|%0, %1}";
2019         }
2021     default:
2022       gcc_unreachable ();
2023     }
2025   [(set_attr "type" "sselog1,ssemov,ssemov")
2026    (set_attr "prefix" "vex")
2027    (set (attr "mode")
2028         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2029                     (match_operand 1 "ext_sse_reg_operand"))
2030                  (const_string "XI")
2031                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2032                  (const_string "V8SF")
2033                (and (eq_attr "alternative" "2")
2034                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2035                  (const_string "V8SF")
2036               ]
2037               (const_string "OI")))])
2039 (define_insn "*movti_internal"
2040   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2041         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2042   "(TARGET_64BIT || TARGET_SSE)
2043    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2045   switch (get_attr_type (insn))
2046     {
2047     case TYPE_MULTI:
2048       return "#";
2050     case TYPE_SSELOG1:
2051       return standard_sse_constant_opcode (insn, operands[1]);
2053     case TYPE_SSEMOV:
2054       /* TDmode values are passed as TImode on the stack.  Moving them
2055          to stack may result in unaligned memory access.  */
2056       if (misaligned_operand (operands[0], TImode)
2057           || misaligned_operand (operands[1], TImode))
2058         {
2059           if (get_attr_mode (insn) == MODE_V4SF)
2060             return "%vmovups\t{%1, %0|%0, %1}";
2061           else if (get_attr_mode (insn) == MODE_XI)
2062             return "vmovdqu32\t{%1, %0|%0, %1}";
2063           else
2064             return "%vmovdqu\t{%1, %0|%0, %1}";
2065         }
2066       else
2067         {
2068           if (get_attr_mode (insn) == MODE_V4SF)
2069             return "%vmovaps\t{%1, %0|%0, %1}";
2070           else if (get_attr_mode (insn) == MODE_XI)
2071             return "vmovdqa32\t{%1, %0|%0, %1}";
2072           else
2073             return "%vmovdqa\t{%1, %0|%0, %1}";
2074         }
2076     default:
2077       gcc_unreachable ();
2078     }
2080   [(set_attr "isa" "x64,x64,*,*,*")
2081    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2082    (set (attr "prefix")
2083      (if_then_else (eq_attr "type" "sselog1,ssemov")
2084        (const_string "maybe_vex")
2085        (const_string "orig")))
2086    (set (attr "mode")
2087         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2088                     (match_operand 1 "ext_sse_reg_operand"))
2089                  (const_string "XI")
2090                (eq_attr "alternative" "0,1")
2091                  (const_string "DI")
2092                (ior (not (match_test "TARGET_SSE2"))
2093                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2094                  (const_string "V4SF")
2095                (and (eq_attr "alternative" "4")
2096                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2097                  (const_string "V4SF")
2098                (match_test "TARGET_AVX")
2099                  (const_string "TI")
2100                (match_test "optimize_function_for_size_p (cfun)")
2101                  (const_string "V4SF")
2102                ]
2103                (const_string "TI")))])
2105 (define_split
2106   [(set (match_operand:TI 0 "nonimmediate_operand")
2107         (match_operand:TI 1 "general_operand"))]
2108   "reload_completed
2109    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2110   [(const_int 0)]
2111   "ix86_split_long_move (operands); DONE;")
2113 (define_insn "*movdi_internal"
2114   [(set (match_operand:DI 0 "nonimmediate_operand"
2115     "=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")
2116         (match_operand:DI 1 "general_operand"
2117     "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"))]
2118   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2120   switch (get_attr_type (insn))
2121     {
2122     case TYPE_MSKMOV:
2123       return "kmovq\t{%1, %0|%0, %1}";
2125     case TYPE_MULTI:
2126       return "#";
2128     case TYPE_MMX:
2129       return "pxor\t%0, %0";
2131     case TYPE_MMXMOV:
2132       /* Handle broken assemblers that require movd instead of movq.  */
2133       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2134           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2135         return "movd\t{%1, %0|%0, %1}";
2136       return "movq\t{%1, %0|%0, %1}";
2138     case TYPE_SSELOG1:
2139       if (GENERAL_REG_P (operands[0]))
2140         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2142       return standard_sse_constant_opcode (insn, operands[1]);
2144     case TYPE_SSEMOV:
2145       switch (get_attr_mode (insn))
2146         {
2147         case MODE_DI:
2148           /* Handle broken assemblers that require movd instead of movq.  */
2149           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2150               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2151             return "%vmovd\t{%1, %0|%0, %1}";
2152           return "%vmovq\t{%1, %0|%0, %1}";
2153         case MODE_TI:
2154           return "%vmovdqa\t{%1, %0|%0, %1}";
2155         case MODE_XI:
2156           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2158         case MODE_V2SF:
2159           gcc_assert (!TARGET_AVX);
2160           return "movlps\t{%1, %0|%0, %1}";
2161         case MODE_V4SF:
2162           return "%vmovaps\t{%1, %0|%0, %1}";
2164         default:
2165           gcc_unreachable ();
2166         }
2168     case TYPE_SSECVT:
2169       if (SSE_REG_P (operands[0]))
2170         return "movq2dq\t{%1, %0|%0, %1}";
2171       else
2172         return "movdq2q\t{%1, %0|%0, %1}";
2174     case TYPE_LEA:
2175       return "lea{q}\t{%E1, %0|%0, %E1}";
2177     case TYPE_IMOV:
2178       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2179       if (get_attr_mode (insn) == MODE_SI)
2180         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2181       else if (which_alternative == 4)
2182         return "movabs{q}\t{%1, %0|%0, %1}";
2183       else if (ix86_use_lea_for_mov (insn, operands))
2184         return "lea{q}\t{%E1, %0|%0, %E1}";
2185       else
2186         return "mov{q}\t{%1, %0|%0, %1}";
2188     default:
2189       gcc_unreachable ();
2190     }
2192   [(set (attr "isa")
2193      (cond [(eq_attr "alternative" "0,1")
2194               (const_string "nox64")
2195             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2196               (const_string "x64")
2197             (eq_attr "alternative" "17")
2198               (const_string "x64_sse4")
2199            ]
2200            (const_string "*")))
2201    (set (attr "type")
2202      (cond [(eq_attr "alternative" "0,1")
2203               (const_string "multi")
2204             (eq_attr "alternative" "6")
2205               (const_string "mmx")
2206             (eq_attr "alternative" "7,8,9,10,11")
2207               (const_string "mmxmov")
2208             (eq_attr "alternative" "12,17")
2209               (const_string "sselog1")
2210             (eq_attr "alternative" "13,14,15,16,18")
2211               (const_string "ssemov")
2212             (eq_attr "alternative" "19,20")
2213               (const_string "ssecvt")
2214             (eq_attr "alternative" "21,22,23,24")
2215               (const_string "mskmov")
2216             (and (match_operand 0 "register_operand")
2217                  (match_operand 1 "pic_32bit_operand"))
2218               (const_string "lea")
2219            ]
2220            (const_string "imov")))
2221    (set (attr "modrm")
2222      (if_then_else
2223        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2224          (const_string "0")
2225          (const_string "*")))
2226    (set (attr "length_immediate")
2227      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2228               (const_string "8")
2229             (eq_attr "alternative" "17")
2230               (const_string "1")
2231            ]
2232            (const_string "*")))
2233    (set (attr "prefix_rex")
2234      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2235        (const_string "1")
2236        (const_string "*")))
2237    (set (attr "prefix_extra")
2238      (if_then_else (eq_attr "alternative" "17")
2239        (const_string "1")
2240        (const_string "*")))
2241    (set (attr "prefix")
2242      (if_then_else (eq_attr "type" "sselog1,ssemov")
2243        (const_string "maybe_vex")
2244        (const_string "orig")))
2245    (set (attr "prefix_data16")
2246      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2247        (const_string "1")
2248        (const_string "*")))
2249    (set (attr "mode")
2250      (cond [(eq_attr "alternative" "2")
2251               (const_string "SI")
2252             (eq_attr "alternative" "12,13")
2253               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2254                           (match_operand 1 "ext_sse_reg_operand"))
2255                        (const_string "XI")
2256                      (ior (not (match_test "TARGET_SSE2"))
2257                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2258                        (const_string "V4SF")
2259                      (match_test "TARGET_AVX")
2260                        (const_string "TI")
2261                      (match_test "optimize_function_for_size_p (cfun)")
2262                        (const_string "V4SF")
2263                     ]
2264                     (const_string "TI"))
2266             (and (eq_attr "alternative" "14,15")
2267                  (not (match_test "TARGET_SSE2")))
2268               (const_string "V2SF")
2269             (eq_attr "alternative" "17")
2270               (const_string "TI")
2271            ]
2272            (const_string "DI")))])
2274 (define_split
2275   [(set (match_operand:DI 0 "nonimmediate_operand")
2276         (match_operand:DI 1 "general_operand"))]
2277   "!TARGET_64BIT && reload_completed
2278    && !(MMX_REG_P (operands[0])
2279         || SSE_REG_P (operands[0])
2280         || MASK_REG_P (operands[0]))
2281    && !(MMX_REG_P (operands[1])
2282         || SSE_REG_P (operands[1])
2283         || MASK_REG_P (operands[1]))"
2284   [(const_int 0)]
2285   "ix86_split_long_move (operands); DONE;")
2287 (define_insn "*movsi_internal"
2288   [(set (match_operand:SI 0 "nonimmediate_operand"
2289                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2290         (match_operand:SI 1 "general_operand"
2291                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2292   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2294   switch (get_attr_type (insn))
2295     {
2296     case TYPE_SSELOG1:
2297       if (GENERAL_REG_P (operands[0]))
2298         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2300       return standard_sse_constant_opcode (insn, operands[1]);
2302     case TYPE_MSKMOV:
2303       return "kmovd\t{%1, %0|%0, %1}";
2305     case TYPE_SSEMOV:
2306       switch (get_attr_mode (insn))
2307         {
2308         case MODE_SI:
2309           return "%vmovd\t{%1, %0|%0, %1}";
2310         case MODE_TI:
2311           return "%vmovdqa\t{%1, %0|%0, %1}";
2312         case MODE_XI:
2313           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2315         case MODE_V4SF:
2316           return "%vmovaps\t{%1, %0|%0, %1}";
2318         case MODE_SF:
2319           gcc_assert (!TARGET_AVX);
2320           return "movss\t{%1, %0|%0, %1}";
2322         default:
2323           gcc_unreachable ();
2324         }
2326     case TYPE_MMX:
2327       return "pxor\t%0, %0";
2329     case TYPE_MMXMOV:
2330       switch (get_attr_mode (insn))
2331         {
2332         case MODE_DI:
2333           return "movq\t{%1, %0|%0, %1}";
2334         case MODE_SI:
2335           return "movd\t{%1, %0|%0, %1}";
2337         default:
2338           gcc_unreachable ();
2339         }
2341     case TYPE_LEA:
2342       return "lea{l}\t{%E1, %0|%0, %E1}";
2344     case TYPE_IMOV:
2345       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2346       if (ix86_use_lea_for_mov (insn, operands))
2347         return "lea{l}\t{%E1, %0|%0, %E1}";
2348       else
2349         return "mov{l}\t{%1, %0|%0, %1}";
2351     default:
2352       gcc_unreachable ();
2353     }
2355   [(set (attr "isa")
2356      (if_then_else (eq_attr "alternative" "11")
2357        (const_string "sse4")
2358        (const_string "*")))
2359    (set (attr "type")
2360      (cond [(eq_attr "alternative" "2")
2361               (const_string "mmx")
2362             (eq_attr "alternative" "3,4,5")
2363               (const_string "mmxmov")
2364             (eq_attr "alternative" "6,11")
2365               (const_string "sselog1")
2366             (eq_attr "alternative" "7,8,9,10,12")
2367               (const_string "ssemov")
2368             (eq_attr "alternative" "13,14")
2369               (const_string "mskmov")
2370             (and (match_operand 0 "register_operand")
2371                  (match_operand 1 "pic_32bit_operand"))
2372               (const_string "lea")
2373            ]
2374            (const_string "imov")))
2375    (set (attr "length_immediate")
2376      (if_then_else (eq_attr "alternative" "11")
2377        (const_string "1")
2378        (const_string "*")))
2379    (set (attr "prefix_extra")
2380      (if_then_else (eq_attr "alternative" "11")
2381        (const_string "1")
2382        (const_string "*")))
2383    (set (attr "prefix")
2384      (if_then_else (eq_attr "type" "sselog1,ssemov")
2385        (const_string "maybe_vex")
2386        (const_string "orig")))
2387    (set (attr "prefix_data16")
2388      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2389        (const_string "1")
2390        (const_string "*")))
2391    (set (attr "mode")
2392      (cond [(eq_attr "alternative" "2,3")
2393               (const_string "DI")
2394             (eq_attr "alternative" "6,7")
2395               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2396                           (match_operand 1 "ext_sse_reg_operand"))
2397                        (const_string "XI")
2398                      (ior (not (match_test "TARGET_SSE2"))
2399                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2400                        (const_string "V4SF")
2401                      (match_test "TARGET_AVX")
2402                        (const_string "TI")
2403                      (match_test "optimize_function_for_size_p (cfun)")
2404                        (const_string "V4SF")
2405                     ]
2406                     (const_string "TI"))
2408             (and (eq_attr "alternative" "8,9")
2409                  (not (match_test "TARGET_SSE2")))
2410               (const_string "SF")
2411             (eq_attr "alternative" "11")
2412               (const_string "TI")
2413            ]
2414            (const_string "SI")))])
2416 (define_insn "kmovw"
2417   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2418         (unspec:HI
2419           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2420           UNSPEC_KMOV))]
2421   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2422   "@
2423    kmovw\t{%k1, %0|%0, %k1}
2424    kmovw\t{%1, %0|%0, %1}";
2425   [(set_attr "mode" "HI")
2426    (set_attr "type" "mskmov")
2427    (set_attr "prefix" "vex")])
2430 (define_insn "*movhi_internal"
2431   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2432         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2433   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2435   switch (get_attr_type (insn))
2436     {
2437     case TYPE_IMOVX:
2438       /* movzwl is faster than movw on p2 due to partial word stalls,
2439          though not as fast as an aligned movl.  */
2440       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2442     case TYPE_MSKMOV:
2443       switch (which_alternative)
2444         {
2445         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2446         case 5: return "kmovw\t{%1, %0|%0, %1}";
2447         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2448         default: gcc_unreachable ();
2449         }
2451     default:
2452       if (get_attr_mode (insn) == MODE_SI)
2453         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2454       else
2455         return "mov{w}\t{%1, %0|%0, %1}";
2456     }
2458   [(set (attr "type")
2459      (cond [(eq_attr "alternative" "4,5,6")
2460               (const_string "mskmov")
2461             (match_test "optimize_function_for_size_p (cfun)")
2462               (const_string "imov")
2463             (and (eq_attr "alternative" "0")
2464                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2465                       (not (match_test "TARGET_HIMODE_MATH"))))
2466               (const_string "imov")
2467             (and (eq_attr "alternative" "1,2")
2468                  (match_operand:HI 1 "aligned_operand"))
2469               (const_string "imov")
2470             (and (match_test "TARGET_MOVX")
2471                  (eq_attr "alternative" "0,2"))
2472               (const_string "imovx")
2473            ]
2474            (const_string "imov")))
2475     (set (attr "prefix")
2476       (if_then_else (eq_attr "alternative" "4,5,6")
2477         (const_string "vex")
2478         (const_string "orig")))
2479     (set (attr "mode")
2480       (cond [(eq_attr "type" "imovx")
2481                (const_string "SI")
2482              (and (eq_attr "alternative" "1,2")
2483                   (match_operand:HI 1 "aligned_operand"))
2484                (const_string "SI")
2485              (and (eq_attr "alternative" "0")
2486                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2487                        (not (match_test "TARGET_HIMODE_MATH"))))
2488                (const_string "SI")
2489             ]
2490             (const_string "HI")))])
2492 ;; Situation is quite tricky about when to choose full sized (SImode) move
2493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2494 ;; partial register dependency machines (such as AMD Athlon), where QImode
2495 ;; moves issue extra dependency and for partial register stalls machines
2496 ;; that don't use QImode patterns (and QImode move cause stall on the next
2497 ;; instruction).
2499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2500 ;; register stall machines with, where we use QImode instructions, since
2501 ;; partial register stall can be caused there.  Then we use movzx.
2503 (define_insn "*movqi_internal"
2504   [(set (match_operand:QI 0 "nonimmediate_operand"
2505                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2506         (match_operand:QI 1 "general_operand"
2507                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2508   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510   switch (get_attr_type (insn))
2511     {
2512     case TYPE_IMOVX:
2513       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2514       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2516     case TYPE_MSKMOV:
2517       switch (which_alternative)
2518         {
2519         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2520                                        : "kmovw\t{%k1, %0|%0, %k1}";
2521         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2522                                        : "kmovw\t{%1, %0|%0, %1}";
2523         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2524                                        : "kmovw\t{%1, %k0|%k0, %1}";
2525         case 10:
2526         case 11:
2527           gcc_assert (TARGET_AVX512DQ);
2528           return "kmovb\t{%1, %0|%0, %1}";
2529         default: gcc_unreachable ();
2530         }
2532     default:
2533       if (get_attr_mode (insn) == MODE_SI)
2534         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2535       else
2536         return "mov{b}\t{%1, %0|%0, %1}";
2537     }
2539   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2540    (set (attr "type")
2541      (cond [(eq_attr "alternative" "7,8,9,10,11")
2542               (const_string "mskmov")
2543             (and (eq_attr "alternative" "5")
2544                  (not (match_operand:QI 1 "aligned_operand")))
2545               (const_string "imovx")
2546             (match_test "optimize_function_for_size_p (cfun)")
2547               (const_string "imov")
2548             (and (eq_attr "alternative" "3")
2549                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2550                       (not (match_test "TARGET_QIMODE_MATH"))))
2551               (const_string "imov")
2552             (eq_attr "alternative" "3,5")
2553               (const_string "imovx")
2554             (and (match_test "TARGET_MOVX")
2555                  (eq_attr "alternative" "2"))
2556               (const_string "imovx")
2557            ]
2558            (const_string "imov")))
2559    (set (attr "prefix")
2560      (if_then_else (eq_attr "alternative" "7,8,9")
2561        (const_string "vex")
2562        (const_string "orig")))
2563    (set (attr "mode")
2564       (cond [(eq_attr "alternative" "3,4,5")
2565                (const_string "SI")
2566              (eq_attr "alternative" "6")
2567                (const_string "QI")
2568              (eq_attr "type" "imovx")
2569                (const_string "SI")
2570              (and (eq_attr "type" "imov")
2571                   (and (eq_attr "alternative" "0,1")
2572                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2573                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2574                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2575                (const_string "SI")
2576              ;; Avoid partial register stalls when not using QImode arithmetic
2577              (and (eq_attr "type" "imov")
2578                   (and (eq_attr "alternative" "0,1")
2579                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2580                             (not (match_test "TARGET_QIMODE_MATH")))))
2581                (const_string "SI")
2582            ]
2583            (const_string "QI")))])
2585 ;; Stores and loads of ax to arbitrary constant address.
2586 ;; We fake an second form of instruction to force reload to load address
2587 ;; into register when rax is not available
2588 (define_insn "*movabs<mode>_1"
2589   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2590         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2591   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2592   "@
2593    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2594    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2595   [(set_attr "type" "imov")
2596    (set_attr "modrm" "0,*")
2597    (set_attr "length_address" "8,0")
2598    (set_attr "length_immediate" "0,*")
2599    (set_attr "memory" "store")
2600    (set_attr "mode" "<MODE>")])
2602 (define_insn "*movabs<mode>_2"
2603   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2604         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2605   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2606   "@
2607    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2608    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2609   [(set_attr "type" "imov")
2610    (set_attr "modrm" "0,*")
2611    (set_attr "length_address" "8,0")
2612    (set_attr "length_immediate" "0")
2613    (set_attr "memory" "load")
2614    (set_attr "mode" "<MODE>")])
2616 (define_insn "*swap<mode>"
2617   [(set (match_operand:SWI48 0 "register_operand" "+r")
2618         (match_operand:SWI48 1 "register_operand" "+r"))
2619    (set (match_dup 1)
2620         (match_dup 0))]
2621   ""
2622   "xchg{<imodesuffix>}\t%1, %0"
2623   [(set_attr "type" "imov")
2624    (set_attr "mode" "<MODE>")
2625    (set_attr "pent_pair" "np")
2626    (set_attr "athlon_decode" "vector")
2627    (set_attr "amdfam10_decode" "double")
2628    (set_attr "bdver1_decode" "double")])
2630 (define_insn "*swap<mode>_1"
2631   [(set (match_operand:SWI12 0 "register_operand" "+r")
2632         (match_operand:SWI12 1 "register_operand" "+r"))
2633    (set (match_dup 1)
2634         (match_dup 0))]
2635   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2636   "xchg{l}\t%k1, %k0"
2637   [(set_attr "type" "imov")
2638    (set_attr "mode" "SI")
2639    (set_attr "pent_pair" "np")
2640    (set_attr "athlon_decode" "vector")
2641    (set_attr "amdfam10_decode" "double")
2642    (set_attr "bdver1_decode" "double")])
2644 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2645 ;; is disabled for AMDFAM10
2646 (define_insn "*swap<mode>_2"
2647   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2648         (match_operand:SWI12 1 "register_operand" "+<r>"))
2649    (set (match_dup 1)
2650         (match_dup 0))]
2651   "TARGET_PARTIAL_REG_STALL"
2652   "xchg{<imodesuffix>}\t%1, %0"
2653   [(set_attr "type" "imov")
2654    (set_attr "mode" "<MODE>")
2655    (set_attr "pent_pair" "np")
2656    (set_attr "athlon_decode" "vector")])
2658 (define_expand "movstrict<mode>"
2659   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2660         (match_operand:SWI12 1 "general_operand"))]
2661   ""
2663   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2664     FAIL;
2665   if (GET_CODE (operands[0]) == SUBREG
2666       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2667     FAIL;
2668   /* Don't generate memory->memory moves, go through a register */
2669   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2670     operands[1] = force_reg (<MODE>mode, operands[1]);
2673 (define_insn "*movstrict<mode>_1"
2674   [(set (strict_low_part
2675           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2676         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2677   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2678    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2679   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2680   [(set_attr "type" "imov")
2681    (set_attr "mode" "<MODE>")])
2683 (define_insn "*movstrict<mode>_xor"
2684   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2685         (match_operand:SWI12 1 "const0_operand"))
2686    (clobber (reg:CC FLAGS_REG))]
2687   "reload_completed"
2688   "xor{<imodesuffix>}\t%0, %0"
2689   [(set_attr "type" "alu1")
2690    (set_attr "mode" "<MODE>")
2691    (set_attr "length_immediate" "0")])
2693 (define_insn "*mov<mode>_extv_1"
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 "*movqi_extv_1"
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_insn "*mov<mode>_extzv_1"
2731   [(set (match_operand:SWI48 0 "register_operand" "=R")
2732         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2733                             (const_int 8)
2734                             (const_int 8)))]
2735   ""
2736   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2737   [(set_attr "type" "imovx")
2738    (set_attr "mode" "SI")])
2740 (define_insn "*movqi_extzv_2"
2741   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2742         (subreg:QI
2743           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2744                            (const_int 8)
2745                            (const_int 8)) 0))]
2746   ""
2748   switch (get_attr_type (insn))
2749     {
2750     case TYPE_IMOVX:
2751       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2752     default:
2753       return "mov{b}\t{%h1, %0|%0, %h1}";
2754     }
2756   [(set_attr "isa" "*,*,nox64")
2757    (set (attr "type")
2758      (if_then_else (and (match_operand:QI 0 "register_operand")
2759                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2760                              (match_test "TARGET_MOVX")))
2761         (const_string "imovx")
2762         (const_string "imov")))
2763    (set (attr "mode")
2764      (if_then_else (eq_attr "type" "imovx")
2765         (const_string "SI")
2766         (const_string "QI")))])
2768 (define_insn "mov<mode>_insv_1"
2769   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2770                              (const_int 8)
2771                              (const_int 8))
2772         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2773   ""
2775   if (CONST_INT_P (operands[1]))
2776     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2777   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2779   [(set_attr "isa" "*,nox64")
2780    (set_attr "type" "imov")
2781    (set_attr "mode" "QI")])
2783 (define_insn "*movqi_insv_2"
2784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2785                          (const_int 8)
2786                          (const_int 8))
2787         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2788                      (const_int 8)))]
2789   ""
2790   "mov{b}\t{%h1, %h0|%h0, %h1}"
2791   [(set_attr "type" "imov")
2792    (set_attr "mode" "QI")])
2794 ;; Floating point push instructions.
2796 (define_insn "*pushtf"
2797   [(set (match_operand:TF 0 "push_operand" "=<,<")
2798         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2799   "TARGET_64BIT || TARGET_SSE"
2801   /* This insn should be already split before reg-stack.  */
2802   gcc_unreachable ();
2804   [(set_attr "isa" "*,x64")
2805    (set_attr "type" "multi")
2806    (set_attr "unit" "sse,*")
2807    (set_attr "mode" "TF,DI")])
2809 ;; %%% Kill this when call knows how to work this out.
2810 (define_split
2811   [(set (match_operand:TF 0 "push_operand")
2812         (match_operand:TF 1 "sse_reg_operand"))]
2813   "TARGET_SSE && reload_completed"
2814   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2815    (set (match_dup 0) (match_dup 1))]
2817   /* Preserve memory attributes. */
2818   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2821 (define_insn "*pushxf"
2822   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2823         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2824   ""
2826   /* This insn should be already split before reg-stack.  */
2827   gcc_unreachable ();
2829   [(set_attr "type" "multi")
2830    (set_attr "unit" "i387,*,*,*")
2831    (set (attr "mode")
2832         (cond [(eq_attr "alternative" "1,2,3")
2833                  (if_then_else (match_test "TARGET_64BIT")
2834                    (const_string "DI")
2835                    (const_string "SI"))
2836               ]
2837               (const_string "XF")))
2838    (set (attr "preferred_for_size")
2839      (cond [(eq_attr "alternative" "1")
2840               (symbol_ref "false")]
2841            (symbol_ref "true")))])
2843 ;; %%% Kill this when call knows how to work this out.
2844 (define_split
2845   [(set (match_operand:XF 0 "push_operand")
2846         (match_operand:XF 1 "fp_register_operand"))]
2847   "reload_completed"
2848   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2849    (set (match_dup 0) (match_dup 1))]
2851   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2852   /* Preserve memory attributes. */
2853   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2856 (define_insn "*pushdf"
2857   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2858         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2859   ""
2861   /* This insn should be already split before reg-stack.  */
2862   gcc_unreachable ();
2864   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2865    (set_attr "type" "multi")
2866    (set_attr "unit" "i387,*,*,*,*,sse")
2867    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2868    (set (attr "preferred_for_size")
2869      (cond [(eq_attr "alternative" "1")
2870               (symbol_ref "false")]
2871            (symbol_ref "true")))
2872    (set (attr "preferred_for_speed")
2873      (cond [(eq_attr "alternative" "1")
2874               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2875            (symbol_ref "true")))])
2876    
2877 ;; %%% Kill this when call knows how to work this out.
2878 (define_split
2879   [(set (match_operand:DF 0 "push_operand")
2880         (match_operand:DF 1 "any_fp_register_operand"))]
2881   "reload_completed"
2882   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2883    (set (match_dup 0) (match_dup 1))]
2885   /* Preserve memory attributes. */
2886   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2889 (define_insn "*pushsf_rex64"
2890   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2891         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2892   "TARGET_64BIT"
2894   /* Anything else should be already split before reg-stack.  */
2895   gcc_assert (which_alternative == 1);
2896   return "push{q}\t%q1";
2898   [(set_attr "type" "multi,push,multi")
2899    (set_attr "unit" "i387,*,*")
2900    (set_attr "mode" "SF,DI,SF")])
2902 (define_insn "*pushsf"
2903   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2904         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2905   "!TARGET_64BIT"
2907   /* Anything else should be already split before reg-stack.  */
2908   gcc_assert (which_alternative == 1);
2909   return "push{l}\t%1";
2911   [(set_attr "type" "multi,push,multi")
2912    (set_attr "unit" "i387,*,*")
2913    (set_attr "mode" "SF,SI,SF")])
2915 ;; %%% Kill this when call knows how to work this out.
2916 (define_split
2917   [(set (match_operand:SF 0 "push_operand")
2918         (match_operand:SF 1 "any_fp_register_operand"))]
2919   "reload_completed"
2920   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2921    (set (match_dup 0) (match_dup 1))]
2923   rtx op = XEXP (operands[0], 0);
2924   if (GET_CODE (op) == PRE_DEC)
2925     {
2926       gcc_assert (!TARGET_64BIT);
2927       op = GEN_INT (-4);
2928     }
2929   else
2930     {
2931       op = XEXP (XEXP (op, 1), 1);
2932       gcc_assert (CONST_INT_P (op));
2933     }
2934   operands[2] = op;
2935   /* Preserve memory attributes. */
2936   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2939 (define_split
2940   [(set (match_operand:SF 0 "push_operand")
2941         (match_operand:SF 1 "memory_operand"))]
2942   "reload_completed
2943    && (operands[2] = find_constant_src (insn))"
2944   [(set (match_dup 0) (match_dup 2))])
2946 (define_split
2947   [(set (match_operand 0 "push_operand")
2948         (match_operand 1 "general_operand"))]
2949   "reload_completed
2950    && (GET_MODE (operands[0]) == TFmode
2951        || GET_MODE (operands[0]) == XFmode
2952        || GET_MODE (operands[0]) == DFmode)
2953    && !ANY_FP_REG_P (operands[1])"
2954   [(const_int 0)]
2955   "ix86_split_long_move (operands); DONE;")
2957 ;; Floating point move instructions.
2959 (define_expand "movtf"
2960   [(set (match_operand:TF 0 "nonimmediate_operand")
2961         (match_operand:TF 1 "nonimmediate_operand"))]
2962   "TARGET_64BIT || TARGET_SSE"
2963   "ix86_expand_move (TFmode, operands); DONE;")
2965 (define_expand "mov<mode>"
2966   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2967         (match_operand:X87MODEF 1 "general_operand"))]
2968   ""
2969   "ix86_expand_move (<MODE>mode, operands); DONE;")
2971 (define_insn "*movtf_internal"
2972   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2973         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2974   "(TARGET_64BIT || TARGET_SSE)
2975    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2976    && (!can_create_pseudo_p ()
2977        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2978        || GET_CODE (operands[1]) != CONST_DOUBLE
2979        || (optimize_function_for_size_p (cfun)
2980            && standard_sse_constant_p (operands[1])
2981            && !memory_operand (operands[0], TFmode))
2982        || (!TARGET_MEMORY_MISMATCH_STALL
2983            && memory_operand (operands[0], TFmode)))"
2985   switch (get_attr_type (insn))
2986     {
2987     case TYPE_SSELOG1:
2988       return standard_sse_constant_opcode (insn, operands[1]);
2990     case TYPE_SSEMOV:
2991       /* Handle misaligned load/store since we
2992          don't have movmisaligntf pattern. */
2993       if (misaligned_operand (operands[0], TFmode)
2994           || misaligned_operand (operands[1], TFmode))
2995         {
2996           if (get_attr_mode (insn) == MODE_V4SF)
2997             return "%vmovups\t{%1, %0|%0, %1}";
2998           else
2999             return "%vmovdqu\t{%1, %0|%0, %1}";
3000         }
3001       else
3002         {
3003           if (get_attr_mode (insn) == MODE_V4SF)
3004             return "%vmovaps\t{%1, %0|%0, %1}";
3005           else
3006             return "%vmovdqa\t{%1, %0|%0, %1}";
3007         }
3009     case TYPE_MULTI:
3010         return "#";
3012     default:
3013       gcc_unreachable ();
3014     }
3016   [(set_attr "isa" "*,*,*,x64,x64")
3017    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3018    (set (attr "prefix")
3019      (if_then_else (eq_attr "type" "sselog1,ssemov")
3020        (const_string "maybe_vex")
3021        (const_string "orig")))
3022    (set (attr "mode")
3023         (cond [(eq_attr "alternative" "3,4")
3024                  (const_string "DI")
3025                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3026                  (const_string "V4SF")
3027                (and (eq_attr "alternative" "2")
3028                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3029                  (const_string "V4SF")
3030                (match_test "TARGET_AVX")
3031                  (const_string "TI")
3032                (ior (not (match_test "TARGET_SSE2"))
3033                     (match_test "optimize_function_for_size_p (cfun)"))
3034                  (const_string "V4SF")
3035                ]
3036                (const_string "TI")))])
3038 ;; Possible store forwarding (partial memory) stall
3039 ;; in alternatives 4, 6, 7 and 8.
3040 (define_insn "*movxf_internal"
3041   [(set (match_operand:XF 0 "nonimmediate_operand"
3042          "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3043         (match_operand:XF 1 "general_operand"
3044          "fm,f,G,roF,r , *roF,*r,F ,C"))]
3045   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3046    && (!can_create_pseudo_p ()
3047        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3048        || GET_CODE (operands[1]) != CONST_DOUBLE
3049        || (optimize_function_for_size_p (cfun)
3050            && standard_80387_constant_p (operands[1]) > 0
3051            && !memory_operand (operands[0], XFmode))
3052        || (!TARGET_MEMORY_MISMATCH_STALL
3053            && memory_operand (operands[0], XFmode)))"
3055   switch (get_attr_type (insn))
3056     {
3057     case TYPE_FMOV:
3058       if (which_alternative == 2)
3059         return standard_80387_constant_opcode (operands[1]);
3060       return output_387_reg_move (insn, operands);
3062     case TYPE_MULTI:
3063       return "#";
3065     default:
3066       gcc_unreachable ();
3067     }
3069   [(set (attr "isa")
3070         (cond [(eq_attr "alternative" "7")
3071                  (const_string "nox64")
3072                (eq_attr "alternative" "8")
3073                  (const_string "x64")
3074               ]
3075               (const_string "*")))
3076    (set (attr "type")
3077         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3078                  (const_string "multi")
3079               ]
3080               (const_string "fmov")))
3081    (set (attr "mode")
3082         (cond [(eq_attr "alternative" "3,4,5,6,7,8")
3083                  (if_then_else (match_test "TARGET_64BIT")
3084                    (const_string "DI")
3085                    (const_string "SI"))
3086               ]
3087               (const_string "XF")))
3088    (set (attr "preferred_for_size")
3089      (cond [(eq_attr "alternative" "3,4")
3090               (symbol_ref "false")]
3091            (symbol_ref "true")))])
3092    
3093 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3094 (define_insn "*movdf_internal"
3095   [(set (match_operand:DF 0 "nonimmediate_operand"
3096     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3097         (match_operand:DF 1 "general_operand"
3098     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3099   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3100    && (!can_create_pseudo_p ()
3101        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3102        || GET_CODE (operands[1]) != CONST_DOUBLE
3103        || (optimize_function_for_size_p (cfun)
3104            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3105                 && standard_80387_constant_p (operands[1]) > 0)
3106                || (TARGET_SSE2 && TARGET_SSE_MATH
3107                    && standard_sse_constant_p (operands[1])))
3108            && !memory_operand (operands[0], DFmode))
3109        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3110            && memory_operand (operands[0], DFmode)))"
3112   switch (get_attr_type (insn))
3113     {
3114     case TYPE_FMOV:
3115       if (which_alternative == 2)
3116         return standard_80387_constant_opcode (operands[1]);
3117       return output_387_reg_move (insn, operands);
3119     case TYPE_MULTI:
3120       return "#";
3122     case TYPE_IMOV:
3123       if (get_attr_mode (insn) == MODE_SI)
3124         return "mov{l}\t{%1, %k0|%k0, %1}";
3125       else if (which_alternative == 11)
3126         return "movabs{q}\t{%1, %0|%0, %1}";
3127       else
3128         return "mov{q}\t{%1, %0|%0, %1}";
3130     case TYPE_SSELOG1:
3131       return standard_sse_constant_opcode (insn, operands[1]);
3133     case TYPE_SSEMOV:
3134       switch (get_attr_mode (insn))
3135         {
3136         case MODE_DF:
3137           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3138             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3139           return "%vmovsd\t{%1, %0|%0, %1}";
3141         case MODE_V4SF:
3142           return "%vmovaps\t{%1, %0|%0, %1}";
3143         case MODE_V8DF:
3144           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3145         case MODE_V2DF:
3146           return "%vmovapd\t{%1, %0|%0, %1}";
3148         case MODE_V2SF:
3149           gcc_assert (!TARGET_AVX);
3150           return "movlps\t{%1, %0|%0, %1}";
3151         case MODE_V1DF:
3152           gcc_assert (!TARGET_AVX);
3153           return "movlpd\t{%1, %0|%0, %1}";
3155         case MODE_DI:
3156           /* Handle broken assemblers that require movd instead of movq.  */
3157           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3158               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3159             return "%vmovd\t{%1, %0|%0, %1}";
3160           return "%vmovq\t{%1, %0|%0, %1}";
3162         default:
3163           gcc_unreachable ();
3164         }
3166     default:
3167       gcc_unreachable ();
3168     }
3170   [(set (attr "isa")
3171         (cond [(eq_attr "alternative" "3,4,5,6,7")
3172                  (const_string "nox64")
3173                (eq_attr "alternative" "8,9,10,11,20,21")
3174                  (const_string "x64")
3175                (eq_attr "alternative" "12,13,14,15")
3176                  (const_string "sse2")
3177               ]
3178               (const_string "*")))
3179    (set (attr "type")
3180         (cond [(eq_attr "alternative" "0,1,2")
3181                  (const_string "fmov")
3182                (eq_attr "alternative" "3,4,5,6,7")
3183                  (const_string "multi")
3184                (eq_attr "alternative" "8,9,10,11")
3185                  (const_string "imov")
3186                (eq_attr "alternative" "12,16")
3187                  (const_string "sselog1")
3188               ]
3189               (const_string "ssemov")))
3190    (set (attr "modrm")
3191      (if_then_else (eq_attr "alternative" "11")
3192        (const_string "0")
3193        (const_string "*")))
3194    (set (attr "length_immediate")
3195      (if_then_else (eq_attr "alternative" "11")
3196        (const_string "8")
3197        (const_string "*")))
3198    (set (attr "prefix")
3199      (if_then_else (eq_attr "type" "sselog1,ssemov")
3200        (const_string "maybe_vex")
3201        (const_string "orig")))
3202    (set (attr "prefix_data16")
3203      (if_then_else
3204        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3205             (eq_attr "mode" "V1DF"))
3206        (const_string "1")
3207        (const_string "*")))
3208    (set (attr "mode")
3209         (cond [(eq_attr "alternative" "3,4,5,6,7,10")
3210                  (const_string "SI")
3211                (eq_attr "alternative" "8,9,11,20,21")
3212                  (const_string "DI")
3214                /* xorps is one byte shorter for non-AVX targets.  */
3215                (eq_attr "alternative" "12,16")
3216                  (cond [(not (match_test "TARGET_SSE2"))
3217                           (const_string "V4SF")
3218                         (match_test "TARGET_AVX512F")
3219                           (const_string "XI")
3220                         (match_test "TARGET_AVX")
3221                           (const_string "V2DF")
3222                         (match_test "optimize_function_for_size_p (cfun)")
3223                           (const_string "V4SF")
3224                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3225                           (const_string "TI")
3226                        ]
3227                        (const_string "V2DF"))
3229                /* For architectures resolving dependencies on
3230                   whole SSE registers use movapd to break dependency
3231                   chains, otherwise use short move to avoid extra work.  */
3233                /* movaps is one byte shorter for non-AVX targets.  */
3234                (eq_attr "alternative" "13,17")
3235                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3236                              (match_operand 1 "ext_sse_reg_operand"))
3237                           (const_string "V8DF")
3238                         (ior (not (match_test "TARGET_SSE2"))
3239                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3240                           (const_string "V4SF")
3241                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3242                           (const_string "V2DF")
3243                         (match_test "TARGET_AVX")
3244                           (const_string "DF")
3245                         (match_test "optimize_function_for_size_p (cfun)")
3246                           (const_string "V4SF")
3247                        ]
3248                        (const_string "DF"))
3250                /* For architectures resolving dependencies on register
3251                   parts we may avoid extra work to zero out upper part
3252                   of register.  */
3253                (eq_attr "alternative" "14,18")
3254                  (cond [(not (match_test "TARGET_SSE2"))
3255                           (const_string "V2SF")
3256                         (match_test "TARGET_AVX")
3257                           (const_string "DF")
3258                         (match_test "TARGET_SSE_SPLIT_REGS")
3259                           (const_string "V1DF")
3260                        ]
3261                        (const_string "DF"))
3263                (and (eq_attr "alternative" "15,19")
3264                     (not (match_test "TARGET_SSE2")))
3265                  (const_string "V2SF")
3266               ]
3267               (const_string "DF")))
3268    (set (attr "preferred_for_size")
3269      (cond [(eq_attr "alternative" "3,4")
3270               (symbol_ref "false")]
3271            (symbol_ref "true")))
3272    (set (attr "preferred_for_speed")
3273      (cond [(eq_attr "alternative" "3,4")
3274               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3275            (symbol_ref "true")))])
3277 (define_insn "*movsf_internal"
3278   [(set (match_operand:SF 0 "nonimmediate_operand"
3279           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3280         (match_operand:SF 1 "general_operand"
3281           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3282   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3283    && (!can_create_pseudo_p ()
3284        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3285        || GET_CODE (operands[1]) != CONST_DOUBLE
3286        || (optimize_function_for_size_p (cfun)
3287            && ((!TARGET_SSE_MATH
3288                 && standard_80387_constant_p (operands[1]) > 0)
3289                || (TARGET_SSE_MATH
3290                    && standard_sse_constant_p (operands[1]))))
3291        || memory_operand (operands[0], SFmode))"
3293   switch (get_attr_type (insn))
3294     {
3295     case TYPE_FMOV:
3296       if (which_alternative == 2)
3297         return standard_80387_constant_opcode (operands[1]);
3298       return output_387_reg_move (insn, operands);
3300     case TYPE_IMOV:
3301       return "mov{l}\t{%1, %0|%0, %1}";
3303     case TYPE_SSELOG1:
3304       return standard_sse_constant_opcode (insn, operands[1]);
3306     case TYPE_SSEMOV:
3307       switch (get_attr_mode (insn))
3308         {
3309         case MODE_SF:
3310           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3311             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3312           return "%vmovss\t{%1, %0|%0, %1}";
3314         case MODE_V16SF:
3315           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3316         case MODE_V4SF:
3317           return "%vmovaps\t{%1, %0|%0, %1}";
3319         case MODE_SI:
3320           return "%vmovd\t{%1, %0|%0, %1}";
3322         default:
3323           gcc_unreachable ();
3324         }
3326     case TYPE_MMXMOV:
3327       switch (get_attr_mode (insn))
3328         {
3329         case MODE_DI:
3330           return "movq\t{%1, %0|%0, %1}";
3331         case MODE_SI:
3332           return "movd\t{%1, %0|%0, %1}";
3334         default:
3335           gcc_unreachable ();
3336         }
3338     default:
3339       gcc_unreachable ();
3340     }
3342   [(set (attr "type")
3343         (cond [(eq_attr "alternative" "0,1,2")
3344                  (const_string "fmov")
3345                (eq_attr "alternative" "3,4")
3346                  (const_string "imov")
3347                (eq_attr "alternative" "5")
3348                  (const_string "sselog1")
3349                (eq_attr "alternative" "11,12,13,14,15")
3350                  (const_string "mmxmov")
3351               ]
3352               (const_string "ssemov")))
3353    (set (attr "prefix")
3354      (if_then_else (eq_attr "type" "sselog1,ssemov")
3355        (const_string "maybe_vex")
3356        (const_string "orig")))
3357    (set (attr "prefix_data16")
3358      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3359        (const_string "1")
3360        (const_string "*")))
3361    (set (attr "mode")
3362         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3363                  (const_string "SI")
3364                (eq_attr "alternative" "11")
3365                  (const_string "DI")
3366                (eq_attr "alternative" "5")
3367                  (cond [(not (match_test "TARGET_SSE2"))
3368                           (const_string "V4SF")
3369                         (match_test "TARGET_AVX512F")
3370                           (const_string "V16SF")
3371                         (match_test "TARGET_AVX")
3372                           (const_string "V4SF")
3373                         (match_test "optimize_function_for_size_p (cfun)")
3374                           (const_string "V4SF")
3375                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3376                           (const_string "TI")
3377                        ]
3378                        (const_string "V4SF"))
3380                /* For architectures resolving dependencies on
3381                   whole SSE registers use APS move to break dependency
3382                   chains, otherwise use short move to avoid extra work.
3384                   Do the same for architectures resolving dependencies on
3385                   the parts.  While in DF mode it is better to always handle
3386                   just register parts, the SF mode is different due to lack
3387                   of instructions to load just part of the register.  It is
3388                   better to maintain the whole registers in single format
3389                   to avoid problems on using packed logical operations.  */
3390                (eq_attr "alternative" "6")
3391                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3392                               (match_operand 1 "ext_sse_reg_operand"))
3393                           (const_string "V16SF")
3394                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3395                              (match_test "TARGET_SSE_SPLIT_REGS"))
3396                           (const_string "V4SF")
3397                        ]
3398                        (const_string "SF"))
3399               ]
3400               (const_string "SF")))])
3402 (define_split
3403   [(set (match_operand 0 "any_fp_register_operand")
3404         (match_operand 1 "memory_operand"))]
3405   "reload_completed
3406    && (GET_MODE (operands[0]) == TFmode
3407        || GET_MODE (operands[0]) == XFmode
3408        || GET_MODE (operands[0]) == DFmode
3409        || GET_MODE (operands[0]) == SFmode)
3410    && (operands[2] = find_constant_src (insn))"
3411   [(set (match_dup 0) (match_dup 2))]
3413   rtx c = operands[2];
3414   int r = REGNO (operands[0]);
3416   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3417       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3418     FAIL;
3421 (define_split
3422   [(set (match_operand 0 "any_fp_register_operand")
3423         (float_extend (match_operand 1 "memory_operand")))]
3424   "reload_completed
3425    && (GET_MODE (operands[0]) == TFmode
3426        || GET_MODE (operands[0]) == XFmode
3427        || GET_MODE (operands[0]) == DFmode)
3428    && (operands[2] = find_constant_src (insn))"
3429   [(set (match_dup 0) (match_dup 2))]
3431   rtx c = operands[2];
3432   int r = REGNO (operands[0]);
3434   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3435       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3436     FAIL;
3439 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3440 (define_split
3441   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3442         (match_operand:X87MODEF 1 "immediate_operand"))]
3443   "reload_completed
3444    && (standard_80387_constant_p (operands[1]) == 8
3445        || standard_80387_constant_p (operands[1]) == 9)"
3446   [(set (match_dup 0)(match_dup 1))
3447    (set (match_dup 0)
3448         (neg:X87MODEF (match_dup 0)))]
3450   REAL_VALUE_TYPE r;
3452   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3453   if (real_isnegzero (&r))
3454     operands[1] = CONST0_RTX (<MODE>mode);
3455   else
3456     operands[1] = CONST1_RTX (<MODE>mode);
3459 (define_split
3460   [(set (match_operand 0 "nonimmediate_operand")
3461         (match_operand 1 "general_operand"))]
3462   "reload_completed
3463    && (GET_MODE (operands[0]) == TFmode
3464        || GET_MODE (operands[0]) == XFmode
3465        || GET_MODE (operands[0]) == DFmode)
3466    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3467   [(const_int 0)]
3468   "ix86_split_long_move (operands); DONE;")
3470 (define_insn "swapxf"
3471   [(set (match_operand:XF 0 "register_operand" "+f")
3472         (match_operand:XF 1 "register_operand" "+f"))
3473    (set (match_dup 1)
3474         (match_dup 0))]
3475   "TARGET_80387"
3477   if (STACK_TOP_P (operands[0]))
3478     return "fxch\t%1";
3479   else
3480     return "fxch\t%0";
3482   [(set_attr "type" "fxch")
3483    (set_attr "mode" "XF")])
3485 (define_insn "*swap<mode>"
3486   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3487         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3488    (set (match_dup 1)
3489         (match_dup 0))]
3490   "TARGET_80387 || reload_completed"
3492   if (STACK_TOP_P (operands[0]))
3493     return "fxch\t%1";
3494   else
3495     return "fxch\t%0";
3497   [(set_attr "type" "fxch")
3498    (set_attr "mode" "<MODE>")])
3500 ;; Zero extension instructions
3502 (define_expand "zero_extendsidi2"
3503   [(set (match_operand:DI 0 "nonimmediate_operand")
3504         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3506 (define_insn "*zero_extendsidi2"
3507   [(set (match_operand:DI 0 "nonimmediate_operand"
3508                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3509         (zero_extend:DI
3510          (match_operand:SI 1 "x86_64_zext_operand"
3511                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3512   ""
3514   switch (get_attr_type (insn))
3515     {
3516     case TYPE_IMOVX:
3517       if (ix86_use_lea_for_mov (insn, operands))
3518         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3519       else
3520         return "mov{l}\t{%1, %k0|%k0, %1}";
3522     case TYPE_MULTI:
3523       return "#";
3525     case TYPE_MMXMOV:
3526       return "movd\t{%1, %0|%0, %1}";
3528     case TYPE_SSELOG1:
3529       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3531     case TYPE_SSEMOV:
3532       if (GENERAL_REG_P (operands[0]))
3533         return "%vmovd\t{%1, %k0|%k0, %1}";
3535       return "%vmovd\t{%1, %0|%0, %1}";
3537     default:
3538       gcc_unreachable ();
3539     }
3541   [(set (attr "isa")
3542      (cond [(eq_attr "alternative" "0,1,2")
3543               (const_string "nox64")
3544             (eq_attr "alternative" "3,7")
3545               (const_string "x64")
3546             (eq_attr "alternative" "8")
3547               (const_string "x64_sse4")
3548             (eq_attr "alternative" "10")
3549               (const_string "sse2")
3550            ]
3551            (const_string "*")))
3552    (set (attr "type")
3553      (cond [(eq_attr "alternative" "0,1,2,4")
3554               (const_string "multi")
3555             (eq_attr "alternative" "5,6")
3556               (const_string "mmxmov")
3557             (eq_attr "alternative" "7,9,10")
3558               (const_string "ssemov")
3559             (eq_attr "alternative" "8")
3560               (const_string "sselog1")
3561            ]
3562            (const_string "imovx")))
3563    (set (attr "prefix_extra")
3564      (if_then_else (eq_attr "alternative" "8")
3565        (const_string "1")
3566        (const_string "*")))
3567    (set (attr "length_immediate")
3568      (if_then_else (eq_attr "alternative" "8")
3569        (const_string "1")
3570        (const_string "*")))
3571    (set (attr "prefix")
3572      (if_then_else (eq_attr "type" "ssemov,sselog1")
3573        (const_string "maybe_vex")
3574        (const_string "orig")))
3575    (set (attr "prefix_0f")
3576      (if_then_else (eq_attr "type" "imovx")
3577        (const_string "0")
3578        (const_string "*")))
3579    (set (attr "mode")
3580      (cond [(eq_attr "alternative" "5,6")
3581               (const_string "DI")
3582             (eq_attr "alternative" "7,8,9")
3583               (const_string "TI")
3584            ]
3585            (const_string "SI")))])
3587 (define_split
3588   [(set (match_operand:DI 0 "memory_operand")
3589         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3590   "reload_completed"
3591   [(set (match_dup 4) (const_int 0))]
3592   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3594 (define_split
3595   [(set (match_operand:DI 0 "register_operand")
3596         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3597   "!TARGET_64BIT && reload_completed
3598    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3599    && true_regnum (operands[0]) == true_regnum (operands[1])"
3600   [(set (match_dup 4) (const_int 0))]
3601   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3603 (define_split
3604   [(set (match_operand:DI 0 "nonimmediate_operand")
3605         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3606   "!TARGET_64BIT && reload_completed
3607    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3609   [(set (match_dup 3) (match_dup 1))
3610    (set (match_dup 4) (const_int 0))]
3611   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613 (define_insn "zero_extend<mode>di2"
3614   [(set (match_operand:DI 0 "register_operand" "=r")
3615         (zero_extend:DI
3616          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3617   "TARGET_64BIT"
3618   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3619   [(set_attr "type" "imovx")
3620    (set_attr "mode" "SI")])
3622 (define_expand "zero_extend<mode>si2"
3623   [(set (match_operand:SI 0 "register_operand")
3624         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3625   ""
3627   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3628     {
3629       operands[1] = force_reg (<MODE>mode, operands[1]);
3630       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3631       DONE;
3632     }
3635 (define_insn_and_split "zero_extend<mode>si2_and"
3636   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3637         (zero_extend:SI
3638           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3639    (clobber (reg:CC FLAGS_REG))]
3640   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3641   "#"
3642   "&& reload_completed"
3643   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3644               (clobber (reg:CC FLAGS_REG))])]
3646   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3647     {
3648       ix86_expand_clear (operands[0]);
3650       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3651       emit_insn (gen_movstrict<mode>
3652                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3653       DONE;
3654     }
3656   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3658   [(set_attr "type" "alu1")
3659    (set_attr "mode" "SI")])
3661 (define_insn "*zero_extend<mode>si2"
3662   [(set (match_operand:SI 0 "register_operand" "=r")
3663         (zero_extend:SI
3664           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3665   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3666   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3667   [(set_attr "type" "imovx")
3668    (set_attr "mode" "SI")])
3670 (define_expand "zero_extendqihi2"
3671   [(set (match_operand:HI 0 "register_operand")
3672         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3673   ""
3675   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3676     {
3677       operands[1] = force_reg (QImode, operands[1]);
3678       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3679       DONE;
3680     }
3683 (define_insn_and_split "zero_extendqihi2_and"
3684   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3685         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3686    (clobber (reg:CC FLAGS_REG))]
3687   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3688   "#"
3689   "&& reload_completed"
3690   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3691               (clobber (reg:CC FLAGS_REG))])]
3693   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3694     {
3695       ix86_expand_clear (operands[0]);
3697       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3698       emit_insn (gen_movstrictqi
3699                   (gen_lowpart (QImode, operands[0]), operands[1]));
3700       DONE;
3701     }
3703   operands[0] = gen_lowpart (SImode, operands[0]);
3705   [(set_attr "type" "alu1")
3706    (set_attr "mode" "SI")])
3708 ; zero extend to SImode to avoid partial register stalls
3709 (define_insn "*zero_extendqihi2"
3710   [(set (match_operand:HI 0 "register_operand" "=r")
3711         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3712   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3713   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3714   [(set_attr "type" "imovx")
3715    (set_attr "mode" "SI")])
3717 ;; Sign extension instructions
3719 (define_expand "extendsidi2"
3720   [(set (match_operand:DI 0 "register_operand")
3721         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3722   ""
3724   if (!TARGET_64BIT)
3725     {
3726       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3727       DONE;
3728     }
3731 (define_insn "*extendsidi2_rex64"
3732   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3733         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3734   "TARGET_64BIT"
3735   "@
3736    {cltq|cdqe}
3737    movs{lq|x}\t{%1, %0|%0, %1}"
3738   [(set_attr "type" "imovx")
3739    (set_attr "mode" "DI")
3740    (set_attr "prefix_0f" "0")
3741    (set_attr "modrm" "0,1")])
3743 (define_insn "extendsidi2_1"
3744   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3745         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3746    (clobber (reg:CC FLAGS_REG))
3747    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3748   "!TARGET_64BIT"
3749   "#")
3751 ;; Split the memory case.  If the source register doesn't die, it will stay
3752 ;; this way, if it does die, following peephole2s take care of it.
3753 (define_split
3754   [(set (match_operand:DI 0 "memory_operand")
3755         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3756    (clobber (reg:CC FLAGS_REG))
3757    (clobber (match_operand:SI 2 "register_operand"))]
3758   "reload_completed"
3759   [(const_int 0)]
3761   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3763   emit_move_insn (operands[3], operands[1]);
3765   /* Generate a cltd if possible and doing so it profitable.  */
3766   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3767       && true_regnum (operands[1]) == AX_REG
3768       && true_regnum (operands[2]) == DX_REG)
3769     {
3770       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3771     }
3772   else
3773     {
3774       emit_move_insn (operands[2], operands[1]);
3775       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3776     }
3777   emit_move_insn (operands[4], operands[2]);
3778   DONE;
3781 ;; Peepholes for the case where the source register does die, after
3782 ;; being split with the above splitter.
3783 (define_peephole2
3784   [(set (match_operand:SI 0 "memory_operand")
3785         (match_operand:SI 1 "register_operand"))
3786    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3787    (parallel [(set (match_dup 2)
3788                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3789                (clobber (reg:CC FLAGS_REG))])
3790    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3791   "REGNO (operands[1]) != REGNO (operands[2])
3792    && peep2_reg_dead_p (2, operands[1])
3793    && peep2_reg_dead_p (4, operands[2])
3794    && !reg_mentioned_p (operands[2], operands[3])"
3795   [(set (match_dup 0) (match_dup 1))
3796    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3797               (clobber (reg:CC FLAGS_REG))])
3798    (set (match_dup 3) (match_dup 1))])
3800 (define_peephole2
3801   [(set (match_operand:SI 0 "memory_operand")
3802         (match_operand:SI 1 "register_operand"))
3803    (parallel [(set (match_operand:SI 2 "register_operand")
3804                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3805                (clobber (reg:CC FLAGS_REG))])
3806    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3807   "/* cltd is shorter than sarl $31, %eax */
3808    !optimize_function_for_size_p (cfun)
3809    && true_regnum (operands[1]) == AX_REG
3810    && true_regnum (operands[2]) == DX_REG
3811    && peep2_reg_dead_p (2, operands[1])
3812    && peep2_reg_dead_p (3, operands[2])
3813    && !reg_mentioned_p (operands[2], operands[3])"
3814   [(set (match_dup 0) (match_dup 1))
3815    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3816               (clobber (reg:CC FLAGS_REG))])
3817    (set (match_dup 3) (match_dup 1))])
3819 ;; Extend to register case.  Optimize case where source and destination
3820 ;; registers match and cases where we can use cltd.
3821 (define_split
3822   [(set (match_operand:DI 0 "register_operand")
3823         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3824    (clobber (reg:CC FLAGS_REG))
3825    (clobber (match_scratch:SI 2))]
3826   "reload_completed"
3827   [(const_int 0)]
3829   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3831   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3832     emit_move_insn (operands[3], operands[1]);
3834   /* Generate a cltd if possible and doing so it profitable.  */
3835   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3836       && true_regnum (operands[3]) == AX_REG
3837       && true_regnum (operands[4]) == DX_REG)
3838     {
3839       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3840       DONE;
3841     }
3843   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3844     emit_move_insn (operands[4], operands[1]);
3846   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3847   DONE;
3850 (define_insn "extend<mode>di2"
3851   [(set (match_operand:DI 0 "register_operand" "=r")
3852         (sign_extend:DI
3853          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3854   "TARGET_64BIT"
3855   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3856   [(set_attr "type" "imovx")
3857    (set_attr "mode" "DI")])
3859 (define_insn "extendhisi2"
3860   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3861         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3862   ""
3864   switch (get_attr_prefix_0f (insn))
3865     {
3866     case 0:
3867       return "{cwtl|cwde}";
3868     default:
3869       return "movs{wl|x}\t{%1, %0|%0, %1}";
3870     }
3872   [(set_attr "type" "imovx")
3873    (set_attr "mode" "SI")
3874    (set (attr "prefix_0f")
3875      ;; movsx is short decodable while cwtl is vector decoded.
3876      (if_then_else (and (eq_attr "cpu" "!k6")
3877                         (eq_attr "alternative" "0"))
3878         (const_string "0")
3879         (const_string "1")))
3880    (set (attr "modrm")
3881      (if_then_else (eq_attr "prefix_0f" "0")
3882         (const_string "0")
3883         (const_string "1")))])
3885 (define_insn "*extendhisi2_zext"
3886   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3887         (zero_extend:DI
3888          (sign_extend:SI
3889           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3890   "TARGET_64BIT"
3892   switch (get_attr_prefix_0f (insn))
3893     {
3894     case 0:
3895       return "{cwtl|cwde}";
3896     default:
3897       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3898     }
3900   [(set_attr "type" "imovx")
3901    (set_attr "mode" "SI")
3902    (set (attr "prefix_0f")
3903      ;; movsx is short decodable while cwtl is vector decoded.
3904      (if_then_else (and (eq_attr "cpu" "!k6")
3905                         (eq_attr "alternative" "0"))
3906         (const_string "0")
3907         (const_string "1")))
3908    (set (attr "modrm")
3909      (if_then_else (eq_attr "prefix_0f" "0")
3910         (const_string "0")
3911         (const_string "1")))])
3913 (define_insn "extendqisi2"
3914   [(set (match_operand:SI 0 "register_operand" "=r")
3915         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3916   ""
3917   "movs{bl|x}\t{%1, %0|%0, %1}"
3918    [(set_attr "type" "imovx")
3919     (set_attr "mode" "SI")])
3921 (define_insn "*extendqisi2_zext"
3922   [(set (match_operand:DI 0 "register_operand" "=r")
3923         (zero_extend:DI
3924           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3925   "TARGET_64BIT"
3926   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3927    [(set_attr "type" "imovx")
3928     (set_attr "mode" "SI")])
3930 (define_insn "extendqihi2"
3931   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3932         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3933   ""
3935   switch (get_attr_prefix_0f (insn))
3936     {
3937     case 0:
3938       return "{cbtw|cbw}";
3939     default:
3940       return "movs{bw|x}\t{%1, %0|%0, %1}";
3941     }
3943   [(set_attr "type" "imovx")
3944    (set_attr "mode" "HI")
3945    (set (attr "prefix_0f")
3946      ;; movsx is short decodable while cwtl is vector decoded.
3947      (if_then_else (and (eq_attr "cpu" "!k6")
3948                         (eq_attr "alternative" "0"))
3949         (const_string "0")
3950         (const_string "1")))
3951    (set (attr "modrm")
3952      (if_then_else (eq_attr "prefix_0f" "0")
3953         (const_string "0")
3954         (const_string "1")))])
3956 ;; Conversions between float and double.
3958 ;; These are all no-ops in the model used for the 80387.
3959 ;; So just emit moves.
3961 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3962 (define_split
3963   [(set (match_operand:DF 0 "push_operand")
3964         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3965   "reload_completed"
3966   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3967    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3969 (define_split
3970   [(set (match_operand:XF 0 "push_operand")
3971         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3972   "reload_completed"
3973   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3974    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3975   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3977 (define_expand "extendsfdf2"
3978   [(set (match_operand:DF 0 "nonimmediate_operand")
3979         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3980   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3982   /* ??? Needed for compress_float_constant since all fp constants
3983      are TARGET_LEGITIMATE_CONSTANT_P.  */
3984   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3985     {
3986       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3987           && standard_80387_constant_p (operands[1]) > 0)
3988         {
3989           operands[1] = simplify_const_unary_operation
3990             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3991           emit_move_insn_1 (operands[0], operands[1]);
3992           DONE;
3993         }
3994       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3995     }
3998 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3999    cvtss2sd:
4000       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4001       cvtps2pd xmm2,xmm1
4002    We do the conversion post reload to avoid producing of 128bit spills
4003    that might lead to ICE on 32bit target.  The sequence unlikely combine
4004    anyway.  */
4005 (define_split
4006   [(set (match_operand:DF 0 "register_operand")
4007         (float_extend:DF
4008           (match_operand:SF 1 "nonimmediate_operand")))]
4009   "TARGET_USE_VECTOR_FP_CONVERTS
4010    && optimize_insn_for_speed_p ()
4011    && reload_completed && SSE_REG_P (operands[0])"
4012    [(set (match_dup 2)
4013          (float_extend:V2DF
4014            (vec_select:V2SF
4015              (match_dup 3)
4016              (parallel [(const_int 0) (const_int 1)]))))]
4018   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4019   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4020   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4021      Try to avoid move when unpacking can be done in source.  */
4022   if (REG_P (operands[1]))
4023     {
4024       /* If it is unsafe to overwrite upper half of source, we need
4025          to move to destination and unpack there.  */
4026       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4027            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4028           && true_regnum (operands[0]) != true_regnum (operands[1]))
4029         {
4030           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4031           emit_move_insn (tmp, operands[1]);
4032         }
4033       else
4034         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4035       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4036                                              operands[3]));
4037     }
4038   else
4039     emit_insn (gen_vec_setv4sf_0 (operands[3],
4040                                   CONST0_RTX (V4SFmode), operands[1]));
4043 ;; It's more profitable to split and then extend in the same register.
4044 (define_peephole2
4045   [(set (match_operand:DF 0 "register_operand")
4046         (float_extend:DF
4047           (match_operand:SF 1 "memory_operand")))]
4048   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4049    && optimize_insn_for_speed_p ()
4050    && SSE_REG_P (operands[0])"
4051   [(set (match_dup 2) (match_dup 1))
4052    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4053   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4055 (define_insn "*extendsfdf2_mixed"
4056   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4057         (float_extend:DF
4058           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4059   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4061   switch (which_alternative)
4062     {
4063     case 0:
4064     case 1:
4065       return output_387_reg_move (insn, operands);
4067     case 2:
4068       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4070     default:
4071       gcc_unreachable ();
4072     }
4074   [(set_attr "type" "fmov,fmov,ssecvt")
4075    (set_attr "prefix" "orig,orig,maybe_vex")
4076    (set_attr "mode" "SF,XF,DF")])
4078 (define_insn "*extendsfdf2_sse"
4079   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4080         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4081   "TARGET_SSE2 && TARGET_SSE_MATH"
4082   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4083   [(set_attr "type" "ssecvt")
4084    (set_attr "prefix" "maybe_vex")
4085    (set_attr "mode" "DF")])
4087 (define_insn "*extendsfdf2_i387"
4088   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4089         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4090   "TARGET_80387"
4091   "* return output_387_reg_move (insn, operands);"
4092   [(set_attr "type" "fmov")
4093    (set_attr "mode" "SF,XF")])
4095 (define_expand "extend<mode>xf2"
4096   [(set (match_operand:XF 0 "nonimmediate_operand")
4097         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4098   "TARGET_80387"
4100   /* ??? Needed for compress_float_constant since all fp constants
4101      are TARGET_LEGITIMATE_CONSTANT_P.  */
4102   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4103     {
4104       if (standard_80387_constant_p (operands[1]) > 0)
4105         {
4106           operands[1] = simplify_const_unary_operation
4107             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4108           emit_move_insn_1 (operands[0], operands[1]);
4109           DONE;
4110         }
4111       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4112     }
4115 (define_insn "*extend<mode>xf2_i387"
4116   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4117         (float_extend:XF
4118           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4119   "TARGET_80387"
4120   "* return output_387_reg_move (insn, operands);"
4121   [(set_attr "type" "fmov")
4122    (set_attr "mode" "<MODE>,XF")])
4124 ;; %%% This seems bad bad news.
4125 ;; This cannot output into an f-reg because there is no way to be sure
4126 ;; of truncating in that case.  Otherwise this is just like a simple move
4127 ;; insn.  So we pretend we can output to a reg in order to get better
4128 ;; register preferencing, but we really use a stack slot.
4130 ;; Conversion from DFmode to SFmode.
4132 (define_expand "truncdfsf2"
4133   [(set (match_operand:SF 0 "nonimmediate_operand")
4134         (float_truncate:SF
4135           (match_operand:DF 1 "nonimmediate_operand")))]
4136   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4138   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4139     ;
4140   else if (flag_unsafe_math_optimizations)
4141     ;
4142   else
4143     {
4144       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4145       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4146       DONE;
4147     }
4150 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4151    cvtsd2ss:
4152       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4153       cvtpd2ps xmm2,xmm1
4154    We do the conversion post reload to avoid producing of 128bit spills
4155    that might lead to ICE on 32bit target.  The sequence unlikely combine
4156    anyway.  */
4157 (define_split
4158   [(set (match_operand:SF 0 "register_operand")
4159         (float_truncate:SF
4160           (match_operand:DF 1 "nonimmediate_operand")))]
4161   "TARGET_USE_VECTOR_FP_CONVERTS
4162    && optimize_insn_for_speed_p ()
4163    && reload_completed && SSE_REG_P (operands[0])"
4164    [(set (match_dup 2)
4165          (vec_concat:V4SF
4166            (float_truncate:V2SF
4167              (match_dup 4))
4168            (match_dup 3)))]
4170   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4171   operands[3] = CONST0_RTX (V2SFmode);
4172   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4173   /* Use movsd for loading from memory, unpcklpd for registers.
4174      Try to avoid move when unpacking can be done in source, or SSE3
4175      movddup is available.  */
4176   if (REG_P (operands[1]))
4177     {
4178       if (!TARGET_SSE3
4179           && true_regnum (operands[0]) != true_regnum (operands[1])
4180           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4181               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4182         {
4183           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4184           emit_move_insn (tmp, operands[1]);
4185           operands[1] = tmp;
4186         }
4187       else if (!TARGET_SSE3)
4188         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4189       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4190     }
4191   else
4192     emit_insn (gen_sse2_loadlpd (operands[4],
4193                                  CONST0_RTX (V2DFmode), operands[1]));
4196 ;; It's more profitable to split and then extend in the same register.
4197 (define_peephole2
4198   [(set (match_operand:SF 0 "register_operand")
4199         (float_truncate:SF
4200           (match_operand:DF 1 "memory_operand")))]
4201   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4202    && optimize_insn_for_speed_p ()
4203    && SSE_REG_P (operands[0])"
4204   [(set (match_dup 2) (match_dup 1))
4205    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4206   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4208 (define_expand "truncdfsf2_with_temp"
4209   [(parallel [(set (match_operand:SF 0)
4210                    (float_truncate:SF (match_operand:DF 1)))
4211               (clobber (match_operand:SF 2))])])
4213 (define_insn "*truncdfsf_fast_mixed"
4214   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4215         (float_truncate:SF
4216           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4217   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4219   switch (which_alternative)
4220     {
4221     case 0:
4222       return output_387_reg_move (insn, operands);
4223     case 1:
4224       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4225     default:
4226       gcc_unreachable ();
4227     }
4229   [(set_attr "type" "fmov,ssecvt")
4230    (set_attr "prefix" "orig,maybe_vex")
4231    (set_attr "mode" "SF")])
4233 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4234 ;; because nothing we do here is unsafe.
4235 (define_insn "*truncdfsf_fast_sse"
4236   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4237         (float_truncate:SF
4238           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4239   "TARGET_SSE2 && TARGET_SSE_MATH"
4240   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4241   [(set_attr "type" "ssecvt")
4242    (set_attr "prefix" "maybe_vex")
4243    (set_attr "mode" "SF")])
4245 (define_insn "*truncdfsf_fast_i387"
4246   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4247         (float_truncate:SF
4248           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4249   "TARGET_80387 && flag_unsafe_math_optimizations"
4250   "* return output_387_reg_move (insn, operands);"
4251   [(set_attr "type" "fmov")
4252    (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_mixed"
4255   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4256         (float_truncate:SF
4257           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4258    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4259   "TARGET_MIX_SSE_I387"
4261   switch (which_alternative)
4262     {
4263     case 0:
4264       return output_387_reg_move (insn, operands);
4265     case 1:
4266       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4268     default:
4269       return "#";
4270     }
4272   [(set_attr "isa" "*,sse2,*,*,*")
4273    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4274    (set_attr "unit" "*,*,i387,i387,i387")
4275    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4276    (set_attr "mode" "SF")])
4278 (define_insn "*truncdfsf_i387"
4279   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4280         (float_truncate:SF
4281           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4282    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4283   "TARGET_80387"
4285   switch (which_alternative)
4286     {
4287     case 0:
4288       return output_387_reg_move (insn, operands);
4290     default:
4291       return "#";
4292     }
4294   [(set_attr "type" "fmov,multi,multi,multi")
4295    (set_attr "unit" "*,i387,i387,i387")
4296    (set_attr "mode" "SF")])
4298 (define_insn "*truncdfsf2_i387_1"
4299   [(set (match_operand:SF 0 "memory_operand" "=m")
4300         (float_truncate:SF
4301           (match_operand:DF 1 "register_operand" "f")))]
4302   "TARGET_80387
4303    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4304    && !TARGET_MIX_SSE_I387"
4305   "* return output_387_reg_move (insn, operands);"
4306   [(set_attr "type" "fmov")
4307    (set_attr "mode" "SF")])
4309 (define_split
4310   [(set (match_operand:SF 0 "register_operand")
4311         (float_truncate:SF
4312          (match_operand:DF 1 "fp_register_operand")))
4313    (clobber (match_operand 2))]
4314   "reload_completed"
4315   [(set (match_dup 2) (match_dup 1))
4316    (set (match_dup 0) (match_dup 2))]
4317   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4319 ;; Conversion from XFmode to {SF,DF}mode
4321 (define_expand "truncxf<mode>2"
4322   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4323                    (float_truncate:MODEF
4324                      (match_operand:XF 1 "register_operand")))
4325               (clobber (match_dup 2))])]
4326   "TARGET_80387"
4328   if (flag_unsafe_math_optimizations)
4329     {
4330       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4331       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4332       if (reg != operands[0])
4333         emit_move_insn (operands[0], reg);
4334       DONE;
4335     }
4336   else
4337     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4340 (define_insn "*truncxfsf2_mixed"
4341   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4342         (float_truncate:SF
4343           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4344    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4345   "TARGET_80387"
4347   gcc_assert (!which_alternative);
4348   return output_387_reg_move (insn, operands);
4350   [(set_attr "type" "fmov,multi,multi,multi")
4351    (set_attr "unit" "*,i387,i387,i387")
4352    (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4356         (float_truncate:DF
4357           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4358    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4359   "TARGET_80387"
4361   gcc_assert (!which_alternative);
4362   return output_387_reg_move (insn, operands);
4364   [(set_attr "isa" "*,*,sse2,*")
4365    (set_attr "type" "fmov,multi,multi,multi")
4366    (set_attr "unit" "*,i387,i387,i387")
4367    (set_attr "mode" "DF")])
4369 (define_insn "truncxf<mode>2_i387_noop"
4370   [(set (match_operand:MODEF 0 "register_operand" "=f")
4371         (float_truncate:MODEF
4372           (match_operand:XF 1 "register_operand" "f")))]
4373   "TARGET_80387 && flag_unsafe_math_optimizations"
4374   "* return output_387_reg_move (insn, operands);"
4375   [(set_attr "type" "fmov")
4376    (set_attr "mode" "<MODE>")])
4378 (define_insn "*truncxf<mode>2_i387"
4379   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4380         (float_truncate:MODEF
4381           (match_operand:XF 1 "register_operand" "f")))]
4382   "TARGET_80387"
4383   "* return output_387_reg_move (insn, operands);"
4384   [(set_attr "type" "fmov")
4385    (set_attr "mode" "<MODE>")])
4387 (define_split
4388   [(set (match_operand:MODEF 0 "register_operand")
4389         (float_truncate:MODEF
4390           (match_operand:XF 1 "register_operand")))
4391    (clobber (match_operand:MODEF 2 "memory_operand"))]
4392   "TARGET_80387 && reload_completed"
4393   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4394    (set (match_dup 0) (match_dup 2))])
4396 (define_split
4397   [(set (match_operand:MODEF 0 "memory_operand")
4398         (float_truncate:MODEF
4399           (match_operand:XF 1 "register_operand")))
4400    (clobber (match_operand:MODEF 2 "memory_operand"))]
4401   "TARGET_80387"
4402   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4404 ;; Signed conversion to DImode.
4406 (define_expand "fix_truncxfdi2"
4407   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4408                    (fix:DI (match_operand:XF 1 "register_operand")))
4409               (clobber (reg:CC FLAGS_REG))])]
4410   "TARGET_80387"
4412   if (TARGET_FISTTP)
4413    {
4414      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4415      DONE;
4416    }
4419 (define_expand "fix_trunc<mode>di2"
4420   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4421                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4422               (clobber (reg:CC FLAGS_REG))])]
4423   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425   if (TARGET_FISTTP
4426       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4427    {
4428      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4429      DONE;
4430    }
4431   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4432    {
4433      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4434      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4435      if (out != operands[0])
4436         emit_move_insn (operands[0], out);
4437      DONE;
4438    }
4441 ;; Signed conversion to SImode.
4443 (define_expand "fix_truncxfsi2"
4444   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4445                    (fix:SI (match_operand:XF 1 "register_operand")))
4446               (clobber (reg:CC FLAGS_REG))])]
4447   "TARGET_80387"
4449   if (TARGET_FISTTP)
4450    {
4451      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4452      DONE;
4453    }
4456 (define_expand "fix_trunc<mode>si2"
4457   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4458                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4459               (clobber (reg:CC FLAGS_REG))])]
4460   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462   if (TARGET_FISTTP
4463       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4464    {
4465      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4466      DONE;
4467    }
4468   if (SSE_FLOAT_MODE_P (<MODE>mode))
4469    {
4470      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4471      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4472      if (out != operands[0])
4473         emit_move_insn (operands[0], out);
4474      DONE;
4475    }
4478 ;; Signed conversion to HImode.
4480 (define_expand "fix_trunc<mode>hi2"
4481   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4482                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4483               (clobber (reg:CC FLAGS_REG))])]
4484   "TARGET_80387
4485    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487   if (TARGET_FISTTP)
4488    {
4489      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4490      DONE;
4491    }
4494 ;; Unsigned conversion to SImode.
4496 (define_expand "fixuns_trunc<mode>si2"
4497   [(parallel
4498     [(set (match_operand:SI 0 "register_operand")
4499           (unsigned_fix:SI
4500             (match_operand:MODEF 1 "nonimmediate_operand")))
4501      (use (match_dup 2))
4502      (clobber (match_scratch:<ssevecmode> 3))
4503      (clobber (match_scratch:<ssevecmode> 4))])]
4504   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4506   machine_mode mode = <MODE>mode;
4507   machine_mode vecmode = <ssevecmode>mode;
4508   REAL_VALUE_TYPE TWO31r;
4509   rtx two31;
4511   if (optimize_insn_for_size_p ())
4512     FAIL;
4514   real_ldexp (&TWO31r, &dconst1, 31);
4515   two31 = const_double_from_real_value (TWO31r, mode);
4516   two31 = ix86_build_const_vector (vecmode, true, two31);
4517   operands[2] = force_reg (vecmode, two31);
4520 (define_insn_and_split "*fixuns_trunc<mode>_1"
4521   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4522         (unsigned_fix:SI
4523           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4524    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4525    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4526    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4527   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4528    && optimize_function_for_speed_p (cfun)"
4529   "#"
4530   "&& reload_completed"
4531   [(const_int 0)]
4533   ix86_split_convert_uns_si_sse (operands);
4534   DONE;
4537 ;; Unsigned conversion to HImode.
4538 ;; Without these patterns, we'll try the unsigned SI conversion which
4539 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4541 (define_expand "fixuns_trunc<mode>hi2"
4542   [(set (match_dup 2)
4543         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4544    (set (match_operand:HI 0 "nonimmediate_operand")
4545         (subreg:HI (match_dup 2) 0))]
4546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4547   "operands[2] = gen_reg_rtx (SImode);")
4549 ;; When SSE is available, it is always faster to use it!
4550 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4551   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4552         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4553   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4554    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4555   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "prefix" "maybe_vex")
4558    (set (attr "prefix_rex")
4559         (if_then_else
4560           (match_test "<SWI48:MODE>mode == DImode")
4561           (const_string "1")
4562           (const_string "*")))
4563    (set_attr "mode" "<MODEF:MODE>")
4564    (set_attr "athlon_decode" "double,vector")
4565    (set_attr "amdfam10_decode" "double,double")
4566    (set_attr "bdver1_decode" "double,double")])
4568 ;; Avoid vector decoded forms of the instruction.
4569 (define_peephole2
4570   [(match_scratch:MODEF 2 "x")
4571    (set (match_operand:SWI48 0 "register_operand")
4572         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4573   "TARGET_AVOID_VECTOR_DECODE
4574    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4575    && optimize_insn_for_speed_p ()"
4576   [(set (match_dup 2) (match_dup 1))
4577    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4579 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4580   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4581         (fix:SWI248x (match_operand 1 "register_operand")))]
4582   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583    && TARGET_FISTTP
4584    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4585          && (TARGET_64BIT || <MODE>mode != DImode))
4586         && TARGET_SSE_MATH)
4587    && can_create_pseudo_p ()"
4588   "#"
4589   "&& 1"
4590   [(const_int 0)]
4592   if (memory_operand (operands[0], VOIDmode))
4593     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4594   else
4595     {
4596       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4597       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4598                                                             operands[1],
4599                                                             operands[2]));
4600     }
4601   DONE;
4603   [(set_attr "type" "fisttp")
4604    (set_attr "mode" "<MODE>")])
4606 (define_insn "fix_trunc<mode>_i387_fisttp"
4607   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4608         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4609    (clobber (match_scratch:XF 2 "=&1f"))]
4610   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4611    && TARGET_FISTTP
4612    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4613          && (TARGET_64BIT || <MODE>mode != DImode))
4614         && TARGET_SSE_MATH)"
4615   "* return output_fix_trunc (insn, operands, true);"
4616   [(set_attr "type" "fisttp")
4617    (set_attr "mode" "<MODE>")])
4619 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4620   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4621         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4622    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4623    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4624   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4625    && TARGET_FISTTP
4626    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627         && (TARGET_64BIT || <MODE>mode != DImode))
4628         && TARGET_SSE_MATH)"
4629   "#"
4630   [(set_attr "type" "fisttp")
4631    (set_attr "mode" "<MODE>")])
4633 (define_split
4634   [(set (match_operand:SWI248x 0 "register_operand")
4635         (fix:SWI248x (match_operand 1 "register_operand")))
4636    (clobber (match_operand:SWI248x 2 "memory_operand"))
4637    (clobber (match_scratch 3))]
4638   "reload_completed"
4639   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4640               (clobber (match_dup 3))])
4641    (set (match_dup 0) (match_dup 2))])
4643 (define_split
4644   [(set (match_operand:SWI248x 0 "memory_operand")
4645         (fix:SWI248x (match_operand 1 "register_operand")))
4646    (clobber (match_operand:SWI248x 2 "memory_operand"))
4647    (clobber (match_scratch 3))]
4648   "reload_completed"
4649   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4650               (clobber (match_dup 3))])])
4652 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4653 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4654 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4655 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4656 ;; function in i386.c.
4657 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4658   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4659         (fix:SWI248x (match_operand 1 "register_operand")))
4660    (clobber (reg:CC FLAGS_REG))]
4661   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4662    && !TARGET_FISTTP
4663    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4664          && (TARGET_64BIT || <MODE>mode != DImode))
4665    && can_create_pseudo_p ()"
4666   "#"
4667   "&& 1"
4668   [(const_int 0)]
4670   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4672   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4673   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4674   if (memory_operand (operands[0], VOIDmode))
4675     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4676                                          operands[2], operands[3]));
4677   else
4678     {
4679       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4680       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4681                                                      operands[2], operands[3],
4682                                                      operands[4]));
4683     }
4684   DONE;
4686   [(set_attr "type" "fistp")
4687    (set_attr "i387_cw" "trunc")
4688    (set_attr "mode" "<MODE>")])
4690 (define_insn "fix_truncdi_i387"
4691   [(set (match_operand:DI 0 "memory_operand" "=m")
4692         (fix:DI (match_operand 1 "register_operand" "f")))
4693    (use (match_operand:HI 2 "memory_operand" "m"))
4694    (use (match_operand:HI 3 "memory_operand" "m"))
4695    (clobber (match_scratch:XF 4 "=&1f"))]
4696   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4697    && !TARGET_FISTTP
4698    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4699   "* return output_fix_trunc (insn, operands, false);"
4700   [(set_attr "type" "fistp")
4701    (set_attr "i387_cw" "trunc")
4702    (set_attr "mode" "DI")])
4704 (define_insn "fix_truncdi_i387_with_temp"
4705   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4706         (fix:DI (match_operand 1 "register_operand" "f,f")))
4707    (use (match_operand:HI 2 "memory_operand" "m,m"))
4708    (use (match_operand:HI 3 "memory_operand" "m,m"))
4709    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4710    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4711   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4712    && !TARGET_FISTTP
4713    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4714   "#"
4715   [(set_attr "type" "fistp")
4716    (set_attr "i387_cw" "trunc")
4717    (set_attr "mode" "DI")])
4719 (define_split
4720   [(set (match_operand:DI 0 "register_operand")
4721         (fix:DI (match_operand 1 "register_operand")))
4722    (use (match_operand:HI 2 "memory_operand"))
4723    (use (match_operand:HI 3 "memory_operand"))
4724    (clobber (match_operand:DI 4 "memory_operand"))
4725    (clobber (match_scratch 5))]
4726   "reload_completed"
4727   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4728               (use (match_dup 2))
4729               (use (match_dup 3))
4730               (clobber (match_dup 5))])
4731    (set (match_dup 0) (match_dup 4))])
4733 (define_split
4734   [(set (match_operand:DI 0 "memory_operand")
4735         (fix:DI (match_operand 1 "register_operand")))
4736    (use (match_operand:HI 2 "memory_operand"))
4737    (use (match_operand:HI 3 "memory_operand"))
4738    (clobber (match_operand:DI 4 "memory_operand"))
4739    (clobber (match_scratch 5))]
4740   "reload_completed"
4741   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4742               (use (match_dup 2))
4743               (use (match_dup 3))
4744               (clobber (match_dup 5))])])
4746 (define_insn "fix_trunc<mode>_i387"
4747   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4748         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4749    (use (match_operand:HI 2 "memory_operand" "m"))
4750    (use (match_operand:HI 3 "memory_operand" "m"))]
4751   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4752    && !TARGET_FISTTP
4753    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4754   "* return output_fix_trunc (insn, operands, false);"
4755   [(set_attr "type" "fistp")
4756    (set_attr "i387_cw" "trunc")
4757    (set_attr "mode" "<MODE>")])
4759 (define_insn "fix_trunc<mode>_i387_with_temp"
4760   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4761         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4762    (use (match_operand:HI 2 "memory_operand" "m,m"))
4763    (use (match_operand:HI 3 "memory_operand" "m,m"))
4764    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4765   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4766    && !TARGET_FISTTP
4767    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4768   "#"
4769   [(set_attr "type" "fistp")
4770    (set_attr "i387_cw" "trunc")
4771    (set_attr "mode" "<MODE>")])
4773 (define_split
4774   [(set (match_operand:SWI24 0 "register_operand")
4775         (fix:SWI24 (match_operand 1 "register_operand")))
4776    (use (match_operand:HI 2 "memory_operand"))
4777    (use (match_operand:HI 3 "memory_operand"))
4778    (clobber (match_operand:SWI24 4 "memory_operand"))]
4779   "reload_completed"
4780   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4781               (use (match_dup 2))
4782               (use (match_dup 3))])
4783    (set (match_dup 0) (match_dup 4))])
4785 (define_split
4786   [(set (match_operand:SWI24 0 "memory_operand")
4787         (fix:SWI24 (match_operand 1 "register_operand")))
4788    (use (match_operand:HI 2 "memory_operand"))
4789    (use (match_operand:HI 3 "memory_operand"))
4790    (clobber (match_operand:SWI24 4 "memory_operand"))]
4791   "reload_completed"
4792   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4793               (use (match_dup 2))
4794               (use (match_dup 3))])])
4796 (define_insn "x86_fnstcw_1"
4797   [(set (match_operand:HI 0 "memory_operand" "=m")
4798         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4799   "TARGET_80387"
4800   "fnstcw\t%0"
4801   [(set (attr "length")
4802         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4803    (set_attr "mode" "HI")
4804    (set_attr "unit" "i387")
4805    (set_attr "bdver1_decode" "vector")])
4807 (define_insn "x86_fldcw_1"
4808   [(set (reg:HI FPCR_REG)
4809         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4810   "TARGET_80387"
4811   "fldcw\t%0"
4812   [(set (attr "length")
4813         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4814    (set_attr "mode" "HI")
4815    (set_attr "unit" "i387")
4816    (set_attr "athlon_decode" "vector")
4817    (set_attr "amdfam10_decode" "vector")
4818    (set_attr "bdver1_decode" "vector")])
4820 ;; Conversion between fixed point and floating point.
4822 ;; Even though we only accept memory inputs, the backend _really_
4823 ;; wants to be able to do this between registers.  Thankfully, LRA
4824 ;; will fix this up for us during register allocation.
4826 (define_insn "floathi<mode>2"
4827   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4828         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4829   "TARGET_80387
4830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831        || TARGET_MIX_SSE_I387)"
4832   "fild%Z1\t%1"
4833   [(set_attr "type" "fmov")
4834    (set_attr "mode" "<MODE>")
4835    (set_attr "fp_int_src" "true")])
4837 (define_insn "float<SWI48x:mode>xf2"
4838   [(set (match_operand:XF 0 "register_operand" "=f")
4839         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4840   "TARGET_80387"
4841   "fild%Z1\t%1"
4842   [(set_attr "type" "fmov")
4843    (set_attr "mode" "XF")
4844    (set_attr "fp_int_src" "true")])
4846 (define_expand "float<SWI48:mode><MODEF:mode>2"
4847   [(set (match_operand:MODEF 0 "register_operand")
4848         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4849   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4851   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4852       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4853     {
4854       rtx reg = gen_reg_rtx (XFmode);
4855       rtx (*insn)(rtx, rtx);
4857       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4859       if (<MODEF:MODE>mode == SFmode)
4860         insn = gen_truncxfsf2;
4861       else if (<MODEF:MODE>mode == DFmode)
4862         insn = gen_truncxfdf2;
4863       else
4864         gcc_unreachable ();
4866       emit_insn (insn (operands[0], reg));
4867       DONE;
4868     }
4871 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4872   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4873         (float:MODEF
4874           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4875   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4876   "@
4877    fild%Z1\t%1
4878    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4879    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4880   [(set_attr "type" "fmov,sseicvt,sseicvt")
4881    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4882    (set_attr "mode" "<MODEF:MODE>")
4883    (set (attr "prefix_rex")
4884      (if_then_else
4885        (and (eq_attr "prefix" "maybe_vex")
4886             (match_test "<SWI48:MODE>mode == DImode"))
4887        (const_string "1")
4888        (const_string "*")))
4889    (set_attr "unit" "i387,*,*")
4890    (set_attr "athlon_decode" "*,double,direct")
4891    (set_attr "amdfam10_decode" "*,vector,double")
4892    (set_attr "bdver1_decode" "*,double,direct")
4893    (set_attr "fp_int_src" "true")
4894    (set (attr "enabled")
4895      (cond [(eq_attr "alternative" "0")
4896               (symbol_ref "TARGET_MIX_SSE_I387
4897                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4898                                                 <SWI48:MODE>mode)")
4899            ]
4900            (symbol_ref "true")))
4901    (set (attr "preferred_for_speed")
4902      (cond [(eq_attr "alternative" "1")
4903               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4904            (symbol_ref "true")))])
4906 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4907   [(set (match_operand:MODEF 0 "register_operand" "=f")
4908         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4909   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4910   "fild%Z1\t%1"
4911   [(set_attr "type" "fmov")
4912    (set_attr "mode" "<MODEF:MODE>")
4913    (set_attr "fp_int_src" "true")])
4915 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4916 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4917 ;; alternative in sse2_loadld.
4918 (define_split
4919   [(set (match_operand:MODEF 0 "register_operand")
4920         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4921   "TARGET_SSE2 && TARGET_SSE_MATH
4922    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4923    && reload_completed && SSE_REG_P (operands[0])
4924    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4925   [(const_int 0)]
4927   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4928                                      <MODE>mode, 0);
4929   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931   emit_insn (gen_sse2_loadld (operands[4],
4932                               CONST0_RTX (V4SImode), operands[1]));
4934   if (<ssevecmode>mode == V4SFmode)
4935     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4936   else
4937     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4938   DONE;
4941 ;; Avoid partial SSE register dependency stalls
4942 (define_split
4943   [(set (match_operand:MODEF 0 "register_operand")
4944         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4945   "TARGET_SSE2 && TARGET_SSE_MATH
4946    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4947    && optimize_function_for_speed_p (cfun)
4948    && reload_completed && SSE_REG_P (operands[0])"
4949   [(const_int 0)]
4951   const machine_mode vmode = <MODEF:ssevecmode>mode;
4952   const machine_mode mode = <MODEF:MODE>mode;
4953   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4955   emit_move_insn (op0, CONST0_RTX (vmode));
4957   t = gen_rtx_FLOAT (mode, operands[1]);
4958   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4959   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4960   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4961   DONE;
4964 ;; Break partial reg stall for cvtsd2ss.
4966 (define_peephole2
4967   [(set (match_operand:SF 0 "register_operand")
4968         (float_truncate:SF
4969           (match_operand:DF 1 "nonimmediate_operand")))]
4970   "TARGET_SSE2 && TARGET_SSE_MATH
4971    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4972    && optimize_function_for_speed_p (cfun)
4973    && SSE_REG_P (operands[0])
4974    && (!SSE_REG_P (operands[1])
4975        || REGNO (operands[0]) != REGNO (operands[1]))"
4976   [(set (match_dup 0)
4977         (vec_merge:V4SF
4978           (vec_duplicate:V4SF
4979             (float_truncate:V2SF
4980               (match_dup 1)))
4981           (match_dup 0)
4982           (const_int 1)))]
4984   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4985                                      SFmode, 0);
4986   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4987                                      DFmode, 0);
4988   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4991 ;; Break partial reg stall for cvtss2sd.
4993 (define_peephole2
4994   [(set (match_operand:DF 0 "register_operand")
4995         (float_extend:DF
4996           (match_operand:SF 1 "nonimmediate_operand")))]
4997   "TARGET_SSE2 && TARGET_SSE_MATH
4998    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4999    && optimize_function_for_speed_p (cfun)
5000    && SSE_REG_P (operands[0])
5001    && (!SSE_REG_P (operands[1])
5002        || REGNO (operands[0]) != REGNO (operands[1]))"
5003   [(set (match_dup 0)
5004         (vec_merge:V2DF
5005           (float_extend:V2DF
5006             (vec_select:V2SF
5007               (match_dup 1)
5008               (parallel [(const_int 0) (const_int 1)])))
5009           (match_dup 0)
5010           (const_int 1)))]
5012   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5013                                      DFmode, 0);
5014   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5015                                      SFmode, 0);
5016   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5019 ;; Avoid store forwarding (partial memory) stall penalty
5020 ;; by passing DImode value through XMM registers.  */
5022 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5023   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5024         (float:X87MODEF
5025           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5026    (clobber (match_scratch:V4SI 3 "=X,x"))
5027    (clobber (match_scratch:V4SI 4 "=X,x"))
5028    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5029   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5030    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5031    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5032   "#"
5033   [(set_attr "type" "multi")
5034    (set_attr "mode" "<X87MODEF:MODE>")
5035    (set_attr "unit" "i387")
5036    (set_attr "fp_int_src" "true")])
5038 (define_split
5039   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5040         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5041    (clobber (match_scratch:V4SI 3))
5042    (clobber (match_scratch:V4SI 4))
5043    (clobber (match_operand:DI 2 "memory_operand"))]
5044   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5045    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5046    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5047    && reload_completed"
5048   [(set (match_dup 2) (match_dup 3))
5049    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5051   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5052      Assemble the 64-bit DImode value in an xmm register.  */
5053   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5054                               gen_lowpart (SImode, operands[1])));
5055   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5056                               gen_highpart (SImode, operands[1])));
5057   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5058                                          operands[4]));
5060   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5063 (define_split
5064   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5065         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5066    (clobber (match_scratch:V4SI 3))
5067    (clobber (match_scratch:V4SI 4))
5068    (clobber (match_operand:DI 2 "memory_operand"))]
5069   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5070    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5071    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5072    && reload_completed"
5073   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5075 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5076   [(set (match_operand:MODEF 0 "register_operand")
5077         (unsigned_float:MODEF
5078           (match_operand:SWI12 1 "nonimmediate_operand")))]
5079   "!TARGET_64BIT
5080    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5082   operands[1] = convert_to_mode (SImode, operands[1], 1);
5083   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5084   DONE;
5087 ;; Avoid store forwarding (partial memory) stall penalty by extending
5088 ;; SImode value to DImode through XMM register instead of pushing two
5089 ;; SImode values to stack. Also note that fild loads from memory only.
5091 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5092   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5093         (unsigned_float:X87MODEF
5094           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5095    (clobber (match_scratch:DI 3 "=x"))
5096    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5097   "!TARGET_64BIT
5098    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5099    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5100   "#"
5101   "&& reload_completed"
5102   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5103    (set (match_dup 2) (match_dup 3))
5104    (set (match_dup 0)
5105         (float:X87MODEF (match_dup 2)))]
5106   ""
5107   [(set_attr "type" "multi")
5108    (set_attr "mode" "<MODE>")])
5110 (define_expand "floatunssi<mode>2"
5111   [(parallel
5112      [(set (match_operand:X87MODEF 0 "register_operand")
5113            (unsigned_float:X87MODEF
5114              (match_operand:SI 1 "nonimmediate_operand")))
5115       (clobber (match_scratch:DI 3))
5116       (clobber (match_dup 2))])]
5117   "!TARGET_64BIT
5118    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5119         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5120        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5122   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5123     {
5124       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5125       DONE;
5126     }
5127   else
5128     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5131 (define_expand "floatunsdisf2"
5132   [(use (match_operand:SF 0 "register_operand"))
5133    (use (match_operand:DI 1 "nonimmediate_operand"))]
5134   "TARGET_64BIT && TARGET_SSE_MATH"
5135   "x86_emit_floatuns (operands); DONE;")
5137 (define_expand "floatunsdidf2"
5138   [(use (match_operand:DF 0 "register_operand"))
5139    (use (match_operand:DI 1 "nonimmediate_operand"))]
5140   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5141    && TARGET_SSE2 && TARGET_SSE_MATH"
5143   if (TARGET_64BIT)
5144     x86_emit_floatuns (operands);
5145   else
5146     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5147   DONE;
5150 ;; Load effective address instructions
5152 (define_insn_and_split "*lea<mode>"
5153   [(set (match_operand:SWI48 0 "register_operand" "=r")
5154         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5155   ""
5157   if (SImode_address_operand (operands[1], VOIDmode))
5158     {
5159       gcc_assert (TARGET_64BIT);
5160       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5161     }
5162   else 
5163     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5165   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5166   [(const_int 0)]
5168   machine_mode mode = <MODE>mode;
5169   rtx pat;
5171   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5172      change operands[] array behind our back.  */
5173   pat = PATTERN (curr_insn);
5175   operands[0] = SET_DEST (pat);
5176   operands[1] = SET_SRC (pat);
5178   /* Emit all operations in SImode for zero-extended addresses.  */
5179   if (SImode_address_operand (operands[1], VOIDmode))
5180     mode = SImode;
5182   ix86_split_lea_for_addr (curr_insn, operands, mode);
5184   /* Zero-extend return register to DImode for zero-extended addresses.  */
5185   if (mode != <MODE>mode)
5186     emit_insn (gen_zero_extendsidi2
5187                (operands[0], gen_lowpart (mode, operands[0])));
5189   DONE;
5191   [(set_attr "type" "lea")
5192    (set (attr "mode")
5193      (if_then_else
5194        (match_operand 1 "SImode_address_operand")
5195        (const_string "SI")
5196        (const_string "<MODE>")))])
5198 ;; Add instructions
5200 (define_expand "add<mode>3"
5201   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5202         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5203                     (match_operand:SDWIM 2 "<general_operand>")))]
5204   ""
5205   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5207 (define_insn_and_split "*add<dwi>3_doubleword"
5208   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5209         (plus:<DWI>
5210           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5211           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5212    (clobber (reg:CC FLAGS_REG))]
5213   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5214   "#"
5215   "reload_completed"
5216   [(parallel [(set (reg:CCC FLAGS_REG)
5217                    (compare:CCC
5218                      (plus:DWIH (match_dup 1) (match_dup 2))
5219                      (match_dup 1)))
5220               (set (match_dup 0)
5221                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5222    (parallel [(set (match_dup 3)
5223                    (plus:DWIH
5224                      (plus:DWIH
5225                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5226                        (match_dup 4))
5227                      (match_dup 5)))
5228               (clobber (reg:CC FLAGS_REG))])]
5229   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5231 (define_insn "*add<mode>_1"
5232   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5233         (plus:SWI48
5234           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5235           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5236    (clobber (reg:CC FLAGS_REG))]
5237   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5239   switch (get_attr_type (insn))
5240     {
5241     case TYPE_LEA:
5242       return "#";
5244     case TYPE_INCDEC:
5245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5246       if (operands[2] == const1_rtx)
5247         return "inc{<imodesuffix>}\t%0";
5248       else
5249         {
5250           gcc_assert (operands[2] == constm1_rtx);
5251           return "dec{<imodesuffix>}\t%0";
5252         }
5254     default:
5255       /* For most processors, ADD is faster than LEA.  This alternative
5256          was added to use ADD as much as possible.  */
5257       if (which_alternative == 2)
5258         std::swap (operands[1], operands[2]);
5259         
5260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5262         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5264       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5265     }
5267   [(set (attr "type")
5268      (cond [(eq_attr "alternative" "3")
5269               (const_string "lea")
5270             (match_operand:SWI48 2 "incdec_operand")
5271               (const_string "incdec")
5272            ]
5273            (const_string "alu")))
5274    (set (attr "length_immediate")
5275       (if_then_else
5276         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5277         (const_string "1")
5278         (const_string "*")))
5279    (set_attr "mode" "<MODE>")])
5281 ;; It may seem that nonimmediate operand is proper one for operand 1.
5282 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5283 ;; we take care in ix86_binary_operator_ok to not allow two memory
5284 ;; operands so proper swapping will be done in reload.  This allow
5285 ;; patterns constructed from addsi_1 to match.
5287 (define_insn "addsi_1_zext"
5288   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5289         (zero_extend:DI
5290           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5291                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5292    (clobber (reg:CC FLAGS_REG))]
5293   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5295   switch (get_attr_type (insn))
5296     {
5297     case TYPE_LEA:
5298       return "#";
5300     case TYPE_INCDEC:
5301       if (operands[2] == const1_rtx)
5302         return "inc{l}\t%k0";
5303       else
5304         {
5305           gcc_assert (operands[2] == constm1_rtx);
5306           return "dec{l}\t%k0";
5307         }
5309     default:
5310       /* For most processors, ADD is faster than LEA.  This alternative
5311          was added to use ADD as much as possible.  */
5312       if (which_alternative == 1)
5313         std::swap (operands[1], operands[2]);
5315       if (x86_maybe_negate_const_int (&operands[2], SImode))
5316         return "sub{l}\t{%2, %k0|%k0, %2}";
5318       return "add{l}\t{%2, %k0|%k0, %2}";
5319     }
5321   [(set (attr "type")
5322      (cond [(eq_attr "alternative" "2")
5323               (const_string "lea")
5324             (match_operand:SI 2 "incdec_operand")
5325               (const_string "incdec")
5326            ]
5327            (const_string "alu")))
5328    (set (attr "length_immediate")
5329       (if_then_else
5330         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5331         (const_string "1")
5332         (const_string "*")))
5333    (set_attr "mode" "SI")])
5335 (define_insn "*addhi_1"
5336   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5337         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5338                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5339    (clobber (reg:CC FLAGS_REG))]
5340   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5342   switch (get_attr_type (insn))
5343     {
5344     case TYPE_LEA:
5345       return "#";
5347     case TYPE_INCDEC:
5348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349       if (operands[2] == const1_rtx)
5350         return "inc{w}\t%0";
5351       else
5352         {
5353           gcc_assert (operands[2] == constm1_rtx);
5354           return "dec{w}\t%0";
5355         }
5357     default:
5358       /* For most processors, ADD is faster than LEA.  This alternative
5359          was added to use ADD as much as possible.  */
5360       if (which_alternative == 2)
5361         std::swap (operands[1], operands[2]);
5363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364       if (x86_maybe_negate_const_int (&operands[2], HImode))
5365         return "sub{w}\t{%2, %0|%0, %2}";
5367       return "add{w}\t{%2, %0|%0, %2}";
5368     }
5370   [(set (attr "type")
5371      (cond [(eq_attr "alternative" "3")
5372               (const_string "lea")
5373             (match_operand:HI 2 "incdec_operand")
5374               (const_string "incdec")
5375            ]
5376            (const_string "alu")))
5377    (set (attr "length_immediate")
5378       (if_then_else
5379         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5380         (const_string "1")
5381         (const_string "*")))
5382    (set_attr "mode" "HI,HI,HI,SI")])
5384 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5385 (define_insn "*addqi_1"
5386   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5387         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5388                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5389    (clobber (reg:CC FLAGS_REG))]
5390   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5392   bool widen = (which_alternative == 3 || which_alternative == 4);
5394   switch (get_attr_type (insn))
5395     {
5396     case TYPE_LEA:
5397       return "#";
5399     case TYPE_INCDEC:
5400       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401       if (operands[2] == const1_rtx)
5402         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5403       else
5404         {
5405           gcc_assert (operands[2] == constm1_rtx);
5406           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5407         }
5409     default:
5410       /* For most processors, ADD is faster than LEA.  These alternatives
5411          were added to use ADD as much as possible.  */
5412       if (which_alternative == 2 || which_alternative == 4)
5413         std::swap (operands[1], operands[2]);
5415       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5416       if (x86_maybe_negate_const_int (&operands[2], QImode))
5417         {
5418           if (widen)
5419             return "sub{l}\t{%2, %k0|%k0, %2}";
5420           else
5421             return "sub{b}\t{%2, %0|%0, %2}";
5422         }
5423       if (widen)
5424         return "add{l}\t{%k2, %k0|%k0, %k2}";
5425       else
5426         return "add{b}\t{%2, %0|%0, %2}";
5427     }
5429   [(set (attr "type")
5430      (cond [(eq_attr "alternative" "5")
5431               (const_string "lea")
5432             (match_operand:QI 2 "incdec_operand")
5433               (const_string "incdec")
5434            ]
5435            (const_string "alu")))
5436    (set (attr "length_immediate")
5437       (if_then_else
5438         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5439         (const_string "1")
5440         (const_string "*")))
5441    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5443 (define_insn "*addqi_1_slp"
5444   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5445         (plus:QI (match_dup 0)
5446                  (match_operand:QI 1 "general_operand" "qn,qm")))
5447    (clobber (reg:CC FLAGS_REG))]
5448   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5451   switch (get_attr_type (insn))
5452     {
5453     case TYPE_INCDEC:
5454       if (operands[1] == const1_rtx)
5455         return "inc{b}\t%0";
5456       else
5457         {
5458           gcc_assert (operands[1] == constm1_rtx);
5459           return "dec{b}\t%0";
5460         }
5462     default:
5463       if (x86_maybe_negate_const_int (&operands[1], QImode))
5464         return "sub{b}\t{%1, %0|%0, %1}";
5466       return "add{b}\t{%1, %0|%0, %1}";
5467     }
5469   [(set (attr "type")
5470      (if_then_else (match_operand:QI 1 "incdec_operand")
5471         (const_string "incdec")
5472         (const_string "alu1")))
5473    (set (attr "memory")
5474      (if_then_else (match_operand 1 "memory_operand")
5475         (const_string "load")
5476         (const_string "none")))
5477    (set_attr "mode" "QI")])
5479 ;; Split non destructive adds if we cannot use lea.
5480 (define_split
5481   [(set (match_operand:SWI48 0 "register_operand")
5482         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5483                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5484    (clobber (reg:CC FLAGS_REG))]
5485   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5486   [(set (match_dup 0) (match_dup 1))
5487    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5488               (clobber (reg:CC FLAGS_REG))])])
5490 ;; Convert add to the lea pattern to avoid flags dependency.
5491 (define_split
5492   [(set (match_operand:SWI 0 "register_operand")
5493         (plus:SWI (match_operand:SWI 1 "register_operand")
5494                   (match_operand:SWI 2 "<nonmemory_operand>")))
5495    (clobber (reg:CC FLAGS_REG))]
5496   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5497   [(const_int 0)]
5499   machine_mode mode = <MODE>mode;
5500   rtx pat;
5502   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5503     { 
5504       mode = SImode; 
5505       operands[0] = gen_lowpart (mode, operands[0]);
5506       operands[1] = gen_lowpart (mode, operands[1]);
5507       operands[2] = gen_lowpart (mode, operands[2]);
5508     }
5510   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5512   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5513   DONE;
5516 ;; Split non destructive adds if we cannot use lea.
5517 (define_split
5518   [(set (match_operand:DI 0 "register_operand")
5519         (zero_extend:DI
5520           (plus:SI (match_operand:SI 1 "register_operand")
5521                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5522    (clobber (reg:CC FLAGS_REG))]
5523   "TARGET_64BIT
5524    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5525   [(set (match_dup 3) (match_dup 1))
5526    (parallel [(set (match_dup 0)
5527                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5528               (clobber (reg:CC FLAGS_REG))])]
5529   "operands[3] = gen_lowpart (SImode, operands[0]);")
5531 ;; Convert add to the lea pattern to avoid flags dependency.
5532 (define_split
5533   [(set (match_operand:DI 0 "register_operand")
5534         (zero_extend:DI
5535           (plus:SI (match_operand:SI 1 "register_operand")
5536                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5537    (clobber (reg:CC FLAGS_REG))]
5538   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5539   [(set (match_dup 0)
5540         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5542 (define_insn "*add<mode>_2"
5543   [(set (reg FLAGS_REG)
5544         (compare
5545           (plus:SWI
5546             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5547             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5548           (const_int 0)))
5549    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5550         (plus:SWI (match_dup 1) (match_dup 2)))]
5551   "ix86_match_ccmode (insn, CCGOCmode)
5552    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5554   switch (get_attr_type (insn))
5555     {
5556     case TYPE_INCDEC:
5557       if (operands[2] == const1_rtx)
5558         return "inc{<imodesuffix>}\t%0";
5559       else
5560         {
5561           gcc_assert (operands[2] == constm1_rtx);
5562           return "dec{<imodesuffix>}\t%0";
5563         }
5565     default:
5566       if (which_alternative == 2)
5567         std::swap (operands[1], operands[2]);
5568         
5569       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5571         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5573       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5574     }
5576   [(set (attr "type")
5577      (if_then_else (match_operand:SWI 2 "incdec_operand")
5578         (const_string "incdec")
5579         (const_string "alu")))
5580    (set (attr "length_immediate")
5581       (if_then_else
5582         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5583         (const_string "1")
5584         (const_string "*")))
5585    (set_attr "mode" "<MODE>")])
5587 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5588 (define_insn "*addsi_2_zext"
5589   [(set (reg FLAGS_REG)
5590         (compare
5591           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5592                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5593           (const_int 0)))
5594    (set (match_operand:DI 0 "register_operand" "=r,r")
5595         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5596   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5597    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5599   switch (get_attr_type (insn))
5600     {
5601     case TYPE_INCDEC:
5602       if (operands[2] == const1_rtx)
5603         return "inc{l}\t%k0";
5604       else
5605         {
5606           gcc_assert (operands[2] == constm1_rtx);
5607           return "dec{l}\t%k0";
5608         }
5610     default:
5611       if (which_alternative == 1)
5612         std::swap (operands[1], operands[2]);
5614       if (x86_maybe_negate_const_int (&operands[2], SImode))
5615         return "sub{l}\t{%2, %k0|%k0, %2}";
5617       return "add{l}\t{%2, %k0|%k0, %2}";
5618     }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:SI 2 "incdec_operand")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set (attr "length_immediate")
5625       (if_then_else
5626         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5627         (const_string "1")
5628         (const_string "*")))
5629    (set_attr "mode" "SI")])
5631 (define_insn "*add<mode>_3"
5632   [(set (reg FLAGS_REG)
5633         (compare
5634           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5635           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5636    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5637   "ix86_match_ccmode (insn, CCZmode)
5638    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5640   switch (get_attr_type (insn))
5641     {
5642     case TYPE_INCDEC:
5643       if (operands[2] == const1_rtx)
5644         return "inc{<imodesuffix>}\t%0";
5645       else
5646         {
5647           gcc_assert (operands[2] == constm1_rtx);
5648           return "dec{<imodesuffix>}\t%0";
5649         }
5651     default:
5652       if (which_alternative == 1)
5653         std::swap (operands[1], operands[2]);
5655       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5656       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5657         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5659       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5660     }
5662   [(set (attr "type")
5663      (if_then_else (match_operand:SWI 2 "incdec_operand")
5664         (const_string "incdec")
5665         (const_string "alu")))
5666    (set (attr "length_immediate")
5667       (if_then_else
5668         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5669         (const_string "1")
5670         (const_string "*")))
5671    (set_attr "mode" "<MODE>")])
5673 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5674 (define_insn "*addsi_3_zext"
5675   [(set (reg FLAGS_REG)
5676         (compare
5677           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5678           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5679    (set (match_operand:DI 0 "register_operand" "=r,r")
5680         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5681   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5682    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5684   switch (get_attr_type (insn))
5685     {
5686     case TYPE_INCDEC:
5687       if (operands[2] == const1_rtx)
5688         return "inc{l}\t%k0";
5689       else
5690         {
5691           gcc_assert (operands[2] == constm1_rtx);
5692           return "dec{l}\t%k0";
5693         }
5695     default:
5696       if (which_alternative == 1)
5697         std::swap (operands[1], operands[2]);
5699       if (x86_maybe_negate_const_int (&operands[2], SImode))
5700         return "sub{l}\t{%2, %k0|%k0, %2}";
5702       return "add{l}\t{%2, %k0|%k0, %2}";
5703     }
5705   [(set (attr "type")
5706      (if_then_else (match_operand:SI 2 "incdec_operand")
5707         (const_string "incdec")
5708         (const_string "alu")))
5709    (set (attr "length_immediate")
5710       (if_then_else
5711         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5712         (const_string "1")
5713         (const_string "*")))
5714    (set_attr "mode" "SI")])
5716 ; For comparisons against 1, -1 and 128, we may generate better code
5717 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5718 ; is matched then.  We can't accept general immediate, because for
5719 ; case of overflows,  the result is messed up.
5720 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5721 ; only for comparisons not depending on it.
5723 (define_insn "*adddi_4"
5724   [(set (reg FLAGS_REG)
5725         (compare
5726           (match_operand:DI 1 "nonimmediate_operand" "0")
5727           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5728    (clobber (match_scratch:DI 0 "=rm"))]
5729   "TARGET_64BIT
5730    && ix86_match_ccmode (insn, CCGCmode)"
5732   switch (get_attr_type (insn))
5733     {
5734     case TYPE_INCDEC:
5735       if (operands[2] == constm1_rtx)
5736         return "inc{q}\t%0";
5737       else
5738         {
5739           gcc_assert (operands[2] == const1_rtx);
5740           return "dec{q}\t%0";
5741         }
5743     default:
5744       if (x86_maybe_negate_const_int (&operands[2], DImode))
5745         return "add{q}\t{%2, %0|%0, %2}";
5747       return "sub{q}\t{%2, %0|%0, %2}";
5748     }
5750   [(set (attr "type")
5751      (if_then_else (match_operand:DI 2 "incdec_operand")
5752         (const_string "incdec")
5753         (const_string "alu")))
5754    (set (attr "length_immediate")
5755       (if_then_else
5756         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5757         (const_string "1")
5758         (const_string "*")))
5759    (set_attr "mode" "DI")])
5761 ; For comparisons against 1, -1 and 128, we may generate better code
5762 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5763 ; is matched then.  We can't accept general immediate, because for
5764 ; case of overflows,  the result is messed up.
5765 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5766 ; only for comparisons not depending on it.
5768 (define_insn "*add<mode>_4"
5769   [(set (reg FLAGS_REG)
5770         (compare
5771           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5772           (match_operand:SWI124 2 "const_int_operand" "n")))
5773    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5774   "ix86_match_ccmode (insn, CCGCmode)"
5776   switch (get_attr_type (insn))
5777     {
5778     case TYPE_INCDEC:
5779       if (operands[2] == constm1_rtx)
5780         return "inc{<imodesuffix>}\t%0";
5781       else
5782         {
5783           gcc_assert (operands[2] == const1_rtx);
5784           return "dec{<imodesuffix>}\t%0";
5785         }
5787     default:
5788       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5789         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5791       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5792     }
5794   [(set (attr "type")
5795      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5796         (const_string "incdec")
5797         (const_string "alu")))
5798    (set (attr "length_immediate")
5799       (if_then_else
5800         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5801         (const_string "1")
5802         (const_string "*")))
5803    (set_attr "mode" "<MODE>")])
5805 (define_insn "*add<mode>_5"
5806   [(set (reg FLAGS_REG)
5807         (compare
5808           (plus:SWI
5809             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5810             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5811           (const_int 0)))
5812    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5813   "ix86_match_ccmode (insn, CCGOCmode)
5814    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5816   switch (get_attr_type (insn))
5817     {
5818     case TYPE_INCDEC:
5819       if (operands[2] == const1_rtx)
5820         return "inc{<imodesuffix>}\t%0";
5821       else
5822         {
5823           gcc_assert (operands[2] == constm1_rtx);
5824           return "dec{<imodesuffix>}\t%0";
5825         }
5827     default:
5828       if (which_alternative == 1)
5829         std::swap (operands[1], operands[2]);
5831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5832       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5833         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5835       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5836     }
5838   [(set (attr "type")
5839      (if_then_else (match_operand:SWI 2 "incdec_operand")
5840         (const_string "incdec")
5841         (const_string "alu")))
5842    (set (attr "length_immediate")
5843       (if_then_else
5844         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5845         (const_string "1")
5846         (const_string "*")))
5847    (set_attr "mode" "<MODE>")])
5849 (define_insn "addqi_ext_1"
5850   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5851                          (const_int 8)
5852                          (const_int 8))
5853         (plus:SI
5854           (zero_extract:SI
5855             (match_operand 1 "ext_register_operand" "0,0")
5856             (const_int 8)
5857             (const_int 8))
5858           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5859    (clobber (reg:CC FLAGS_REG))]
5860   ""
5862   switch (get_attr_type (insn))
5863     {
5864     case TYPE_INCDEC:
5865       if (operands[2] == const1_rtx)
5866         return "inc{b}\t%h0";
5867       else
5868         {
5869           gcc_assert (operands[2] == constm1_rtx);
5870           return "dec{b}\t%h0";
5871         }
5873     default:
5874       return "add{b}\t{%2, %h0|%h0, %2}";
5875     }
5877   [(set_attr "isa" "*,nox64")
5878    (set (attr "type")
5879      (if_then_else (match_operand:QI 2 "incdec_operand")
5880         (const_string "incdec")
5881         (const_string "alu")))
5882    (set_attr "modrm" "1")
5883    (set_attr "mode" "QI")])
5885 (define_insn "*addqi_ext_2"
5886   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5887                          (const_int 8)
5888                          (const_int 8))
5889         (plus:SI
5890           (zero_extract:SI
5891             (match_operand 1 "ext_register_operand" "%0")
5892             (const_int 8)
5893             (const_int 8))
5894           (zero_extract:SI
5895             (match_operand 2 "ext_register_operand" "Q")
5896             (const_int 8)
5897             (const_int 8))))
5898    (clobber (reg:CC FLAGS_REG))]
5899   ""
5900   "add{b}\t{%h2, %h0|%h0, %h2}"
5901   [(set_attr "type" "alu")
5902    (set_attr "mode" "QI")])
5904 ;; Add with jump on overflow.
5905 (define_expand "addv<mode>4"
5906   [(parallel [(set (reg:CCO FLAGS_REG)
5907                    (eq:CCO (plus:<DWI>
5908                               (sign_extend:<DWI>
5909                                  (match_operand:SWI 1 "nonimmediate_operand"))
5910                               (match_dup 4))
5911                            (sign_extend:<DWI>
5912                               (plus:SWI (match_dup 1)
5913                                         (match_operand:SWI 2
5914                                            "<general_operand>")))))
5915               (set (match_operand:SWI 0 "register_operand")
5916                    (plus:SWI (match_dup 1) (match_dup 2)))])
5917    (set (pc) (if_then_else
5918                (eq (reg:CCO FLAGS_REG) (const_int 0))
5919                (label_ref (match_operand 3))
5920                (pc)))]
5921   ""
5923   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5924   if (CONST_INT_P (operands[2]))
5925     operands[4] = operands[2];
5926   else
5927     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5930 (define_insn "*addv<mode>4"
5931   [(set (reg:CCO FLAGS_REG)
5932         (eq:CCO (plus:<DWI>
5933                    (sign_extend:<DWI>
5934                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5935                    (sign_extend:<DWI>
5936                       (match_operand:SWI 2 "<general_sext_operand>"
5937                                            "<r>mWe,<r>We")))
5938                 (sign_extend:<DWI>
5939                    (plus:SWI (match_dup 1) (match_dup 2)))))
5940    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5941         (plus:SWI (match_dup 1) (match_dup 2)))]
5942   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5943   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5944   [(set_attr "type" "alu")
5945    (set_attr "mode" "<MODE>")])
5947 (define_insn "*addv<mode>4_1"
5948   [(set (reg:CCO FLAGS_REG)
5949         (eq:CCO (plus:<DWI>
5950                    (sign_extend:<DWI>
5951                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5952                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5953                 (sign_extend:<DWI>
5954                    (plus:SWI (match_dup 1)
5955                              (match_operand:SWI 2 "x86_64_immediate_operand"
5956                                                   "<i>")))))
5957    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5958         (plus:SWI (match_dup 1) (match_dup 2)))]
5959   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5960    && CONST_INT_P (operands[2])
5961    && INTVAL (operands[2]) == INTVAL (operands[3])"
5962   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5963   [(set_attr "type" "alu")
5964    (set_attr "mode" "<MODE>")
5965    (set (attr "length_immediate")
5966         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5967                   (const_string "1")
5968                (match_test "<MODE_SIZE> == 8")
5969                   (const_string "4")]
5970               (const_string "<MODE_SIZE>")))])
5972 ;; The lea patterns for modes less than 32 bits need to be matched by
5973 ;; several insns converted to real lea by splitters.
5975 (define_insn_and_split "*lea_general_1"
5976   [(set (match_operand 0 "register_operand" "=r")
5977         (plus (plus (match_operand 1 "index_register_operand" "l")
5978                     (match_operand 2 "register_operand" "r"))
5979               (match_operand 3 "immediate_operand" "i")))]
5980   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5981    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5982    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5983    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5984    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5985        || GET_MODE (operands[3]) == VOIDmode)"
5986   "#"
5987   "&& reload_completed"
5988   [(const_int 0)]
5990   machine_mode mode = SImode;
5991   rtx pat;
5993   operands[0] = gen_lowpart (mode, operands[0]);
5994   operands[1] = gen_lowpart (mode, operands[1]);
5995   operands[2] = gen_lowpart (mode, operands[2]);
5996   operands[3] = gen_lowpart (mode, operands[3]);
5998   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5999                       operands[3]);
6001   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6002   DONE;
6004   [(set_attr "type" "lea")
6005    (set_attr "mode" "SI")])
6007 (define_insn_and_split "*lea_general_2"
6008   [(set (match_operand 0 "register_operand" "=r")
6009         (plus (mult (match_operand 1 "index_register_operand" "l")
6010                     (match_operand 2 "const248_operand" "n"))
6011               (match_operand 3 "nonmemory_operand" "ri")))]
6012   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6013    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6014    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6015    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6016        || GET_MODE (operands[3]) == VOIDmode)"
6017   "#"
6018   "&& reload_completed"
6019   [(const_int 0)]
6021   machine_mode mode = SImode;
6022   rtx pat;
6024   operands[0] = gen_lowpart (mode, operands[0]);
6025   operands[1] = gen_lowpart (mode, operands[1]);
6026   operands[3] = gen_lowpart (mode, operands[3]);
6028   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6029                       operands[3]);
6031   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6032   DONE;
6034   [(set_attr "type" "lea")
6035    (set_attr "mode" "SI")])
6037 (define_insn_and_split "*lea_general_3"
6038   [(set (match_operand 0 "register_operand" "=r")
6039         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6040                           (match_operand 2 "const248_operand" "n"))
6041                     (match_operand 3 "register_operand" "r"))
6042               (match_operand 4 "immediate_operand" "i")))]
6043   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6044    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6045    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6046    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6047   "#"
6048   "&& reload_completed"
6049   [(const_int 0)]
6051   machine_mode mode = SImode;
6052   rtx pat;
6054   operands[0] = gen_lowpart (mode, operands[0]);
6055   operands[1] = gen_lowpart (mode, operands[1]);
6056   operands[3] = gen_lowpart (mode, operands[3]);
6057   operands[4] = gen_lowpart (mode, operands[4]);
6059   pat = gen_rtx_PLUS (mode,
6060                       gen_rtx_PLUS (mode,
6061                                     gen_rtx_MULT (mode, operands[1],
6062                                                         operands[2]),
6063                                     operands[3]),
6064                       operands[4]);
6066   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6067   DONE;
6069   [(set_attr "type" "lea")
6070    (set_attr "mode" "SI")])
6072 (define_insn_and_split "*lea_general_4"
6073   [(set (match_operand 0 "register_operand" "=r")
6074         (any_or (ashift
6075                   (match_operand 1 "index_register_operand" "l")
6076                   (match_operand 2 "const_int_operand" "n"))
6077                 (match_operand 3 "const_int_operand" "n")))]
6078   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6079       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6080     || GET_MODE (operands[0]) == SImode
6081     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6082    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6083    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6084    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6085        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6086   "#"
6087   "&& reload_completed"
6088   [(const_int 0)]
6090   machine_mode mode = GET_MODE (operands[0]);
6091   rtx pat;
6093   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6094     { 
6095       mode = SImode; 
6096       operands[0] = gen_lowpart (mode, operands[0]);
6097       operands[1] = gen_lowpart (mode, operands[1]);
6098     }
6100   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6102   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6103                        INTVAL (operands[3]));
6105   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6106   DONE;
6108   [(set_attr "type" "lea")
6109    (set (attr "mode")
6110       (if_then_else (match_operand:DI 0)
6111         (const_string "DI")
6112         (const_string "SI")))])
6114 ;; Subtract instructions
6116 (define_expand "sub<mode>3"
6117   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6118         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6119                      (match_operand:SDWIM 2 "<general_operand>")))]
6120   ""
6121   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6123 (define_insn_and_split "*sub<dwi>3_doubleword"
6124   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6125         (minus:<DWI>
6126           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6127           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6128    (clobber (reg:CC FLAGS_REG))]
6129   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6130   "#"
6131   "reload_completed"
6132   [(parallel [(set (reg:CC FLAGS_REG)
6133                    (compare:CC (match_dup 1) (match_dup 2)))
6134               (set (match_dup 0)
6135                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6136    (parallel [(set (match_dup 3)
6137                    (minus:DWIH
6138                      (minus:DWIH
6139                        (match_dup 4)
6140                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6141                      (match_dup 5)))
6142               (clobber (reg:CC FLAGS_REG))])]
6143   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6145 (define_insn "*sub<mode>_1"
6146   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6147         (minus:SWI
6148           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6149           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6150    (clobber (reg:CC FLAGS_REG))]
6151   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6152   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6153   [(set_attr "type" "alu")
6154    (set_attr "mode" "<MODE>")])
6156 (define_insn "*subsi_1_zext"
6157   [(set (match_operand:DI 0 "register_operand" "=r")
6158         (zero_extend:DI
6159           (minus:SI (match_operand:SI 1 "register_operand" "0")
6160                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6161    (clobber (reg:CC FLAGS_REG))]
6162   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6163   "sub{l}\t{%2, %k0|%k0, %2}"
6164   [(set_attr "type" "alu")
6165    (set_attr "mode" "SI")])
6167 (define_insn "*subqi_1_slp"
6168   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6169         (minus:QI (match_dup 0)
6170                   (match_operand:QI 1 "general_operand" "qn,qm")))
6171    (clobber (reg:CC FLAGS_REG))]
6172   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6173    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6174   "sub{b}\t{%1, %0|%0, %1}"
6175   [(set_attr "type" "alu1")
6176    (set_attr "mode" "QI")])
6178 (define_insn "*sub<mode>_2"
6179   [(set (reg FLAGS_REG)
6180         (compare
6181           (minus:SWI
6182             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6183             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6184           (const_int 0)))
6185    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6186         (minus:SWI (match_dup 1) (match_dup 2)))]
6187   "ix86_match_ccmode (insn, CCGOCmode)
6188    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6189   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6190   [(set_attr "type" "alu")
6191    (set_attr "mode" "<MODE>")])
6193 (define_insn "*subsi_2_zext"
6194   [(set (reg FLAGS_REG)
6195         (compare
6196           (minus:SI (match_operand:SI 1 "register_operand" "0")
6197                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6198           (const_int 0)))
6199    (set (match_operand:DI 0 "register_operand" "=r")
6200         (zero_extend:DI
6201           (minus:SI (match_dup 1)
6202                     (match_dup 2))))]
6203   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6204    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6205   "sub{l}\t{%2, %k0|%k0, %2}"
6206   [(set_attr "type" "alu")
6207    (set_attr "mode" "SI")])
6209 ;; Subtract with jump on overflow.
6210 (define_expand "subv<mode>4"
6211   [(parallel [(set (reg:CCO FLAGS_REG)
6212                    (eq:CCO (minus:<DWI>
6213                               (sign_extend:<DWI>
6214                                  (match_operand:SWI 1 "nonimmediate_operand"))
6215                               (match_dup 4))
6216                            (sign_extend:<DWI>
6217                               (minus:SWI (match_dup 1)
6218                                          (match_operand:SWI 2
6219                                             "<general_operand>")))))
6220               (set (match_operand:SWI 0 "register_operand")
6221                    (minus:SWI (match_dup 1) (match_dup 2)))])
6222    (set (pc) (if_then_else
6223                (eq (reg:CCO FLAGS_REG) (const_int 0))
6224                (label_ref (match_operand 3))
6225                (pc)))]
6226   ""
6228   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6229   if (CONST_INT_P (operands[2]))
6230     operands[4] = operands[2];
6231   else
6232     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6235 (define_insn "*subv<mode>4"
6236   [(set (reg:CCO FLAGS_REG)
6237         (eq:CCO (minus:<DWI>
6238                    (sign_extend:<DWI>
6239                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6240                    (sign_extend:<DWI>
6241                       (match_operand:SWI 2 "<general_sext_operand>"
6242                                            "<r>We,<r>m")))
6243                 (sign_extend:<DWI>
6244                    (minus:SWI (match_dup 1) (match_dup 2)))))
6245    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6246         (minus:SWI (match_dup 1) (match_dup 2)))]
6247   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6248   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6249   [(set_attr "type" "alu")
6250    (set_attr "mode" "<MODE>")])
6252 (define_insn "*subv<mode>4_1"
6253   [(set (reg:CCO FLAGS_REG)
6254         (eq:CCO (minus:<DWI>
6255                    (sign_extend:<DWI>
6256                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6257                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6258                 (sign_extend:<DWI>
6259                    (minus:SWI (match_dup 1)
6260                               (match_operand:SWI 2 "x86_64_immediate_operand"
6261                                                    "<i>")))))
6262    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6263         (minus:SWI (match_dup 1) (match_dup 2)))]
6264   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6265    && CONST_INT_P (operands[2])
6266    && INTVAL (operands[2]) == INTVAL (operands[3])"
6267   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6268   [(set_attr "type" "alu")
6269    (set_attr "mode" "<MODE>")
6270    (set (attr "length_immediate")
6271         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6272                   (const_string "1")
6273                (match_test "<MODE_SIZE> == 8")
6274                   (const_string "4")]
6275               (const_string "<MODE_SIZE>")))])
6277 (define_insn "*sub<mode>_3"
6278   [(set (reg FLAGS_REG)
6279         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6280                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6281    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6282         (minus:SWI (match_dup 1) (match_dup 2)))]
6283   "ix86_match_ccmode (insn, CCmode)
6284    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6285   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6286   [(set_attr "type" "alu")
6287    (set_attr "mode" "<MODE>")])
6289 (define_insn "*subsi_3_zext"
6290   [(set (reg FLAGS_REG)
6291         (compare (match_operand:SI 1 "register_operand" "0")
6292                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6293    (set (match_operand:DI 0 "register_operand" "=r")
6294         (zero_extend:DI
6295           (minus:SI (match_dup 1)
6296                     (match_dup 2))))]
6297   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6298    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6299   "sub{l}\t{%2, %1|%1, %2}"
6300   [(set_attr "type" "alu")
6301    (set_attr "mode" "SI")])
6303 ;; Add with carry and subtract with borrow
6305 (define_insn "add<mode>3_carry"
6306   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6307         (plus:SWI
6308           (plus:SWI
6309             (match_operator:SWI 4 "ix86_carry_flag_operator"
6310              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6311             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6312           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6313    (clobber (reg:CC FLAGS_REG))]
6314   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6315   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6316   [(set_attr "type" "alu")
6317    (set_attr "use_carry" "1")
6318    (set_attr "pent_pair" "pu")
6319    (set_attr "mode" "<MODE>")])
6321 (define_insn "*addsi3_carry_zext"
6322   [(set (match_operand:DI 0 "register_operand" "=r")
6323         (zero_extend:DI
6324           (plus:SI
6325             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6326                       [(reg FLAGS_REG) (const_int 0)])
6327                      (match_operand:SI 1 "register_operand" "%0"))
6328             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6329    (clobber (reg:CC FLAGS_REG))]
6330   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6331   "adc{l}\t{%2, %k0|%k0, %2}"
6332   [(set_attr "type" "alu")
6333    (set_attr "use_carry" "1")
6334    (set_attr "pent_pair" "pu")
6335    (set_attr "mode" "SI")])
6337 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6339 (define_insn "addcarry<mode>"
6340   [(set (reg:CCC FLAGS_REG)
6341         (compare:CCC
6342           (plus:SWI48
6343             (plus:SWI48
6344               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6345                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6346               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6347             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6348           (match_dup 1)))
6349    (set (match_operand:SWI48 0 "register_operand" "=r")
6350         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6351                                  [(match_dup 3) (const_int 0)])
6352                                 (match_dup 1))
6353                     (match_dup 2)))]
6354   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6355   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6356   [(set_attr "type" "alu")
6357    (set_attr "use_carry" "1")
6358    (set_attr "pent_pair" "pu")
6359    (set_attr "mode" "<MODE>")])
6361 (define_insn "sub<mode>3_carry"
6362   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6363         (minus:SWI
6364           (minus:SWI
6365             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6366             (match_operator:SWI 4 "ix86_carry_flag_operator"
6367              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6368           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6369    (clobber (reg:CC FLAGS_REG))]
6370   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6371   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6372   [(set_attr "type" "alu")
6373    (set_attr "use_carry" "1")
6374    (set_attr "pent_pair" "pu")
6375    (set_attr "mode" "<MODE>")])
6377 (define_insn "*subsi3_carry_zext"
6378   [(set (match_operand:DI 0 "register_operand" "=r")
6379         (zero_extend:DI
6380           (minus:SI
6381             (minus:SI
6382               (match_operand:SI 1 "register_operand" "0")
6383               (match_operator:SI 3 "ix86_carry_flag_operator"
6384                [(reg FLAGS_REG) (const_int 0)]))
6385             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6386    (clobber (reg:CC FLAGS_REG))]
6387   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6388   "sbb{l}\t{%2, %k0|%k0, %2}"
6389   [(set_attr "type" "alu")
6390    (set_attr "use_carry" "1")
6391    (set_attr "pent_pair" "pu")
6392    (set_attr "mode" "SI")])
6394 (define_insn "subborrow<mode>"
6395   [(set (reg:CCC FLAGS_REG)
6396         (compare:CCC
6397           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6398           (plus:SWI48
6399             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6400              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6401             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6402    (set (match_operand:SWI48 0 "register_operand" "=r")
6403         (minus:SWI48 (minus:SWI48 (match_dup 1)
6404                                   (match_op_dup 4
6405                                    [(match_dup 3) (const_int 0)]))
6406                      (match_dup 2)))]
6407   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6408   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6409   [(set_attr "type" "alu")
6410    (set_attr "use_carry" "1")
6411    (set_attr "pent_pair" "pu")
6412    (set_attr "mode" "<MODE>")])
6414 ;; Overflow setting add instructions
6416 (define_expand "addqi3_cconly_overflow"
6417   [(parallel
6418      [(set (reg:CCC FLAGS_REG)
6419            (compare:CCC
6420              (plus:QI
6421                (match_operand:QI 0 "nonimmediate_operand")
6422                (match_operand:QI 1 "general_operand"))
6423              (match_dup 0)))
6424       (clobber (match_scratch:QI 2))])]
6425   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6427 (define_insn "*add<mode>3_cconly_overflow"
6428   [(set (reg:CCC FLAGS_REG)
6429         (compare:CCC
6430           (plus:SWI
6431             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6432             (match_operand:SWI 2 "<general_operand>" "<g>"))
6433           (match_dup 1)))
6434    (clobber (match_scratch:SWI 0 "=<r>"))]
6435   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6436   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6437   [(set_attr "type" "alu")
6438    (set_attr "mode" "<MODE>")])
6440 (define_insn "*add<mode>3_cc_overflow"
6441   [(set (reg:CCC FLAGS_REG)
6442         (compare:CCC
6443             (plus:SWI
6444                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6445                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6446             (match_dup 1)))
6447    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448         (plus:SWI (match_dup 1) (match_dup 2)))]
6449   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6450   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6451   [(set_attr "type" "alu")
6452    (set_attr "mode" "<MODE>")])
6454 (define_insn "*addsi3_zext_cc_overflow"
6455   [(set (reg:CCC FLAGS_REG)
6456         (compare:CCC
6457           (plus:SI
6458             (match_operand:SI 1 "nonimmediate_operand" "%0")
6459             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460           (match_dup 1)))
6461    (set (match_operand:DI 0 "register_operand" "=r")
6462         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6463   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6464   "add{l}\t{%2, %k0|%k0, %2}"
6465   [(set_attr "type" "alu")
6466    (set_attr "mode" "SI")])
6468 ;; The patterns that match these are at the end of this file.
6470 (define_expand "<plusminus_insn>xf3"
6471   [(set (match_operand:XF 0 "register_operand")
6472         (plusminus:XF
6473           (match_operand:XF 1 "register_operand")
6474           (match_operand:XF 2 "register_operand")))]
6475   "TARGET_80387")
6477 (define_expand "<plusminus_insn><mode>3"
6478   [(set (match_operand:MODEF 0 "register_operand")
6479         (plusminus:MODEF
6480           (match_operand:MODEF 1 "register_operand")
6481           (match_operand:MODEF 2 "nonimmediate_operand")))]
6482   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6483     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6485 ;; Multiply instructions
6487 (define_expand "mul<mode>3"
6488   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6489                    (mult:SWIM248
6490                      (match_operand:SWIM248 1 "register_operand")
6491                      (match_operand:SWIM248 2 "<general_operand>")))
6492               (clobber (reg:CC FLAGS_REG))])])
6494 (define_expand "mulqi3"
6495   [(parallel [(set (match_operand:QI 0 "register_operand")
6496                    (mult:QI
6497                      (match_operand:QI 1 "register_operand")
6498                      (match_operand:QI 2 "nonimmediate_operand")))
6499               (clobber (reg:CC FLAGS_REG))])]
6500   "TARGET_QIMODE_MATH")
6502 ;; On AMDFAM10
6503 ;; IMUL reg32/64, reg32/64, imm8        Direct
6504 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6505 ;; IMUL reg32/64, reg32/64, imm32       Direct
6506 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6507 ;; IMUL reg32/64, reg32/64              Direct
6508 ;; IMUL reg32/64, mem32/64              Direct
6510 ;; On BDVER1, all above IMULs use DirectPath
6512 (define_insn "*mul<mode>3_1"
6513   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6514         (mult:SWI48
6515           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6516           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6517    (clobber (reg:CC FLAGS_REG))]
6518   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6519   "@
6520    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6521    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6522    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6523   [(set_attr "type" "imul")
6524    (set_attr "prefix_0f" "0,0,1")
6525    (set (attr "athlon_decode")
6526         (cond [(eq_attr "cpu" "athlon")
6527                   (const_string "vector")
6528                (eq_attr "alternative" "1")
6529                   (const_string "vector")
6530                (and (eq_attr "alternative" "2")
6531                     (match_operand 1 "memory_operand"))
6532                   (const_string "vector")]
6533               (const_string "direct")))
6534    (set (attr "amdfam10_decode")
6535         (cond [(and (eq_attr "alternative" "0,1")
6536                     (match_operand 1 "memory_operand"))
6537                   (const_string "vector")]
6538               (const_string "direct")))
6539    (set_attr "bdver1_decode" "direct")
6540    (set_attr "mode" "<MODE>")])
6542 (define_insn "*mulsi3_1_zext"
6543   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6544         (zero_extend:DI
6545           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6546                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6547    (clobber (reg:CC FLAGS_REG))]
6548   "TARGET_64BIT
6549    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6550   "@
6551    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6552    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6553    imul{l}\t{%2, %k0|%k0, %2}"
6554   [(set_attr "type" "imul")
6555    (set_attr "prefix_0f" "0,0,1")
6556    (set (attr "athlon_decode")
6557         (cond [(eq_attr "cpu" "athlon")
6558                   (const_string "vector")
6559                (eq_attr "alternative" "1")
6560                   (const_string "vector")
6561                (and (eq_attr "alternative" "2")
6562                     (match_operand 1 "memory_operand"))
6563                   (const_string "vector")]
6564               (const_string "direct")))
6565    (set (attr "amdfam10_decode")
6566         (cond [(and (eq_attr "alternative" "0,1")
6567                     (match_operand 1 "memory_operand"))
6568                   (const_string "vector")]
6569               (const_string "direct")))
6570    (set_attr "bdver1_decode" "direct")
6571    (set_attr "mode" "SI")])
6573 ;; On AMDFAM10
6574 ;; IMUL reg16, reg16, imm8      VectorPath
6575 ;; IMUL reg16, mem16, imm8      VectorPath
6576 ;; IMUL reg16, reg16, imm16     VectorPath
6577 ;; IMUL reg16, mem16, imm16     VectorPath
6578 ;; IMUL reg16, reg16            Direct
6579 ;; IMUL reg16, mem16            Direct
6581 ;; On BDVER1, all HI MULs use DoublePath
6583 (define_insn "*mulhi3_1"
6584   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6585         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6586                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6587    (clobber (reg:CC FLAGS_REG))]
6588   "TARGET_HIMODE_MATH
6589    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6590   "@
6591    imul{w}\t{%2, %1, %0|%0, %1, %2}
6592    imul{w}\t{%2, %1, %0|%0, %1, %2}
6593    imul{w}\t{%2, %0|%0, %2}"
6594   [(set_attr "type" "imul")
6595    (set_attr "prefix_0f" "0,0,1")
6596    (set (attr "athlon_decode")
6597         (cond [(eq_attr "cpu" "athlon")
6598                   (const_string "vector")
6599                (eq_attr "alternative" "1,2")
6600                   (const_string "vector")]
6601               (const_string "direct")))
6602    (set (attr "amdfam10_decode")
6603         (cond [(eq_attr "alternative" "0,1")
6604                   (const_string "vector")]
6605               (const_string "direct")))
6606    (set_attr "bdver1_decode" "double")
6607    (set_attr "mode" "HI")])
6609 ;;On AMDFAM10 and BDVER1
6610 ;; MUL reg8     Direct
6611 ;; MUL mem8     Direct
6613 (define_insn "*mulqi3_1"
6614   [(set (match_operand:QI 0 "register_operand" "=a")
6615         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6616                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6617    (clobber (reg:CC FLAGS_REG))]
6618   "TARGET_QIMODE_MATH
6619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6620   "mul{b}\t%2"
6621   [(set_attr "type" "imul")
6622    (set_attr "length_immediate" "0")
6623    (set (attr "athlon_decode")
6624      (if_then_else (eq_attr "cpu" "athlon")
6625         (const_string "vector")
6626         (const_string "direct")))
6627    (set_attr "amdfam10_decode" "direct")
6628    (set_attr "bdver1_decode" "direct")
6629    (set_attr "mode" "QI")])
6631 ;; Multiply with jump on overflow.
6632 (define_expand "mulv<mode>4"
6633   [(parallel [(set (reg:CCO FLAGS_REG)
6634                    (eq:CCO (mult:<DWI>
6635                               (sign_extend:<DWI>
6636                                  (match_operand:SWI48 1 "register_operand"))
6637                               (match_dup 4))
6638                            (sign_extend:<DWI>
6639                               (mult:SWI48 (match_dup 1)
6640                                           (match_operand:SWI48 2
6641                                              "<general_operand>")))))
6642               (set (match_operand:SWI48 0 "register_operand")
6643                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6644    (set (pc) (if_then_else
6645                (eq (reg:CCO FLAGS_REG) (const_int 0))
6646                (label_ref (match_operand 3))
6647                (pc)))]
6648   ""
6650   if (CONST_INT_P (operands[2]))
6651     operands[4] = operands[2];
6652   else
6653     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6656 (define_insn "*mulv<mode>4"
6657   [(set (reg:CCO FLAGS_REG)
6658         (eq:CCO (mult:<DWI>
6659                    (sign_extend:<DWI>
6660                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6661                    (sign_extend:<DWI>
6662                       (match_operand:SWI48 2 "<general_sext_operand>"
6663                                              "We,mr")))
6664                 (sign_extend:<DWI>
6665                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6666    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6667         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6668   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6669   "@
6670    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6671    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6672   [(set_attr "type" "imul")
6673    (set_attr "prefix_0f" "0,1")
6674    (set (attr "athlon_decode")
6675         (cond [(eq_attr "cpu" "athlon")
6676                   (const_string "vector")
6677                (eq_attr "alternative" "0")
6678                   (const_string "vector")
6679                (and (eq_attr "alternative" "1")
6680                     (match_operand 1 "memory_operand"))
6681                   (const_string "vector")]
6682               (const_string "direct")))
6683    (set (attr "amdfam10_decode")
6684         (cond [(and (eq_attr "alternative" "1")
6685                     (match_operand 1 "memory_operand"))
6686                   (const_string "vector")]
6687               (const_string "direct")))
6688    (set_attr "bdver1_decode" "direct")
6689    (set_attr "mode" "<MODE>")])
6691 (define_insn "*mulv<mode>4_1"
6692   [(set (reg:CCO FLAGS_REG)
6693         (eq:CCO (mult:<DWI>
6694                    (sign_extend:<DWI>
6695                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6696                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6697                 (sign_extend:<DWI>
6698                    (mult:SWI48 (match_dup 1)
6699                                (match_operand:SWI 2 "x86_64_immediate_operand"
6700                                                     "K,<i>")))))
6701    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6702         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6703   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6704    && CONST_INT_P (operands[2])
6705    && INTVAL (operands[2]) == INTVAL (operands[3])"
6706   "@
6707    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6708    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6709   [(set_attr "type" "imul")
6710    (set (attr "athlon_decode")
6711         (cond [(eq_attr "cpu" "athlon")
6712                   (const_string "vector")
6713                (eq_attr "alternative" "1")
6714                   (const_string "vector")]
6715               (const_string "direct")))
6716    (set (attr "amdfam10_decode")
6717         (cond [(match_operand 1 "memory_operand")
6718                   (const_string "vector")]
6719               (const_string "direct")))
6720    (set_attr "bdver1_decode" "direct")
6721    (set_attr "mode" "<MODE>")
6722    (set (attr "length_immediate")
6723         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6724                   (const_string "1")
6725                (match_test "<MODE_SIZE> == 8")
6726                   (const_string "4")]
6727               (const_string "<MODE_SIZE>")))])
6729 (define_expand "umulv<mode>4"
6730   [(parallel [(set (reg:CCO FLAGS_REG)
6731                    (eq:CCO (mult:<DWI>
6732                               (zero_extend:<DWI>
6733                                  (match_operand:SWI48 1
6734                                                       "nonimmediate_operand"))
6735                               (zero_extend:<DWI>
6736                                  (match_operand:SWI48 2
6737                                                       "nonimmediate_operand")))
6738                            (zero_extend:<DWI>
6739                               (mult:SWI48 (match_dup 1) (match_dup 2)))))
6740               (set (match_operand:SWI48 0 "register_operand")
6741                    (mult:SWI48 (match_dup 1) (match_dup 2)))
6742               (clobber (match_scratch:SWI48 4))])
6743    (set (pc) (if_then_else
6744                (eq (reg:CCO FLAGS_REG) (const_int 0))
6745                (label_ref (match_operand 3))
6746                (pc)))]
6747   ""
6749   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6750     operands[1] = force_reg (<MODE>mode, operands[1]);
6753 (define_insn "*umulv<mode>4"
6754   [(set (reg:CCO FLAGS_REG)
6755         (eq:CCO (mult:<DWI>
6756                    (zero_extend:<DWI>
6757                       (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6758                    (zero_extend:<DWI>
6759                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6760                 (zero_extend:<DWI>
6761                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6762    (set (match_operand:SWI48 0 "register_operand" "=a")
6763         (mult:SWI48 (match_dup 1) (match_dup 2)))
6764    (clobber (match_scratch:SWI48 3 "=d"))]
6765   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6766   "mul{<imodesuffix>}\t%2"
6767   [(set_attr "type" "imul")
6768    (set_attr "length_immediate" "0")
6769    (set (attr "athlon_decode")
6770      (if_then_else (eq_attr "cpu" "athlon")
6771        (const_string "vector")
6772        (const_string "double")))
6773    (set_attr "amdfam10_decode" "double")
6774    (set_attr "bdver1_decode" "direct")
6775    (set_attr "mode" "<MODE>")])
6777 (define_expand "<u>mulvqi4"
6778   [(parallel [(set (reg:CCO FLAGS_REG)
6779                    (eq:CCO (mult:HI
6780                               (any_extend:HI
6781                                  (match_operand:QI 1 "nonimmediate_operand"))
6782                               (any_extend:HI
6783                                  (match_operand:QI 2 "nonimmediate_operand")))
6784                            (any_extend:HI
6785                               (mult:QI (match_dup 1) (match_dup 2)))))
6786               (set (match_operand:QI 0 "register_operand")
6787                    (mult:QI (match_dup 1) (match_dup 2)))])
6788    (set (pc) (if_then_else
6789                (eq (reg:CCO FLAGS_REG) (const_int 0))
6790                (label_ref (match_operand 3))
6791                (pc)))]
6792   "TARGET_QIMODE_MATH"
6794   if (MEM_P (operands[1]) && MEM_P (operands[2]))
6795     operands[1] = force_reg (QImode, operands[1]);
6798 (define_insn "*<u>mulvqi4"
6799   [(set (reg:CCO FLAGS_REG)
6800         (eq:CCO (mult:HI
6801                    (any_extend:HI
6802                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
6803                    (any_extend:HI
6804                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
6805                 (any_extend:HI
6806                    (mult:QI (match_dup 1) (match_dup 2)))))
6807    (set (match_operand:QI 0 "register_operand" "=a")
6808         (mult:QI (match_dup 1) (match_dup 2)))]
6809   "TARGET_QIMODE_MATH
6810    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811   "<sgnprefix>mul{b}\t%2"
6812   [(set_attr "type" "imul")
6813    (set_attr "length_immediate" "0")
6814    (set (attr "athlon_decode")
6815      (if_then_else (eq_attr "cpu" "athlon")
6816         (const_string "vector")
6817         (const_string "direct")))
6818    (set_attr "amdfam10_decode" "direct")
6819    (set_attr "bdver1_decode" "direct")
6820    (set_attr "mode" "QI")])
6822 (define_expand "<u>mul<mode><dwi>3"
6823   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6824                    (mult:<DWI>
6825                      (any_extend:<DWI>
6826                        (match_operand:DWIH 1 "nonimmediate_operand"))
6827                      (any_extend:<DWI>
6828                        (match_operand:DWIH 2 "register_operand"))))
6829               (clobber (reg:CC FLAGS_REG))])])
6831 (define_expand "<u>mulqihi3"
6832   [(parallel [(set (match_operand:HI 0 "register_operand")
6833                    (mult:HI
6834                      (any_extend:HI
6835                        (match_operand:QI 1 "nonimmediate_operand"))
6836                      (any_extend:HI
6837                        (match_operand:QI 2 "register_operand"))))
6838               (clobber (reg:CC FLAGS_REG))])]
6839   "TARGET_QIMODE_MATH")
6841 (define_insn "*bmi2_umulditi3_1"
6842   [(set (match_operand:DI 0 "register_operand" "=r")
6843         (mult:DI
6844           (match_operand:DI 2 "nonimmediate_operand" "%d")
6845           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6846    (set (match_operand:DI 1 "register_operand" "=r")
6847         (truncate:DI
6848           (lshiftrt:TI
6849             (mult:TI (zero_extend:TI (match_dup 2))
6850                      (zero_extend:TI (match_dup 3)))
6851             (const_int 64))))]
6852   "TARGET_64BIT && TARGET_BMI2
6853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854   "mulx\t{%3, %0, %1|%1, %0, %3}"
6855   [(set_attr "type" "imulx")
6856    (set_attr "prefix" "vex")
6857    (set_attr "mode" "DI")])
6859 (define_insn "*bmi2_umulsidi3_1"
6860   [(set (match_operand:SI 0 "register_operand" "=r")
6861         (mult:SI
6862           (match_operand:SI 2 "nonimmediate_operand" "%d")
6863           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6864    (set (match_operand:SI 1 "register_operand" "=r")
6865         (truncate:SI
6866           (lshiftrt:DI
6867             (mult:DI (zero_extend:DI (match_dup 2))
6868                      (zero_extend:DI (match_dup 3)))
6869             (const_int 32))))]
6870   "!TARGET_64BIT && TARGET_BMI2
6871    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872   "mulx\t{%3, %0, %1|%1, %0, %3}"
6873   [(set_attr "type" "imulx")
6874    (set_attr "prefix" "vex")
6875    (set_attr "mode" "SI")])
6877 (define_insn "*umul<mode><dwi>3_1"
6878   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6879         (mult:<DWI>
6880           (zero_extend:<DWI>
6881             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6882           (zero_extend:<DWI>
6883             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886   "@
6887    #
6888    mul{<imodesuffix>}\t%2"
6889   [(set_attr "isa" "bmi2,*")
6890    (set_attr "type" "imulx,imul")
6891    (set_attr "length_immediate" "*,0")
6892    (set (attr "athlon_decode")
6893         (cond [(eq_attr "alternative" "1")
6894                  (if_then_else (eq_attr "cpu" "athlon")
6895                    (const_string "vector")
6896                    (const_string "double"))]
6897               (const_string "*")))
6898    (set_attr "amdfam10_decode" "*,double")
6899    (set_attr "bdver1_decode" "*,direct")
6900    (set_attr "prefix" "vex,orig")
6901    (set_attr "mode" "<MODE>")])
6903 ;; Convert mul to the mulx pattern to avoid flags dependency.
6904 (define_split
6905  [(set (match_operand:<DWI> 0 "register_operand")
6906        (mult:<DWI>
6907          (zero_extend:<DWI>
6908            (match_operand:DWIH 1 "register_operand"))
6909          (zero_extend:<DWI>
6910            (match_operand:DWIH 2 "nonimmediate_operand"))))
6911   (clobber (reg:CC FLAGS_REG))]
6912  "TARGET_BMI2 && reload_completed
6913   && true_regnum (operands[1]) == DX_REG"
6914   [(parallel [(set (match_dup 3)
6915                    (mult:DWIH (match_dup 1) (match_dup 2)))
6916               (set (match_dup 4)
6917                    (truncate:DWIH
6918                      (lshiftrt:<DWI>
6919                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6920                                    (zero_extend:<DWI> (match_dup 2)))
6921                        (match_dup 5))))])]
6923   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6925   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6928 (define_insn "*mul<mode><dwi>3_1"
6929   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6930         (mult:<DWI>
6931           (sign_extend:<DWI>
6932             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6933           (sign_extend:<DWI>
6934             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6935    (clobber (reg:CC FLAGS_REG))]
6936   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937   "imul{<imodesuffix>}\t%2"
6938   [(set_attr "type" "imul")
6939    (set_attr "length_immediate" "0")
6940    (set (attr "athlon_decode")
6941      (if_then_else (eq_attr "cpu" "athlon")
6942         (const_string "vector")
6943         (const_string "double")))
6944    (set_attr "amdfam10_decode" "double")
6945    (set_attr "bdver1_decode" "direct")
6946    (set_attr "mode" "<MODE>")])
6948 (define_insn "*<u>mulqihi3_1"
6949   [(set (match_operand:HI 0 "register_operand" "=a")
6950         (mult:HI
6951           (any_extend:HI
6952             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6953           (any_extend:HI
6954             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6955    (clobber (reg:CC FLAGS_REG))]
6956   "TARGET_QIMODE_MATH
6957    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6958   "<sgnprefix>mul{b}\t%2"
6959   [(set_attr "type" "imul")
6960    (set_attr "length_immediate" "0")
6961    (set (attr "athlon_decode")
6962      (if_then_else (eq_attr "cpu" "athlon")
6963         (const_string "vector")
6964         (const_string "direct")))
6965    (set_attr "amdfam10_decode" "direct")
6966    (set_attr "bdver1_decode" "direct")
6967    (set_attr "mode" "QI")])
6969 (define_expand "<s>mul<mode>3_highpart"
6970   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6971                    (truncate:SWI48
6972                      (lshiftrt:<DWI>
6973                        (mult:<DWI>
6974                          (any_extend:<DWI>
6975                            (match_operand:SWI48 1 "nonimmediate_operand"))
6976                          (any_extend:<DWI>
6977                            (match_operand:SWI48 2 "register_operand")))
6978                        (match_dup 4))))
6979               (clobber (match_scratch:SWI48 3))
6980               (clobber (reg:CC FLAGS_REG))])]
6981   ""
6982   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6984 (define_insn "*<s>muldi3_highpart_1"
6985   [(set (match_operand:DI 0 "register_operand" "=d")
6986         (truncate:DI
6987           (lshiftrt:TI
6988             (mult:TI
6989               (any_extend:TI
6990                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6991               (any_extend:TI
6992                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6993             (const_int 64))))
6994    (clobber (match_scratch:DI 3 "=1"))
6995    (clobber (reg:CC FLAGS_REG))]
6996   "TARGET_64BIT
6997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998   "<sgnprefix>mul{q}\t%2"
6999   [(set_attr "type" "imul")
7000    (set_attr "length_immediate" "0")
7001    (set (attr "athlon_decode")
7002      (if_then_else (eq_attr "cpu" "athlon")
7003         (const_string "vector")
7004         (const_string "double")))
7005    (set_attr "amdfam10_decode" "double")
7006    (set_attr "bdver1_decode" "direct")
7007    (set_attr "mode" "DI")])
7009 (define_insn "*<s>mulsi3_highpart_1"
7010   [(set (match_operand:SI 0 "register_operand" "=d")
7011         (truncate:SI
7012           (lshiftrt:DI
7013             (mult:DI
7014               (any_extend:DI
7015                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7016               (any_extend:DI
7017                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7018             (const_int 32))))
7019    (clobber (match_scratch:SI 3 "=1"))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022   "<sgnprefix>mul{l}\t%2"
7023   [(set_attr "type" "imul")
7024    (set_attr "length_immediate" "0")
7025    (set (attr "athlon_decode")
7026      (if_then_else (eq_attr "cpu" "athlon")
7027         (const_string "vector")
7028         (const_string "double")))
7029    (set_attr "amdfam10_decode" "double")
7030    (set_attr "bdver1_decode" "direct")
7031    (set_attr "mode" "SI")])
7033 (define_insn "*<s>mulsi3_highpart_zext"
7034   [(set (match_operand:DI 0 "register_operand" "=d")
7035         (zero_extend:DI (truncate:SI
7036           (lshiftrt:DI
7037             (mult:DI (any_extend:DI
7038                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7039                      (any_extend:DI
7040                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7041             (const_int 32)))))
7042    (clobber (match_scratch:SI 3 "=1"))
7043    (clobber (reg:CC FLAGS_REG))]
7044   "TARGET_64BIT
7045    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046   "<sgnprefix>mul{l}\t%2"
7047   [(set_attr "type" "imul")
7048    (set_attr "length_immediate" "0")
7049    (set (attr "athlon_decode")
7050      (if_then_else (eq_attr "cpu" "athlon")
7051         (const_string "vector")
7052         (const_string "double")))
7053    (set_attr "amdfam10_decode" "double")
7054    (set_attr "bdver1_decode" "direct")
7055    (set_attr "mode" "SI")])
7057 ;; The patterns that match these are at the end of this file.
7059 (define_expand "mulxf3"
7060   [(set (match_operand:XF 0 "register_operand")
7061         (mult:XF (match_operand:XF 1 "register_operand")
7062                  (match_operand:XF 2 "register_operand")))]
7063   "TARGET_80387")
7065 (define_expand "mul<mode>3"
7066   [(set (match_operand:MODEF 0 "register_operand")
7067         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7068                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7069   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7070     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7072 ;; Divide instructions
7074 ;; The patterns that match these are at the end of this file.
7076 (define_expand "divxf3"
7077   [(set (match_operand:XF 0 "register_operand")
7078         (div:XF (match_operand:XF 1 "register_operand")
7079                 (match_operand:XF 2 "register_operand")))]
7080   "TARGET_80387")
7082 (define_expand "divdf3"
7083   [(set (match_operand:DF 0 "register_operand")
7084         (div:DF (match_operand:DF 1 "register_operand")
7085                 (match_operand:DF 2 "nonimmediate_operand")))]
7086    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7087     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7089 (define_expand "divsf3"
7090   [(set (match_operand:SF 0 "register_operand")
7091         (div:SF (match_operand:SF 1 "register_operand")
7092                 (match_operand:SF 2 "nonimmediate_operand")))]
7093   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7094     || TARGET_SSE_MATH"
7096   if (TARGET_SSE_MATH
7097       && TARGET_RECIP_DIV
7098       && optimize_insn_for_speed_p ()
7099       && flag_finite_math_only && !flag_trapping_math
7100       && flag_unsafe_math_optimizations)
7101     {
7102       ix86_emit_swdivsf (operands[0], operands[1],
7103                          operands[2], SFmode);
7104       DONE;
7105     }
7108 ;; Divmod instructions.
7110 (define_expand "divmod<mode>4"
7111   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7112                    (div:SWIM248
7113                      (match_operand:SWIM248 1 "register_operand")
7114                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7115               (set (match_operand:SWIM248 3 "register_operand")
7116                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7117               (clobber (reg:CC FLAGS_REG))])])
7119 ;; Split with 8bit unsigned divide:
7120 ;;      if (dividend an divisor are in [0-255])
7121 ;;         use 8bit unsigned integer divide
7122 ;;       else
7123 ;;         use original integer divide
7124 (define_split
7125   [(set (match_operand:SWI48 0 "register_operand")
7126         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7127                     (match_operand:SWI48 3 "nonimmediate_operand")))
7128    (set (match_operand:SWI48 1 "register_operand")
7129         (mod:SWI48 (match_dup 2) (match_dup 3)))
7130    (clobber (reg:CC FLAGS_REG))]
7131   "TARGET_USE_8BIT_IDIV
7132    && TARGET_QIMODE_MATH
7133    && can_create_pseudo_p ()
7134    && !optimize_insn_for_size_p ()"
7135   [(const_int 0)]
7136   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7138 (define_insn_and_split "divmod<mode>4_1"
7139   [(set (match_operand:SWI48 0 "register_operand" "=a")
7140         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7141                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7142    (set (match_operand:SWI48 1 "register_operand" "=&d")
7143         (mod:SWI48 (match_dup 2) (match_dup 3)))
7144    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7145    (clobber (reg:CC FLAGS_REG))]
7146   ""
7147   "#"
7148   "reload_completed"
7149   [(parallel [(set (match_dup 1)
7150                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7151               (clobber (reg:CC FLAGS_REG))])
7152    (parallel [(set (match_dup 0)
7153                    (div:SWI48 (match_dup 2) (match_dup 3)))
7154               (set (match_dup 1)
7155                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7156               (use (match_dup 1))
7157               (clobber (reg:CC FLAGS_REG))])]
7159   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7161   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7162     operands[4] = operands[2];
7163   else
7164     {
7165       /* Avoid use of cltd in favor of a mov+shift.  */
7166       emit_move_insn (operands[1], operands[2]);
7167       operands[4] = operands[1];
7168     }
7170   [(set_attr "type" "multi")
7171    (set_attr "mode" "<MODE>")])
7173 (define_insn_and_split "*divmod<mode>4"
7174   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7175         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7176                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7177    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7178         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7179    (clobber (reg:CC FLAGS_REG))]
7180   ""
7181   "#"
7182   "reload_completed"
7183   [(parallel [(set (match_dup 1)
7184                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7185               (clobber (reg:CC FLAGS_REG))])
7186    (parallel [(set (match_dup 0)
7187                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7188               (set (match_dup 1)
7189                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7190               (use (match_dup 1))
7191               (clobber (reg:CC FLAGS_REG))])]
7193   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7195   if (<MODE>mode != HImode
7196       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7197     operands[4] = operands[2];
7198   else
7199     {
7200       /* Avoid use of cltd in favor of a mov+shift.  */
7201       emit_move_insn (operands[1], operands[2]);
7202       operands[4] = operands[1];
7203     }
7205   [(set_attr "type" "multi")
7206    (set_attr "mode" "<MODE>")])
7208 (define_insn "*divmod<mode>4_noext"
7209   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7210         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7211                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7212    (set (match_operand:SWIM248 1 "register_operand" "=d")
7213         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7214    (use (match_operand:SWIM248 4 "register_operand" "1"))
7215    (clobber (reg:CC FLAGS_REG))]
7216   ""
7217   "idiv{<imodesuffix>}\t%3"
7218   [(set_attr "type" "idiv")
7219    (set_attr "mode" "<MODE>")])
7221 (define_expand "divmodqi4"
7222   [(parallel [(set (match_operand:QI 0 "register_operand")
7223                    (div:QI
7224                      (match_operand:QI 1 "register_operand")
7225                      (match_operand:QI 2 "nonimmediate_operand")))
7226               (set (match_operand:QI 3 "register_operand")
7227                    (mod:QI (match_dup 1) (match_dup 2)))
7228               (clobber (reg:CC FLAGS_REG))])]
7229   "TARGET_QIMODE_MATH"
7231   rtx div, mod, insn;
7232   rtx tmp0, tmp1;
7233   
7234   tmp0 = gen_reg_rtx (HImode);
7235   tmp1 = gen_reg_rtx (HImode);
7237   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7238      in AX.  */
7239   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7240   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7242   /* Extract remainder from AH.  */
7243   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7244   insn = emit_move_insn (operands[3], tmp1);
7246   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7247   set_unique_reg_note (insn, REG_EQUAL, mod);
7249   /* Extract quotient from AL.  */
7250   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7252   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7253   set_unique_reg_note (insn, REG_EQUAL, div);
7255   DONE;
7258 ;; Divide AX by r/m8, with result stored in
7259 ;; AL <- Quotient
7260 ;; AH <- Remainder
7261 ;; Change div/mod to HImode and extend the second argument to HImode
7262 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7263 ;; combine may fail.
7264 (define_insn "divmodhiqi3"
7265   [(set (match_operand:HI 0 "register_operand" "=a")
7266         (ior:HI
7267           (ashift:HI
7268             (zero_extend:HI
7269               (truncate:QI
7270                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7271                         (sign_extend:HI
7272                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7273             (const_int 8))
7274           (zero_extend:HI
7275             (truncate:QI
7276               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7277    (clobber (reg:CC FLAGS_REG))]
7278   "TARGET_QIMODE_MATH"
7279   "idiv{b}\t%2"
7280   [(set_attr "type" "idiv")
7281    (set_attr "mode" "QI")])
7283 (define_expand "udivmod<mode>4"
7284   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7285                    (udiv:SWIM248
7286                      (match_operand:SWIM248 1 "register_operand")
7287                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7288               (set (match_operand:SWIM248 3 "register_operand")
7289                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7290               (clobber (reg:CC FLAGS_REG))])])
7292 ;; Split with 8bit unsigned divide:
7293 ;;      if (dividend an divisor are in [0-255])
7294 ;;         use 8bit unsigned integer divide
7295 ;;       else
7296 ;;         use original integer divide
7297 (define_split
7298   [(set (match_operand:SWI48 0 "register_operand")
7299         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7300                     (match_operand:SWI48 3 "nonimmediate_operand")))
7301    (set (match_operand:SWI48 1 "register_operand")
7302         (umod:SWI48 (match_dup 2) (match_dup 3)))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "TARGET_USE_8BIT_IDIV
7305    && TARGET_QIMODE_MATH
7306    && can_create_pseudo_p ()
7307    && !optimize_insn_for_size_p ()"
7308   [(const_int 0)]
7309   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7311 (define_insn_and_split "udivmod<mode>4_1"
7312   [(set (match_operand:SWI48 0 "register_operand" "=a")
7313         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7314                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7315    (set (match_operand:SWI48 1 "register_operand" "=&d")
7316         (umod:SWI48 (match_dup 2) (match_dup 3)))
7317    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7318    (clobber (reg:CC FLAGS_REG))]
7319   ""
7320   "#"
7321   "reload_completed"
7322   [(set (match_dup 1) (const_int 0))
7323    (parallel [(set (match_dup 0)
7324                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7325               (set (match_dup 1)
7326                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7327               (use (match_dup 1))
7328               (clobber (reg:CC FLAGS_REG))])]
7329   ""
7330   [(set_attr "type" "multi")
7331    (set_attr "mode" "<MODE>")])
7333 (define_insn_and_split "*udivmod<mode>4"
7334   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7335         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7336                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7337    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7338         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7339    (clobber (reg:CC FLAGS_REG))]
7340   ""
7341   "#"
7342   "reload_completed"
7343   [(set (match_dup 1) (const_int 0))
7344    (parallel [(set (match_dup 0)
7345                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7346               (set (match_dup 1)
7347                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7348               (use (match_dup 1))
7349               (clobber (reg:CC FLAGS_REG))])]
7350   ""
7351   [(set_attr "type" "multi")
7352    (set_attr "mode" "<MODE>")])
7354 ;; Optimize division or modulo by constant power of 2, if the constant
7355 ;; materializes only after expansion.
7356 (define_insn_and_split "*udivmod<mode>4_pow2"
7357   [(set (match_operand:SWI48 0 "register_operand" "=r")
7358         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7359                     (match_operand:SWI48 3 "const_int_operand" "n")))
7360    (set (match_operand:SWI48 1 "register_operand" "=r")
7361         (umod:SWI48 (match_dup 2) (match_dup 3)))
7362    (clobber (reg:CC FLAGS_REG))]
7363   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7364    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7365   "#"
7366   "&& 1"
7367   [(set (match_dup 1) (match_dup 2))
7368    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7369               (clobber (reg:CC FLAGS_REG))])
7370    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7371               (clobber (reg:CC FLAGS_REG))])]
7373   int v = exact_log2 (UINTVAL (operands[3]));
7374   operands[4] = GEN_INT (v);
7375   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7377   [(set_attr "type" "multi")
7378    (set_attr "mode" "<MODE>")])
7380 (define_insn "*udivmod<mode>4_noext"
7381   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7382         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7383                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7384    (set (match_operand:SWIM248 1 "register_operand" "=d")
7385         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7386    (use (match_operand:SWIM248 4 "register_operand" "1"))
7387    (clobber (reg:CC FLAGS_REG))]
7388   ""
7389   "div{<imodesuffix>}\t%3"
7390   [(set_attr "type" "idiv")
7391    (set_attr "mode" "<MODE>")])
7393 (define_expand "udivmodqi4"
7394   [(parallel [(set (match_operand:QI 0 "register_operand")
7395                    (udiv:QI
7396                      (match_operand:QI 1 "register_operand")
7397                      (match_operand:QI 2 "nonimmediate_operand")))
7398               (set (match_operand:QI 3 "register_operand")
7399                    (umod:QI (match_dup 1) (match_dup 2)))
7400               (clobber (reg:CC FLAGS_REG))])]
7401   "TARGET_QIMODE_MATH"
7403   rtx div, mod, insn;
7404   rtx tmp0, tmp1;
7405   
7406   tmp0 = gen_reg_rtx (HImode);
7407   tmp1 = gen_reg_rtx (HImode);
7409   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7410      in AX.  */
7411   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7412   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7414   /* Extract remainder from AH.  */
7415   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7416   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7417   insn = emit_move_insn (operands[3], tmp1);
7419   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7420   set_unique_reg_note (insn, REG_EQUAL, mod);
7422   /* Extract quotient from AL.  */
7423   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7425   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7426   set_unique_reg_note (insn, REG_EQUAL, div);
7428   DONE;
7431 (define_insn "udivmodhiqi3"
7432   [(set (match_operand:HI 0 "register_operand" "=a")
7433         (ior:HI
7434           (ashift:HI
7435             (zero_extend:HI
7436               (truncate:QI
7437                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7438                         (zero_extend:HI
7439                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7440             (const_int 8))
7441           (zero_extend:HI
7442             (truncate:QI
7443               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7444    (clobber (reg:CC FLAGS_REG))]
7445   "TARGET_QIMODE_MATH"
7446   "div{b}\t%2"
7447   [(set_attr "type" "idiv")
7448    (set_attr "mode" "QI")])
7450 ;; We cannot use div/idiv for double division, because it causes
7451 ;; "division by zero" on the overflow and that's not what we expect
7452 ;; from truncate.  Because true (non truncating) double division is
7453 ;; never generated, we can't create this insn anyway.
7455 ;(define_insn ""
7456 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7457 ;       (truncate:SI
7458 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7459 ;                  (zero_extend:DI
7460 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7461 ;   (set (match_operand:SI 3 "register_operand" "=d")
7462 ;       (truncate:SI
7463 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7464 ;   (clobber (reg:CC FLAGS_REG))]
7465 ;  ""
7466 ;  "div{l}\t{%2, %0|%0, %2}"
7467 ;  [(set_attr "type" "idiv")])
7469 ;;- Logical AND instructions
7471 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7472 ;; Note that this excludes ah.
7474 (define_expand "testsi_ccno_1"
7475   [(set (reg:CCNO FLAGS_REG)
7476         (compare:CCNO
7477           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7478                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7479           (const_int 0)))])
7481 (define_expand "testqi_ccz_1"
7482   [(set (reg:CCZ FLAGS_REG)
7483         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7484                              (match_operand:QI 1 "nonmemory_operand"))
7485                  (const_int 0)))])
7487 (define_expand "testdi_ccno_1"
7488   [(set (reg:CCNO FLAGS_REG)
7489         (compare:CCNO
7490           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7491                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7492           (const_int 0)))]
7493   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7495 (define_insn "*testdi_1"
7496   [(set (reg FLAGS_REG)
7497         (compare
7498          (and:DI
7499           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7500           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7501          (const_int 0)))]
7502   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7503    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7504   "@
7505    test{l}\t{%k1, %k0|%k0, %k1}
7506    test{l}\t{%k1, %k0|%k0, %k1}
7507    test{q}\t{%1, %0|%0, %1}
7508    test{q}\t{%1, %0|%0, %1}
7509    test{q}\t{%1, %0|%0, %1}"
7510   [(set_attr "type" "test")
7511    (set_attr "modrm" "0,1,0,1,1")
7512    (set_attr "mode" "SI,SI,DI,DI,DI")])
7514 (define_insn "*testqi_1_maybe_si"
7515   [(set (reg FLAGS_REG)
7516         (compare
7517           (and:QI
7518             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7519             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7520           (const_int 0)))]
7521    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7522     && ix86_match_ccmode (insn,
7523                          CONST_INT_P (operands[1])
7524                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7526   if (which_alternative == 3)
7527     {
7528       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7529         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7530       return "test{l}\t{%1, %k0|%k0, %1}";
7531     }
7532   return "test{b}\t{%1, %0|%0, %1}";
7534   [(set_attr "type" "test")
7535    (set_attr "modrm" "0,1,1,1")
7536    (set_attr "mode" "QI,QI,QI,SI")
7537    (set_attr "pent_pair" "uv,np,uv,np")])
7539 (define_insn "*test<mode>_1"
7540   [(set (reg FLAGS_REG)
7541         (compare
7542          (and:SWI124
7543           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7544           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7545          (const_int 0)))]
7546   "ix86_match_ccmode (insn, CCNOmode)
7547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7548   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7549   [(set_attr "type" "test")
7550    (set_attr "modrm" "0,1,1")
7551    (set_attr "mode" "<MODE>")
7552    (set_attr "pent_pair" "uv,np,uv")])
7554 (define_expand "testqi_ext_ccno_0"
7555   [(set (reg:CCNO FLAGS_REG)
7556         (compare:CCNO
7557           (and:SI
7558             (zero_extract:SI
7559               (match_operand 0 "ext_register_operand")
7560               (const_int 8)
7561               (const_int 8))
7562             (match_operand 1 "const_int_operand"))
7563           (const_int 0)))])
7565 (define_insn "*testqi_ext_0"
7566   [(set (reg FLAGS_REG)
7567         (compare
7568           (and:SI
7569             (zero_extract:SI
7570               (match_operand 0 "ext_register_operand" "Q")
7571               (const_int 8)
7572               (const_int 8))
7573             (match_operand 1 "const_int_operand" "n"))
7574           (const_int 0)))]
7575   "ix86_match_ccmode (insn, CCNOmode)"
7576   "test{b}\t{%1, %h0|%h0, %1}"
7577   [(set_attr "type" "test")
7578    (set_attr "mode" "QI")
7579    (set_attr "length_immediate" "1")
7580    (set_attr "modrm" "1")
7581    (set_attr "pent_pair" "np")])
7583 (define_insn "*testqi_ext_1"
7584   [(set (reg FLAGS_REG)
7585         (compare
7586           (and:SI
7587             (zero_extract:SI
7588               (match_operand 0 "ext_register_operand" "Q,Q")
7589               (const_int 8)
7590               (const_int 8))
7591             (zero_extend:SI
7592               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7593           (const_int 0)))]
7594   "ix86_match_ccmode (insn, CCNOmode)"
7595   "test{b}\t{%1, %h0|%h0, %1}"
7596   [(set_attr "isa" "*,nox64")
7597    (set_attr "type" "test")
7598    (set_attr "mode" "QI")])
7600 (define_insn "*testqi_ext_2"
7601   [(set (reg FLAGS_REG)
7602         (compare
7603           (and:SI
7604             (zero_extract:SI
7605               (match_operand 0 "ext_register_operand" "Q")
7606               (const_int 8)
7607               (const_int 8))
7608             (zero_extract:SI
7609               (match_operand 1 "ext_register_operand" "Q")
7610               (const_int 8)
7611               (const_int 8)))
7612           (const_int 0)))]
7613   "ix86_match_ccmode (insn, CCNOmode)"
7614   "test{b}\t{%h1, %h0|%h0, %h1}"
7615   [(set_attr "type" "test")
7616    (set_attr "mode" "QI")])
7618 ;; Combine likes to form bit extractions for some tests.  Humor it.
7619 (define_insn "*testqi_ext_3"
7620   [(set (reg FLAGS_REG)
7621         (compare (zero_extract:SWI48
7622                    (match_operand 0 "nonimmediate_operand" "rm")
7623                    (match_operand:SWI48 1 "const_int_operand")
7624                    (match_operand:SWI48 2 "const_int_operand"))
7625                  (const_int 0)))]
7626   "ix86_match_ccmode (insn, CCNOmode)
7627    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7628        || GET_MODE (operands[0]) == SImode
7629        || GET_MODE (operands[0]) == HImode
7630        || GET_MODE (operands[0]) == QImode)
7631    /* Ensure that resulting mask is zero or sign extended operand.  */
7632    && INTVAL (operands[2]) >= 0
7633    && ((INTVAL (operands[1]) > 0
7634         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7635        || (<MODE>mode == DImode
7636            && INTVAL (operands[1]) > 32
7637            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7638   "#")
7640 (define_split
7641   [(set (match_operand 0 "flags_reg_operand")
7642         (match_operator 1 "compare_operator"
7643           [(zero_extract
7644              (match_operand 2 "nonimmediate_operand")
7645              (match_operand 3 "const_int_operand")
7646              (match_operand 4 "const_int_operand"))
7647            (const_int 0)]))]
7648   "ix86_match_ccmode (insn, CCNOmode)"
7649   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7651   rtx val = operands[2];
7652   HOST_WIDE_INT len = INTVAL (operands[3]);
7653   HOST_WIDE_INT pos = INTVAL (operands[4]);
7654   HOST_WIDE_INT mask;
7655   machine_mode mode, submode;
7657   mode = GET_MODE (val);
7658   if (MEM_P (val))
7659     {
7660       /* ??? Combine likes to put non-volatile mem extractions in QImode
7661          no matter the size of the test.  So find a mode that works.  */
7662       if (! MEM_VOLATILE_P (val))
7663         {
7664           mode = smallest_mode_for_size (pos + len, MODE_INT);
7665           val = adjust_address (val, mode, 0);
7666         }
7667     }
7668   else if (GET_CODE (val) == SUBREG
7669            && (submode = GET_MODE (SUBREG_REG (val)),
7670                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7671            && pos + len <= GET_MODE_BITSIZE (submode)
7672            && GET_MODE_CLASS (submode) == MODE_INT)
7673     {
7674       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7675       mode = submode;
7676       val = SUBREG_REG (val);
7677     }
7678   else if (mode == HImode && pos + len <= 8)
7679     {
7680       /* Small HImode tests can be converted to QImode.  */
7681       mode = QImode;
7682       val = gen_lowpart (QImode, val);
7683     }
7685   if (len == HOST_BITS_PER_WIDE_INT)
7686     mask = -1;
7687   else
7688     mask = ((HOST_WIDE_INT)1 << len) - 1;
7689   mask <<= pos;
7691   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7694 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7695 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7696 ;; this is relatively important trick.
7697 ;; Do the conversion only post-reload to avoid limiting of the register class
7698 ;; to QI regs.
7699 (define_split
7700   [(set (match_operand 0 "flags_reg_operand")
7701         (match_operator 1 "compare_operator"
7702           [(and (match_operand 2 "register_operand")
7703                 (match_operand 3 "const_int_operand"))
7704            (const_int 0)]))]
7705    "reload_completed
7706     && QI_REG_P (operands[2])
7707     && GET_MODE (operands[2]) != QImode
7708     && ((ix86_match_ccmode (insn, CCZmode)
7709          && !(INTVAL (operands[3]) & ~(255 << 8)))
7710         || (ix86_match_ccmode (insn, CCNOmode)
7711             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7712   [(set (match_dup 0)
7713         (match_op_dup 1
7714           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7715                    (match_dup 3))
7716            (const_int 0)]))]
7718   operands[2] = gen_lowpart (SImode, operands[2]);
7719   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7722 (define_split
7723   [(set (match_operand 0 "flags_reg_operand")
7724         (match_operator 1 "compare_operator"
7725           [(and (match_operand 2 "nonimmediate_operand")
7726                 (match_operand 3 "const_int_operand"))
7727            (const_int 0)]))]
7728    "reload_completed
7729     && GET_MODE (operands[2]) != QImode
7730     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7731     && ((ix86_match_ccmode (insn, CCZmode)
7732          && !(INTVAL (operands[3]) & ~255))
7733         || (ix86_match_ccmode (insn, CCNOmode)
7734             && !(INTVAL (operands[3]) & ~127)))"
7735   [(set (match_dup 0)
7736         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7737                          (const_int 0)]))]
7739   operands[2] = gen_lowpart (QImode, operands[2]);
7740   operands[3] = gen_lowpart (QImode, operands[3]);
7743 (define_split
7744   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7745         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7746                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7747    (clobber (reg:CC FLAGS_REG))]
7748   "TARGET_AVX512F && reload_completed"
7749   [(set (match_dup 0)
7750         (any_logic:SWI1248x (match_dup 1)
7751                             (match_dup 2)))])
7753 (define_insn "*k<logic><mode>"
7754   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7755         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7756                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7757   "TARGET_AVX512F"
7758   {
7759     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7760       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7761     else
7762       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7763   }
7764   [(set_attr "mode" "<MODE>")
7765    (set_attr "type" "msklog")
7766    (set_attr "prefix" "vex")])
7768 ;; %%% This used to optimize known byte-wide and operations to memory,
7769 ;; and sometimes to QImode registers.  If this is considered useful,
7770 ;; it should be done with splitters.
7772 (define_expand "and<mode>3"
7773   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7774         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7775                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7776   ""
7778   machine_mode mode = <MODE>mode;
7779   rtx (*insn) (rtx, rtx);
7781   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7782     {
7783       HOST_WIDE_INT ival = INTVAL (operands[2]);
7785       if (ival == (HOST_WIDE_INT) 0xffffffff)
7786         mode = SImode;
7787       else if (ival == 0xffff)
7788         mode = HImode;
7789       else if (ival == 0xff)
7790         mode = QImode;
7791       }
7793   if (mode == <MODE>mode)
7794     {
7795       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7796       DONE;
7797     }
7799   if (<MODE>mode == DImode)
7800     insn = (mode == SImode)
7801            ? gen_zero_extendsidi2
7802            : (mode == HImode)
7803            ? gen_zero_extendhidi2
7804            : gen_zero_extendqidi2;
7805   else if (<MODE>mode == SImode)
7806     insn = (mode == HImode)
7807            ? gen_zero_extendhisi2
7808            : gen_zero_extendqisi2;
7809   else if (<MODE>mode == HImode)
7810     insn = gen_zero_extendqihi2;
7811   else
7812     gcc_unreachable ();
7814   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7815   DONE;
7818 (define_insn "*anddi_1"
7819   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7820         (and:DI
7821          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7822          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7826   switch (get_attr_type (insn))
7827     {
7828     case TYPE_IMOVX:
7829       return "#";
7831     case TYPE_MSKLOG:
7832       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7834     default:
7835       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7836       if (get_attr_mode (insn) == MODE_SI)
7837         return "and{l}\t{%k2, %k0|%k0, %k2}";
7838       else
7839         return "and{q}\t{%2, %0|%0, %2}";
7840     }
7842   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7843    (set_attr "length_immediate" "*,*,*,0,0")
7844    (set (attr "prefix_rex")
7845      (if_then_else
7846        (and (eq_attr "type" "imovx")
7847             (and (match_test "INTVAL (operands[2]) == 0xff")
7848                  (match_operand 1 "ext_QIreg_operand")))
7849        (const_string "1")
7850        (const_string "*")))
7851    (set_attr "mode" "SI,DI,DI,SI,DI")])
7853 (define_insn "*andsi_1"
7854   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7855         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7856                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7857    (clobber (reg:CC FLAGS_REG))]
7858   "ix86_binary_operator_ok (AND, SImode, operands)"
7860   switch (get_attr_type (insn))
7861     {
7862     case TYPE_IMOVX:
7863       return "#";
7865     case TYPE_MSKLOG:
7866       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7868     default:
7869       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7870       return "and{l}\t{%2, %0|%0, %2}";
7871     }
7873   [(set_attr "type" "alu,alu,imovx,msklog")
7874    (set (attr "prefix_rex")
7875      (if_then_else
7876        (and (eq_attr "type" "imovx")
7877             (and (match_test "INTVAL (operands[2]) == 0xff")
7878                  (match_operand 1 "ext_QIreg_operand")))
7879        (const_string "1")
7880        (const_string "*")))
7881    (set_attr "length_immediate" "*,*,0,0")
7882    (set_attr "mode" "SI")])
7884 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7885 (define_insn "*andsi_1_zext"
7886   [(set (match_operand:DI 0 "register_operand" "=r")
7887         (zero_extend:DI
7888           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7889                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7890    (clobber (reg:CC FLAGS_REG))]
7891   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7892   "and{l}\t{%2, %k0|%k0, %2}"
7893   [(set_attr "type" "alu")
7894    (set_attr "mode" "SI")])
7896 (define_insn "*andhi_1"
7897   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7898         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7899                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7900    (clobber (reg:CC FLAGS_REG))]
7901   "ix86_binary_operator_ok (AND, HImode, operands)"
7903   switch (get_attr_type (insn))
7904     {
7905     case TYPE_IMOVX:
7906       return "#";
7908     case TYPE_MSKLOG:
7909       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7911     default:
7912       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7913       return "and{w}\t{%2, %0|%0, %2}";
7914     }
7916   [(set_attr "type" "alu,alu,imovx,msklog")
7917    (set_attr "length_immediate" "*,*,0,*")
7918    (set (attr "prefix_rex")
7919      (if_then_else
7920        (and (eq_attr "type" "imovx")
7921             (match_operand 1 "ext_QIreg_operand"))
7922        (const_string "1")
7923        (const_string "*")))
7924    (set_attr "mode" "HI,HI,SI,HI")])
7926 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7927 (define_insn "*andqi_1"
7928   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7929         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7930                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7931    (clobber (reg:CC FLAGS_REG))]
7932   "ix86_binary_operator_ok (AND, QImode, operands)"
7934   switch (which_alternative)
7935     {
7936     case 0:
7937     case 1:
7938       return "and{b}\t{%2, %0|%0, %2}";
7939     case 2:
7940       return "and{l}\t{%k2, %k0|%k0, %k2}";
7941     case 3:
7942       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7943                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7944     default:
7945       gcc_unreachable ();
7946     }
7948   [(set_attr "type" "alu,alu,alu,msklog")
7949    (set_attr "mode" "QI,QI,SI,HI")])
7951 (define_insn "*andqi_1_slp"
7952   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7953         (and:QI (match_dup 0)
7954                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7955    (clobber (reg:CC FLAGS_REG))]
7956   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7957    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7958   "and{b}\t{%1, %0|%0, %1}"
7959   [(set_attr "type" "alu1")
7960    (set_attr "mode" "QI")])
7962 (define_insn "kandn<mode>"
7963   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7964         (and:SWI12
7965           (not:SWI12
7966             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7967           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7968    (clobber (reg:CC FLAGS_REG))]
7969   "TARGET_AVX512F"
7971   switch (which_alternative)
7972     {
7973     case 0:
7974       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7975     case 1:
7976       return "#";
7977     case 2:
7978       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7979         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7980       else
7981         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7982     default:
7983       gcc_unreachable ();
7984     }
7986   [(set_attr "isa" "bmi,*,avx512f")
7987    (set_attr "type" "bitmanip,*,msklog")
7988    (set_attr "prefix" "*,*,vex")
7989    (set_attr "btver2_decode" "direct,*,*")
7990    (set_attr "mode" "<MODE>")])
7992 (define_split
7993   [(set (match_operand:SWI12 0 "general_reg_operand")
7994         (and:SWI12
7995           (not:SWI12
7996             (match_dup 0))
7997           (match_operand:SWI12 1 "general_reg_operand")))
7998    (clobber (reg:CC FLAGS_REG))]
7999   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8000   [(set (match_dup 0)
8001         (not:HI (match_dup 0)))
8002    (parallel [(set (match_dup 0)
8003                    (and:HI (match_dup 0)
8004                            (match_dup 1)))
8005               (clobber (reg:CC FLAGS_REG))])])
8007 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8008 (define_split
8009   [(set (match_operand:DI 0 "register_operand")
8010         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8011                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8012    (clobber (reg:CC FLAGS_REG))]
8013   "TARGET_64BIT"
8014   [(parallel [(set (match_dup 0)
8015                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8016               (clobber (reg:CC FLAGS_REG))])]
8017   "operands[2] = gen_lowpart (SImode, operands[2]);")
8019 (define_split
8020   [(set (match_operand:SWI248 0 "register_operand")
8021         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8022                     (match_operand:SWI248 2 "const_int_operand")))
8023    (clobber (reg:CC FLAGS_REG))]
8024   "reload_completed
8025    && true_regnum (operands[0]) != true_regnum (operands[1])"
8026   [(const_int 0)]
8028   HOST_WIDE_INT ival = INTVAL (operands[2]);
8029   machine_mode mode;
8030   rtx (*insn) (rtx, rtx);
8032   if (ival == (HOST_WIDE_INT) 0xffffffff)
8033     mode = SImode;
8034   else if (ival == 0xffff)
8035     mode = HImode;
8036   else
8037     {
8038       gcc_assert (ival == 0xff);
8039       mode = QImode;
8040     }
8042   if (<MODE>mode == DImode)
8043     insn = (mode == SImode)
8044            ? gen_zero_extendsidi2
8045            : (mode == HImode)
8046            ? gen_zero_extendhidi2
8047            : gen_zero_extendqidi2;
8048   else
8049     {
8050       if (<MODE>mode != SImode)
8051         /* Zero extend to SImode to avoid partial register stalls.  */
8052         operands[0] = gen_lowpart (SImode, operands[0]);
8054       insn = (mode == HImode)
8055              ? gen_zero_extendhisi2
8056              : gen_zero_extendqisi2;
8057     }
8058   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8059   DONE;
8062 (define_split
8063   [(set (match_operand 0 "register_operand")
8064         (and (match_dup 0)
8065              (const_int -65536)))
8066    (clobber (reg:CC FLAGS_REG))]
8067   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8068     || optimize_function_for_size_p (cfun)"
8069   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8070   "operands[1] = gen_lowpart (HImode, operands[0]);")
8072 (define_split
8073   [(set (match_operand 0 "ext_register_operand")
8074         (and (match_dup 0)
8075              (const_int -256)))
8076    (clobber (reg:CC FLAGS_REG))]
8077   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8078    && reload_completed"
8079   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8080   "operands[1] = gen_lowpart (QImode, operands[0]);")
8082 (define_split
8083   [(set (match_operand 0 "ext_register_operand")
8084         (and (match_dup 0)
8085              (const_int -65281)))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8088    && reload_completed"
8089   [(parallel [(set (zero_extract:SI (match_dup 0)
8090                                     (const_int 8)
8091                                     (const_int 8))
8092                    (xor:SI
8093                      (zero_extract:SI (match_dup 0)
8094                                       (const_int 8)
8095                                       (const_int 8))
8096                      (zero_extract:SI (match_dup 0)
8097                                       (const_int 8)
8098                                       (const_int 8))))
8099               (clobber (reg:CC FLAGS_REG))])]
8100   "operands[0] = gen_lowpart (SImode, operands[0]);")
8102 (define_insn "*anddi_2"
8103   [(set (reg FLAGS_REG)
8104         (compare
8105          (and:DI
8106           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8107           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8108          (const_int 0)))
8109    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8110         (and:DI (match_dup 1) (match_dup 2)))]
8111   "TARGET_64BIT
8112    && ix86_match_ccmode
8113         (insn,
8114          /* If we are going to emit andl instead of andq, and the operands[2]
8115             constant might have the SImode sign bit set, make sure the sign
8116             flag isn't tested, because the instruction will set the sign flag
8117             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8118             conservatively assume it might have bit 31 set.  */
8119          (satisfies_constraint_Z (operands[2])
8120           && (!CONST_INT_P (operands[2])
8121               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8122          ? CCZmode : CCNOmode)
8123    && ix86_binary_operator_ok (AND, DImode, operands)"
8124   "@
8125    and{l}\t{%k2, %k0|%k0, %k2}
8126    and{q}\t{%2, %0|%0, %2}
8127    and{q}\t{%2, %0|%0, %2}"
8128   [(set_attr "type" "alu")
8129    (set_attr "mode" "SI,DI,DI")])
8131 (define_insn "*andqi_2_maybe_si"
8132   [(set (reg FLAGS_REG)
8133         (compare (and:QI
8134                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8135                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8136                  (const_int 0)))
8137    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8138         (and:QI (match_dup 1) (match_dup 2)))]
8139   "ix86_binary_operator_ok (AND, QImode, operands)
8140    && ix86_match_ccmode (insn,
8141                          CONST_INT_P (operands[2])
8142                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8144   if (which_alternative == 2)
8145     {
8146       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8147         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8148       return "and{l}\t{%2, %k0|%k0, %2}";
8149     }
8150   return "and{b}\t{%2, %0|%0, %2}";
8152   [(set_attr "type" "alu")
8153    (set_attr "mode" "QI,QI,SI")])
8155 (define_insn "*and<mode>_2"
8156   [(set (reg FLAGS_REG)
8157         (compare (and:SWI124
8158                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8159                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8160                  (const_int 0)))
8161    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8162         (and:SWI124 (match_dup 1) (match_dup 2)))]
8163   "ix86_match_ccmode (insn, CCNOmode)
8164    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8165   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8166   [(set_attr "type" "alu")
8167    (set_attr "mode" "<MODE>")])
8169 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8170 (define_insn "*andsi_2_zext"
8171   [(set (reg FLAGS_REG)
8172         (compare (and:SI
8173                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8174                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8175                  (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8179    && ix86_binary_operator_ok (AND, SImode, operands)"
8180   "and{l}\t{%2, %k0|%k0, %2}"
8181   [(set_attr "type" "alu")
8182    (set_attr "mode" "SI")])
8184 (define_insn "*andqi_2_slp"
8185   [(set (reg FLAGS_REG)
8186         (compare (and:QI
8187                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8188                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8189                  (const_int 0)))
8190    (set (strict_low_part (match_dup 0))
8191         (and:QI (match_dup 0) (match_dup 1)))]
8192   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8193    && ix86_match_ccmode (insn, CCNOmode)
8194    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8195   "and{b}\t{%1, %0|%0, %1}"
8196   [(set_attr "type" "alu1")
8197    (set_attr "mode" "QI")])
8199 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8200 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8201 ;; for a QImode operand, which of course failed.
8202 (define_insn "andqi_ext_0"
8203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8204                          (const_int 8)
8205                          (const_int 8))
8206         (and:SI
8207           (zero_extract:SI
8208             (match_operand 1 "ext_register_operand" "0")
8209             (const_int 8)
8210             (const_int 8))
8211           (match_operand 2 "const_int_operand" "n")))
8212    (clobber (reg:CC FLAGS_REG))]
8213   ""
8214   "and{b}\t{%2, %h0|%h0, %2}"
8215   [(set_attr "type" "alu")
8216    (set_attr "length_immediate" "1")
8217    (set_attr "modrm" "1")
8218    (set_attr "mode" "QI")])
8220 ;; Generated by peephole translating test to and.  This shows up
8221 ;; often in fp comparisons.
8222 (define_insn "*andqi_ext_0_cc"
8223   [(set (reg FLAGS_REG)
8224         (compare
8225           (and:SI
8226             (zero_extract:SI
8227               (match_operand 1 "ext_register_operand" "0")
8228               (const_int 8)
8229               (const_int 8))
8230             (match_operand 2 "const_int_operand" "n"))
8231           (const_int 0)))
8232    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8233                          (const_int 8)
8234                          (const_int 8))
8235         (and:SI
8236           (zero_extract:SI
8237             (match_dup 1)
8238             (const_int 8)
8239             (const_int 8))
8240           (match_dup 2)))]
8241   "ix86_match_ccmode (insn, CCNOmode)"
8242   "and{b}\t{%2, %h0|%h0, %2}"
8243   [(set_attr "type" "alu")
8244    (set_attr "length_immediate" "1")
8245    (set_attr "modrm" "1")
8246    (set_attr "mode" "QI")])
8248 (define_insn "*andqi_ext_1"
8249   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8250                          (const_int 8)
8251                          (const_int 8))
8252         (and:SI
8253           (zero_extract:SI
8254             (match_operand 1 "ext_register_operand" "0,0")
8255             (const_int 8)
8256             (const_int 8))
8257           (zero_extend:SI
8258             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8259    (clobber (reg:CC FLAGS_REG))]
8260   ""
8261   "and{b}\t{%2, %h0|%h0, %2}"
8262   [(set_attr "isa" "*,nox64")
8263    (set_attr "type" "alu")
8264    (set_attr "length_immediate" "0")
8265    (set_attr "mode" "QI")])
8267 (define_insn "*andqi_ext_2"
8268   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8269                          (const_int 8)
8270                          (const_int 8))
8271         (and:SI
8272           (zero_extract:SI
8273             (match_operand 1 "ext_register_operand" "%0")
8274             (const_int 8)
8275             (const_int 8))
8276           (zero_extract:SI
8277             (match_operand 2 "ext_register_operand" "Q")
8278             (const_int 8)
8279             (const_int 8))))
8280    (clobber (reg:CC FLAGS_REG))]
8281   ""
8282   "and{b}\t{%h2, %h0|%h0, %h2}"
8283   [(set_attr "type" "alu")
8284    (set_attr "length_immediate" "0")
8285    (set_attr "mode" "QI")])
8287 ;; Convert wide AND instructions with immediate operand to shorter QImode
8288 ;; equivalents when possible.
8289 ;; Don't do the splitting with memory operands, since it introduces risk
8290 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8291 ;; for size, but that can (should?) be handled by generic code instead.
8292 (define_split
8293   [(set (match_operand 0 "register_operand")
8294         (and (match_operand 1 "register_operand")
8295              (match_operand 2 "const_int_operand")))
8296    (clobber (reg:CC FLAGS_REG))]
8297    "reload_completed
8298     && QI_REG_P (operands[0])
8299     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8300     && !(~INTVAL (operands[2]) & ~(255 << 8))
8301     && GET_MODE (operands[0]) != QImode"
8302   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8303                    (and:SI (zero_extract:SI (match_dup 1)
8304                                             (const_int 8) (const_int 8))
8305                            (match_dup 2)))
8306               (clobber (reg:CC FLAGS_REG))])]
8308   operands[0] = gen_lowpart (SImode, operands[0]);
8309   operands[1] = gen_lowpart (SImode, operands[1]);
8310   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8313 ;; Since AND can be encoded with sign extended immediate, this is only
8314 ;; profitable when 7th bit is not set.
8315 (define_split
8316   [(set (match_operand 0 "register_operand")
8317         (and (match_operand 1 "general_operand")
8318              (match_operand 2 "const_int_operand")))
8319    (clobber (reg:CC FLAGS_REG))]
8320    "reload_completed
8321     && ANY_QI_REG_P (operands[0])
8322     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8323     && !(~INTVAL (operands[2]) & ~255)
8324     && !(INTVAL (operands[2]) & 128)
8325     && GET_MODE (operands[0]) != QImode"
8326   [(parallel [(set (strict_low_part (match_dup 0))
8327                    (and:QI (match_dup 1)
8328                            (match_dup 2)))
8329               (clobber (reg:CC FLAGS_REG))])]
8331   operands[0] = gen_lowpart (QImode, operands[0]);
8332   operands[1] = gen_lowpart (QImode, operands[1]);
8333   operands[2] = gen_lowpart (QImode, operands[2]);
8336 ;; Logical inclusive and exclusive OR instructions
8338 ;; %%% This used to optimize known byte-wide and operations to memory.
8339 ;; If this is considered useful, it should be done with splitters.
8341 (define_expand "<code><mode>3"
8342   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8343         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8344                      (match_operand:SWIM 2 "<general_operand>")))]
8345   ""
8346   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8348 (define_insn "*<code><mode>_1"
8349   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8350         (any_or:SWI48
8351          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8352          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8355   "@
8356    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8357    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8358    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8359   [(set_attr "type" "alu,alu,msklog")
8360    (set_attr "mode" "<MODE>")])
8362 (define_insn "*<code>hi_1"
8363   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8364         (any_or:HI
8365          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8366          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8369   "@
8370   <logic>{w}\t{%2, %0|%0, %2}
8371   <logic>{w}\t{%2, %0|%0, %2}
8372   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8373   [(set_attr "type" "alu,alu,msklog")
8374    (set_attr "mode" "HI")])
8376 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8377 (define_insn "*<code>qi_1"
8378   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8379         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8380                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8383   "@
8384    <logic>{b}\t{%2, %0|%0, %2}
8385    <logic>{b}\t{%2, %0|%0, %2}
8386    <logic>{l}\t{%k2, %k0|%k0, %k2}
8387    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8388   [(set_attr "type" "alu,alu,alu,msklog")
8389    (set_attr "mode" "QI,QI,SI,HI")])
8391 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8392 (define_insn "*<code>si_1_zext"
8393   [(set (match_operand:DI 0 "register_operand" "=r")
8394         (zero_extend:DI
8395          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8396                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8397    (clobber (reg:CC FLAGS_REG))]
8398   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8399   "<logic>{l}\t{%2, %k0|%k0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "SI")])
8403 (define_insn "*<code>si_1_zext_imm"
8404   [(set (match_operand:DI 0 "register_operand" "=r")
8405         (any_or:DI
8406          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8407          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8408    (clobber (reg:CC FLAGS_REG))]
8409   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8410   "<logic>{l}\t{%2, %k0|%k0, %2}"
8411   [(set_attr "type" "alu")
8412    (set_attr "mode" "SI")])
8414 (define_insn "*<code>qi_1_slp"
8415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8416         (any_or:QI (match_dup 0)
8417                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8418    (clobber (reg:CC FLAGS_REG))]
8419   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8421   "<logic>{b}\t{%1, %0|%0, %1}"
8422   [(set_attr "type" "alu1")
8423    (set_attr "mode" "QI")])
8425 (define_insn "*<code><mode>_2"
8426   [(set (reg FLAGS_REG)
8427         (compare (any_or:SWI
8428                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8429                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8430                  (const_int 0)))
8431    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8432         (any_or:SWI (match_dup 1) (match_dup 2)))]
8433   "ix86_match_ccmode (insn, CCNOmode)
8434    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8435   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "mode" "<MODE>")])
8439 (define_insn "kxnor<mode>"
8440   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8441         (not:SWI12
8442           (xor:SWI12
8443             (match_operand:SWI12 1 "register_operand" "0,k")
8444             (match_operand:SWI12 2 "register_operand" "r,k"))))
8445    (clobber (reg:CC FLAGS_REG))]
8446   "TARGET_AVX512F"
8448   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8449     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8450   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8452   [(set_attr "type" "*,msklog")
8453    (set_attr "prefix" "*,vex")
8454    (set_attr "mode" "<MODE>")])
8456 (define_insn "kxnor<mode>"
8457   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8458         (not:SWI48x
8459           (xor:SWI48x
8460             (match_operand:SWI48x 1 "register_operand" "0,k")
8461             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8462    (clobber (reg:CC FLAGS_REG))]
8463   "TARGET_AVX512BW"
8464   "@
8465    #
8466    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8467   [(set_attr "type" "*,msklog")
8468    (set_attr "prefix" "*,vex")
8469    (set_attr "mode" "<MODE>")])
8471 (define_split
8472   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8473         (not:SWI1248x
8474           (xor:SWI1248x
8475             (match_dup 0)
8476             (match_operand:SWI1248x 1 "general_reg_operand"))))
8477    (clobber (reg:CC FLAGS_REG))]
8478   "TARGET_AVX512F && reload_completed"
8479    [(parallel [(set (match_dup 0)
8480                     (xor:SWI1248x (match_dup 0)
8481                                   (match_dup 1)))
8482                (clobber (reg:CC FLAGS_REG))])
8483     (set (match_dup 0)
8484          (not:SWI1248x (match_dup 0)))])
8486 ;;There are kortrest[bdq] but no intrinsics for them.
8487 ;;We probably don't need to implement them.
8488 (define_insn "kortestzhi"
8489   [(set (reg:CCZ FLAGS_REG)
8490         (compare:CCZ
8491           (ior:HI
8492             (match_operand:HI 0 "register_operand" "k")
8493             (match_operand:HI 1 "register_operand" "k"))
8494           (const_int 0)))]
8495   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8496   "kortestw\t{%1, %0|%0, %1}"
8497   [(set_attr "mode" "HI")
8498    (set_attr "type" "msklog")
8499    (set_attr "prefix" "vex")])
8501 (define_insn "kortestchi"
8502   [(set (reg:CCC FLAGS_REG)
8503         (compare:CCC
8504           (ior:HI
8505             (match_operand:HI 0 "register_operand" "k")
8506             (match_operand:HI 1 "register_operand" "k"))
8507           (const_int -1)))]
8508   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8509   "kortestw\t{%1, %0|%0, %1}"
8510   [(set_attr "mode" "HI")
8511    (set_attr "type" "msklog")
8512    (set_attr "prefix" "vex")])
8514 (define_insn "kunpckhi"
8515   [(set (match_operand:HI 0 "register_operand" "=k")
8516         (ior:HI
8517           (ashift:HI
8518             (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8519             (const_int 8))
8520           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8521   "TARGET_AVX512F"
8522   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8523   [(set_attr "mode" "HI")
8524    (set_attr "type" "msklog")
8525    (set_attr "prefix" "vex")])
8527 (define_insn "kunpcksi"
8528   [(set (match_operand:SI 0 "register_operand" "=k")
8529         (ior:SI
8530           (ashift:SI
8531             (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8532             (const_int 16))
8533           (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8534   "TARGET_AVX512BW"
8535   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8536   [(set_attr "mode" "SI")])
8538 (define_insn "kunpckdi"
8539   [(set (match_operand:DI 0 "register_operand" "=k")
8540         (ior:DI
8541           (ashift:DI
8542             (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8543             (const_int 32))
8544           (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8545   "TARGET_AVX512BW"
8546   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8547   [(set_attr "mode" "DI")])
8549 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8550 ;; ??? Special case for immediate operand is missing - it is tricky.
8551 (define_insn "*<code>si_2_zext"
8552   [(set (reg FLAGS_REG)
8553         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8554                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8555                  (const_int 0)))
8556    (set (match_operand:DI 0 "register_operand" "=r")
8557         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8558   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8559    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8560   "<logic>{l}\t{%2, %k0|%k0, %2}"
8561   [(set_attr "type" "alu")
8562    (set_attr "mode" "SI")])
8564 (define_insn "*<code>si_2_zext_imm"
8565   [(set (reg FLAGS_REG)
8566         (compare (any_or:SI
8567                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8568                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8569                  (const_int 0)))
8570    (set (match_operand:DI 0 "register_operand" "=r")
8571         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8572   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8573    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8574   "<logic>{l}\t{%2, %k0|%k0, %2}"
8575   [(set_attr "type" "alu")
8576    (set_attr "mode" "SI")])
8578 (define_insn "*<code>qi_2_slp"
8579   [(set (reg FLAGS_REG)
8580         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8581                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8582                  (const_int 0)))
8583    (set (strict_low_part (match_dup 0))
8584         (any_or:QI (match_dup 0) (match_dup 1)))]
8585   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8586    && ix86_match_ccmode (insn, CCNOmode)
8587    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8588   "<logic>{b}\t{%1, %0|%0, %1}"
8589   [(set_attr "type" "alu1")
8590    (set_attr "mode" "QI")])
8592 (define_insn "*<code><mode>_3"
8593   [(set (reg FLAGS_REG)
8594         (compare (any_or:SWI
8595                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8596                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8597                  (const_int 0)))
8598    (clobber (match_scratch:SWI 0 "=<r>"))]
8599   "ix86_match_ccmode (insn, CCNOmode)
8600    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8601   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8602   [(set_attr "type" "alu")
8603    (set_attr "mode" "<MODE>")])
8605 (define_insn "*<code>qi_ext_0"
8606   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8607                          (const_int 8)
8608                          (const_int 8))
8609         (any_or:SI
8610           (zero_extract:SI
8611             (match_operand 1 "ext_register_operand" "0")
8612             (const_int 8)
8613             (const_int 8))
8614           (match_operand 2 "const_int_operand" "n")))
8615    (clobber (reg:CC FLAGS_REG))]
8616   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8617   "<logic>{b}\t{%2, %h0|%h0, %2}"
8618   [(set_attr "type" "alu")
8619    (set_attr "length_immediate" "1")
8620    (set_attr "modrm" "1")
8621    (set_attr "mode" "QI")])
8623 (define_insn "*<code>qi_ext_1"
8624   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8625                          (const_int 8)
8626                          (const_int 8))
8627         (any_or:SI
8628           (zero_extract:SI
8629             (match_operand 1 "ext_register_operand" "0,0")
8630             (const_int 8)
8631             (const_int 8))
8632           (zero_extend:SI
8633             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8634    (clobber (reg:CC FLAGS_REG))]
8635   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8636   "<logic>{b}\t{%2, %h0|%h0, %2}"
8637   [(set_attr "isa" "*,nox64")
8638    (set_attr "type" "alu")
8639    (set_attr "length_immediate" "0")
8640    (set_attr "mode" "QI")])
8642 (define_insn "*<code>qi_ext_2"
8643   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8644                          (const_int 8)
8645                          (const_int 8))
8646         (any_or:SI
8647           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8648                            (const_int 8)
8649                            (const_int 8))
8650           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8651                            (const_int 8)
8652                            (const_int 8))))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8655   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "length_immediate" "0")
8658    (set_attr "mode" "QI")])
8660 (define_split
8661   [(set (match_operand 0 "register_operand")
8662         (any_or (match_operand 1 "register_operand")
8663                 (match_operand 2 "const_int_operand")))
8664    (clobber (reg:CC FLAGS_REG))]
8665    "reload_completed
8666     && QI_REG_P (operands[0])
8667     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8668     && !(INTVAL (operands[2]) & ~(255 << 8))
8669     && GET_MODE (operands[0]) != QImode"
8670   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8671                    (any_or:SI (zero_extract:SI (match_dup 1)
8672                                                (const_int 8) (const_int 8))
8673                               (match_dup 2)))
8674               (clobber (reg:CC FLAGS_REG))])]
8676   operands[0] = gen_lowpart (SImode, operands[0]);
8677   operands[1] = gen_lowpart (SImode, operands[1]);
8678   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8681 ;; Since OR can be encoded with sign extended immediate, this is only
8682 ;; profitable when 7th bit is set.
8683 (define_split
8684   [(set (match_operand 0 "register_operand")
8685         (any_or (match_operand 1 "general_operand")
8686                 (match_operand 2 "const_int_operand")))
8687    (clobber (reg:CC FLAGS_REG))]
8688    "reload_completed
8689     && ANY_QI_REG_P (operands[0])
8690     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8691     && !(INTVAL (operands[2]) & ~255)
8692     && (INTVAL (operands[2]) & 128)
8693     && GET_MODE (operands[0]) != QImode"
8694   [(parallel [(set (strict_low_part (match_dup 0))
8695                    (any_or:QI (match_dup 1)
8696                               (match_dup 2)))
8697               (clobber (reg:CC FLAGS_REG))])]
8699   operands[0] = gen_lowpart (QImode, operands[0]);
8700   operands[1] = gen_lowpart (QImode, operands[1]);
8701   operands[2] = gen_lowpart (QImode, operands[2]);
8704 (define_expand "xorqi_cc_ext_1"
8705   [(parallel [
8706      (set (reg:CCNO FLAGS_REG)
8707           (compare:CCNO
8708             (xor:SI
8709               (zero_extract:SI
8710                 (match_operand 1 "ext_register_operand")
8711                 (const_int 8)
8712                 (const_int 8))
8713               (match_operand:QI 2 "const_int_operand"))
8714             (const_int 0)))
8715      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8716                            (const_int 8)
8717                            (const_int 8))
8718           (xor:SI
8719             (zero_extract:SI
8720              (match_dup 1)
8721              (const_int 8)
8722              (const_int 8))
8723             (match_dup 2)))])])
8725 (define_insn "*xorqi_cc_ext_1"
8726   [(set (reg FLAGS_REG)
8727         (compare
8728           (xor:SI
8729             (zero_extract:SI
8730               (match_operand 1 "ext_register_operand" "0,0")
8731               (const_int 8)
8732               (const_int 8))
8733             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8734           (const_int 0)))
8735    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8736                          (const_int 8)
8737                          (const_int 8))
8738         (xor:SI
8739           (zero_extract:SI
8740            (match_dup 1)
8741            (const_int 8)
8742            (const_int 8))
8743           (match_dup 2)))]
8744   "ix86_match_ccmode (insn, CCNOmode)"
8745   "xor{b}\t{%2, %h0|%h0, %2}"
8746   [(set_attr "isa" "*,nox64")
8747    (set_attr "type" "alu")
8748    (set_attr "modrm" "1")
8749    (set_attr "mode" "QI")])
8751 ;; Negation instructions
8753 (define_expand "neg<mode>2"
8754   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8755         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8756   ""
8757   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8759 (define_insn_and_split "*neg<dwi>2_doubleword"
8760   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8761         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8762    (clobber (reg:CC FLAGS_REG))]
8763   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8764   "#"
8765   "reload_completed"
8766   [(parallel
8767     [(set (reg:CCZ FLAGS_REG)
8768           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8769      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8770    (parallel
8771     [(set (match_dup 2)
8772           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8773                                 (match_dup 3))
8774                      (const_int 0)))
8775      (clobber (reg:CC FLAGS_REG))])
8776    (parallel
8777     [(set (match_dup 2)
8778           (neg:DWIH (match_dup 2)))
8779      (clobber (reg:CC FLAGS_REG))])]
8780   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8782 (define_insn "*neg<mode>2_1"
8783   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8784         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8785    (clobber (reg:CC FLAGS_REG))]
8786   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8787   "neg{<imodesuffix>}\t%0"
8788   [(set_attr "type" "negnot")
8789    (set_attr "mode" "<MODE>")])
8791 ;; Combine is quite creative about this pattern.
8792 (define_insn "*negsi2_1_zext"
8793   [(set (match_operand:DI 0 "register_operand" "=r")
8794         (lshiftrt:DI
8795           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8796                              (const_int 32)))
8797         (const_int 32)))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8800   "neg{l}\t%k0"
8801   [(set_attr "type" "negnot")
8802    (set_attr "mode" "SI")])
8804 ;; The problem with neg is that it does not perform (compare x 0),
8805 ;; it really performs (compare 0 x), which leaves us with the zero
8806 ;; flag being the only useful item.
8808 (define_insn "*neg<mode>2_cmpz"
8809   [(set (reg:CCZ FLAGS_REG)
8810         (compare:CCZ
8811           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8812                    (const_int 0)))
8813    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8814         (neg:SWI (match_dup 1)))]
8815   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8816   "neg{<imodesuffix>}\t%0"
8817   [(set_attr "type" "negnot")
8818    (set_attr "mode" "<MODE>")])
8820 (define_insn "*negsi2_cmpz_zext"
8821   [(set (reg:CCZ FLAGS_REG)
8822         (compare:CCZ
8823           (lshiftrt:DI
8824             (neg:DI (ashift:DI
8825                       (match_operand:DI 1 "register_operand" "0")
8826                       (const_int 32)))
8827             (const_int 32))
8828           (const_int 0)))
8829    (set (match_operand:DI 0 "register_operand" "=r")
8830         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8831                                         (const_int 32)))
8832                      (const_int 32)))]
8833   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8834   "neg{l}\t%k0"
8835   [(set_attr "type" "negnot")
8836    (set_attr "mode" "SI")])
8838 ;; Negate with jump on overflow.
8839 (define_expand "negv<mode>3"
8840   [(parallel [(set (reg:CCO FLAGS_REG)
8841                    (ne:CCO (match_operand:SWI 1 "register_operand")
8842                            (match_dup 3)))
8843               (set (match_operand:SWI 0 "register_operand")
8844                    (neg:SWI (match_dup 1)))])
8845    (set (pc) (if_then_else
8846                (eq (reg:CCO FLAGS_REG) (const_int 0))
8847                (label_ref (match_operand 2))
8848                (pc)))]
8849   ""
8851   operands[3]
8852     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8853                     <MODE>mode);
8856 (define_insn "*negv<mode>3"
8857   [(set (reg:CCO FLAGS_REG)
8858         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8859                 (match_operand:SWI 2 "const_int_operand")))
8860    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8861         (neg:SWI (match_dup 1)))]
8862   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8863    && mode_signbit_p (<MODE>mode, operands[2])"
8864   "neg{<imodesuffix>}\t%0"
8865   [(set_attr "type" "negnot")
8866    (set_attr "mode" "<MODE>")])
8868 ;; Changing of sign for FP values is doable using integer unit too.
8870 (define_expand "<code><mode>2"
8871   [(set (match_operand:X87MODEF 0 "register_operand")
8872         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8873   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8874   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8876 (define_insn "*absneg<mode>2_mixed"
8877   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8878         (match_operator:MODEF 3 "absneg_operator"
8879           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8880    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8881    (clobber (reg:CC FLAGS_REG))]
8882   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8883   "#")
8885 (define_insn "*absneg<mode>2_sse"
8886   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8887         (match_operator:MODEF 3 "absneg_operator"
8888           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8889    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8890    (clobber (reg:CC FLAGS_REG))]
8891   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8892   "#")
8894 (define_insn "*absneg<mode>2_i387"
8895   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8896         (match_operator:X87MODEF 3 "absneg_operator"
8897           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8898    (use (match_operand 2))
8899    (clobber (reg:CC FLAGS_REG))]
8900   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8901   "#")
8903 (define_expand "<code>tf2"
8904   [(set (match_operand:TF 0 "register_operand")
8905         (absneg:TF (match_operand:TF 1 "register_operand")))]
8906   "TARGET_SSE"
8907   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8909 (define_insn "*absnegtf2_sse"
8910   [(set (match_operand:TF 0 "register_operand" "=x,x")
8911         (match_operator:TF 3 "absneg_operator"
8912           [(match_operand:TF 1 "register_operand" "0,x")]))
8913    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8914    (clobber (reg:CC FLAGS_REG))]
8915   "TARGET_SSE"
8916   "#")
8918 ;; Splitters for fp abs and neg.
8920 (define_split
8921   [(set (match_operand 0 "fp_register_operand")
8922         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8923    (use (match_operand 2))
8924    (clobber (reg:CC FLAGS_REG))]
8925   "reload_completed"
8926   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8928 (define_split
8929   [(set (match_operand 0 "register_operand")
8930         (match_operator 3 "absneg_operator"
8931           [(match_operand 1 "register_operand")]))
8932    (use (match_operand 2 "nonimmediate_operand"))
8933    (clobber (reg:CC FLAGS_REG))]
8934   "reload_completed && SSE_REG_P (operands[0])"
8935   [(set (match_dup 0) (match_dup 3))]
8937   machine_mode mode = GET_MODE (operands[0]);
8938   machine_mode vmode = GET_MODE (operands[2]);
8939   rtx tmp;
8941   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8942   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8943   if (operands_match_p (operands[0], operands[2]))
8944     std::swap (operands[1], operands[2]);
8945   if (GET_CODE (operands[3]) == ABS)
8946     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8947   else
8948     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8949   operands[3] = tmp;
8952 (define_split
8953   [(set (match_operand:SF 0 "register_operand")
8954         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8955    (use (match_operand:V4SF 2))
8956    (clobber (reg:CC FLAGS_REG))]
8957   "reload_completed"
8958   [(parallel [(set (match_dup 0) (match_dup 1))
8959               (clobber (reg:CC FLAGS_REG))])]
8961   rtx tmp;
8962   operands[0] = gen_lowpart (SImode, operands[0]);
8963   if (GET_CODE (operands[1]) == ABS)
8964     {
8965       tmp = gen_int_mode (0x7fffffff, SImode);
8966       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8967     }
8968   else
8969     {
8970       tmp = gen_int_mode (0x80000000, SImode);
8971       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8972     }
8973   operands[1] = tmp;
8976 (define_split
8977   [(set (match_operand:DF 0 "register_operand")
8978         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8979    (use (match_operand 2))
8980    (clobber (reg:CC FLAGS_REG))]
8981   "reload_completed"
8982   [(parallel [(set (match_dup 0) (match_dup 1))
8983               (clobber (reg:CC FLAGS_REG))])]
8985   rtx tmp;
8986   if (TARGET_64BIT)
8987     {
8988       tmp = gen_lowpart (DImode, operands[0]);
8989       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8990       operands[0] = tmp;
8992       if (GET_CODE (operands[1]) == ABS)
8993         tmp = const0_rtx;
8994       else
8995         tmp = gen_rtx_NOT (DImode, tmp);
8996     }
8997   else
8998     {
8999       operands[0] = gen_highpart (SImode, operands[0]);
9000       if (GET_CODE (operands[1]) == ABS)
9001         {
9002           tmp = gen_int_mode (0x7fffffff, SImode);
9003           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9004         }
9005       else
9006         {
9007           tmp = gen_int_mode (0x80000000, SImode);
9008           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9009         }
9010     }
9011   operands[1] = tmp;
9014 (define_split
9015   [(set (match_operand:XF 0 "register_operand")
9016         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9017    (use (match_operand 2))
9018    (clobber (reg:CC FLAGS_REG))]
9019   "reload_completed"
9020   [(parallel [(set (match_dup 0) (match_dup 1))
9021               (clobber (reg:CC FLAGS_REG))])]
9023   rtx tmp;
9024   operands[0] = gen_rtx_REG (SImode,
9025                              true_regnum (operands[0])
9026                              + (TARGET_64BIT ? 1 : 2));
9027   if (GET_CODE (operands[1]) == ABS)
9028     {
9029       tmp = GEN_INT (0x7fff);
9030       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9031     }
9032   else
9033     {
9034       tmp = GEN_INT (0x8000);
9035       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9036     }
9037   operands[1] = tmp;
9040 ;; Conditionalize these after reload. If they match before reload, we
9041 ;; lose the clobber and ability to use integer instructions.
9043 (define_insn "*<code><mode>2_1"
9044   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9045         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9046   "TARGET_80387
9047    && (reload_completed
9048        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9049   "f<absneg_mnemonic>"
9050   [(set_attr "type" "fsgn")
9051    (set_attr "mode" "<MODE>")])
9053 (define_insn "*<code>extendsfdf2"
9054   [(set (match_operand:DF 0 "register_operand" "=f")
9055         (absneg:DF (float_extend:DF
9056                      (match_operand:SF 1 "register_operand" "0"))))]
9057   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9058   "f<absneg_mnemonic>"
9059   [(set_attr "type" "fsgn")
9060    (set_attr "mode" "DF")])
9062 (define_insn "*<code>extendsfxf2"
9063   [(set (match_operand:XF 0 "register_operand" "=f")
9064         (absneg:XF (float_extend:XF
9065                      (match_operand:SF 1 "register_operand" "0"))))]
9066   "TARGET_80387"
9067   "f<absneg_mnemonic>"
9068   [(set_attr "type" "fsgn")
9069    (set_attr "mode" "XF")])
9071 (define_insn "*<code>extenddfxf2"
9072   [(set (match_operand:XF 0 "register_operand" "=f")
9073         (absneg:XF (float_extend:XF
9074                      (match_operand:DF 1 "register_operand" "0"))))]
9075   "TARGET_80387"
9076   "f<absneg_mnemonic>"
9077   [(set_attr "type" "fsgn")
9078    (set_attr "mode" "XF")])
9080 ;; Copysign instructions
9082 (define_mode_iterator CSGNMODE [SF DF TF])
9083 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9085 (define_expand "copysign<mode>3"
9086   [(match_operand:CSGNMODE 0 "register_operand")
9087    (match_operand:CSGNMODE 1 "nonmemory_operand")
9088    (match_operand:CSGNMODE 2 "register_operand")]
9089   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9090    || (TARGET_SSE && (<MODE>mode == TFmode))"
9091   "ix86_expand_copysign (operands); DONE;")
9093 (define_insn_and_split "copysign<mode>3_const"
9094   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9095         (unspec:CSGNMODE
9096           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9097            (match_operand:CSGNMODE 2 "register_operand" "0")
9098            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9099           UNSPEC_COPYSIGN))]
9100   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9101    || (TARGET_SSE && (<MODE>mode == TFmode))"
9102   "#"
9103   "&& reload_completed"
9104   [(const_int 0)]
9105   "ix86_split_copysign_const (operands); DONE;")
9107 (define_insn "copysign<mode>3_var"
9108   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9109         (unspec:CSGNMODE
9110           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9111            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9112            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9113            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9114           UNSPEC_COPYSIGN))
9115    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9116   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9117    || (TARGET_SSE && (<MODE>mode == TFmode))"
9118   "#")
9120 (define_split
9121   [(set (match_operand:CSGNMODE 0 "register_operand")
9122         (unspec:CSGNMODE
9123           [(match_operand:CSGNMODE 2 "register_operand")
9124            (match_operand:CSGNMODE 3 "register_operand")
9125            (match_operand:<CSGNVMODE> 4)
9126            (match_operand:<CSGNVMODE> 5)]
9127           UNSPEC_COPYSIGN))
9128    (clobber (match_scratch:<CSGNVMODE> 1))]
9129   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9130     || (TARGET_SSE && (<MODE>mode == TFmode)))
9131    && reload_completed"
9132   [(const_int 0)]
9133   "ix86_split_copysign_var (operands); DONE;")
9135 ;; One complement instructions
9137 (define_expand "one_cmpl<mode>2"
9138   [(set (match_operand:SWIM 0 "nonimmediate_operand")
9139         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9140   ""
9141   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9143 (define_insn "*one_cmpl<mode>2_1"
9144   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9145         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9146   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9147   "@
9148    not{<imodesuffix>}\t%0
9149    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9150   [(set_attr "isa" "*,avx512bw")
9151    (set_attr "type" "negnot,msklog")
9152    (set_attr "prefix" "*,vex")
9153    (set_attr "mode" "<MODE>")])
9155 (define_insn "*one_cmplhi2_1"
9156   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9157         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9158   "ix86_unary_operator_ok (NOT, HImode, operands)"
9159   "@
9160    not{w}\t%0
9161    knotw\t{%1, %0|%0, %1}"
9162   [(set_attr "isa" "*,avx512f")
9163    (set_attr "type" "negnot,msklog")
9164    (set_attr "prefix" "*,vex")
9165    (set_attr "mode" "HI")])
9167 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9168 (define_insn "*one_cmplqi2_1"
9169   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9170         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9171   "ix86_unary_operator_ok (NOT, QImode, operands)"
9173   switch (which_alternative)
9174     {
9175     case 0:
9176       return "not{b}\t%0";
9177     case 1:
9178       return "not{l}\t%k0";
9179     case 2:
9180       if (TARGET_AVX512DQ)
9181         return "knotb\t{%1, %0|%0, %1}";
9182       return "knotw\t{%1, %0|%0, %1}";
9183     default:
9184       gcc_unreachable ();
9185     }
9187   [(set_attr "isa" "*,*,avx512f")
9188    (set_attr "type" "negnot,negnot,msklog")
9189    (set_attr "prefix" "*,*,vex")
9190    (set_attr "mode" "QI,SI,QI")])
9192 ;; ??? Currently never generated - xor is used instead.
9193 (define_insn "*one_cmplsi2_1_zext"
9194   [(set (match_operand:DI 0 "register_operand" "=r")
9195         (zero_extend:DI
9196           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9197   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9198   "not{l}\t%k0"
9199   [(set_attr "type" "negnot")
9200    (set_attr "mode" "SI")])
9202 (define_insn "*one_cmpl<mode>2_2"
9203   [(set (reg FLAGS_REG)
9204         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9205                  (const_int 0)))
9206    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9207         (not:SWI (match_dup 1)))]
9208   "ix86_match_ccmode (insn, CCNOmode)
9209    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9210   "#"
9211   [(set_attr "type" "alu1")
9212    (set_attr "mode" "<MODE>")])
9214 (define_split
9215   [(set (match_operand 0 "flags_reg_operand")
9216         (match_operator 2 "compare_operator"
9217           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9218            (const_int 0)]))
9219    (set (match_operand:SWI 1 "nonimmediate_operand")
9220         (not:SWI (match_dup 3)))]
9221   "ix86_match_ccmode (insn, CCNOmode)"
9222   [(parallel [(set (match_dup 0)
9223                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9224                                     (const_int 0)]))
9225               (set (match_dup 1)
9226                    (xor:SWI (match_dup 3) (const_int -1)))])])
9228 ;; ??? Currently never generated - xor is used instead.
9229 (define_insn "*one_cmplsi2_2_zext"
9230   [(set (reg FLAGS_REG)
9231         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9232                  (const_int 0)))
9233    (set (match_operand:DI 0 "register_operand" "=r")
9234         (zero_extend:DI (not:SI (match_dup 1))))]
9235   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9236    && ix86_unary_operator_ok (NOT, SImode, operands)"
9237   "#"
9238   [(set_attr "type" "alu1")
9239    (set_attr "mode" "SI")])
9241 (define_split
9242   [(set (match_operand 0 "flags_reg_operand")
9243         (match_operator 2 "compare_operator"
9244           [(not:SI (match_operand:SI 3 "register_operand"))
9245            (const_int 0)]))
9246    (set (match_operand:DI 1 "register_operand")
9247         (zero_extend:DI (not:SI (match_dup 3))))]
9248   "ix86_match_ccmode (insn, CCNOmode)"
9249   [(parallel [(set (match_dup 0)
9250                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9251                                     (const_int 0)]))
9252               (set (match_dup 1)
9253                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9255 ;; Shift instructions
9257 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9258 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9259 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9260 ;; from the assembler input.
9262 ;; This instruction shifts the target reg/mem as usual, but instead of
9263 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9264 ;; is a left shift double, bits are taken from the high order bits of
9265 ;; reg, else if the insn is a shift right double, bits are taken from the
9266 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9267 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9269 ;; Since sh[lr]d does not change the `reg' operand, that is done
9270 ;; separately, making all shifts emit pairs of shift double and normal
9271 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9272 ;; support a 63 bit shift, each shift where the count is in a reg expands
9273 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9275 ;; If the shift count is a constant, we need never emit more than one
9276 ;; shift pair, instead using moves and sign extension for counts greater
9277 ;; than 31.
9279 (define_expand "ashl<mode>3"
9280   [(set (match_operand:SDWIM 0 "<shift_operand>")
9281         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9282                       (match_operand:QI 2 "nonmemory_operand")))]
9283   ""
9284   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9286 (define_insn "*ashl<mode>3_doubleword"
9287   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9288         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9289                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9290    (clobber (reg:CC FLAGS_REG))]
9291   ""
9292   "#"
9293   [(set_attr "type" "multi")])
9295 (define_split
9296   [(set (match_operand:DWI 0 "register_operand")
9297         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9298                     (match_operand:QI 2 "nonmemory_operand")))
9299    (clobber (reg:CC FLAGS_REG))]
9300   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9301   [(const_int 0)]
9302   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9304 ;; By default we don't ask for a scratch register, because when DWImode
9305 ;; values are manipulated, registers are already at a premium.  But if
9306 ;; we have one handy, we won't turn it away.
9308 (define_peephole2
9309   [(match_scratch:DWIH 3 "r")
9310    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9311                    (ashift:<DWI>
9312                      (match_operand:<DWI> 1 "nonmemory_operand")
9313                      (match_operand:QI 2 "nonmemory_operand")))
9314               (clobber (reg:CC FLAGS_REG))])
9315    (match_dup 3)]
9316   "TARGET_CMOVE"
9317   [(const_int 0)]
9318   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9320 (define_insn "x86_64_shld"
9321   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9322         (ior:DI (ashift:DI (match_dup 0)
9323                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9324                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9325                   (minus:QI (const_int 64) (match_dup 2)))))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "TARGET_64BIT"
9328   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9329   [(set_attr "type" "ishift")
9330    (set_attr "prefix_0f" "1")
9331    (set_attr "mode" "DI")
9332    (set_attr "athlon_decode" "vector")
9333    (set_attr "amdfam10_decode" "vector")
9334    (set_attr "bdver1_decode" "vector")])
9336 (define_insn "x86_shld"
9337   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9338         (ior:SI (ashift:SI (match_dup 0)
9339                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9340                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9341                   (minus:QI (const_int 32) (match_dup 2)))))
9342    (clobber (reg:CC FLAGS_REG))]
9343   ""
9344   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9345   [(set_attr "type" "ishift")
9346    (set_attr "prefix_0f" "1")
9347    (set_attr "mode" "SI")
9348    (set_attr "pent_pair" "np")
9349    (set_attr "athlon_decode" "vector")
9350    (set_attr "amdfam10_decode" "vector")
9351    (set_attr "bdver1_decode" "vector")])
9353 (define_expand "x86_shift<mode>_adj_1"
9354   [(set (reg:CCZ FLAGS_REG)
9355         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9356                              (match_dup 4))
9357                      (const_int 0)))
9358    (set (match_operand:SWI48 0 "register_operand")
9359         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9360                             (match_operand:SWI48 1 "register_operand")
9361                             (match_dup 0)))
9362    (set (match_dup 1)
9363         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9364                             (match_operand:SWI48 3 "register_operand")
9365                             (match_dup 1)))]
9366   "TARGET_CMOVE"
9367   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9369 (define_expand "x86_shift<mode>_adj_2"
9370   [(use (match_operand:SWI48 0 "register_operand"))
9371    (use (match_operand:SWI48 1 "register_operand"))
9372    (use (match_operand:QI 2 "register_operand"))]
9373   ""
9375   rtx_code_label *label = gen_label_rtx ();
9376   rtx tmp;
9378   emit_insn (gen_testqi_ccz_1 (operands[2],
9379                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9381   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9382   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9383   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9384                               gen_rtx_LABEL_REF (VOIDmode, label),
9385                               pc_rtx);
9386   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9387   JUMP_LABEL (tmp) = label;
9389   emit_move_insn (operands[0], operands[1]);
9390   ix86_expand_clear (operands[1]);
9392   emit_label (label);
9393   LABEL_NUSES (label) = 1;
9395   DONE;
9398 ;; Avoid useless masking of count operand.
9399 (define_insn "*ashl<mode>3_mask"
9400   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9401         (ashift:SWI48
9402           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9403           (subreg:QI
9404             (and:SI
9405               (match_operand:SI 2 "register_operand" "c")
9406               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9407    (clobber (reg:CC FLAGS_REG))]
9408   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9409    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9410       == GET_MODE_BITSIZE (<MODE>mode)-1"
9412   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9414   [(set_attr "type" "ishift")
9415    (set_attr "mode" "<MODE>")])
9417 (define_insn "*bmi2_ashl<mode>3_1"
9418   [(set (match_operand:SWI48 0 "register_operand" "=r")
9419         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9420                       (match_operand:SWI48 2 "register_operand" "r")))]
9421   "TARGET_BMI2"
9422   "shlx\t{%2, %1, %0|%0, %1, %2}"
9423   [(set_attr "type" "ishiftx")
9424    (set_attr "mode" "<MODE>")])
9426 (define_insn "*ashl<mode>3_1"
9427   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9428         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9429                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9430    (clobber (reg:CC FLAGS_REG))]
9431   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9433   switch (get_attr_type (insn))
9434     {
9435     case TYPE_LEA:
9436     case TYPE_ISHIFTX:
9437       return "#";
9439     case TYPE_ALU:
9440       gcc_assert (operands[2] == const1_rtx);
9441       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9442       return "add{<imodesuffix>}\t%0, %0";
9444     default:
9445       if (operands[2] == const1_rtx
9446           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9447         return "sal{<imodesuffix>}\t%0";
9448       else
9449         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9450     }
9452   [(set_attr "isa" "*,*,bmi2")
9453    (set (attr "type")
9454      (cond [(eq_attr "alternative" "1")
9455               (const_string "lea")
9456             (eq_attr "alternative" "2")
9457               (const_string "ishiftx")
9458             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9459                       (match_operand 0 "register_operand"))
9460                  (match_operand 2 "const1_operand"))
9461               (const_string "alu")
9462            ]
9463            (const_string "ishift")))
9464    (set (attr "length_immediate")
9465      (if_then_else
9466        (ior (eq_attr "type" "alu")
9467             (and (eq_attr "type" "ishift")
9468                  (and (match_operand 2 "const1_operand")
9469                       (ior (match_test "TARGET_SHIFT1")
9470                            (match_test "optimize_function_for_size_p (cfun)")))))
9471        (const_string "0")
9472        (const_string "*")))
9473    (set_attr "mode" "<MODE>")])
9475 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9476 (define_split
9477   [(set (match_operand:SWI48 0 "register_operand")
9478         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9479                       (match_operand:QI 2 "register_operand")))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "TARGET_BMI2 && reload_completed"
9482   [(set (match_dup 0)
9483         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9484   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9486 (define_insn "*bmi2_ashlsi3_1_zext"
9487   [(set (match_operand:DI 0 "register_operand" "=r")
9488         (zero_extend:DI
9489           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9490                      (match_operand:SI 2 "register_operand" "r"))))]
9491   "TARGET_64BIT && TARGET_BMI2"
9492   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9493   [(set_attr "type" "ishiftx")
9494    (set_attr "mode" "SI")])
9496 (define_insn "*ashlsi3_1_zext"
9497   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9498         (zero_extend:DI
9499           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9500                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9501    (clobber (reg:CC FLAGS_REG))]
9502   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504   switch (get_attr_type (insn))
9505     {
9506     case TYPE_LEA:
9507     case TYPE_ISHIFTX:
9508       return "#";
9510     case TYPE_ALU:
9511       gcc_assert (operands[2] == const1_rtx);
9512       return "add{l}\t%k0, %k0";
9514     default:
9515       if (operands[2] == const1_rtx
9516           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9517         return "sal{l}\t%k0";
9518       else
9519         return "sal{l}\t{%2, %k0|%k0, %2}";
9520     }
9522   [(set_attr "isa" "*,*,bmi2")
9523    (set (attr "type")
9524      (cond [(eq_attr "alternative" "1")
9525               (const_string "lea")
9526             (eq_attr "alternative" "2")
9527               (const_string "ishiftx")
9528             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9529                  (match_operand 2 "const1_operand"))
9530               (const_string "alu")
9531            ]
9532            (const_string "ishift")))
9533    (set (attr "length_immediate")
9534      (if_then_else
9535        (ior (eq_attr "type" "alu")
9536             (and (eq_attr "type" "ishift")
9537                  (and (match_operand 2 "const1_operand")
9538                       (ior (match_test "TARGET_SHIFT1")
9539                            (match_test "optimize_function_for_size_p (cfun)")))))
9540        (const_string "0")
9541        (const_string "*")))
9542    (set_attr "mode" "SI")])
9544 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9545 (define_split
9546   [(set (match_operand:DI 0 "register_operand")
9547         (zero_extend:DI
9548           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9549                      (match_operand:QI 2 "register_operand"))))
9550    (clobber (reg:CC FLAGS_REG))]
9551   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9552   [(set (match_dup 0)
9553         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9554   "operands[2] = gen_lowpart (SImode, operands[2]);")
9556 (define_insn "*ashlhi3_1"
9557   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9558         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9559                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9560    (clobber (reg:CC FLAGS_REG))]
9561   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9563   switch (get_attr_type (insn))
9564     {
9565     case TYPE_LEA:
9566       return "#";
9568     case TYPE_ALU:
9569       gcc_assert (operands[2] == const1_rtx);
9570       return "add{w}\t%0, %0";
9572     default:
9573       if (operands[2] == const1_rtx
9574           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9575         return "sal{w}\t%0";
9576       else
9577         return "sal{w}\t{%2, %0|%0, %2}";
9578     }
9580   [(set (attr "type")
9581      (cond [(eq_attr "alternative" "1")
9582               (const_string "lea")
9583             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584                       (match_operand 0 "register_operand"))
9585                  (match_operand 2 "const1_operand"))
9586               (const_string "alu")
9587            ]
9588            (const_string "ishift")))
9589    (set (attr "length_immediate")
9590      (if_then_else
9591        (ior (eq_attr "type" "alu")
9592             (and (eq_attr "type" "ishift")
9593                  (and (match_operand 2 "const1_operand")
9594                       (ior (match_test "TARGET_SHIFT1")
9595                            (match_test "optimize_function_for_size_p (cfun)")))))
9596        (const_string "0")
9597        (const_string "*")))
9598    (set_attr "mode" "HI,SI")])
9600 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9601 (define_insn "*ashlqi3_1"
9602   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9603         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9604                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9608   switch (get_attr_type (insn))
9609     {
9610     case TYPE_LEA:
9611       return "#";
9613     case TYPE_ALU:
9614       gcc_assert (operands[2] == const1_rtx);
9615       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9616         return "add{l}\t%k0, %k0";
9617       else
9618         return "add{b}\t%0, %0";
9620     default:
9621       if (operands[2] == const1_rtx
9622           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9623         {
9624           if (get_attr_mode (insn) == MODE_SI)
9625             return "sal{l}\t%k0";
9626           else
9627             return "sal{b}\t%0";
9628         }
9629       else
9630         {
9631           if (get_attr_mode (insn) == MODE_SI)
9632             return "sal{l}\t{%2, %k0|%k0, %2}";
9633           else
9634             return "sal{b}\t{%2, %0|%0, %2}";
9635         }
9636     }
9638   [(set (attr "type")
9639      (cond [(eq_attr "alternative" "2")
9640               (const_string "lea")
9641             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9642                       (match_operand 0 "register_operand"))
9643                  (match_operand 2 "const1_operand"))
9644               (const_string "alu")
9645            ]
9646            (const_string "ishift")))
9647    (set (attr "length_immediate")
9648      (if_then_else
9649        (ior (eq_attr "type" "alu")
9650             (and (eq_attr "type" "ishift")
9651                  (and (match_operand 2 "const1_operand")
9652                       (ior (match_test "TARGET_SHIFT1")
9653                            (match_test "optimize_function_for_size_p (cfun)")))))
9654        (const_string "0")
9655        (const_string "*")))
9656    (set_attr "mode" "QI,SI,SI")])
9658 (define_insn "*ashlqi3_1_slp"
9659   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9660         (ashift:QI (match_dup 0)
9661                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "(optimize_function_for_size_p (cfun)
9664     || !TARGET_PARTIAL_FLAG_REG_STALL
9665     || (operands[1] == const1_rtx
9666         && (TARGET_SHIFT1
9667             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9669   switch (get_attr_type (insn))
9670     {
9671     case TYPE_ALU:
9672       gcc_assert (operands[1] == const1_rtx);
9673       return "add{b}\t%0, %0";
9675     default:
9676       if (operands[1] == const1_rtx
9677           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9678         return "sal{b}\t%0";
9679       else
9680         return "sal{b}\t{%1, %0|%0, %1}";
9681     }
9683   [(set (attr "type")
9684      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9685                       (match_operand 0 "register_operand"))
9686                  (match_operand 1 "const1_operand"))
9687               (const_string "alu")
9688            ]
9689            (const_string "ishift1")))
9690    (set (attr "length_immediate")
9691      (if_then_else
9692        (ior (eq_attr "type" "alu")
9693             (and (eq_attr "type" "ishift1")
9694                  (and (match_operand 1 "const1_operand")
9695                       (ior (match_test "TARGET_SHIFT1")
9696                            (match_test "optimize_function_for_size_p (cfun)")))))
9697        (const_string "0")
9698        (const_string "*")))
9699    (set_attr "mode" "QI")])
9701 ;; Convert ashift to the lea pattern to avoid flags dependency.
9702 (define_split
9703   [(set (match_operand 0 "register_operand")
9704         (ashift (match_operand 1 "index_register_operand")
9705                 (match_operand:QI 2 "const_int_operand")))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9708    && reload_completed
9709    && true_regnum (operands[0]) != true_regnum (operands[1])"
9710   [(const_int 0)]
9712   machine_mode mode = GET_MODE (operands[0]);
9713   rtx pat;
9715   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9716     { 
9717       mode = SImode; 
9718       operands[0] = gen_lowpart (mode, operands[0]);
9719       operands[1] = gen_lowpart (mode, operands[1]);
9720     }
9722   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9724   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9726   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9727   DONE;
9730 ;; Convert ashift to the lea pattern to avoid flags dependency.
9731 (define_split
9732   [(set (match_operand:DI 0 "register_operand")
9733         (zero_extend:DI
9734           (ashift:SI (match_operand:SI 1 "index_register_operand")
9735                      (match_operand:QI 2 "const_int_operand"))))
9736    (clobber (reg:CC FLAGS_REG))]
9737   "TARGET_64BIT && reload_completed
9738    && true_regnum (operands[0]) != true_regnum (operands[1])"
9739   [(set (match_dup 0)
9740         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9742   operands[1] = gen_lowpart (SImode, operands[1]);
9743   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9746 ;; This pattern can't accept a variable shift count, since shifts by
9747 ;; zero don't affect the flags.  We assume that shifts by constant
9748 ;; zero are optimized away.
9749 (define_insn "*ashl<mode>3_cmp"
9750   [(set (reg FLAGS_REG)
9751         (compare
9752           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9753                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9754           (const_int 0)))
9755    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9756         (ashift:SWI (match_dup 1) (match_dup 2)))]
9757   "(optimize_function_for_size_p (cfun)
9758     || !TARGET_PARTIAL_FLAG_REG_STALL
9759     || (operands[2] == const1_rtx
9760         && (TARGET_SHIFT1
9761             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9762    && ix86_match_ccmode (insn, CCGOCmode)
9763    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9765   switch (get_attr_type (insn))
9766     {
9767     case TYPE_ALU:
9768       gcc_assert (operands[2] == const1_rtx);
9769       return "add{<imodesuffix>}\t%0, %0";
9771     default:
9772       if (operands[2] == const1_rtx
9773           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9774         return "sal{<imodesuffix>}\t%0";
9775       else
9776         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9777     }
9779   [(set (attr "type")
9780      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9781                       (match_operand 0 "register_operand"))
9782                  (match_operand 2 "const1_operand"))
9783               (const_string "alu")
9784            ]
9785            (const_string "ishift")))
9786    (set (attr "length_immediate")
9787      (if_then_else
9788        (ior (eq_attr "type" "alu")
9789             (and (eq_attr "type" "ishift")
9790                  (and (match_operand 2 "const1_operand")
9791                       (ior (match_test "TARGET_SHIFT1")
9792                            (match_test "optimize_function_for_size_p (cfun)")))))
9793        (const_string "0")
9794        (const_string "*")))
9795    (set_attr "mode" "<MODE>")])
9797 (define_insn "*ashlsi3_cmp_zext"
9798   [(set (reg FLAGS_REG)
9799         (compare
9800           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9801                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9802           (const_int 0)))
9803    (set (match_operand:DI 0 "register_operand" "=r")
9804         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9805   "TARGET_64BIT
9806    && (optimize_function_for_size_p (cfun)
9807        || !TARGET_PARTIAL_FLAG_REG_STALL
9808        || (operands[2] == const1_rtx
9809            && (TARGET_SHIFT1
9810                || TARGET_DOUBLE_WITH_ADD)))
9811    && ix86_match_ccmode (insn, CCGOCmode)
9812    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9814   switch (get_attr_type (insn))
9815     {
9816     case TYPE_ALU:
9817       gcc_assert (operands[2] == const1_rtx);
9818       return "add{l}\t%k0, %k0";
9820     default:
9821       if (operands[2] == const1_rtx
9822           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9823         return "sal{l}\t%k0";
9824       else
9825         return "sal{l}\t{%2, %k0|%k0, %2}";
9826     }
9828   [(set (attr "type")
9829      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9830                  (match_operand 2 "const1_operand"))
9831               (const_string "alu")
9832            ]
9833            (const_string "ishift")))
9834    (set (attr "length_immediate")
9835      (if_then_else
9836        (ior (eq_attr "type" "alu")
9837             (and (eq_attr "type" "ishift")
9838                  (and (match_operand 2 "const1_operand")
9839                       (ior (match_test "TARGET_SHIFT1")
9840                            (match_test "optimize_function_for_size_p (cfun)")))))
9841        (const_string "0")
9842        (const_string "*")))
9843    (set_attr "mode" "SI")])
9845 (define_insn "*ashl<mode>3_cconly"
9846   [(set (reg FLAGS_REG)
9847         (compare
9848           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9849                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9850           (const_int 0)))
9851    (clobber (match_scratch:SWI 0 "=<r>"))]
9852   "(optimize_function_for_size_p (cfun)
9853     || !TARGET_PARTIAL_FLAG_REG_STALL
9854     || (operands[2] == const1_rtx
9855         && (TARGET_SHIFT1
9856             || TARGET_DOUBLE_WITH_ADD)))
9857    && ix86_match_ccmode (insn, CCGOCmode)"
9859   switch (get_attr_type (insn))
9860     {
9861     case TYPE_ALU:
9862       gcc_assert (operands[2] == const1_rtx);
9863       return "add{<imodesuffix>}\t%0, %0";
9865     default:
9866       if (operands[2] == const1_rtx
9867           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868         return "sal{<imodesuffix>}\t%0";
9869       else
9870         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9871     }
9873   [(set (attr "type")
9874      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9875                       (match_operand 0 "register_operand"))
9876                  (match_operand 2 "const1_operand"))
9877               (const_string "alu")
9878            ]
9879            (const_string "ishift")))
9880    (set (attr "length_immediate")
9881      (if_then_else
9882        (ior (eq_attr "type" "alu")
9883             (and (eq_attr "type" "ishift")
9884                  (and (match_operand 2 "const1_operand")
9885                       (ior (match_test "TARGET_SHIFT1")
9886                            (match_test "optimize_function_for_size_p (cfun)")))))
9887        (const_string "0")
9888        (const_string "*")))
9889    (set_attr "mode" "<MODE>")])
9891 ;; See comment above `ashl<mode>3' about how this works.
9893 (define_expand "<shift_insn><mode>3"
9894   [(set (match_operand:SDWIM 0 "<shift_operand>")
9895         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9896                            (match_operand:QI 2 "nonmemory_operand")))]
9897   ""
9898   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9900 ;; Avoid useless masking of count operand.
9901 (define_insn "*<shift_insn><mode>3_mask"
9902   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9903         (any_shiftrt:SWI48
9904           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9905           (subreg:QI
9906             (and:SI
9907               (match_operand:SI 2 "register_operand" "c")
9908               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9909    (clobber (reg:CC FLAGS_REG))]
9910   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9911    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9912       == GET_MODE_BITSIZE (<MODE>mode)-1"
9914   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9916   [(set_attr "type" "ishift")
9917    (set_attr "mode" "<MODE>")])
9919 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9920   [(set (match_operand:DWI 0 "register_operand" "=r")
9921         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9922                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9923    (clobber (reg:CC FLAGS_REG))]
9924   ""
9925   "#"
9926   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9927   [(const_int 0)]
9928   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9929   [(set_attr "type" "multi")])
9931 ;; By default we don't ask for a scratch register, because when DWImode
9932 ;; values are manipulated, registers are already at a premium.  But if
9933 ;; we have one handy, we won't turn it away.
9935 (define_peephole2
9936   [(match_scratch:DWIH 3 "r")
9937    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9938                    (any_shiftrt:<DWI>
9939                      (match_operand:<DWI> 1 "register_operand")
9940                      (match_operand:QI 2 "nonmemory_operand")))
9941               (clobber (reg:CC FLAGS_REG))])
9942    (match_dup 3)]
9943   "TARGET_CMOVE"
9944   [(const_int 0)]
9945   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9947 (define_insn "x86_64_shrd"
9948   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9949         (ior:DI (lshiftrt:DI (match_dup 0)
9950                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9951                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9952                   (minus:QI (const_int 64) (match_dup 2)))))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "TARGET_64BIT"
9955   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9956   [(set_attr "type" "ishift")
9957    (set_attr "prefix_0f" "1")
9958    (set_attr "mode" "DI")
9959    (set_attr "athlon_decode" "vector")
9960    (set_attr "amdfam10_decode" "vector")
9961    (set_attr "bdver1_decode" "vector")])
9963 (define_insn "x86_shrd"
9964   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9965         (ior:SI (lshiftrt:SI (match_dup 0)
9966                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9967                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9968                   (minus:QI (const_int 32) (match_dup 2)))))
9969    (clobber (reg:CC FLAGS_REG))]
9970   ""
9971   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9972   [(set_attr "type" "ishift")
9973    (set_attr "prefix_0f" "1")
9974    (set_attr "mode" "SI")
9975    (set_attr "pent_pair" "np")
9976    (set_attr "athlon_decode" "vector")
9977    (set_attr "amdfam10_decode" "vector")
9978    (set_attr "bdver1_decode" "vector")])
9980 (define_insn "ashrdi3_cvt"
9981   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9982         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9983                      (match_operand:QI 2 "const_int_operand")))
9984    (clobber (reg:CC FLAGS_REG))]
9985   "TARGET_64BIT && INTVAL (operands[2]) == 63
9986    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9987    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9988   "@
9989    {cqto|cqo}
9990    sar{q}\t{%2, %0|%0, %2}"
9991   [(set_attr "type" "imovx,ishift")
9992    (set_attr "prefix_0f" "0,*")
9993    (set_attr "length_immediate" "0,*")
9994    (set_attr "modrm" "0,1")
9995    (set_attr "mode" "DI")])
9997 (define_insn "ashrsi3_cvt"
9998   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9999         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10000                      (match_operand:QI 2 "const_int_operand")))
10001    (clobber (reg:CC FLAGS_REG))]
10002   "INTVAL (operands[2]) == 31
10003    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10004    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10005   "@
10006    {cltd|cdq}
10007    sar{l}\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" "SI")])
10014 (define_insn "*ashrsi3_cvt_zext"
10015   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10016         (zero_extend:DI
10017           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10018                        (match_operand:QI 2 "const_int_operand"))))
10019    (clobber (reg:CC FLAGS_REG))]
10020   "TARGET_64BIT && INTVAL (operands[2]) == 31
10021    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10022    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10023   "@
10024    {cltd|cdq}
10025    sar{l}\t{%2, %k0|%k0, %2}"
10026   [(set_attr "type" "imovx,ishift")
10027    (set_attr "prefix_0f" "0,*")
10028    (set_attr "length_immediate" "0,*")
10029    (set_attr "modrm" "0,1")
10030    (set_attr "mode" "SI")])
10032 (define_expand "x86_shift<mode>_adj_3"
10033   [(use (match_operand:SWI48 0 "register_operand"))
10034    (use (match_operand:SWI48 1 "register_operand"))
10035    (use (match_operand:QI 2 "register_operand"))]
10036   ""
10038   rtx_code_label *label = gen_label_rtx ();
10039   rtx tmp;
10041   emit_insn (gen_testqi_ccz_1 (operands[2],
10042                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10044   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10045   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10046   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10047                               gen_rtx_LABEL_REF (VOIDmode, label),
10048                               pc_rtx);
10049   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10050   JUMP_LABEL (tmp) = label;
10052   emit_move_insn (operands[0], operands[1]);
10053   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10054                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10055   emit_label (label);
10056   LABEL_NUSES (label) = 1;
10058   DONE;
10061 (define_insn "*bmi2_<shift_insn><mode>3_1"
10062   [(set (match_operand:SWI48 0 "register_operand" "=r")
10063         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10064                            (match_operand:SWI48 2 "register_operand" "r")))]
10065   "TARGET_BMI2"
10066   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10067   [(set_attr "type" "ishiftx")
10068    (set_attr "mode" "<MODE>")])
10070 (define_insn "*<shift_insn><mode>3_1"
10071   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10072         (any_shiftrt:SWI48
10073           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10074           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10075    (clobber (reg:CC FLAGS_REG))]
10076   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10078   switch (get_attr_type (insn))
10079     {
10080     case TYPE_ISHIFTX:
10081       return "#";
10083     default:
10084       if (operands[2] == const1_rtx
10085           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10086         return "<shift>{<imodesuffix>}\t%0";
10087       else
10088         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10089     }
10091   [(set_attr "isa" "*,bmi2")
10092    (set_attr "type" "ishift,ishiftx")
10093    (set (attr "length_immediate")
10094      (if_then_else
10095        (and (match_operand 2 "const1_operand")
10096             (ior (match_test "TARGET_SHIFT1")
10097                  (match_test "optimize_function_for_size_p (cfun)")))
10098        (const_string "0")
10099        (const_string "*")))
10100    (set_attr "mode" "<MODE>")])
10102 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10103 (define_split
10104   [(set (match_operand:SWI48 0 "register_operand")
10105         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10106                            (match_operand:QI 2 "register_operand")))
10107    (clobber (reg:CC FLAGS_REG))]
10108   "TARGET_BMI2 && reload_completed"
10109   [(set (match_dup 0)
10110         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10111   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10113 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10114   [(set (match_operand:DI 0 "register_operand" "=r")
10115         (zero_extend:DI
10116           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10117                           (match_operand:SI 2 "register_operand" "r"))))]
10118   "TARGET_64BIT && TARGET_BMI2"
10119   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10120   [(set_attr "type" "ishiftx")
10121    (set_attr "mode" "SI")])
10123 (define_insn "*<shift_insn>si3_1_zext"
10124   [(set (match_operand:DI 0 "register_operand" "=r,r")
10125         (zero_extend:DI
10126           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10127                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10128    (clobber (reg:CC FLAGS_REG))]
10129   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10131   switch (get_attr_type (insn))
10132     {
10133     case TYPE_ISHIFTX:
10134       return "#";
10136     default:
10137       if (operands[2] == const1_rtx
10138           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10139         return "<shift>{l}\t%k0";
10140       else
10141         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10142     }
10144   [(set_attr "isa" "*,bmi2")
10145    (set_attr "type" "ishift,ishiftx")
10146    (set (attr "length_immediate")
10147      (if_then_else
10148        (and (match_operand 2 "const1_operand")
10149             (ior (match_test "TARGET_SHIFT1")
10150                  (match_test "optimize_function_for_size_p (cfun)")))
10151        (const_string "0")
10152        (const_string "*")))
10153    (set_attr "mode" "SI")])
10155 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10156 (define_split
10157   [(set (match_operand:DI 0 "register_operand")
10158         (zero_extend:DI
10159           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10160                           (match_operand:QI 2 "register_operand"))))
10161    (clobber (reg:CC FLAGS_REG))]
10162   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10163   [(set (match_dup 0)
10164         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10165   "operands[2] = gen_lowpart (SImode, operands[2]);")
10167 (define_insn "*<shift_insn><mode>3_1"
10168   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10169         (any_shiftrt:SWI12
10170           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10171           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10172    (clobber (reg:CC FLAGS_REG))]
10173   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10175   if (operands[2] == const1_rtx
10176       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177     return "<shift>{<imodesuffix>}\t%0";
10178   else
10179     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10181   [(set_attr "type" "ishift")
10182    (set (attr "length_immediate")
10183      (if_then_else
10184        (and (match_operand 2 "const1_operand")
10185             (ior (match_test "TARGET_SHIFT1")
10186                  (match_test "optimize_function_for_size_p (cfun)")))
10187        (const_string "0")
10188        (const_string "*")))
10189    (set_attr "mode" "<MODE>")])
10191 (define_insn "*<shift_insn>qi3_1_slp"
10192   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10193         (any_shiftrt:QI (match_dup 0)
10194                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "(optimize_function_for_size_p (cfun)
10197     || !TARGET_PARTIAL_REG_STALL
10198     || (operands[1] == const1_rtx
10199         && TARGET_SHIFT1))"
10201   if (operands[1] == const1_rtx
10202       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10203     return "<shift>{b}\t%0";
10204   else
10205     return "<shift>{b}\t{%1, %0|%0, %1}";
10207   [(set_attr "type" "ishift1")
10208    (set (attr "length_immediate")
10209      (if_then_else
10210        (and (match_operand 1 "const1_operand")
10211             (ior (match_test "TARGET_SHIFT1")
10212                  (match_test "optimize_function_for_size_p (cfun)")))
10213        (const_string "0")
10214        (const_string "*")))
10215    (set_attr "mode" "QI")])
10217 ;; This pattern can't accept a variable shift count, since shifts by
10218 ;; zero don't affect the flags.  We assume that shifts by constant
10219 ;; zero are optimized away.
10220 (define_insn "*<shift_insn><mode>3_cmp"
10221   [(set (reg FLAGS_REG)
10222         (compare
10223           (any_shiftrt:SWI
10224             (match_operand:SWI 1 "nonimmediate_operand" "0")
10225             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10226           (const_int 0)))
10227    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10228         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10229   "(optimize_function_for_size_p (cfun)
10230     || !TARGET_PARTIAL_FLAG_REG_STALL
10231     || (operands[2] == const1_rtx
10232         && TARGET_SHIFT1))
10233    && ix86_match_ccmode (insn, CCGOCmode)
10234    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10236   if (operands[2] == const1_rtx
10237       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238     return "<shift>{<imodesuffix>}\t%0";
10239   else
10240     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242   [(set_attr "type" "ishift")
10243    (set (attr "length_immediate")
10244      (if_then_else
10245        (and (match_operand 2 "const1_operand")
10246             (ior (match_test "TARGET_SHIFT1")
10247                  (match_test "optimize_function_for_size_p (cfun)")))
10248        (const_string "0")
10249        (const_string "*")))
10250    (set_attr "mode" "<MODE>")])
10252 (define_insn "*<shift_insn>si3_cmp_zext"
10253   [(set (reg FLAGS_REG)
10254         (compare
10255           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10256                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10257           (const_int 0)))
10258    (set (match_operand:DI 0 "register_operand" "=r")
10259         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10260   "TARGET_64BIT
10261    && (optimize_function_for_size_p (cfun)
10262        || !TARGET_PARTIAL_FLAG_REG_STALL
10263        || (operands[2] == const1_rtx
10264            && TARGET_SHIFT1))
10265    && ix86_match_ccmode (insn, CCGOCmode)
10266    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10268   if (operands[2] == const1_rtx
10269       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10270     return "<shift>{l}\t%k0";
10271   else
10272     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10274   [(set_attr "type" "ishift")
10275    (set (attr "length_immediate")
10276      (if_then_else
10277        (and (match_operand 2 "const1_operand")
10278             (ior (match_test "TARGET_SHIFT1")
10279                  (match_test "optimize_function_for_size_p (cfun)")))
10280        (const_string "0")
10281        (const_string "*")))
10282    (set_attr "mode" "SI")])
10284 (define_insn "*<shift_insn><mode>3_cconly"
10285   [(set (reg FLAGS_REG)
10286         (compare
10287           (any_shiftrt:SWI
10288             (match_operand:SWI 1 "register_operand" "0")
10289             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10290           (const_int 0)))
10291    (clobber (match_scratch:SWI 0 "=<r>"))]
10292   "(optimize_function_for_size_p (cfun)
10293     || !TARGET_PARTIAL_FLAG_REG_STALL
10294     || (operands[2] == const1_rtx
10295         && TARGET_SHIFT1))
10296    && ix86_match_ccmode (insn, CCGOCmode)"
10298   if (operands[2] == const1_rtx
10299       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10300     return "<shift>{<imodesuffix>}\t%0";
10301   else
10302     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10304   [(set_attr "type" "ishift")
10305    (set (attr "length_immediate")
10306      (if_then_else
10307        (and (match_operand 2 "const1_operand")
10308             (ior (match_test "TARGET_SHIFT1")
10309                  (match_test "optimize_function_for_size_p (cfun)")))
10310        (const_string "0")
10311        (const_string "*")))
10312    (set_attr "mode" "<MODE>")])
10314 ;; Rotate instructions
10316 (define_expand "<rotate_insn>ti3"
10317   [(set (match_operand:TI 0 "register_operand")
10318         (any_rotate:TI (match_operand:TI 1 "register_operand")
10319                        (match_operand:QI 2 "nonmemory_operand")))]
10320   "TARGET_64BIT"
10322   if (const_1_to_63_operand (operands[2], VOIDmode))
10323     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10324                 (operands[0], operands[1], operands[2]));
10325   else
10326     FAIL;
10328   DONE;
10331 (define_expand "<rotate_insn>di3"
10332   [(set (match_operand:DI 0 "shiftdi_operand")
10333         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10334                        (match_operand:QI 2 "nonmemory_operand")))]
10335  ""
10337   if (TARGET_64BIT)
10338     ix86_expand_binary_operator (<CODE>, DImode, operands);
10339   else if (const_1_to_31_operand (operands[2], VOIDmode))
10340     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10341                 (operands[0], operands[1], operands[2]));
10342   else
10343     FAIL;
10345   DONE;
10348 (define_expand "<rotate_insn><mode>3"
10349   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10350         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10351                             (match_operand:QI 2 "nonmemory_operand")))]
10352   ""
10353   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10355 ;; Avoid useless masking of count operand.
10356 (define_insn "*<rotate_insn><mode>3_mask"
10357   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10358         (any_rotate:SWI48
10359           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10360           (subreg:QI
10361             (and:SI
10362               (match_operand:SI 2 "register_operand" "c")
10363               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10366    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10367       == GET_MODE_BITSIZE (<MODE>mode)-1"
10369   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10371   [(set_attr "type" "rotate")
10372    (set_attr "mode" "<MODE>")])
10374 ;; Implement rotation using two double-precision
10375 ;; shift instructions and a scratch register.
10377 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10378  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10379        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10380                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10381   (clobber (reg:CC FLAGS_REG))
10382   (clobber (match_scratch:DWIH 3 "=&r"))]
10383  ""
10384  "#"
10385  "reload_completed"
10386  [(set (match_dup 3) (match_dup 4))
10387   (parallel
10388    [(set (match_dup 4)
10389          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10390                    (lshiftrt:DWIH (match_dup 5)
10391                                   (minus:QI (match_dup 6) (match_dup 2)))))
10392     (clobber (reg:CC FLAGS_REG))])
10393   (parallel
10394    [(set (match_dup 5)
10395          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10396                    (lshiftrt:DWIH (match_dup 3)
10397                                   (minus:QI (match_dup 6) (match_dup 2)))))
10398     (clobber (reg:CC FLAGS_REG))])]
10400   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10402   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10405 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10406  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10407        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10408                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10409   (clobber (reg:CC FLAGS_REG))
10410   (clobber (match_scratch:DWIH 3 "=&r"))]
10411  ""
10412  "#"
10413  "reload_completed"
10414  [(set (match_dup 3) (match_dup 4))
10415   (parallel
10416    [(set (match_dup 4)
10417          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10418                    (ashift:DWIH (match_dup 5)
10419                                 (minus:QI (match_dup 6) (match_dup 2)))))
10420     (clobber (reg:CC FLAGS_REG))])
10421   (parallel
10422    [(set (match_dup 5)
10423          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10424                    (ashift:DWIH (match_dup 3)
10425                                 (minus:QI (match_dup 6) (match_dup 2)))))
10426     (clobber (reg:CC FLAGS_REG))])]
10428   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10430   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10433 (define_insn "*bmi2_rorx<mode>3_1"
10434   [(set (match_operand:SWI48 0 "register_operand" "=r")
10435         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10436                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10437   "TARGET_BMI2"
10438   "rorx\t{%2, %1, %0|%0, %1, %2}"
10439   [(set_attr "type" "rotatex")
10440    (set_attr "mode" "<MODE>")])
10442 (define_insn "*<rotate_insn><mode>3_1"
10443   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10444         (any_rotate:SWI48
10445           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10446           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10447    (clobber (reg:CC FLAGS_REG))]
10448   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10450   switch (get_attr_type (insn))
10451     {
10452     case TYPE_ROTATEX:
10453       return "#";
10455     default:
10456       if (operands[2] == const1_rtx
10457           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10458         return "<rotate>{<imodesuffix>}\t%0";
10459       else
10460         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10461     }
10463   [(set_attr "isa" "*,bmi2")
10464    (set_attr "type" "rotate,rotatex")
10465    (set (attr "length_immediate")
10466      (if_then_else
10467        (and (eq_attr "type" "rotate")
10468             (and (match_operand 2 "const1_operand")
10469                  (ior (match_test "TARGET_SHIFT1")
10470                       (match_test "optimize_function_for_size_p (cfun)"))))
10471        (const_string "0")
10472        (const_string "*")))
10473    (set_attr "mode" "<MODE>")])
10475 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10476 (define_split
10477   [(set (match_operand:SWI48 0 "register_operand")
10478         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10479                       (match_operand:QI 2 "immediate_operand")))
10480    (clobber (reg:CC FLAGS_REG))]
10481   "TARGET_BMI2 && reload_completed"
10482   [(set (match_dup 0)
10483         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10485   operands[2]
10486     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10489 (define_split
10490   [(set (match_operand:SWI48 0 "register_operand")
10491         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10492                         (match_operand:QI 2 "immediate_operand")))
10493    (clobber (reg:CC FLAGS_REG))]
10494   "TARGET_BMI2 && reload_completed"
10495   [(set (match_dup 0)
10496         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10498 (define_insn "*bmi2_rorxsi3_1_zext"
10499   [(set (match_operand:DI 0 "register_operand" "=r")
10500         (zero_extend:DI
10501           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10502                        (match_operand:QI 2 "immediate_operand" "I"))))]
10503   "TARGET_64BIT && TARGET_BMI2"
10504   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10505   [(set_attr "type" "rotatex")
10506    (set_attr "mode" "SI")])
10508 (define_insn "*<rotate_insn>si3_1_zext"
10509   [(set (match_operand:DI 0 "register_operand" "=r,r")
10510         (zero_extend:DI
10511           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10512                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10516   switch (get_attr_type (insn))
10517     {
10518     case TYPE_ROTATEX:
10519       return "#";
10521     default:
10522       if (operands[2] == const1_rtx
10523           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10524         return "<rotate>{l}\t%k0";
10525       else
10526         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10527     }
10529   [(set_attr "isa" "*,bmi2")
10530    (set_attr "type" "rotate,rotatex")
10531    (set (attr "length_immediate")
10532      (if_then_else
10533        (and (eq_attr "type" "rotate")
10534             (and (match_operand 2 "const1_operand")
10535                  (ior (match_test "TARGET_SHIFT1")
10536                       (match_test "optimize_function_for_size_p (cfun)"))))
10537        (const_string "0")
10538        (const_string "*")))
10539    (set_attr "mode" "SI")])
10541 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10542 (define_split
10543   [(set (match_operand:DI 0 "register_operand")
10544         (zero_extend:DI
10545           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10546                      (match_operand:QI 2 "immediate_operand"))))
10547    (clobber (reg:CC FLAGS_REG))]
10548   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10549   [(set (match_dup 0)
10550         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10552   operands[2]
10553     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10556 (define_split
10557   [(set (match_operand:DI 0 "register_operand")
10558         (zero_extend:DI
10559           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10560                        (match_operand:QI 2 "immediate_operand"))))
10561    (clobber (reg:CC FLAGS_REG))]
10562   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10563   [(set (match_dup 0)
10564         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10566 (define_insn "*<rotate_insn><mode>3_1"
10567   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10568         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10569                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10570    (clobber (reg:CC FLAGS_REG))]
10571   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10573   if (operands[2] == const1_rtx
10574       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10575     return "<rotate>{<imodesuffix>}\t%0";
10576   else
10577     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10579   [(set_attr "type" "rotate")
10580    (set (attr "length_immediate")
10581      (if_then_else
10582        (and (match_operand 2 "const1_operand")
10583             (ior (match_test "TARGET_SHIFT1")
10584                  (match_test "optimize_function_for_size_p (cfun)")))
10585        (const_string "0")
10586        (const_string "*")))
10587    (set_attr "mode" "<MODE>")])
10589 (define_insn "*<rotate_insn>qi3_1_slp"
10590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10591         (any_rotate:QI (match_dup 0)
10592                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10593    (clobber (reg:CC FLAGS_REG))]
10594   "(optimize_function_for_size_p (cfun)
10595     || !TARGET_PARTIAL_REG_STALL
10596     || (operands[1] == const1_rtx
10597         && TARGET_SHIFT1))"
10599   if (operands[1] == const1_rtx
10600       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601     return "<rotate>{b}\t%0";
10602   else
10603     return "<rotate>{b}\t{%1, %0|%0, %1}";
10605   [(set_attr "type" "rotate1")
10606    (set (attr "length_immediate")
10607      (if_then_else
10608        (and (match_operand 1 "const1_operand")
10609             (ior (match_test "TARGET_SHIFT1")
10610                  (match_test "optimize_function_for_size_p (cfun)")))
10611        (const_string "0")
10612        (const_string "*")))
10613    (set_attr "mode" "QI")])
10615 (define_split
10616  [(set (match_operand:HI 0 "register_operand")
10617        (any_rotate:HI (match_dup 0) (const_int 8)))
10618   (clobber (reg:CC FLAGS_REG))]
10619  "reload_completed
10620   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10621  [(parallel [(set (strict_low_part (match_dup 0))
10622                   (bswap:HI (match_dup 0)))
10623              (clobber (reg:CC FLAGS_REG))])])
10625 ;; Bit set / bit test instructions
10627 (define_expand "extv"
10628   [(set (match_operand:SI 0 "register_operand")
10629         (sign_extract:SI (match_operand:SI 1 "register_operand")
10630                          (match_operand:SI 2 "const8_operand")
10631                          (match_operand:SI 3 "const8_operand")))]
10632   ""
10634   /* Handle extractions from %ah et al.  */
10635   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10636     FAIL;
10638   /* From mips.md: extract_bit_field doesn't verify that our source
10639      matches the predicate, so check it again here.  */
10640   if (! ext_register_operand (operands[1], VOIDmode))
10641     FAIL;
10644 (define_expand "extzv"
10645   [(set (match_operand:SI 0 "register_operand")
10646         (zero_extract:SI (match_operand 1 "ext_register_operand")
10647                          (match_operand:SI 2 "const8_operand")
10648                          (match_operand:SI 3 "const8_operand")))]
10649   ""
10651   /* Handle extractions from %ah et al.  */
10652   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10653     FAIL;
10655   /* From mips.md: extract_bit_field doesn't verify that our source
10656      matches the predicate, so check it again here.  */
10657   if (! ext_register_operand (operands[1], VOIDmode))
10658     FAIL;
10661 (define_expand "insv"
10662   [(set (zero_extract (match_operand 0 "register_operand")
10663                       (match_operand 1 "const_int_operand")
10664                       (match_operand 2 "const_int_operand"))
10665         (match_operand 3 "register_operand"))]
10666   ""
10668   rtx (*gen_mov_insv_1) (rtx, rtx);
10670   if (ix86_expand_pinsr (operands))
10671     DONE;
10673   /* Handle insertions to %ah et al.  */
10674   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10675     FAIL;
10677   /* From mips.md: insert_bit_field doesn't verify that our source
10678      matches the predicate, so check it again here.  */
10679   if (! ext_register_operand (operands[0], VOIDmode))
10680     FAIL;
10682   gen_mov_insv_1 = (TARGET_64BIT
10683                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10685   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10686   DONE;
10689 ;; %%% bts, btr, btc, bt.
10690 ;; In general these instructions are *slow* when applied to memory,
10691 ;; since they enforce atomic operation.  When applied to registers,
10692 ;; it depends on the cpu implementation.  They're never faster than
10693 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10694 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10695 ;; within the instruction itself, so operating on bits in the high
10696 ;; 32-bits of a register becomes easier.
10698 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10699 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10700 ;; negdf respectively, so they can never be disabled entirely.
10702 (define_insn "*btsq"
10703   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10704                          (const_int 1)
10705                          (match_operand:DI 1 "const_0_to_63_operand"))
10706         (const_int 1))
10707    (clobber (reg:CC FLAGS_REG))]
10708   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10709   "bts{q}\t{%1, %0|%0, %1}"
10710   [(set_attr "type" "alu1")
10711    (set_attr "prefix_0f" "1")
10712    (set_attr "mode" "DI")])
10714 (define_insn "*btrq"
10715   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10716                          (const_int 1)
10717                          (match_operand:DI 1 "const_0_to_63_operand"))
10718         (const_int 0))
10719    (clobber (reg:CC FLAGS_REG))]
10720   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10721   "btr{q}\t{%1, %0|%0, %1}"
10722   [(set_attr "type" "alu1")
10723    (set_attr "prefix_0f" "1")
10724    (set_attr "mode" "DI")])
10726 (define_insn "*btcq"
10727   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10728                          (const_int 1)
10729                          (match_operand:DI 1 "const_0_to_63_operand"))
10730         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10731    (clobber (reg:CC FLAGS_REG))]
10732   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10733   "btc{q}\t{%1, %0|%0, %1}"
10734   [(set_attr "type" "alu1")
10735    (set_attr "prefix_0f" "1")
10736    (set_attr "mode" "DI")])
10738 ;; Allow Nocona to avoid these instructions if a register is available.
10740 (define_peephole2
10741   [(match_scratch:DI 2 "r")
10742    (parallel [(set (zero_extract:DI
10743                      (match_operand:DI 0 "register_operand")
10744                      (const_int 1)
10745                      (match_operand:DI 1 "const_0_to_63_operand"))
10746                    (const_int 1))
10747               (clobber (reg:CC FLAGS_REG))])]
10748   "TARGET_64BIT && !TARGET_USE_BT"
10749   [(const_int 0)]
10751   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10752   rtx op1;
10754   if (HOST_BITS_PER_WIDE_INT >= 64)
10755     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10756   else if (i < HOST_BITS_PER_WIDE_INT)
10757     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10758   else
10759     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10761   op1 = immed_double_const (lo, hi, DImode);
10762   if (i >= 31)
10763     {
10764       emit_move_insn (operands[2], op1);
10765       op1 = operands[2];
10766     }
10768   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10769   DONE;
10772 (define_peephole2
10773   [(match_scratch:DI 2 "r")
10774    (parallel [(set (zero_extract:DI
10775                      (match_operand:DI 0 "register_operand")
10776                      (const_int 1)
10777                      (match_operand:DI 1 "const_0_to_63_operand"))
10778                    (const_int 0))
10779               (clobber (reg:CC FLAGS_REG))])]
10780   "TARGET_64BIT && !TARGET_USE_BT"
10781   [(const_int 0)]
10783   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10784   rtx op1;
10786   if (HOST_BITS_PER_WIDE_INT >= 64)
10787     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10788   else if (i < HOST_BITS_PER_WIDE_INT)
10789     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10790   else
10791     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10793   op1 = immed_double_const (~lo, ~hi, DImode);
10794   if (i >= 32)
10795     {
10796       emit_move_insn (operands[2], op1);
10797       op1 = operands[2];
10798     }
10800   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10801   DONE;
10804 (define_peephole2
10805   [(match_scratch:DI 2 "r")
10806    (parallel [(set (zero_extract:DI
10807                      (match_operand:DI 0 "register_operand")
10808                      (const_int 1)
10809                      (match_operand:DI 1 "const_0_to_63_operand"))
10810               (not:DI (zero_extract:DI
10811                         (match_dup 0) (const_int 1) (match_dup 1))))
10812               (clobber (reg:CC FLAGS_REG))])]
10813   "TARGET_64BIT && !TARGET_USE_BT"
10814   [(const_int 0)]
10816   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10817   rtx op1;
10819   if (HOST_BITS_PER_WIDE_INT >= 64)
10820     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10821   else if (i < HOST_BITS_PER_WIDE_INT)
10822     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10823   else
10824     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10826   op1 = immed_double_const (lo, hi, DImode);
10827   if (i >= 31)
10828     {
10829       emit_move_insn (operands[2], op1);
10830       op1 = operands[2];
10831     }
10833   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10834   DONE;
10837 (define_insn "*bt<mode>"
10838   [(set (reg:CCC FLAGS_REG)
10839         (compare:CCC
10840           (zero_extract:SWI48
10841             (match_operand:SWI48 0 "register_operand" "r")
10842             (const_int 1)
10843             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10844           (const_int 0)))]
10845   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10846   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10847   [(set_attr "type" "alu1")
10848    (set_attr "prefix_0f" "1")
10849    (set_attr "mode" "<MODE>")])
10851 ;; Store-flag instructions.
10853 ;; For all sCOND expanders, also expand the compare or test insn that
10854 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10856 (define_insn_and_split "*setcc_di_1"
10857   [(set (match_operand:DI 0 "register_operand" "=q")
10858         (match_operator:DI 1 "ix86_comparison_operator"
10859           [(reg FLAGS_REG) (const_int 0)]))]
10860   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10861   "#"
10862   "&& reload_completed"
10863   [(set (match_dup 2) (match_dup 1))
10864    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10866   operands[1] = shallow_copy_rtx (operands[1]);
10867   PUT_MODE (operands[1], QImode);
10868   operands[2] = gen_lowpart (QImode, operands[0]);
10871 (define_insn_and_split "*setcc_si_1_and"
10872   [(set (match_operand:SI 0 "register_operand" "=q")
10873         (match_operator:SI 1 "ix86_comparison_operator"
10874           [(reg FLAGS_REG) (const_int 0)]))
10875    (clobber (reg:CC FLAGS_REG))]
10876   "!TARGET_PARTIAL_REG_STALL
10877    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10878   "#"
10879   "&& reload_completed"
10880   [(set (match_dup 2) (match_dup 1))
10881    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10882               (clobber (reg:CC FLAGS_REG))])]
10884   operands[1] = shallow_copy_rtx (operands[1]);
10885   PUT_MODE (operands[1], QImode);
10886   operands[2] = gen_lowpart (QImode, operands[0]);
10889 (define_insn_and_split "*setcc_si_1_movzbl"
10890   [(set (match_operand:SI 0 "register_operand" "=q")
10891         (match_operator:SI 1 "ix86_comparison_operator"
10892           [(reg FLAGS_REG) (const_int 0)]))]
10893   "!TARGET_PARTIAL_REG_STALL
10894    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10895   "#"
10896   "&& reload_completed"
10897   [(set (match_dup 2) (match_dup 1))
10898    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10900   operands[1] = shallow_copy_rtx (operands[1]);
10901   PUT_MODE (operands[1], QImode);
10902   operands[2] = gen_lowpart (QImode, operands[0]);
10905 (define_insn "*setcc_qi"
10906   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10907         (match_operator:QI 1 "ix86_comparison_operator"
10908           [(reg FLAGS_REG) (const_int 0)]))]
10909   ""
10910   "set%C1\t%0"
10911   [(set_attr "type" "setcc")
10912    (set_attr "mode" "QI")])
10914 (define_insn "*setcc_qi_slp"
10915   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10916         (match_operator:QI 1 "ix86_comparison_operator"
10917           [(reg FLAGS_REG) (const_int 0)]))]
10918   ""
10919   "set%C1\t%0"
10920   [(set_attr "type" "setcc")
10921    (set_attr "mode" "QI")])
10923 ;; In general it is not safe to assume too much about CCmode registers,
10924 ;; so simplify-rtx stops when it sees a second one.  Under certain
10925 ;; conditions this is safe on x86, so help combine not create
10927 ;;      seta    %al
10928 ;;      testb   %al, %al
10929 ;;      sete    %al
10931 (define_split
10932   [(set (match_operand:QI 0 "nonimmediate_operand")
10933         (ne:QI (match_operator 1 "ix86_comparison_operator"
10934                  [(reg FLAGS_REG) (const_int 0)])
10935             (const_int 0)))]
10936   ""
10937   [(set (match_dup 0) (match_dup 1))]
10939   operands[1] = shallow_copy_rtx (operands[1]);
10940   PUT_MODE (operands[1], QImode);
10943 (define_split
10944   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10945         (ne:QI (match_operator 1 "ix86_comparison_operator"
10946                  [(reg FLAGS_REG) (const_int 0)])
10947             (const_int 0)))]
10948   ""
10949   [(set (match_dup 0) (match_dup 1))]
10951   operands[1] = shallow_copy_rtx (operands[1]);
10952   PUT_MODE (operands[1], QImode);
10955 (define_split
10956   [(set (match_operand:QI 0 "nonimmediate_operand")
10957         (eq:QI (match_operator 1 "ix86_comparison_operator"
10958                  [(reg FLAGS_REG) (const_int 0)])
10959             (const_int 0)))]
10960   ""
10961   [(set (match_dup 0) (match_dup 1))]
10963   operands[1] = shallow_copy_rtx (operands[1]);
10964   PUT_MODE (operands[1], QImode);
10965   PUT_CODE (operands[1],
10966             ix86_reverse_condition (GET_CODE (operands[1]),
10967                                     GET_MODE (XEXP (operands[1], 0))));
10969   /* Make sure that (a) the CCmode we have for the flags is strong
10970      enough for the reversed compare or (b) we have a valid FP compare.  */
10971   if (! ix86_comparison_operator (operands[1], VOIDmode))
10972     FAIL;
10975 (define_split
10976   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10977         (eq:QI (match_operator 1 "ix86_comparison_operator"
10978                  [(reg FLAGS_REG) (const_int 0)])
10979             (const_int 0)))]
10980   ""
10981   [(set (match_dup 0) (match_dup 1))]
10983   operands[1] = shallow_copy_rtx (operands[1]);
10984   PUT_MODE (operands[1], QImode);
10985   PUT_CODE (operands[1],
10986             ix86_reverse_condition (GET_CODE (operands[1]),
10987                                     GET_MODE (XEXP (operands[1], 0))));
10989   /* Make sure that (a) the CCmode we have for the flags is strong
10990      enough for the reversed compare or (b) we have a valid FP compare.  */
10991   if (! ix86_comparison_operator (operands[1], VOIDmode))
10992     FAIL;
10995 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10996 ;; subsequent logical operations are used to imitate conditional moves.
10997 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10998 ;; it directly.
11000 (define_insn "setcc_<mode>_sse"
11001   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11002         (match_operator:MODEF 3 "sse_comparison_operator"
11003           [(match_operand:MODEF 1 "register_operand" "0,x")
11004            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11005   "SSE_FLOAT_MODE_P (<MODE>mode)"
11006   "@
11007    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11008    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11009   [(set_attr "isa" "noavx,avx")
11010    (set_attr "type" "ssecmp")
11011    (set_attr "length_immediate" "1")
11012    (set_attr "prefix" "orig,vex")
11013    (set_attr "mode" "<MODE>")])
11015 ;; Basic conditional jump instructions.
11016 ;; We ignore the overflow flag for signed branch instructions.
11018 (define_insn "*jcc_1_bnd"
11019   [(set (pc)
11020         (if_then_else (match_operator 1 "ix86_comparison_operator"
11021                                       [(reg FLAGS_REG) (const_int 0)])
11022                       (label_ref (match_operand 0))
11023                       (pc)))]
11024   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11025   "bnd %+j%C1\t%l0"
11026   [(set_attr "type" "ibr")
11027    (set_attr "modrm" "0")
11028    (set (attr "length")
11029            (if_then_else (and (ge (minus (match_dup 0) (pc))
11030                                   (const_int -126))
11031                               (lt (minus (match_dup 0) (pc))
11032                                   (const_int 128)))
11033              (const_int 3)
11034              (const_int 7)))])
11036 (define_insn "*jcc_1"
11037   [(set (pc)
11038         (if_then_else (match_operator 1 "ix86_comparison_operator"
11039                                       [(reg FLAGS_REG) (const_int 0)])
11040                       (label_ref (match_operand 0))
11041                       (pc)))]
11042   ""
11043   "%+j%C1\t%l0"
11044   [(set_attr "type" "ibr")
11045    (set_attr "modrm" "0")
11046    (set (attr "length")
11047            (if_then_else (and (ge (minus (match_dup 0) (pc))
11048                                   (const_int -126))
11049                               (lt (minus (match_dup 0) (pc))
11050                                   (const_int 128)))
11051              (const_int 2)
11052              (const_int 6)))])
11054 (define_insn "*jcc_2_bnd"
11055   [(set (pc)
11056         (if_then_else (match_operator 1 "ix86_comparison_operator"
11057                                       [(reg FLAGS_REG) (const_int 0)])
11058                       (pc)
11059                       (label_ref (match_operand 0))))]
11060   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11061   "bnd %+j%c1\t%l0"
11062   [(set_attr "type" "ibr")
11063    (set_attr "modrm" "0")
11064    (set (attr "length")
11065            (if_then_else (and (ge (minus (match_dup 0) (pc))
11066                                   (const_int -126))
11067                               (lt (minus (match_dup 0) (pc))
11068                                   (const_int 128)))
11069              (const_int 3)
11070              (const_int 7)))])
11072 (define_insn "*jcc_2"
11073   [(set (pc)
11074         (if_then_else (match_operator 1 "ix86_comparison_operator"
11075                                       [(reg FLAGS_REG) (const_int 0)])
11076                       (pc)
11077                       (label_ref (match_operand 0))))]
11078   ""
11079   "%+j%c1\t%l0"
11080   [(set_attr "type" "ibr")
11081    (set_attr "modrm" "0")
11082    (set (attr "length")
11083            (if_then_else (and (ge (minus (match_dup 0) (pc))
11084                                   (const_int -126))
11085                               (lt (minus (match_dup 0) (pc))
11086                                   (const_int 128)))
11087              (const_int 2)
11088              (const_int 6)))])
11090 ;; In general it is not safe to assume too much about CCmode registers,
11091 ;; so simplify-rtx stops when it sees a second one.  Under certain
11092 ;; conditions this is safe on x86, so help combine not create
11094 ;;      seta    %al
11095 ;;      testb   %al, %al
11096 ;;      je      Lfoo
11098 (define_split
11099   [(set (pc)
11100         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11101                                       [(reg FLAGS_REG) (const_int 0)])
11102                           (const_int 0))
11103                       (label_ref (match_operand 1))
11104                       (pc)))]
11105   ""
11106   [(set (pc)
11107         (if_then_else (match_dup 0)
11108                       (label_ref (match_dup 1))
11109                       (pc)))]
11111   operands[0] = shallow_copy_rtx (operands[0]);
11112   PUT_MODE (operands[0], VOIDmode);
11115 (define_split
11116   [(set (pc)
11117         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11118                                       [(reg FLAGS_REG) (const_int 0)])
11119                           (const_int 0))
11120                       (label_ref (match_operand 1))
11121                       (pc)))]
11122   ""
11123   [(set (pc)
11124         (if_then_else (match_dup 0)
11125                       (label_ref (match_dup 1))
11126                       (pc)))]
11128   operands[0] = shallow_copy_rtx (operands[0]);
11129   PUT_MODE (operands[0], VOIDmode);
11130   PUT_CODE (operands[0],
11131             ix86_reverse_condition (GET_CODE (operands[0]),
11132                                     GET_MODE (XEXP (operands[0], 0))));
11134   /* Make sure that (a) the CCmode we have for the flags is strong
11135      enough for the reversed compare or (b) we have a valid FP compare.  */
11136   if (! ix86_comparison_operator (operands[0], VOIDmode))
11137     FAIL;
11140 ;; zero_extend in SImode is correct also for DImode, since this is what combine
11141 ;; pass generates from shift insn with QImode operand.  Actually, the mode
11142 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11143 ;; appropriate modulo of the bit offset value.
11145 (define_insn_and_split "*jcc_bt<mode>"
11146   [(set (pc)
11147         (if_then_else (match_operator 0 "bt_comparison_operator"
11148                         [(zero_extract:SWI48
11149                            (match_operand:SWI48 1 "register_operand" "r")
11150                            (const_int 1)
11151                            (zero_extend:SI
11152                              (match_operand:QI 2 "register_operand" "r")))
11153                          (const_int 0)])
11154                       (label_ref (match_operand 3))
11155                       (pc)))
11156    (clobber (reg:CC FLAGS_REG))]
11157   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11158   "#"
11159   "&& 1"
11160   [(set (reg:CCC FLAGS_REG)
11161         (compare:CCC
11162           (zero_extract:SWI48
11163             (match_dup 1)
11164             (const_int 1)
11165             (match_dup 2))
11166           (const_int 0)))
11167    (set (pc)
11168         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11169                       (label_ref (match_dup 3))
11170                       (pc)))]
11172   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11173   operands[0] = shallow_copy_rtx (operands[0]);
11174   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11177 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11178 ;; zero extended to SImode.
11179 (define_insn_and_split "*jcc_bt<mode>_1"
11180   [(set (pc)
11181         (if_then_else (match_operator 0 "bt_comparison_operator"
11182                         [(zero_extract:SWI48
11183                            (match_operand:SWI48 1 "register_operand" "r")
11184                            (const_int 1)
11185                            (match_operand:SI 2 "register_operand" "r"))
11186                          (const_int 0)])
11187                       (label_ref (match_operand 3))
11188                       (pc)))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11191   "#"
11192   "&& 1"
11193   [(set (reg:CCC FLAGS_REG)
11194         (compare:CCC
11195           (zero_extract:SWI48
11196             (match_dup 1)
11197             (const_int 1)
11198             (match_dup 2))
11199           (const_int 0)))
11200    (set (pc)
11201         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11202                       (label_ref (match_dup 3))
11203                       (pc)))]
11205   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11206   operands[0] = shallow_copy_rtx (operands[0]);
11207   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11210 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11211 ;; also for DImode, this is what combine produces.
11212 (define_insn_and_split "*jcc_bt<mode>_mask"
11213   [(set (pc)
11214         (if_then_else (match_operator 0 "bt_comparison_operator"
11215                         [(zero_extract:SWI48
11216                            (match_operand:SWI48 1 "register_operand" "r")
11217                            (const_int 1)
11218                            (and:SI
11219                              (match_operand:SI 2 "register_operand" "r")
11220                              (match_operand:SI 3 "const_int_operand" "n")))])
11221                       (label_ref (match_operand 4))
11222                       (pc)))
11223    (clobber (reg:CC FLAGS_REG))]
11224   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11225    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11226       == GET_MODE_BITSIZE (<MODE>mode)-1"
11227   "#"
11228   "&& 1"
11229   [(set (reg:CCC FLAGS_REG)
11230         (compare:CCC
11231           (zero_extract:SWI48
11232             (match_dup 1)
11233             (const_int 1)
11234             (match_dup 2))
11235           (const_int 0)))
11236    (set (pc)
11237         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11238                       (label_ref (match_dup 4))
11239                       (pc)))]
11241   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11242   operands[0] = shallow_copy_rtx (operands[0]);
11243   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11246 (define_insn_and_split "*jcc_btsi_1"
11247   [(set (pc)
11248         (if_then_else (match_operator 0 "bt_comparison_operator"
11249                         [(and:SI
11250                            (lshiftrt:SI
11251                              (match_operand:SI 1 "register_operand" "r")
11252                              (match_operand:QI 2 "register_operand" "r"))
11253                            (const_int 1))
11254                          (const_int 0)])
11255                       (label_ref (match_operand 3))
11256                       (pc)))
11257    (clobber (reg:CC FLAGS_REG))]
11258   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11259   "#"
11260   "&& 1"
11261   [(set (reg:CCC FLAGS_REG)
11262         (compare:CCC
11263           (zero_extract:SI
11264             (match_dup 1)
11265             (const_int 1)
11266             (match_dup 2))
11267           (const_int 0)))
11268    (set (pc)
11269         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11270                       (label_ref (match_dup 3))
11271                       (pc)))]
11273   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11274   operands[0] = shallow_copy_rtx (operands[0]);
11275   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11278 ;; avoid useless masking of bit offset operand
11279 (define_insn_and_split "*jcc_btsi_mask_1"
11280   [(set (pc)
11281         (if_then_else
11282           (match_operator 0 "bt_comparison_operator"
11283             [(and:SI
11284                (lshiftrt:SI
11285                  (match_operand:SI 1 "register_operand" "r")
11286                  (subreg:QI
11287                    (and:SI
11288                      (match_operand:SI 2 "register_operand" "r")
11289                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11290                (const_int 1))
11291              (const_int 0)])
11292           (label_ref (match_operand 4))
11293           (pc)))
11294    (clobber (reg:CC FLAGS_REG))]
11295   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11296    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11297   "#"
11298   "&& 1"
11299   [(set (reg:CCC FLAGS_REG)
11300         (compare:CCC
11301           (zero_extract:SI
11302             (match_dup 1)
11303             (const_int 1)
11304             (match_dup 2))
11305           (const_int 0)))
11306    (set (pc)
11307         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11308                       (label_ref (match_dup 4))
11309                       (pc)))]
11311   operands[0] = shallow_copy_rtx (operands[0]);
11312   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11315 ;; Define combination compare-and-branch fp compare instructions to help
11316 ;; combine.
11318 (define_insn "*jcc<mode>_0_i387"
11319   [(set (pc)
11320         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11321                         [(match_operand:X87MODEF 1 "register_operand" "f")
11322                          (match_operand:X87MODEF 2 "const0_operand")])
11323           (label_ref (match_operand 3))
11324           (pc)))
11325    (clobber (reg:CCFP FPSR_REG))
11326    (clobber (reg:CCFP FLAGS_REG))
11327    (clobber (match_scratch:HI 4 "=a"))]
11328   "TARGET_80387 && !TARGET_CMOVE"
11329   "#")
11331 (define_insn "*jcc<mode>_0_r_i387"
11332   [(set (pc)
11333         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11334                         [(match_operand:X87MODEF 1 "register_operand" "f")
11335                          (match_operand:X87MODEF 2 "const0_operand")])
11336           (pc)
11337           (label_ref (match_operand 3))))
11338    (clobber (reg:CCFP FPSR_REG))
11339    (clobber (reg:CCFP FLAGS_REG))
11340    (clobber (match_scratch:HI 4 "=a"))]
11341   "TARGET_80387 && !TARGET_CMOVE"
11342   "#")
11344 (define_insn "*jccxf_i387"
11345   [(set (pc)
11346         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11347                         [(match_operand:XF 1 "register_operand" "f")
11348                          (match_operand:XF 2 "register_operand" "f")])
11349           (label_ref (match_operand 3))
11350           (pc)))
11351    (clobber (reg:CCFP FPSR_REG))
11352    (clobber (reg:CCFP FLAGS_REG))
11353    (clobber (match_scratch:HI 4 "=a"))]
11354   "TARGET_80387 && !TARGET_CMOVE"
11355   "#")
11357 (define_insn "*jccxf_r_i387"
11358   [(set (pc)
11359         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11360                         [(match_operand:XF 1 "register_operand" "f")
11361                          (match_operand:XF 2 "register_operand" "f")])
11362           (pc)
11363           (label_ref (match_operand 3))))
11364    (clobber (reg:CCFP FPSR_REG))
11365    (clobber (reg:CCFP FLAGS_REG))
11366    (clobber (match_scratch:HI 4 "=a"))]
11367   "TARGET_80387 && !TARGET_CMOVE"
11368   "#")
11370 (define_insn "*jcc<mode>_i387"
11371   [(set (pc)
11372         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11373                         [(match_operand:MODEF 1 "register_operand" "f")
11374                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11375           (label_ref (match_operand 3))
11376           (pc)))
11377    (clobber (reg:CCFP FPSR_REG))
11378    (clobber (reg:CCFP FLAGS_REG))
11379    (clobber (match_scratch:HI 4 "=a"))]
11380   "TARGET_80387 && !TARGET_CMOVE"
11381   "#")
11383 (define_insn "*jcc<mode>_r_i387"
11384   [(set (pc)
11385         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11386                         [(match_operand:MODEF 1 "register_operand" "f")
11387                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11388           (pc)
11389           (label_ref (match_operand 3))))
11390    (clobber (reg:CCFP FPSR_REG))
11391    (clobber (reg:CCFP FLAGS_REG))
11392    (clobber (match_scratch:HI 4 "=a"))]
11393   "TARGET_80387 && !TARGET_CMOVE"
11394   "#")
11396 (define_insn "*jccu<mode>_i387"
11397   [(set (pc)
11398         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11399                         [(match_operand:X87MODEF 1 "register_operand" "f")
11400                          (match_operand:X87MODEF 2 "register_operand" "f")])
11401           (label_ref (match_operand 3))
11402           (pc)))
11403    (clobber (reg:CCFP FPSR_REG))
11404    (clobber (reg:CCFP FLAGS_REG))
11405    (clobber (match_scratch:HI 4 "=a"))]
11406   "TARGET_80387 && !TARGET_CMOVE"
11407   "#")
11409 (define_insn "*jccu<mode>_r_i387"
11410   [(set (pc)
11411         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11412                         [(match_operand:X87MODEF 1 "register_operand" "f")
11413                          (match_operand:X87MODEF 2 "register_operand" "f")])
11414           (pc)
11415           (label_ref (match_operand 3))))
11416    (clobber (reg:CCFP FPSR_REG))
11417    (clobber (reg:CCFP FLAGS_REG))
11418    (clobber (match_scratch:HI 4 "=a"))]
11419   "TARGET_80387 && !TARGET_CMOVE"
11420   "#")
11422 (define_split
11423   [(set (pc)
11424         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11425                         [(match_operand:X87MODEF 1 "register_operand")
11426                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11427           (match_operand 3)
11428           (match_operand 4)))
11429    (clobber (reg:CCFP FPSR_REG))
11430    (clobber (reg:CCFP FLAGS_REG))]
11431   "TARGET_80387 && !TARGET_CMOVE
11432    && reload_completed"
11433   [(const_int 0)]
11435   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11436                         operands[3], operands[4], NULL_RTX);
11437   DONE;
11440 (define_split
11441   [(set (pc)
11442         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11443                         [(match_operand:X87MODEF 1 "register_operand")
11444                          (match_operand:X87MODEF 2 "general_operand")])
11445           (match_operand 3)
11446           (match_operand 4)))
11447    (clobber (reg:CCFP FPSR_REG))
11448    (clobber (reg:CCFP FLAGS_REG))
11449    (clobber (match_scratch:HI 5))]
11450   "TARGET_80387 && !TARGET_CMOVE
11451    && reload_completed"
11452   [(const_int 0)]
11454   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11455                         operands[3], operands[4], operands[5]);
11456   DONE;
11459 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11460 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11461 ;; with a precedence over other operators and is always put in the first
11462 ;; place. Swap condition and operands to match ficom instruction.
11464 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11465   [(set (pc)
11466         (if_then_else
11467           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11468             [(match_operator:X87MODEF 1 "float_operator"
11469               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11470              (match_operand:X87MODEF 3 "register_operand" "f")])
11471           (label_ref (match_operand 4))
11472           (pc)))
11473    (clobber (reg:CCFP FPSR_REG))
11474    (clobber (reg:CCFP FLAGS_REG))
11475    (clobber (match_scratch:HI 5 "=a"))]
11476   "TARGET_80387 && !TARGET_CMOVE
11477    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11478        || optimize_function_for_size_p (cfun))"
11479   "#")
11481 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11482   [(set (pc)
11483         (if_then_else
11484           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11485             [(match_operator:X87MODEF 1 "float_operator"
11486               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11487              (match_operand:X87MODEF 3 "register_operand" "f")])
11488           (pc)
11489           (label_ref (match_operand 4))))
11490    (clobber (reg:CCFP FPSR_REG))
11491    (clobber (reg:CCFP FLAGS_REG))
11492    (clobber (match_scratch:HI 5 "=a"))]
11493   "TARGET_80387 && !TARGET_CMOVE
11494    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11495        || optimize_function_for_size_p (cfun))"
11496   "#")
11498 (define_split
11499   [(set (pc)
11500         (if_then_else
11501           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11502             [(match_operator:X87MODEF 1 "float_operator"
11503               [(match_operand:SWI24 2 "memory_operand")])
11504              (match_operand:X87MODEF 3 "register_operand")])
11505           (match_operand 4)
11506           (match_operand 5)))
11507    (clobber (reg:CCFP FPSR_REG))
11508    (clobber (reg:CCFP FLAGS_REG))
11509    (clobber (match_scratch:HI 6))]
11510   "TARGET_80387 && !TARGET_CMOVE
11511    && reload_completed"
11512   [(const_int 0)]
11514   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11515                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11516                         operands[4], operands[5], operands[6]);
11517   DONE;
11520 ;; Unconditional and other jump instructions
11522 (define_insn "jump_bnd"
11523   [(set (pc)
11524         (label_ref (match_operand 0)))]
11525   "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11526   "bnd jmp\t%l0"
11527   [(set_attr "type" "ibr")
11528    (set (attr "length")
11529            (if_then_else (and (ge (minus (match_dup 0) (pc))
11530                                   (const_int -126))
11531                               (lt (minus (match_dup 0) (pc))
11532                                   (const_int 128)))
11533              (const_int 3)
11534              (const_int 6)))
11535    (set_attr "modrm" "0")])
11537 (define_insn "jump"
11538   [(set (pc)
11539         (label_ref (match_operand 0)))]
11540   ""
11541   "jmp\t%l0"
11542   [(set_attr "type" "ibr")
11543    (set (attr "length")
11544            (if_then_else (and (ge (minus (match_dup 0) (pc))
11545                                   (const_int -126))
11546                               (lt (minus (match_dup 0) (pc))
11547                                   (const_int 128)))
11548              (const_int 2)
11549              (const_int 5)))
11550    (set_attr "modrm" "0")])
11552 (define_expand "indirect_jump"
11553   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11554   ""
11556   if (TARGET_X32)
11557     operands[0] = convert_memory_address (word_mode, operands[0]);
11560 (define_insn "*indirect_jump"
11561   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11562   ""
11563   "%!jmp\t%A0"
11564   [(set_attr "type" "ibr")
11565    (set_attr "length_immediate" "0")])
11567 (define_expand "tablejump"
11568   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11569               (use (label_ref (match_operand 1)))])]
11570   ""
11572   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11573      relative.  Convert the relative address to an absolute address.  */
11574   if (flag_pic)
11575     {
11576       rtx op0, op1;
11577       enum rtx_code code;
11579       /* We can't use @GOTOFF for text labels on VxWorks;
11580          see gotoff_operand.  */
11581       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11582         {
11583           code = PLUS;
11584           op0 = operands[0];
11585           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11586         }
11587       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11588         {
11589           code = PLUS;
11590           op0 = operands[0];
11591           op1 = pic_offset_table_rtx;
11592         }
11593       else
11594         {
11595           code = MINUS;
11596           op0 = pic_offset_table_rtx;
11597           op1 = operands[0];
11598         }
11600       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11601                                          OPTAB_DIRECT);
11602     }
11604   if (TARGET_X32)
11605     operands[0] = convert_memory_address (word_mode, operands[0]);
11608 (define_insn "*tablejump_1"
11609   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11610    (use (label_ref (match_operand 1)))]
11611   ""
11612   "%!jmp\t%A0"
11613   [(set_attr "type" "ibr")
11614    (set_attr "length_immediate" "0")])
11616 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11618 (define_peephole2
11619   [(set (reg FLAGS_REG) (match_operand 0))
11620    (set (match_operand:QI 1 "register_operand")
11621         (match_operator:QI 2 "ix86_comparison_operator"
11622           [(reg FLAGS_REG) (const_int 0)]))
11623    (set (match_operand 3 "q_regs_operand")
11624         (zero_extend (match_dup 1)))]
11625   "(peep2_reg_dead_p (3, operands[1])
11626     || operands_match_p (operands[1], operands[3]))
11627    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11628   [(set (match_dup 4) (match_dup 0))
11629    (set (strict_low_part (match_dup 5))
11630         (match_dup 2))]
11632   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11633   operands[5] = gen_lowpart (QImode, operands[3]);
11634   ix86_expand_clear (operands[3]);
11637 (define_peephole2
11638   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11639               (match_operand 4)])
11640    (set (match_operand:QI 1 "register_operand")
11641         (match_operator:QI 2 "ix86_comparison_operator"
11642           [(reg FLAGS_REG) (const_int 0)]))
11643    (set (match_operand 3 "q_regs_operand")
11644         (zero_extend (match_dup 1)))]
11645   "(peep2_reg_dead_p (3, operands[1])
11646     || operands_match_p (operands[1], operands[3]))
11647    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11648   [(parallel [(set (match_dup 5) (match_dup 0))
11649               (match_dup 4)])
11650    (set (strict_low_part (match_dup 6))
11651         (match_dup 2))]
11653   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11654   operands[6] = gen_lowpart (QImode, operands[3]);
11655   ix86_expand_clear (operands[3]);
11658 ;; Similar, but match zero extend with andsi3.
11660 (define_peephole2
11661   [(set (reg FLAGS_REG) (match_operand 0))
11662    (set (match_operand:QI 1 "register_operand")
11663         (match_operator:QI 2 "ix86_comparison_operator"
11664           [(reg FLAGS_REG) (const_int 0)]))
11665    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11666                    (and:SI (match_dup 3) (const_int 255)))
11667               (clobber (reg:CC FLAGS_REG))])]
11668   "REGNO (operands[1]) == REGNO (operands[3])
11669    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11670   [(set (match_dup 4) (match_dup 0))
11671    (set (strict_low_part (match_dup 5))
11672         (match_dup 2))]
11674   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11675   operands[5] = gen_lowpart (QImode, operands[3]);
11676   ix86_expand_clear (operands[3]);
11679 (define_peephole2
11680   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11681               (match_operand 4)])
11682    (set (match_operand:QI 1 "register_operand")
11683         (match_operator:QI 2 "ix86_comparison_operator"
11684           [(reg FLAGS_REG) (const_int 0)]))
11685    (parallel [(set (match_operand 3 "q_regs_operand")
11686                    (zero_extend (match_dup 1)))
11687               (clobber (reg:CC FLAGS_REG))])]
11688   "(peep2_reg_dead_p (3, operands[1])
11689     || operands_match_p (operands[1], operands[3]))
11690    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11691   [(parallel [(set (match_dup 5) (match_dup 0))
11692               (match_dup 4)])
11693    (set (strict_low_part (match_dup 6))
11694         (match_dup 2))]
11696   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11697   operands[6] = gen_lowpart (QImode, operands[3]);
11698   ix86_expand_clear (operands[3]);
11701 ;; Call instructions.
11703 ;; The predicates normally associated with named expanders are not properly
11704 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11705 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11707 ;; P6 processors will jump to the address after the decrement when %esp
11708 ;; is used as a call operand, so they will execute return address as a code.
11709 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11711 ;; Register constraint for call instruction.
11712 (define_mode_attr c [(SI "l") (DI "r")])
11714 ;; Call subroutine returning no value.
11716 (define_expand "call"
11717   [(call (match_operand:QI 0)
11718          (match_operand 1))
11719    (use (match_operand 2))]
11720   ""
11722   ix86_expand_call (NULL, operands[0], operands[1],
11723                     operands[2], NULL, false);
11724   DONE;
11727 (define_expand "sibcall"
11728   [(call (match_operand:QI 0)
11729          (match_operand 1))
11730    (use (match_operand 2))]
11731   ""
11733   ix86_expand_call (NULL, operands[0], operands[1],
11734                     operands[2], NULL, true);
11735   DONE;
11738 (define_insn "*call"
11739   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11740          (match_operand 1))]
11741   "!SIBLING_CALL_P (insn)"
11742   "* return ix86_output_call_insn (insn, operands[0]);"
11743   [(set_attr "type" "call")])
11745 (define_insn "*sibcall"
11746   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11747          (match_operand 1))]
11748   "SIBLING_CALL_P (insn)"
11749   "* return ix86_output_call_insn (insn, operands[0]);"
11750   [(set_attr "type" "call")])
11752 (define_insn "*sibcall_memory"
11753   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11754          (match_operand 1))
11755    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11756   "!TARGET_X32"
11757   "* return ix86_output_call_insn (insn, operands[0]);"
11758   [(set_attr "type" "call")])
11760 (define_peephole2
11761   [(set (match_operand:W 0 "register_operand")
11762         (match_operand:W 1 "memory_operand"))
11763    (call (mem:QI (match_dup 0))
11764          (match_operand 3))]
11765   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11766    && peep2_reg_dead_p (2, operands[0])"
11767   [(parallel [(call (mem:QI (match_dup 1))
11768                     (match_dup 3))
11769               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11771 (define_peephole2
11772   [(set (match_operand:W 0 "register_operand")
11773         (match_operand:W 1 "memory_operand"))
11774    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11775    (call (mem:QI (match_dup 0))
11776          (match_operand 3))]
11777   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11778    && peep2_reg_dead_p (3, operands[0])"
11779   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11780    (parallel [(call (mem:QI (match_dup 1))
11781                     (match_dup 3))
11782               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11784 (define_expand "call_pop"
11785   [(parallel [(call (match_operand:QI 0)
11786                     (match_operand:SI 1))
11787               (set (reg:SI SP_REG)
11788                    (plus:SI (reg:SI SP_REG)
11789                             (match_operand:SI 3)))])]
11790   "!TARGET_64BIT"
11792   ix86_expand_call (NULL, operands[0], operands[1],
11793                     operands[2], operands[3], false);
11794   DONE;
11797 (define_insn "*call_pop"
11798   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11799          (match_operand 1))
11800    (set (reg:SI SP_REG)
11801         (plus:SI (reg:SI SP_REG)
11802                  (match_operand:SI 2 "immediate_operand" "i")))]
11803   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11804   "* return ix86_output_call_insn (insn, operands[0]);"
11805   [(set_attr "type" "call")])
11807 (define_insn "*sibcall_pop"
11808   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11809          (match_operand 1))
11810    (set (reg:SI SP_REG)
11811         (plus:SI (reg:SI SP_REG)
11812                  (match_operand:SI 2 "immediate_operand" "i")))]
11813   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11814   "* return ix86_output_call_insn (insn, operands[0]);"
11815   [(set_attr "type" "call")])
11817 (define_insn "*sibcall_pop_memory"
11818   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11819          (match_operand 1))
11820    (set (reg:SI SP_REG)
11821         (plus:SI (reg:SI SP_REG)
11822                  (match_operand:SI 2 "immediate_operand" "i")))
11823    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11824   "!TARGET_64BIT"
11825   "* return ix86_output_call_insn (insn, operands[0]);"
11826   [(set_attr "type" "call")])
11828 (define_peephole2
11829   [(set (match_operand:SI 0 "register_operand")
11830         (match_operand:SI 1 "memory_operand"))
11831    (parallel [(call (mem:QI (match_dup 0))
11832                     (match_operand 3))
11833               (set (reg:SI SP_REG)
11834                    (plus:SI (reg:SI SP_REG)
11835                             (match_operand:SI 4 "immediate_operand")))])]
11836   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11837    && peep2_reg_dead_p (2, operands[0])"
11838   [(parallel [(call (mem:QI (match_dup 1))
11839                     (match_dup 3))
11840               (set (reg:SI SP_REG)
11841                    (plus:SI (reg:SI SP_REG)
11842                             (match_dup 4)))
11843               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11845 (define_peephole2
11846   [(set (match_operand:SI 0 "register_operand")
11847         (match_operand:SI 1 "memory_operand"))
11848    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11849    (parallel [(call (mem:QI (match_dup 0))
11850                     (match_operand 3))
11851               (set (reg:SI SP_REG)
11852                    (plus:SI (reg:SI SP_REG)
11853                             (match_operand:SI 4 "immediate_operand")))])]
11854   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11855    && peep2_reg_dead_p (3, operands[0])"
11856   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11857    (parallel [(call (mem:QI (match_dup 1))
11858                     (match_dup 3))
11859               (set (reg:SI SP_REG)
11860                    (plus:SI (reg:SI SP_REG)
11861                             (match_dup 4)))
11862               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11864 ;; Combining simple memory jump instruction
11866 (define_peephole2
11867   [(set (match_operand:W 0 "register_operand")
11868         (match_operand:W 1 "memory_operand"))
11869    (set (pc) (match_dup 0))]
11870   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11871   [(set (pc) (match_dup 1))])
11873 ;; Call subroutine, returning value in operand 0
11875 (define_expand "call_value"
11876   [(set (match_operand 0)
11877         (call (match_operand:QI 1)
11878               (match_operand 2)))
11879    (use (match_operand 3))]
11880   ""
11882   ix86_expand_call (operands[0], operands[1], operands[2],
11883                     operands[3], NULL, false);
11884   DONE;
11887 (define_expand "sibcall_value"
11888   [(set (match_operand 0)
11889         (call (match_operand:QI 1)
11890               (match_operand 2)))
11891    (use (match_operand 3))]
11892   ""
11894   ix86_expand_call (operands[0], operands[1], operands[2],
11895                     operands[3], NULL, true);
11896   DONE;
11899 (define_insn "*call_value"
11900   [(set (match_operand 0)
11901         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11902               (match_operand 2)))]
11903   "!SIBLING_CALL_P (insn)"
11904   "* return ix86_output_call_insn (insn, operands[1]);"
11905   [(set_attr "type" "callv")])
11907 (define_insn "*sibcall_value"
11908   [(set (match_operand 0)
11909         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11910               (match_operand 2)))]
11911   "SIBLING_CALL_P (insn)"
11912   "* return ix86_output_call_insn (insn, operands[1]);"
11913   [(set_attr "type" "callv")])
11915 (define_insn "*sibcall_value_memory"
11916   [(set (match_operand 0)
11917         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11918               (match_operand 2)))
11919    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11920   "!TARGET_X32"
11921   "* return ix86_output_call_insn (insn, operands[1]);"
11922   [(set_attr "type" "callv")])
11924 (define_peephole2
11925   [(set (match_operand:W 0 "register_operand")
11926         (match_operand:W 1 "memory_operand"))
11927    (set (match_operand 2)
11928    (call (mem:QI (match_dup 0))
11929                  (match_operand 3)))]
11930   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11931    && peep2_reg_dead_p (2, operands[0])"
11932   [(parallel [(set (match_dup 2)
11933                    (call (mem:QI (match_dup 1))
11934                          (match_dup 3)))
11935               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11937 (define_peephole2
11938   [(set (match_operand:W 0 "register_operand")
11939         (match_operand:W 1 "memory_operand"))
11940    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11941    (set (match_operand 2)
11942         (call (mem:QI (match_dup 0))
11943               (match_operand 3)))]
11944   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11945    && peep2_reg_dead_p (3, operands[0])"
11946   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11947    (parallel [(set (match_dup 2)
11948                    (call (mem:QI (match_dup 1))
11949                          (match_dup 3)))
11950               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11952 (define_expand "call_value_pop"
11953   [(parallel [(set (match_operand 0)
11954                    (call (match_operand:QI 1)
11955                          (match_operand:SI 2)))
11956               (set (reg:SI SP_REG)
11957                    (plus:SI (reg:SI SP_REG)
11958                             (match_operand:SI 4)))])]
11959   "!TARGET_64BIT"
11961   ix86_expand_call (operands[0], operands[1], operands[2],
11962                     operands[3], operands[4], false);
11963   DONE;
11966 (define_insn "*call_value_pop"
11967   [(set (match_operand 0)
11968         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11969               (match_operand 2)))
11970    (set (reg:SI SP_REG)
11971         (plus:SI (reg:SI SP_REG)
11972                  (match_operand:SI 3 "immediate_operand" "i")))]
11973   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11974   "* return ix86_output_call_insn (insn, operands[1]);"
11975   [(set_attr "type" "callv")])
11977 (define_insn "*sibcall_value_pop"
11978   [(set (match_operand 0)
11979         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11980               (match_operand 2)))
11981    (set (reg:SI SP_REG)
11982         (plus:SI (reg:SI SP_REG)
11983                  (match_operand:SI 3 "immediate_operand" "i")))]
11984   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11985   "* return ix86_output_call_insn (insn, operands[1]);"
11986   [(set_attr "type" "callv")])
11988 (define_insn "*sibcall_value_pop_memory"
11989   [(set (match_operand 0)
11990         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11991               (match_operand 2)))
11992    (set (reg:SI SP_REG)
11993         (plus:SI (reg:SI SP_REG)
11994                  (match_operand:SI 3 "immediate_operand" "i")))
11995    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11996   "!TARGET_64BIT"
11997   "* return ix86_output_call_insn (insn, operands[1]);"
11998   [(set_attr "type" "callv")])
12000 (define_peephole2
12001   [(set (match_operand:SI 0 "register_operand")
12002         (match_operand:SI 1 "memory_operand"))
12003    (parallel [(set (match_operand 2)
12004                    (call (mem:QI (match_dup 0))
12005                          (match_operand 3)))
12006               (set (reg:SI SP_REG)
12007                    (plus:SI (reg:SI SP_REG)
12008                             (match_operand:SI 4 "immediate_operand")))])]
12009   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12010    && peep2_reg_dead_p (2, operands[0])"
12011   [(parallel [(set (match_dup 2)
12012                    (call (mem:QI (match_dup 1))
12013                          (match_dup 3)))
12014               (set (reg:SI SP_REG)
12015                    (plus:SI (reg:SI SP_REG)
12016                             (match_dup 4)))
12017               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12019 (define_peephole2
12020   [(set (match_operand:SI 0 "register_operand")
12021         (match_operand:SI 1 "memory_operand"))
12022    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12023    (parallel [(set (match_operand 2)
12024                    (call (mem:QI (match_dup 0))
12025                          (match_operand 3)))
12026               (set (reg:SI SP_REG)
12027                    (plus:SI (reg:SI SP_REG)
12028                             (match_operand:SI 4 "immediate_operand")))])]
12029   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12030    && peep2_reg_dead_p (3, operands[0])"
12031   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12032    (parallel [(set (match_dup 2)
12033                    (call (mem:QI (match_dup 1))
12034                          (match_dup 3)))
12035               (set (reg:SI SP_REG)
12036                    (plus:SI (reg:SI SP_REG)
12037                             (match_dup 4)))
12038               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12040 ;; Call subroutine returning any type.
12042 (define_expand "untyped_call"
12043   [(parallel [(call (match_operand 0)
12044                     (const_int 0))
12045               (match_operand 1)
12046               (match_operand 2)])]
12047   ""
12049   int i;
12051   /* In order to give reg-stack an easier job in validating two
12052      coprocessor registers as containing a possible return value,
12053      simply pretend the untyped call returns a complex long double
12054      value. 
12056      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12057      and should have the default ABI.  */
12059   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12060                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12061                     operands[0], const0_rtx,
12062                     GEN_INT ((TARGET_64BIT
12063                               ? (ix86_abi == SYSV_ABI
12064                                  ? X86_64_SSE_REGPARM_MAX
12065                                  : X86_64_MS_SSE_REGPARM_MAX)
12066                               : X86_32_SSE_REGPARM_MAX)
12067                              - 1),
12068                     NULL, false);
12070   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12071     {
12072       rtx set = XVECEXP (operands[2], 0, i);
12073       emit_move_insn (SET_DEST (set), SET_SRC (set));
12074     }
12076   /* The optimizer does not know that the call sets the function value
12077      registers we stored in the result block.  We avoid problems by
12078      claiming that all hard registers are used and clobbered at this
12079      point.  */
12080   emit_insn (gen_blockage ());
12082   DONE;
12085 ;; Prologue and epilogue instructions
12087 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12088 ;; all of memory.  This blocks insns from being moved across this point.
12090 (define_insn "blockage"
12091   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12092   ""
12093   ""
12094   [(set_attr "length" "0")])
12096 ;; Do not schedule instructions accessing memory across this point.
12098 (define_expand "memory_blockage"
12099   [(set (match_dup 0)
12100         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12101   ""
12103   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12104   MEM_VOLATILE_P (operands[0]) = 1;
12107 (define_insn "*memory_blockage"
12108   [(set (match_operand:BLK 0)
12109         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12110   ""
12111   ""
12112   [(set_attr "length" "0")])
12114 ;; As USE insns aren't meaningful after reload, this is used instead
12115 ;; to prevent deleting instructions setting registers for PIC code
12116 (define_insn "prologue_use"
12117   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12118   ""
12119   ""
12120   [(set_attr "length" "0")])
12122 ;; Insn emitted into the body of a function to return from a function.
12123 ;; This is only done if the function's epilogue is known to be simple.
12124 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12126 (define_expand "return"
12127   [(simple_return)]
12128   "ix86_can_use_return_insn_p ()"
12130   if (crtl->args.pops_args)
12131     {
12132       rtx popc = GEN_INT (crtl->args.pops_args);
12133       emit_jump_insn (gen_simple_return_pop_internal (popc));
12134       DONE;
12135     }
12138 ;; We need to disable this for TARGET_SEH, as otherwise
12139 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12140 ;; the maximum size of prologue in unwind information.
12141 ;; Also disallow shrink-wrapping if using stack slot to pass the
12142 ;; static chain pointer - the first instruction has to be pushl %esi
12143 ;; and it can't be moved around, as we use alternate entry points
12144 ;; in that case.
12146 (define_expand "simple_return"
12147   [(simple_return)]
12148   "!TARGET_SEH && !ix86_static_chain_on_stack"
12150   if (crtl->args.pops_args)
12151     {
12152       rtx popc = GEN_INT (crtl->args.pops_args);
12153       emit_jump_insn (gen_simple_return_pop_internal (popc));
12154       DONE;
12155     }
12158 (define_insn "simple_return_internal"
12159   [(simple_return)]
12160   "reload_completed"
12161   "%!ret"
12162   [(set_attr "length_nobnd" "1")
12163    (set_attr "atom_unit" "jeu")
12164    (set_attr "length_immediate" "0")
12165    (set_attr "modrm" "0")])
12167 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12168 ;; instruction Athlon and K8 have.
12170 (define_insn "simple_return_internal_long"
12171   [(simple_return)
12172    (unspec [(const_int 0)] UNSPEC_REP)]
12173   "reload_completed"
12175   if (ix86_bnd_prefixed_insn_p (insn))
12176     return "%!ret";
12178   return "rep%; ret";
12180   [(set_attr "length" "2")
12181    (set_attr "atom_unit" "jeu")
12182    (set_attr "length_immediate" "0")
12183    (set_attr "prefix_rep" "1")
12184    (set_attr "modrm" "0")])
12186 (define_insn "simple_return_pop_internal"
12187   [(simple_return)
12188    (use (match_operand:SI 0 "const_int_operand"))]
12189   "reload_completed"
12190   "%!ret\t%0"
12191   [(set_attr "length_nobnd" "3")
12192    (set_attr "atom_unit" "jeu")
12193    (set_attr "length_immediate" "2")
12194    (set_attr "modrm" "0")])
12196 (define_insn "simple_return_indirect_internal"
12197   [(simple_return)
12198    (use (match_operand:SI 0 "register_operand" "r"))]
12199   "reload_completed"
12200   "%!jmp\t%A0"
12201   [(set_attr "type" "ibr")
12202    (set_attr "length_immediate" "0")])
12204 (define_insn "nop"
12205   [(const_int 0)]
12206   ""
12207   "nop"
12208   [(set_attr "length" "1")
12209    (set_attr "length_immediate" "0")
12210    (set_attr "modrm" "0")])
12212 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12213 (define_insn "nops"
12214   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12215                     UNSPECV_NOPS)]
12216   "reload_completed"
12218   int num = INTVAL (operands[0]);
12220   gcc_assert (IN_RANGE (num, 1, 8));
12222   while (num--)
12223     fputs ("\tnop\n", asm_out_file);
12225   return "";
12227   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12228    (set_attr "length_immediate" "0")
12229    (set_attr "modrm" "0")])
12231 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12232 ;; branch prediction penalty for the third jump in a 16-byte
12233 ;; block on K8.
12235 (define_insn "pad"
12236   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12237   ""
12239 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12240   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12241 #else
12242   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12243      The align insn is used to avoid 3 jump instructions in the row to improve
12244      branch prediction and the benefits hardly outweigh the cost of extra 8
12245      nops on the average inserted by full alignment pseudo operation.  */
12246 #endif
12247   return "";
12249   [(set_attr "length" "16")])
12251 (define_expand "prologue"
12252   [(const_int 0)]
12253   ""
12254   "ix86_expand_prologue (); DONE;")
12256 (define_insn "set_got"
12257   [(set (match_operand:SI 0 "register_operand" "=r")
12258         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "!TARGET_64BIT"
12261   "* return output_set_got (operands[0], NULL_RTX);"
12262   [(set_attr "type" "multi")
12263    (set_attr "length" "12")])
12265 (define_insn "set_got_labelled"
12266   [(set (match_operand:SI 0 "register_operand" "=r")
12267         (unspec:SI [(label_ref (match_operand 1))]
12268          UNSPEC_SET_GOT))
12269    (clobber (reg:CC FLAGS_REG))]
12270   "!TARGET_64BIT"
12271   "* return output_set_got (operands[0], operands[1]);"
12272   [(set_attr "type" "multi")
12273    (set_attr "length" "12")])
12275 (define_insn "set_got_rex64"
12276   [(set (match_operand:DI 0 "register_operand" "=r")
12277         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12278   "TARGET_64BIT"
12279   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12280   [(set_attr "type" "lea")
12281    (set_attr "length_address" "4")
12282    (set_attr "mode" "DI")])
12284 (define_insn "set_rip_rex64"
12285   [(set (match_operand:DI 0 "register_operand" "=r")
12286         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12287   "TARGET_64BIT"
12288   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12289   [(set_attr "type" "lea")
12290    (set_attr "length_address" "4")
12291    (set_attr "mode" "DI")])
12293 (define_insn "set_got_offset_rex64"
12294   [(set (match_operand:DI 0 "register_operand" "=r")
12295         (unspec:DI
12296           [(label_ref (match_operand 1))]
12297           UNSPEC_SET_GOT_OFFSET))]
12298   "TARGET_LP64"
12299   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12300   [(set_attr "type" "imov")
12301    (set_attr "length_immediate" "0")
12302    (set_attr "length_address" "8")
12303    (set_attr "mode" "DI")])
12305 (define_expand "epilogue"
12306   [(const_int 0)]
12307   ""
12308   "ix86_expand_epilogue (1); DONE;")
12310 (define_expand "sibcall_epilogue"
12311   [(const_int 0)]
12312   ""
12313   "ix86_expand_epilogue (0); DONE;")
12315 (define_expand "eh_return"
12316   [(use (match_operand 0 "register_operand"))]
12317   ""
12319   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12321   /* Tricky bit: we write the address of the handler to which we will
12322      be returning into someone else's stack frame, one word below the
12323      stack address we wish to restore.  */
12324   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12325   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12326   tmp = gen_rtx_MEM (Pmode, tmp);
12327   emit_move_insn (tmp, ra);
12329   emit_jump_insn (gen_eh_return_internal ());
12330   emit_barrier ();
12331   DONE;
12334 (define_insn_and_split "eh_return_internal"
12335   [(eh_return)]
12336   ""
12337   "#"
12338   "epilogue_completed"
12339   [(const_int 0)]
12340   "ix86_expand_epilogue (2); DONE;")
12342 (define_insn "leave"
12343   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12344    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12345    (clobber (mem:BLK (scratch)))]
12346   "!TARGET_64BIT"
12347   "leave"
12348   [(set_attr "type" "leave")])
12350 (define_insn "leave_rex64"
12351   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12352    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12353    (clobber (mem:BLK (scratch)))]
12354   "TARGET_64BIT"
12355   "leave"
12356   [(set_attr "type" "leave")])
12358 ;; Handle -fsplit-stack.
12360 (define_expand "split_stack_prologue"
12361   [(const_int 0)]
12362   ""
12364   ix86_expand_split_stack_prologue ();
12365   DONE;
12368 ;; In order to support the call/return predictor, we use a return
12369 ;; instruction which the middle-end doesn't see.
12370 (define_insn "split_stack_return"
12371   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12372                      UNSPECV_SPLIT_STACK_RETURN)]
12373   ""
12375   if (operands[0] == const0_rtx)
12376     return "ret";
12377   else
12378     return "ret\t%0";
12380   [(set_attr "atom_unit" "jeu")
12381    (set_attr "modrm" "0")
12382    (set (attr "length")
12383         (if_then_else (match_operand:SI 0 "const0_operand")
12384                       (const_int 1)
12385                       (const_int 3)))
12386    (set (attr "length_immediate")
12387         (if_then_else (match_operand:SI 0 "const0_operand")
12388                       (const_int 0)
12389                       (const_int 2)))])
12391 ;; If there are operand 0 bytes available on the stack, jump to
12392 ;; operand 1.
12394 (define_expand "split_stack_space_check"
12395   [(set (pc) (if_then_else
12396               (ltu (minus (reg SP_REG)
12397                           (match_operand 0 "register_operand"))
12398                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12399               (label_ref (match_operand 1))
12400               (pc)))]
12401   ""
12403   rtx reg, size, limit;
12405   reg = gen_reg_rtx (Pmode);
12406   size = force_reg (Pmode, operands[0]);
12407   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12408   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12409                           UNSPEC_STACK_CHECK);
12410   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12411   ix86_expand_branch (GEU, reg, limit, operands[1]);
12413   DONE;
12416 ;; Bit manipulation instructions.
12418 (define_expand "ffs<mode>2"
12419   [(set (match_dup 2) (const_int -1))
12420    (parallel [(set (match_dup 3) (match_dup 4))
12421               (set (match_operand:SWI48 0 "register_operand")
12422                    (ctz:SWI48
12423                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12424    (set (match_dup 0) (if_then_else:SWI48
12425                         (eq (match_dup 3) (const_int 0))
12426                         (match_dup 2)
12427                         (match_dup 0)))
12428    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12429               (clobber (reg:CC FLAGS_REG))])]
12430   ""
12432   machine_mode flags_mode;
12434   if (<MODE>mode == SImode && !TARGET_CMOVE)
12435     {
12436       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12437       DONE;
12438     }
12440   flags_mode
12441     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12443   operands[2] = gen_reg_rtx (<MODE>mode);
12444   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12445   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12448 (define_insn_and_split "ffssi2_no_cmove"
12449   [(set (match_operand:SI 0 "register_operand" "=r")
12450         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12451    (clobber (match_scratch:SI 2 "=&q"))
12452    (clobber (reg:CC FLAGS_REG))]
12453   "!TARGET_CMOVE"
12454   "#"
12455   "&& reload_completed"
12456   [(parallel [(set (match_dup 4) (match_dup 5))
12457               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12458    (set (strict_low_part (match_dup 3))
12459         (eq:QI (match_dup 4) (const_int 0)))
12460    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12461               (clobber (reg:CC FLAGS_REG))])
12462    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12463               (clobber (reg:CC FLAGS_REG))])
12464    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12465               (clobber (reg:CC FLAGS_REG))])]
12467   machine_mode flags_mode
12468     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12470   operands[3] = gen_lowpart (QImode, operands[2]);
12471   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12472   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12474   ix86_expand_clear (operands[2]);
12477 (define_insn "*tzcnt<mode>_1"
12478   [(set (reg:CCC FLAGS_REG)
12479         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12480                      (const_int 0)))
12481    (set (match_operand:SWI48 0 "register_operand" "=r")
12482         (ctz:SWI48 (match_dup 1)))]
12483   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12484   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12485   [(set_attr "type" "alu1")
12486    (set_attr "prefix_0f" "1")
12487    (set_attr "prefix_rep" "1")
12488    (set_attr "btver2_decode" "double")
12489    (set_attr "mode" "<MODE>")])
12491 (define_insn "*bsf<mode>_1"
12492   [(set (reg:CCZ FLAGS_REG)
12493         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12494                      (const_int 0)))
12495    (set (match_operand:SWI48 0 "register_operand" "=r")
12496         (ctz:SWI48 (match_dup 1)))]
12497   ""
12498   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12499   [(set_attr "type" "alu1")
12500    (set_attr "prefix_0f" "1")
12501    (set_attr "btver2_decode" "double")
12502    (set_attr "mode" "<MODE>")])
12504 (define_expand "ctz<mode>2"
12505   [(parallel
12506     [(set (match_operand:SWI248 0 "register_operand")
12507           (ctz:SWI248
12508             (match_operand:SWI248 1 "nonimmediate_operand")))
12509      (clobber (reg:CC FLAGS_REG))])])
12511 ; False dependency happens when destination is only updated by tzcnt,
12512 ; lzcnt or popcnt.  There is no false dependency when destination is
12513 ; also used in source.
12514 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12515   [(set (match_operand:SWI48 0 "register_operand" "=r")
12516         (ctz:SWI48
12517           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12518    (clobber (reg:CC FLAGS_REG))]
12519   "(TARGET_BMI || TARGET_GENERIC)
12520    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12521   "#"
12522   "&& reload_completed"
12523   [(parallel
12524     [(set (match_dup 0)
12525           (ctz:SWI48 (match_dup 1)))
12526      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12527      (clobber (reg:CC FLAGS_REG))])]
12529   if (!reg_mentioned_p (operands[0], operands[1]))
12530     ix86_expand_clear (operands[0]);
12533 (define_insn "*ctz<mode>2_falsedep"
12534   [(set (match_operand:SWI48 0 "register_operand" "=r")
12535         (ctz:SWI48
12536           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12537    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12538            UNSPEC_INSN_FALSE_DEP)
12539    (clobber (reg:CC FLAGS_REG))]
12540   ""
12542   if (TARGET_BMI)
12543     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12544   else if (TARGET_GENERIC)
12545     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12546     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12547   else
12548     gcc_unreachable ();
12550   [(set_attr "type" "alu1")
12551    (set_attr "prefix_0f" "1")
12552    (set_attr "prefix_rep" "1")
12553    (set_attr "mode" "<MODE>")])
12555 (define_insn "*ctz<mode>2"
12556   [(set (match_operand:SWI248 0 "register_operand" "=r")
12557         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12558    (clobber (reg:CC FLAGS_REG))]
12559   ""
12561   if (TARGET_BMI)
12562     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12563   else if (optimize_function_for_size_p (cfun))
12564     ;
12565   else if (TARGET_GENERIC)
12566     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12567     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12569   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12571   [(set_attr "type" "alu1")
12572    (set_attr "prefix_0f" "1")
12573    (set (attr "prefix_rep")
12574      (if_then_else
12575        (ior (match_test "TARGET_BMI")
12576             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12577                  (match_test "TARGET_GENERIC")))
12578        (const_string "1")
12579        (const_string "0")))
12580    (set_attr "mode" "<MODE>")])
12582 (define_expand "clz<mode>2"
12583   [(parallel
12584      [(set (match_operand:SWI248 0 "register_operand")
12585            (minus:SWI248
12586              (match_dup 2)
12587              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12588       (clobber (reg:CC FLAGS_REG))])
12589    (parallel
12590      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12591       (clobber (reg:CC FLAGS_REG))])]
12592   ""
12594   if (TARGET_LZCNT)
12595     {
12596       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12597       DONE;
12598     }
12599   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12602 (define_expand "clz<mode>2_lzcnt"
12603   [(parallel
12604     [(set (match_operand:SWI248 0 "register_operand")
12605           (clz:SWI248
12606             (match_operand:SWI248 1 "nonimmediate_operand")))
12607      (clobber (reg:CC FLAGS_REG))])]
12608   "TARGET_LZCNT")
12610 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12611   [(set (match_operand:SWI48 0 "register_operand" "=r")
12612         (clz:SWI48
12613           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12614    (clobber (reg:CC FLAGS_REG))]
12615   "TARGET_LZCNT
12616    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12617   "#"
12618   "&& reload_completed"
12619   [(parallel
12620     [(set (match_dup 0)
12621           (clz:SWI48 (match_dup 1)))
12622      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12623      (clobber (reg:CC FLAGS_REG))])]
12625   if (!reg_mentioned_p (operands[0], operands[1]))
12626     ix86_expand_clear (operands[0]);
12629 (define_insn "*clz<mode>2_lzcnt_falsedep"
12630   [(set (match_operand:SWI48 0 "register_operand" "=r")
12631         (clz:SWI48
12632           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12633    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12634            UNSPEC_INSN_FALSE_DEP)
12635    (clobber (reg:CC FLAGS_REG))]
12636   "TARGET_LZCNT"
12637   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12638   [(set_attr "prefix_rep" "1")
12639    (set_attr "type" "bitmanip")
12640    (set_attr "mode" "<MODE>")])
12642 (define_insn "*clz<mode>2_lzcnt"
12643   [(set (match_operand:SWI248 0 "register_operand" "=r")
12644         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "TARGET_LZCNT"
12647   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12648   [(set_attr "prefix_rep" "1")
12649    (set_attr "type" "bitmanip")
12650    (set_attr "mode" "<MODE>")])
12652 ;; BMI instructions.
12653 (define_insn "*bmi_andn_<mode>"
12654   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12655         (and:SWI48
12656           (not:SWI48
12657             (match_operand:SWI48 1 "register_operand" "r,r"))
12658             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "TARGET_BMI"
12661   "andn\t{%2, %1, %0|%0, %1, %2}"
12662   [(set_attr "type" "bitmanip")
12663    (set_attr "btver2_decode" "direct, double")
12664    (set_attr "mode" "<MODE>")])
12666 (define_insn "bmi_bextr_<mode>"
12667   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12668         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12669                        (match_operand:SWI48 2 "register_operand" "r,r")]
12670                        UNSPEC_BEXTR))
12671    (clobber (reg:CC FLAGS_REG))]
12672   "TARGET_BMI"
12673   "bextr\t{%2, %1, %0|%0, %1, %2}"
12674   [(set_attr "type" "bitmanip")
12675    (set_attr "btver2_decode" "direct, double")
12676    (set_attr "mode" "<MODE>")])
12678 (define_insn "*bmi_blsi_<mode>"
12679   [(set (match_operand:SWI48 0 "register_operand" "=r")
12680         (and:SWI48
12681           (neg:SWI48
12682             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12683           (match_dup 1)))
12684    (clobber (reg:CC FLAGS_REG))]
12685   "TARGET_BMI"
12686   "blsi\t{%1, %0|%0, %1}"
12687   [(set_attr "type" "bitmanip")
12688    (set_attr "btver2_decode" "double")
12689    (set_attr "mode" "<MODE>")])
12691 (define_insn "*bmi_blsmsk_<mode>"
12692   [(set (match_operand:SWI48 0 "register_operand" "=r")
12693         (xor:SWI48
12694           (plus:SWI48
12695             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12696             (const_int -1))
12697           (match_dup 1)))
12698    (clobber (reg:CC FLAGS_REG))]
12699   "TARGET_BMI"
12700   "blsmsk\t{%1, %0|%0, %1}"
12701   [(set_attr "type" "bitmanip")
12702    (set_attr "btver2_decode" "double")
12703    (set_attr "mode" "<MODE>")])
12705 (define_insn "*bmi_blsr_<mode>"
12706   [(set (match_operand:SWI48 0 "register_operand" "=r")
12707         (and:SWI48
12708           (plus:SWI48
12709             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12710             (const_int -1))
12711           (match_dup 1)))
12712    (clobber (reg:CC FLAGS_REG))]
12713    "TARGET_BMI"
12714    "blsr\t{%1, %0|%0, %1}"
12715   [(set_attr "type" "bitmanip")
12716    (set_attr "btver2_decode" "double")
12717    (set_attr "mode" "<MODE>")])
12719 ;; BMI2 instructions.
12720 (define_expand "bmi2_bzhi_<mode>3"
12721   [(parallel
12722     [(set (match_operand:SWI48 0 "register_operand")
12723           (zero_extract:SWI48
12724             (match_operand:SWI48 1 "nonimmediate_operand")
12725             (umin:SWI48
12726               (and:SWI48 (match_operand:SWI48 2 "register_operand")
12727                          (const_int 255))
12728               (match_dup 3))
12729             (const_int 0)))
12730      (clobber (reg:CC FLAGS_REG))])]
12731   "TARGET_BMI2"
12732   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12734 (define_insn "*bmi2_bzhi_<mode>3"
12735   [(set (match_operand:SWI48 0 "register_operand" "=r")
12736         (zero_extract:SWI48
12737           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12738           (umin:SWI48
12739             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12740                        (const_int 255))
12741             (match_operand:SWI48 3 "const_int_operand" "n"))
12742           (const_int 0)))
12743    (clobber (reg:CC FLAGS_REG))]
12744   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12745   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12746   [(set_attr "type" "bitmanip")
12747    (set_attr "prefix" "vex")
12748    (set_attr "mode" "<MODE>")])
12750 (define_mode_attr k [(SI "k") (DI "q")])
12751 (define_insn "*bmi2_bzhi_<mode>3_1"
12752   [(set (match_operand:SWI48 0 "register_operand" "=r")
12753         (zero_extract:SWI48
12754           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12755           (umin:SWI48
12756             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12757             (match_operand:SWI48 3 "const_int_operand" "n"))
12758           (const_int 0)))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12761   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12762   [(set_attr "type" "bitmanip")
12763    (set_attr "prefix" "vex")
12764    (set_attr "mode" "<MODE>")])
12766 (define_insn "bmi2_pdep_<mode>3"
12767   [(set (match_operand:SWI48 0 "register_operand" "=r")
12768         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12769                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12770                        UNSPEC_PDEP))]
12771   "TARGET_BMI2"
12772   "pdep\t{%2, %1, %0|%0, %1, %2}"
12773   [(set_attr "type" "bitmanip")
12774    (set_attr "prefix" "vex")
12775    (set_attr "mode" "<MODE>")])
12777 (define_insn "bmi2_pext_<mode>3"
12778   [(set (match_operand:SWI48 0 "register_operand" "=r")
12779         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12780                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12781                        UNSPEC_PEXT))]
12782   "TARGET_BMI2"
12783   "pext\t{%2, %1, %0|%0, %1, %2}"
12784   [(set_attr "type" "bitmanip")
12785    (set_attr "prefix" "vex")
12786    (set_attr "mode" "<MODE>")])
12788 ;; TBM instructions.
12789 (define_insn "tbm_bextri_<mode>"
12790   [(set (match_operand:SWI48 0 "register_operand" "=r")
12791         (zero_extract:SWI48
12792           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12793           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12794           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12795    (clobber (reg:CC FLAGS_REG))]
12796    "TARGET_TBM"
12798   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12799   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12801   [(set_attr "type" "bitmanip")
12802    (set_attr "mode" "<MODE>")])
12804 (define_insn "*tbm_blcfill_<mode>"
12805   [(set (match_operand:SWI48 0 "register_operand" "=r")
12806         (and:SWI48
12807           (plus:SWI48
12808             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12809             (const_int 1))
12810           (match_dup 1)))
12811    (clobber (reg:CC FLAGS_REG))]
12812    "TARGET_TBM"
12813    "blcfill\t{%1, %0|%0, %1}"
12814   [(set_attr "type" "bitmanip")
12815    (set_attr "mode" "<MODE>")])
12817 (define_insn "*tbm_blci_<mode>"
12818   [(set (match_operand:SWI48 0 "register_operand" "=r")
12819         (ior:SWI48
12820           (not:SWI48
12821             (plus:SWI48
12822               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12823               (const_int 1)))
12824           (match_dup 1)))
12825    (clobber (reg:CC FLAGS_REG))]
12826    "TARGET_TBM"
12827    "blci\t{%1, %0|%0, %1}"
12828   [(set_attr "type" "bitmanip")
12829    (set_attr "mode" "<MODE>")])
12831 (define_insn "*tbm_blcic_<mode>"
12832   [(set (match_operand:SWI48 0 "register_operand" "=r")
12833         (and:SWI48
12834           (plus:SWI48
12835             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12836             (const_int 1))
12837           (not:SWI48
12838             (match_dup 1))))
12839    (clobber (reg:CC FLAGS_REG))]
12840    "TARGET_TBM"
12841    "blcic\t{%1, %0|%0, %1}"
12842   [(set_attr "type" "bitmanip")
12843    (set_attr "mode" "<MODE>")])
12845 (define_insn "*tbm_blcmsk_<mode>"
12846   [(set (match_operand:SWI48 0 "register_operand" "=r")
12847         (xor:SWI48
12848           (plus:SWI48
12849             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12850             (const_int 1))
12851           (match_dup 1)))
12852    (clobber (reg:CC FLAGS_REG))]
12853    "TARGET_TBM"
12854    "blcmsk\t{%1, %0|%0, %1}"
12855   [(set_attr "type" "bitmanip")
12856    (set_attr "mode" "<MODE>")])
12858 (define_insn "*tbm_blcs_<mode>"
12859   [(set (match_operand:SWI48 0 "register_operand" "=r")
12860         (ior:SWI48
12861           (plus:SWI48
12862             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12863             (const_int 1))
12864           (match_dup 1)))
12865    (clobber (reg:CC FLAGS_REG))]
12866    "TARGET_TBM"
12867    "blcs\t{%1, %0|%0, %1}"
12868   [(set_attr "type" "bitmanip")
12869    (set_attr "mode" "<MODE>")])
12871 (define_insn "*tbm_blsfill_<mode>"
12872   [(set (match_operand:SWI48 0 "register_operand" "=r")
12873         (ior:SWI48
12874           (plus:SWI48
12875             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12876             (const_int -1))
12877           (match_dup 1)))
12878    (clobber (reg:CC FLAGS_REG))]
12879    "TARGET_TBM"
12880    "blsfill\t{%1, %0|%0, %1}"
12881   [(set_attr "type" "bitmanip")
12882    (set_attr "mode" "<MODE>")])
12884 (define_insn "*tbm_blsic_<mode>"
12885   [(set (match_operand:SWI48 0 "register_operand" "=r")
12886         (ior:SWI48
12887           (plus:SWI48
12888             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12889             (const_int -1))
12890           (not:SWI48
12891             (match_dup 1))))
12892    (clobber (reg:CC FLAGS_REG))]
12893    "TARGET_TBM"
12894    "blsic\t{%1, %0|%0, %1}"
12895   [(set_attr "type" "bitmanip")
12896    (set_attr "mode" "<MODE>")])
12898 (define_insn "*tbm_t1mskc_<mode>"
12899   [(set (match_operand:SWI48 0 "register_operand" "=r")
12900         (ior:SWI48
12901           (plus:SWI48
12902             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12903             (const_int 1))
12904           (not:SWI48
12905             (match_dup 1))))
12906    (clobber (reg:CC FLAGS_REG))]
12907    "TARGET_TBM"
12908    "t1mskc\t{%1, %0|%0, %1}"
12909   [(set_attr "type" "bitmanip")
12910    (set_attr "mode" "<MODE>")])
12912 (define_insn "*tbm_tzmsk_<mode>"
12913   [(set (match_operand:SWI48 0 "register_operand" "=r")
12914         (and:SWI48
12915           (plus:SWI48
12916             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12917             (const_int -1))
12918           (not:SWI48
12919             (match_dup 1))))
12920    (clobber (reg:CC FLAGS_REG))]
12921    "TARGET_TBM"
12922    "tzmsk\t{%1, %0|%0, %1}"
12923   [(set_attr "type" "bitmanip")
12924    (set_attr "mode" "<MODE>")])
12926 (define_insn "bsr_rex64"
12927   [(set (match_operand:DI 0 "register_operand" "=r")
12928         (minus:DI (const_int 63)
12929                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12930    (clobber (reg:CC FLAGS_REG))]
12931   "TARGET_64BIT"
12932   "bsr{q}\t{%1, %0|%0, %1}"
12933   [(set_attr "type" "alu1")
12934    (set_attr "prefix_0f" "1")
12935    (set_attr "mode" "DI")])
12937 (define_insn "bsr"
12938   [(set (match_operand:SI 0 "register_operand" "=r")
12939         (minus:SI (const_int 31)
12940                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12941    (clobber (reg:CC FLAGS_REG))]
12942   ""
12943   "bsr{l}\t{%1, %0|%0, %1}"
12944   [(set_attr "type" "alu1")
12945    (set_attr "prefix_0f" "1")
12946    (set_attr "mode" "SI")])
12948 (define_insn "*bsrhi"
12949   [(set (match_operand:HI 0 "register_operand" "=r")
12950         (minus:HI (const_int 15)
12951                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12952    (clobber (reg:CC FLAGS_REG))]
12953   ""
12954   "bsr{w}\t{%1, %0|%0, %1}"
12955   [(set_attr "type" "alu1")
12956    (set_attr "prefix_0f" "1")
12957    (set_attr "mode" "HI")])
12959 (define_expand "popcount<mode>2"
12960   [(parallel
12961     [(set (match_operand:SWI248 0 "register_operand")
12962           (popcount:SWI248
12963             (match_operand:SWI248 1 "nonimmediate_operand")))
12964      (clobber (reg:CC FLAGS_REG))])]
12965   "TARGET_POPCNT")
12967 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12968   [(set (match_operand:SWI48 0 "register_operand" "=r")
12969         (popcount:SWI48
12970           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12971    (clobber (reg:CC FLAGS_REG))]
12972   "TARGET_POPCNT
12973    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12974   "#"
12975   "&& reload_completed"
12976   [(parallel
12977     [(set (match_dup 0)
12978           (popcount:SWI48 (match_dup 1)))
12979      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12980      (clobber (reg:CC FLAGS_REG))])]
12982   if (!reg_mentioned_p (operands[0], operands[1]))
12983     ix86_expand_clear (operands[0]);
12986 (define_insn "*popcount<mode>2_falsedep"
12987   [(set (match_operand:SWI48 0 "register_operand" "=r")
12988         (popcount:SWI48
12989           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12990    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12991            UNSPEC_INSN_FALSE_DEP)
12992    (clobber (reg:CC FLAGS_REG))]
12993   "TARGET_POPCNT"
12995 #if TARGET_MACHO
12996   return "popcnt\t{%1, %0|%0, %1}";
12997 #else
12998   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12999 #endif
13001   [(set_attr "prefix_rep" "1")
13002    (set_attr "type" "bitmanip")
13003    (set_attr "mode" "<MODE>")])
13005 (define_insn "*popcount<mode>2"
13006   [(set (match_operand:SWI248 0 "register_operand" "=r")
13007         (popcount:SWI248
13008           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13009    (clobber (reg:CC FLAGS_REG))]
13010   "TARGET_POPCNT"
13012 #if TARGET_MACHO
13013   return "popcnt\t{%1, %0|%0, %1}";
13014 #else
13015   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13016 #endif
13018   [(set_attr "prefix_rep" "1")
13019    (set_attr "type" "bitmanip")
13020    (set_attr "mode" "<MODE>")])
13022 (define_expand "bswapdi2"
13023   [(set (match_operand:DI 0 "register_operand")
13024         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13025   "TARGET_64BIT"
13027   if (!TARGET_MOVBE)
13028     operands[1] = force_reg (DImode, operands[1]);
13031 (define_expand "bswapsi2"
13032   [(set (match_operand:SI 0 "register_operand")
13033         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13034   ""
13036   if (TARGET_MOVBE)
13037     ;
13038   else if (TARGET_BSWAP)
13039     operands[1] = force_reg (SImode, operands[1]);
13040   else
13041     {
13042       rtx x = operands[0];
13044       emit_move_insn (x, operands[1]);
13045       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13046       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13047       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13048       DONE;
13049     }
13052 (define_insn "*bswap<mode>2_movbe"
13053   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13054         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13055   "TARGET_MOVBE
13056    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13057   "@
13058     bswap\t%0
13059     movbe\t{%1, %0|%0, %1}
13060     movbe\t{%1, %0|%0, %1}"
13061   [(set_attr "type" "bitmanip,imov,imov")
13062    (set_attr "modrm" "0,1,1")
13063    (set_attr "prefix_0f" "*,1,1")
13064    (set_attr "prefix_extra" "*,1,1")
13065    (set_attr "mode" "<MODE>")])
13067 (define_insn "*bswap<mode>2"
13068   [(set (match_operand:SWI48 0 "register_operand" "=r")
13069         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13070   "TARGET_BSWAP"
13071   "bswap\t%0"
13072   [(set_attr "type" "bitmanip")
13073    (set_attr "modrm" "0")
13074    (set_attr "mode" "<MODE>")])
13076 (define_insn "*bswaphi_lowpart_1"
13077   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13078         (bswap:HI (match_dup 0)))
13079    (clobber (reg:CC FLAGS_REG))]
13080   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13081   "@
13082     xchg{b}\t{%h0, %b0|%b0, %h0}
13083     rol{w}\t{$8, %0|%0, 8}"
13084   [(set_attr "length" "2,4")
13085    (set_attr "mode" "QI,HI")])
13087 (define_insn "bswaphi_lowpart"
13088   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13089         (bswap:HI (match_dup 0)))
13090    (clobber (reg:CC FLAGS_REG))]
13091   ""
13092   "rol{w}\t{$8, %0|%0, 8}"
13093   [(set_attr "length" "4")
13094    (set_attr "mode" "HI")])
13096 (define_expand "paritydi2"
13097   [(set (match_operand:DI 0 "register_operand")
13098         (parity:DI (match_operand:DI 1 "register_operand")))]
13099   "! TARGET_POPCNT"
13101   rtx scratch = gen_reg_rtx (QImode);
13102   rtx cond;
13104   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13105                                 NULL_RTX, operands[1]));
13107   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13108                          gen_rtx_REG (CCmode, FLAGS_REG),
13109                          const0_rtx);
13110   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13112   if (TARGET_64BIT)
13113     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13114   else
13115     {
13116       rtx tmp = gen_reg_rtx (SImode);
13118       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13119       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13120     }
13121   DONE;
13124 (define_expand "paritysi2"
13125   [(set (match_operand:SI 0 "register_operand")
13126         (parity:SI (match_operand:SI 1 "register_operand")))]
13127   "! TARGET_POPCNT"
13129   rtx scratch = gen_reg_rtx (QImode);
13130   rtx cond;
13132   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13134   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13135                          gen_rtx_REG (CCmode, FLAGS_REG),
13136                          const0_rtx);
13137   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13139   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13140   DONE;
13143 (define_insn_and_split "paritydi2_cmp"
13144   [(set (reg:CC FLAGS_REG)
13145         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13146                    UNSPEC_PARITY))
13147    (clobber (match_scratch:DI 0 "=r"))
13148    (clobber (match_scratch:SI 1 "=&r"))
13149    (clobber (match_scratch:HI 2 "=Q"))]
13150   "! TARGET_POPCNT"
13151   "#"
13152   "&& reload_completed"
13153   [(parallel
13154      [(set (match_dup 1)
13155            (xor:SI (match_dup 1) (match_dup 4)))
13156       (clobber (reg:CC FLAGS_REG))])
13157    (parallel
13158      [(set (reg:CC FLAGS_REG)
13159            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13160       (clobber (match_dup 1))
13161       (clobber (match_dup 2))])]
13163   operands[4] = gen_lowpart (SImode, operands[3]);
13165   if (TARGET_64BIT)
13166     {
13167       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13168       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13169     }
13170   else
13171     operands[1] = gen_highpart (SImode, operands[3]);
13174 (define_insn_and_split "paritysi2_cmp"
13175   [(set (reg:CC FLAGS_REG)
13176         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13177                    UNSPEC_PARITY))
13178    (clobber (match_scratch:SI 0 "=r"))
13179    (clobber (match_scratch:HI 1 "=&Q"))]
13180   "! TARGET_POPCNT"
13181   "#"
13182   "&& reload_completed"
13183   [(parallel
13184      [(set (match_dup 1)
13185            (xor:HI (match_dup 1) (match_dup 3)))
13186       (clobber (reg:CC FLAGS_REG))])
13187    (parallel
13188      [(set (reg:CC FLAGS_REG)
13189            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13190       (clobber (match_dup 1))])]
13192   operands[3] = gen_lowpart (HImode, operands[2]);
13194   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13195   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13198 (define_insn "*parityhi2_cmp"
13199   [(set (reg:CC FLAGS_REG)
13200         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13201                    UNSPEC_PARITY))
13202    (clobber (match_scratch:HI 0 "=Q"))]
13203   "! TARGET_POPCNT"
13204   "xor{b}\t{%h0, %b0|%b0, %h0}"
13205   [(set_attr "length" "2")
13206    (set_attr "mode" "HI")])
13209 ;; Thread-local storage patterns for ELF.
13211 ;; Note that these code sequences must appear exactly as shown
13212 ;; in order to allow linker relaxation.
13214 (define_insn "*tls_global_dynamic_32_gnu"
13215   [(set (match_operand:SI 0 "register_operand" "=a")
13216         (unspec:SI
13217          [(match_operand:SI 1 "register_operand" "b")
13218           (match_operand 2 "tls_symbolic_operand")
13219           (match_operand 3 "constant_call_address_operand" "Bz")
13220           (reg:SI SP_REG)]
13221          UNSPEC_TLS_GD))
13222    (clobber (match_scratch:SI 4 "=d"))
13223    (clobber (match_scratch:SI 5 "=c"))
13224    (clobber (reg:CC FLAGS_REG))]
13225   "!TARGET_64BIT && TARGET_GNU_TLS"
13227   output_asm_insn
13228     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13229   if (TARGET_SUN_TLS)
13230 #ifdef HAVE_AS_IX86_TLSGDPLT
13231     return "call\t%a2@tlsgdplt";
13232 #else
13233     return "call\t%p3@plt";
13234 #endif
13235   return "call\t%P3";
13237   [(set_attr "type" "multi")
13238    (set_attr "length" "12")])
13240 (define_expand "tls_global_dynamic_32"
13241   [(parallel
13242     [(set (match_operand:SI 0 "register_operand")
13243           (unspec:SI [(match_operand:SI 2 "register_operand")
13244                       (match_operand 1 "tls_symbolic_operand")
13245                       (match_operand 3 "constant_call_address_operand")
13246                       (reg:SI SP_REG)]
13247                      UNSPEC_TLS_GD))
13248      (clobber (match_scratch:SI 4))
13249      (clobber (match_scratch:SI 5))
13250      (clobber (reg:CC FLAGS_REG))])]
13251   ""
13252   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13254 (define_insn "*tls_global_dynamic_64_<mode>"
13255   [(set (match_operand:P 0 "register_operand" "=a")
13256         (call:P
13257          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13258          (match_operand 3)))
13259    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13260               (reg:P SP_REG)]
13261              UNSPEC_TLS_GD)]
13262   "TARGET_64BIT"
13264   if (!TARGET_X32)
13265     fputs (ASM_BYTE "0x66\n", asm_out_file);
13266   output_asm_insn
13267     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13268   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13269   fputs ("\trex64\n", asm_out_file);
13270   if (TARGET_SUN_TLS)
13271     return "call\t%p2@plt";
13272   return "call\t%P2";
13274   [(set_attr "type" "multi")
13275    (set (attr "length")
13276         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13278 (define_insn "*tls_global_dynamic_64_largepic"
13279   [(set (match_operand:DI 0 "register_operand" "=a")
13280         (call:DI
13281          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13282                           (match_operand:DI 3 "immediate_operand" "i")))
13283          (match_operand 4)))
13284    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13285                (reg:DI SP_REG)]
13286               UNSPEC_TLS_GD)]
13287   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13288    && GET_CODE (operands[3]) == CONST
13289    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13290    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13292   output_asm_insn
13293     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13294   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13295   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13296   return "call\t{*%%rax|rax}";
13298   [(set_attr "type" "multi")
13299    (set_attr "length" "22")])
13301 (define_expand "tls_global_dynamic_64_<mode>"
13302   [(parallel
13303     [(set (match_operand:P 0 "register_operand")
13304           (call:P
13305            (mem:QI (match_operand 2))
13306            (const_int 0)))
13307      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13308                 (reg:P SP_REG)]
13309                UNSPEC_TLS_GD)])]
13310   "TARGET_64BIT"
13311   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13313 (define_insn "*tls_local_dynamic_base_32_gnu"
13314   [(set (match_operand:SI 0 "register_operand" "=a")
13315         (unspec:SI
13316          [(match_operand:SI 1 "register_operand" "b")
13317           (match_operand 2 "constant_call_address_operand" "Bz")
13318           (reg:SI SP_REG)]
13319          UNSPEC_TLS_LD_BASE))
13320    (clobber (match_scratch:SI 3 "=d"))
13321    (clobber (match_scratch:SI 4 "=c"))
13322    (clobber (reg:CC FLAGS_REG))]
13323   "!TARGET_64BIT && TARGET_GNU_TLS"
13325   output_asm_insn
13326     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13327   if (TARGET_SUN_TLS)
13328     {
13329       if (HAVE_AS_IX86_TLSLDMPLT)
13330         return "call\t%&@tlsldmplt";
13331       else
13332         return "call\t%p2@plt";
13333     }
13334   return "call\t%P2";
13336   [(set_attr "type" "multi")
13337    (set_attr "length" "11")])
13339 (define_expand "tls_local_dynamic_base_32"
13340   [(parallel
13341      [(set (match_operand:SI 0 "register_operand")
13342            (unspec:SI
13343             [(match_operand:SI 1 "register_operand")
13344              (match_operand 2 "constant_call_address_operand")
13345              (reg:SI SP_REG)]
13346             UNSPEC_TLS_LD_BASE))
13347       (clobber (match_scratch:SI 3))
13348       (clobber (match_scratch:SI 4))
13349       (clobber (reg:CC FLAGS_REG))])]
13350   ""
13351   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13353 (define_insn "*tls_local_dynamic_base_64_<mode>"
13354   [(set (match_operand:P 0 "register_operand" "=a")
13355         (call:P
13356          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13357          (match_operand 2)))
13358    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13359   "TARGET_64BIT"
13361   output_asm_insn
13362     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13363   if (TARGET_SUN_TLS)
13364     return "call\t%p1@plt";
13365   return "call\t%P1";
13367   [(set_attr "type" "multi")
13368    (set_attr "length" "12")])
13370 (define_insn "*tls_local_dynamic_base_64_largepic"
13371   [(set (match_operand:DI 0 "register_operand" "=a")
13372         (call:DI
13373          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13374                           (match_operand:DI 2 "immediate_operand" "i")))
13375          (match_operand 3)))
13376    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13377   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13378    && GET_CODE (operands[2]) == CONST
13379    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13380    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13382   output_asm_insn
13383     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13384   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13385   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13386   return "call\t{*%%rax|rax}";
13388   [(set_attr "type" "multi")
13389    (set_attr "length" "22")])
13391 (define_expand "tls_local_dynamic_base_64_<mode>"
13392   [(parallel
13393      [(set (match_operand:P 0 "register_operand")
13394            (call:P
13395             (mem:QI (match_operand 1))
13396             (const_int 0)))
13397       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13398   "TARGET_64BIT"
13399   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13401 ;; Local dynamic of a single variable is a lose.  Show combine how
13402 ;; to convert that back to global dynamic.
13404 (define_insn_and_split "*tls_local_dynamic_32_once"
13405   [(set (match_operand:SI 0 "register_operand" "=a")
13406         (plus:SI
13407          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13408                      (match_operand 2 "constant_call_address_operand" "Bz")
13409                      (reg:SI SP_REG)]
13410                     UNSPEC_TLS_LD_BASE)
13411          (const:SI (unspec:SI
13412                     [(match_operand 3 "tls_symbolic_operand")]
13413                     UNSPEC_DTPOFF))))
13414    (clobber (match_scratch:SI 4 "=d"))
13415    (clobber (match_scratch:SI 5 "=c"))
13416    (clobber (reg:CC FLAGS_REG))]
13417   ""
13418   "#"
13419   ""
13420   [(parallel
13421      [(set (match_dup 0)
13422            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13423                        (reg:SI SP_REG)]
13424                       UNSPEC_TLS_GD))
13425       (clobber (match_dup 4))
13426       (clobber (match_dup 5))
13427       (clobber (reg:CC FLAGS_REG))])])
13429 ;; Segment register for the thread base ptr load
13430 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13432 ;; Load and add the thread base pointer from %<tp_seg>:0.
13433 (define_insn "*load_tp_x32"
13434   [(set (match_operand:SI 0 "register_operand" "=r")
13435         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13436   "TARGET_X32"
13437   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13438   [(set_attr "type" "imov")
13439    (set_attr "modrm" "0")
13440    (set_attr "length" "7")
13441    (set_attr "memory" "load")
13442    (set_attr "imm_disp" "false")])
13444 (define_insn "*load_tp_x32_zext"
13445   [(set (match_operand:DI 0 "register_operand" "=r")
13446         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13447   "TARGET_X32"
13448   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13449   [(set_attr "type" "imov")
13450    (set_attr "modrm" "0")
13451    (set_attr "length" "7")
13452    (set_attr "memory" "load")
13453    (set_attr "imm_disp" "false")])
13455 (define_insn "*load_tp_<mode>"
13456   [(set (match_operand:P 0 "register_operand" "=r")
13457         (unspec:P [(const_int 0)] UNSPEC_TP))]
13458   "!TARGET_X32"
13459   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13460   [(set_attr "type" "imov")
13461    (set_attr "modrm" "0")
13462    (set_attr "length" "7")
13463    (set_attr "memory" "load")
13464    (set_attr "imm_disp" "false")])
13466 (define_insn "*add_tp_x32"
13467   [(set (match_operand:SI 0 "register_operand" "=r")
13468         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13469                  (match_operand:SI 1 "register_operand" "0")))
13470    (clobber (reg:CC FLAGS_REG))]
13471   "TARGET_X32"
13472   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13473   [(set_attr "type" "alu")
13474    (set_attr "modrm" "0")
13475    (set_attr "length" "7")
13476    (set_attr "memory" "load")
13477    (set_attr "imm_disp" "false")])
13479 (define_insn "*add_tp_x32_zext"
13480   [(set (match_operand:DI 0 "register_operand" "=r")
13481         (zero_extend:DI
13482           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13483                    (match_operand:SI 1 "register_operand" "0"))))
13484    (clobber (reg:CC FLAGS_REG))]
13485   "TARGET_X32"
13486   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13487   [(set_attr "type" "alu")
13488    (set_attr "modrm" "0")
13489    (set_attr "length" "7")
13490    (set_attr "memory" "load")
13491    (set_attr "imm_disp" "false")])
13493 (define_insn "*add_tp_<mode>"
13494   [(set (match_operand:P 0 "register_operand" "=r")
13495         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13496                 (match_operand:P 1 "register_operand" "0")))
13497    (clobber (reg:CC FLAGS_REG))]
13498   "!TARGET_X32"
13499   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13500   [(set_attr "type" "alu")
13501    (set_attr "modrm" "0")
13502    (set_attr "length" "7")
13503    (set_attr "memory" "load")
13504    (set_attr "imm_disp" "false")])
13506 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13507 ;; %rax as destination of the initial executable code sequence.
13508 (define_insn "tls_initial_exec_64_sun"
13509   [(set (match_operand:DI 0 "register_operand" "=a")
13510         (unspec:DI
13511          [(match_operand 1 "tls_symbolic_operand")]
13512          UNSPEC_TLS_IE_SUN))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "TARGET_64BIT && TARGET_SUN_TLS"
13516   output_asm_insn
13517     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13518   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13520   [(set_attr "type" "multi")])
13522 ;; GNU2 TLS patterns can be split.
13524 (define_expand "tls_dynamic_gnu2_32"
13525   [(set (match_dup 3)
13526         (plus:SI (match_operand:SI 2 "register_operand")
13527                  (const:SI
13528                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13529                              UNSPEC_TLSDESC))))
13530    (parallel
13531     [(set (match_operand:SI 0 "register_operand")
13532           (unspec:SI [(match_dup 1) (match_dup 3)
13533                       (match_dup 2) (reg:SI SP_REG)]
13534                       UNSPEC_TLSDESC))
13535      (clobber (reg:CC FLAGS_REG))])]
13536   "!TARGET_64BIT && TARGET_GNU2_TLS"
13538   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13539   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13542 (define_insn "*tls_dynamic_gnu2_lea_32"
13543   [(set (match_operand:SI 0 "register_operand" "=r")
13544         (plus:SI (match_operand:SI 1 "register_operand" "b")
13545                  (const:SI
13546                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13547                               UNSPEC_TLSDESC))))]
13548   "!TARGET_64BIT && TARGET_GNU2_TLS"
13549   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13550   [(set_attr "type" "lea")
13551    (set_attr "mode" "SI")
13552    (set_attr "length" "6")
13553    (set_attr "length_address" "4")])
13555 (define_insn "*tls_dynamic_gnu2_call_32"
13556   [(set (match_operand:SI 0 "register_operand" "=a")
13557         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13558                     (match_operand:SI 2 "register_operand" "0")
13559                     ;; we have to make sure %ebx still points to the GOT
13560                     (match_operand:SI 3 "register_operand" "b")
13561                     (reg:SI SP_REG)]
13562                    UNSPEC_TLSDESC))
13563    (clobber (reg:CC FLAGS_REG))]
13564   "!TARGET_64BIT && TARGET_GNU2_TLS"
13565   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13566   [(set_attr "type" "call")
13567    (set_attr "length" "2")
13568    (set_attr "length_address" "0")])
13570 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13571   [(set (match_operand:SI 0 "register_operand" "=&a")
13572         (plus:SI
13573          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13574                      (match_operand:SI 4)
13575                      (match_operand:SI 2 "register_operand" "b")
13576                      (reg:SI SP_REG)]
13577                     UNSPEC_TLSDESC)
13578          (const:SI (unspec:SI
13579                     [(match_operand 1 "tls_symbolic_operand")]
13580                     UNSPEC_DTPOFF))))
13581    (clobber (reg:CC FLAGS_REG))]
13582   "!TARGET_64BIT && TARGET_GNU2_TLS"
13583   "#"
13584   ""
13585   [(set (match_dup 0) (match_dup 5))]
13587   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13588   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13591 (define_expand "tls_dynamic_gnu2_64"
13592   [(set (match_dup 2)
13593         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13594                    UNSPEC_TLSDESC))
13595    (parallel
13596     [(set (match_operand:DI 0 "register_operand")
13597           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13598                      UNSPEC_TLSDESC))
13599      (clobber (reg:CC FLAGS_REG))])]
13600   "TARGET_64BIT && TARGET_GNU2_TLS"
13602   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13603   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13606 (define_insn "*tls_dynamic_gnu2_lea_64"
13607   [(set (match_operand:DI 0 "register_operand" "=r")
13608         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13609                    UNSPEC_TLSDESC))]
13610   "TARGET_64BIT && TARGET_GNU2_TLS"
13611   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13612   [(set_attr "type" "lea")
13613    (set_attr "mode" "DI")
13614    (set_attr "length" "7")
13615    (set_attr "length_address" "4")])
13617 (define_insn "*tls_dynamic_gnu2_call_64"
13618   [(set (match_operand:DI 0 "register_operand" "=a")
13619         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13620                     (match_operand:DI 2 "register_operand" "0")
13621                     (reg:DI SP_REG)]
13622                    UNSPEC_TLSDESC))
13623    (clobber (reg:CC FLAGS_REG))]
13624   "TARGET_64BIT && TARGET_GNU2_TLS"
13625   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13626   [(set_attr "type" "call")
13627    (set_attr "length" "2")
13628    (set_attr "length_address" "0")])
13630 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13631   [(set (match_operand:DI 0 "register_operand" "=&a")
13632         (plus:DI
13633          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13634                      (match_operand:DI 3)
13635                      (reg:DI SP_REG)]
13636                     UNSPEC_TLSDESC)
13637          (const:DI (unspec:DI
13638                     [(match_operand 1 "tls_symbolic_operand")]
13639                     UNSPEC_DTPOFF))))
13640    (clobber (reg:CC FLAGS_REG))]
13641   "TARGET_64BIT && TARGET_GNU2_TLS"
13642   "#"
13643   ""
13644   [(set (match_dup 0) (match_dup 4))]
13646   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13647   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13650 ;; These patterns match the binary 387 instructions for addM3, subM3,
13651 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13652 ;; SFmode.  The first is the normal insn, the second the same insn but
13653 ;; with one operand a conversion, and the third the same insn but with
13654 ;; the other operand a conversion.  The conversion may be SFmode or
13655 ;; SImode if the target mode DFmode, but only SImode if the target mode
13656 ;; is SFmode.
13658 ;; Gcc is slightly more smart about handling normal two address instructions
13659 ;; so use special patterns for add and mull.
13661 (define_insn "*fop_<mode>_comm_mixed"
13662   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13663         (match_operator:MODEF 3 "binary_fp_operator"
13664           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13665            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13666   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13667    && COMMUTATIVE_ARITH_P (operands[3])
13668    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13669   "* return output_387_binary_op (insn, operands);"
13670   [(set (attr "type")
13671         (if_then_else (eq_attr "alternative" "1,2")
13672            (if_then_else (match_operand:MODEF 3 "mult_operator")
13673               (const_string "ssemul")
13674               (const_string "sseadd"))
13675            (if_then_else (match_operand:MODEF 3 "mult_operator")
13676               (const_string "fmul")
13677               (const_string "fop"))))
13678    (set_attr "isa" "*,noavx,avx")
13679    (set_attr "prefix" "orig,orig,vex")
13680    (set_attr "mode" "<MODE>")])
13682 (define_insn "*fop_<mode>_comm_sse"
13683   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13684         (match_operator:MODEF 3 "binary_fp_operator"
13685           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13686            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13687   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13688    && COMMUTATIVE_ARITH_P (operands[3])
13689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13690   "* return output_387_binary_op (insn, operands);"
13691   [(set (attr "type")
13692         (if_then_else (match_operand:MODEF 3 "mult_operator")
13693            (const_string "ssemul")
13694            (const_string "sseadd")))
13695    (set_attr "isa" "noavx,avx")
13696    (set_attr "prefix" "orig,vex")
13697    (set_attr "mode" "<MODE>")])
13699 (define_insn "*fop_<mode>_comm_i387"
13700   [(set (match_operand:MODEF 0 "register_operand" "=f")
13701         (match_operator:MODEF 3 "binary_fp_operator"
13702           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13703            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13704   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13705    && COMMUTATIVE_ARITH_P (operands[3])
13706    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13707   "* return output_387_binary_op (insn, operands);"
13708   [(set (attr "type")
13709         (if_then_else (match_operand:MODEF 3 "mult_operator")
13710            (const_string "fmul")
13711            (const_string "fop")))
13712    (set_attr "mode" "<MODE>")])
13714 (define_insn "*fop_<mode>_1_mixed"
13715   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13716         (match_operator:MODEF 3 "binary_fp_operator"
13717           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13718            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13719   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13720    && !COMMUTATIVE_ARITH_P (operands[3])
13721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13722   "* return output_387_binary_op (insn, operands);"
13723   [(set (attr "type")
13724         (cond [(and (eq_attr "alternative" "2,3")
13725                     (match_operand:MODEF 3 "mult_operator"))
13726                  (const_string "ssemul")
13727                (and (eq_attr "alternative" "2,3")
13728                     (match_operand:MODEF 3 "div_operator"))
13729                  (const_string "ssediv")
13730                (eq_attr "alternative" "2,3")
13731                  (const_string "sseadd")
13732                (match_operand:MODEF 3 "mult_operator")
13733                  (const_string "fmul")
13734                (match_operand:MODEF 3 "div_operator")
13735                  (const_string "fdiv")
13736               ]
13737               (const_string "fop")))
13738    (set_attr "isa" "*,*,noavx,avx")
13739    (set_attr "prefix" "orig,orig,orig,vex")
13740    (set_attr "mode" "<MODE>")])
13742 (define_insn "*rcpsf2_sse"
13743   [(set (match_operand:SF 0 "register_operand" "=x")
13744         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13745                    UNSPEC_RCP))]
13746   "TARGET_SSE_MATH"
13747   "%vrcpss\t{%1, %d0|%d0, %1}"
13748   [(set_attr "type" "sse")
13749    (set_attr "atom_sse_attr" "rcp")
13750    (set_attr "btver2_sse_attr" "rcp")
13751    (set_attr "prefix" "maybe_vex")
13752    (set_attr "mode" "SF")])
13754 (define_insn "*fop_<mode>_1_sse"
13755   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13756         (match_operator:MODEF 3 "binary_fp_operator"
13757           [(match_operand:MODEF 1 "register_operand" "0,x")
13758            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13759   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13760    && !COMMUTATIVE_ARITH_P (operands[3])"
13761   "* return output_387_binary_op (insn, operands);"
13762   [(set (attr "type")
13763         (cond [(match_operand:MODEF 3 "mult_operator")
13764                  (const_string "ssemul")
13765                (match_operand:MODEF 3 "div_operator")
13766                  (const_string "ssediv")
13767               ]
13768               (const_string "sseadd")))
13769    (set_attr "isa" "noavx,avx")
13770    (set_attr "prefix" "orig,vex")
13771    (set_attr "mode" "<MODE>")])
13773 ;; This pattern is not fully shadowed by the pattern above.
13774 (define_insn "*fop_<mode>_1_i387"
13775   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13776         (match_operator:MODEF 3 "binary_fp_operator"
13777           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13778            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13779   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13780    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781    && !COMMUTATIVE_ARITH_P (operands[3])
13782    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13783   "* return output_387_binary_op (insn, operands);"
13784   [(set (attr "type")
13785         (cond [(match_operand:MODEF 3 "mult_operator")
13786                  (const_string "fmul")
13787                (match_operand:MODEF 3 "div_operator")
13788                  (const_string "fdiv")
13789               ]
13790               (const_string "fop")))
13791    (set_attr "mode" "<MODE>")])
13793 ;; ??? Add SSE splitters for these!
13794 (define_insn "*fop_<MODEF:mode>_2_i387"
13795   [(set (match_operand:MODEF 0 "register_operand" "=f")
13796         (match_operator:MODEF 3 "binary_fp_operator"
13797           [(float:MODEF
13798              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13799            (match_operand:MODEF 2 "register_operand" "0")]))]
13800   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13801    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13802    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13803        || optimize_function_for_size_p (cfun))"
13804   { return output_387_binary_op (insn, operands); }
13805   [(set (attr "type")
13806         (cond [(match_operand:MODEF 3 "mult_operator")
13807                  (const_string "fmul")
13808                (match_operand:MODEF 3 "div_operator")
13809                  (const_string "fdiv")
13810               ]
13811               (const_string "fop")))
13812    (set_attr "fp_int_src" "true")
13813    (set_attr "mode" "<SWI24:MODE>")])
13815 (define_insn "*fop_<MODEF:mode>_3_i387"
13816   [(set (match_operand:MODEF 0 "register_operand" "=f")
13817         (match_operator:MODEF 3 "binary_fp_operator"
13818           [(match_operand:MODEF 1 "register_operand" "0")
13819            (float:MODEF
13820              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13821   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13822    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13823    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13824        || optimize_function_for_size_p (cfun))"
13825   { return output_387_binary_op (insn, operands); }
13826   [(set (attr "type")
13827         (cond [(match_operand:MODEF 3 "mult_operator")
13828                  (const_string "fmul")
13829                (match_operand:MODEF 3 "div_operator")
13830                  (const_string "fdiv")
13831               ]
13832               (const_string "fop")))
13833    (set_attr "fp_int_src" "true")
13834    (set_attr "mode" "<MODE>")])
13836 (define_insn "*fop_df_4_i387"
13837   [(set (match_operand:DF 0 "register_operand" "=f,f")
13838         (match_operator:DF 3 "binary_fp_operator"
13839            [(float_extend:DF
13840              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13841             (match_operand:DF 2 "register_operand" "0,f")]))]
13842   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13843    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13844    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13845   "* return output_387_binary_op (insn, operands);"
13846   [(set (attr "type")
13847         (cond [(match_operand:DF 3 "mult_operator")
13848                  (const_string "fmul")
13849                (match_operand:DF 3 "div_operator")
13850                  (const_string "fdiv")
13851               ]
13852               (const_string "fop")))
13853    (set_attr "mode" "SF")])
13855 (define_insn "*fop_df_5_i387"
13856   [(set (match_operand:DF 0 "register_operand" "=f,f")
13857         (match_operator:DF 3 "binary_fp_operator"
13858           [(match_operand:DF 1 "register_operand" "0,f")
13859            (float_extend:DF
13860             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13861   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13862    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13863   "* return output_387_binary_op (insn, operands);"
13864   [(set (attr "type")
13865         (cond [(match_operand:DF 3 "mult_operator")
13866                  (const_string "fmul")
13867                (match_operand:DF 3 "div_operator")
13868                  (const_string "fdiv")
13869               ]
13870               (const_string "fop")))
13871    (set_attr "mode" "SF")])
13873 (define_insn "*fop_df_6_i387"
13874   [(set (match_operand:DF 0 "register_operand" "=f,f")
13875         (match_operator:DF 3 "binary_fp_operator"
13876           [(float_extend:DF
13877             (match_operand:SF 1 "register_operand" "0,f"))
13878            (float_extend:DF
13879             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13880   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13881    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13882   "* return output_387_binary_op (insn, operands);"
13883   [(set (attr "type")
13884         (cond [(match_operand:DF 3 "mult_operator")
13885                  (const_string "fmul")
13886                (match_operand:DF 3 "div_operator")
13887                  (const_string "fdiv")
13888               ]
13889               (const_string "fop")))
13890    (set_attr "mode" "SF")])
13892 (define_insn "*fop_xf_comm_i387"
13893   [(set (match_operand:XF 0 "register_operand" "=f")
13894         (match_operator:XF 3 "binary_fp_operator"
13895                         [(match_operand:XF 1 "register_operand" "%0")
13896                          (match_operand:XF 2 "register_operand" "f")]))]
13897   "TARGET_80387
13898    && COMMUTATIVE_ARITH_P (operands[3])"
13899   "* return output_387_binary_op (insn, operands);"
13900   [(set (attr "type")
13901         (if_then_else (match_operand:XF 3 "mult_operator")
13902            (const_string "fmul")
13903            (const_string "fop")))
13904    (set_attr "mode" "XF")])
13906 (define_insn "*fop_xf_1_i387"
13907   [(set (match_operand:XF 0 "register_operand" "=f,f")
13908         (match_operator:XF 3 "binary_fp_operator"
13909                         [(match_operand:XF 1 "register_operand" "0,f")
13910                          (match_operand:XF 2 "register_operand" "f,0")]))]
13911   "TARGET_80387
13912    && !COMMUTATIVE_ARITH_P (operands[3])"
13913   "* return output_387_binary_op (insn, operands);"
13914   [(set (attr "type")
13915         (cond [(match_operand:XF 3 "mult_operator")
13916                  (const_string "fmul")
13917                (match_operand:XF 3 "div_operator")
13918                  (const_string "fdiv")
13919               ]
13920               (const_string "fop")))
13921    (set_attr "mode" "XF")])
13923 (define_insn "*fop_xf_2_i387"
13924   [(set (match_operand:XF 0 "register_operand" "=f")
13925         (match_operator:XF 3 "binary_fp_operator"
13926           [(float:XF
13927              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13928            (match_operand:XF 2 "register_operand" "0")]))]
13929   "TARGET_80387
13930    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13931   { return output_387_binary_op (insn, operands); }
13932   [(set (attr "type")
13933         (cond [(match_operand:XF 3 "mult_operator")
13934                  (const_string "fmul")
13935                (match_operand:XF 3 "div_operator")
13936                  (const_string "fdiv")
13937               ]
13938               (const_string "fop")))
13939    (set_attr "fp_int_src" "true")
13940    (set_attr "mode" "<MODE>")])
13942 (define_insn "*fop_xf_3_i387"
13943   [(set (match_operand:XF 0 "register_operand" "=f")
13944         (match_operator:XF 3 "binary_fp_operator"
13945           [(match_operand:XF 1 "register_operand" "0")
13946            (float:XF
13947              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13948   "TARGET_80387
13949    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13950   { return output_387_binary_op (insn, operands); }
13951   [(set (attr "type")
13952         (cond [(match_operand:XF 3 "mult_operator")
13953                  (const_string "fmul")
13954                (match_operand:XF 3 "div_operator")
13955                  (const_string "fdiv")
13956               ]
13957               (const_string "fop")))
13958    (set_attr "fp_int_src" "true")
13959    (set_attr "mode" "<MODE>")])
13961 (define_insn "*fop_xf_4_i387"
13962   [(set (match_operand:XF 0 "register_operand" "=f,f")
13963         (match_operator:XF 3 "binary_fp_operator"
13964            [(float_extend:XF
13965               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13966             (match_operand:XF 2 "register_operand" "0,f")]))]
13967   "TARGET_80387"
13968   "* return output_387_binary_op (insn, operands);"
13969   [(set (attr "type")
13970         (cond [(match_operand:XF 3 "mult_operator")
13971                  (const_string "fmul")
13972                (match_operand:XF 3 "div_operator")
13973                  (const_string "fdiv")
13974               ]
13975               (const_string "fop")))
13976    (set_attr "mode" "<MODE>")])
13978 (define_insn "*fop_xf_5_i387"
13979   [(set (match_operand:XF 0 "register_operand" "=f,f")
13980         (match_operator:XF 3 "binary_fp_operator"
13981           [(match_operand:XF 1 "register_operand" "0,f")
13982            (float_extend:XF
13983              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13984   "TARGET_80387"
13985   "* return output_387_binary_op (insn, operands);"
13986   [(set (attr "type")
13987         (cond [(match_operand:XF 3 "mult_operator")
13988                  (const_string "fmul")
13989                (match_operand:XF 3 "div_operator")
13990                  (const_string "fdiv")
13991               ]
13992               (const_string "fop")))
13993    (set_attr "mode" "<MODE>")])
13995 (define_insn "*fop_xf_6_i387"
13996   [(set (match_operand:XF 0 "register_operand" "=f,f")
13997         (match_operator:XF 3 "binary_fp_operator"
13998           [(float_extend:XF
13999              (match_operand:MODEF 1 "register_operand" "0,f"))
14000            (float_extend:XF
14001              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14002   "TARGET_80387"
14003   "* return output_387_binary_op (insn, operands);"
14004   [(set (attr "type")
14005         (cond [(match_operand:XF 3 "mult_operator")
14006                  (const_string "fmul")
14007                (match_operand:XF 3 "div_operator")
14008                  (const_string "fdiv")
14009               ]
14010               (const_string "fop")))
14011    (set_attr "mode" "<MODE>")])
14013 ;; FPU special functions.
14015 ;; This pattern implements a no-op XFmode truncation for
14016 ;; all fancy i386 XFmode math functions.
14018 (define_insn "truncxf<mode>2_i387_noop_unspec"
14019   [(set (match_operand:MODEF 0 "register_operand" "=f")
14020         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14021         UNSPEC_TRUNC_NOOP))]
14022   "TARGET_USE_FANCY_MATH_387"
14023   "* return output_387_reg_move (insn, operands);"
14024   [(set_attr "type" "fmov")
14025    (set_attr "mode" "<MODE>")])
14027 (define_insn "sqrtxf2"
14028   [(set (match_operand:XF 0 "register_operand" "=f")
14029         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14030   "TARGET_USE_FANCY_MATH_387"
14031   "fsqrt"
14032   [(set_attr "type" "fpspc")
14033    (set_attr "mode" "XF")
14034    (set_attr "athlon_decode" "direct")
14035    (set_attr "amdfam10_decode" "direct")
14036    (set_attr "bdver1_decode" "direct")])
14038 (define_insn "sqrt_extend<mode>xf2_i387"
14039   [(set (match_operand:XF 0 "register_operand" "=f")
14040         (sqrt:XF
14041           (float_extend:XF
14042             (match_operand:MODEF 1 "register_operand" "0"))))]
14043   "TARGET_USE_FANCY_MATH_387"
14044   "fsqrt"
14045   [(set_attr "type" "fpspc")
14046    (set_attr "mode" "XF")
14047    (set_attr "athlon_decode" "direct")
14048    (set_attr "amdfam10_decode" "direct")
14049    (set_attr "bdver1_decode" "direct")])
14051 (define_insn "*rsqrtsf2_sse"
14052   [(set (match_operand:SF 0 "register_operand" "=x")
14053         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14054                    UNSPEC_RSQRT))]
14055   "TARGET_SSE_MATH"
14056   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14057   [(set_attr "type" "sse")
14058    (set_attr "atom_sse_attr" "rcp")
14059    (set_attr "btver2_sse_attr" "rcp")
14060    (set_attr "prefix" "maybe_vex")
14061    (set_attr "mode" "SF")])
14063 (define_expand "rsqrtsf2"
14064   [(set (match_operand:SF 0 "register_operand")
14065         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14066                    UNSPEC_RSQRT))]
14067   "TARGET_SSE_MATH"
14069   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14070   DONE;
14073 (define_insn "*sqrt<mode>2_sse"
14074   [(set (match_operand:MODEF 0 "register_operand" "=x")
14075         (sqrt:MODEF
14076           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14077   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14078   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14079   [(set_attr "type" "sse")
14080    (set_attr "atom_sse_attr" "sqrt")
14081    (set_attr "btver2_sse_attr" "sqrt")
14082    (set_attr "prefix" "maybe_vex")
14083    (set_attr "mode" "<MODE>")
14084    (set_attr "athlon_decode" "*")
14085    (set_attr "amdfam10_decode" "*")
14086    (set_attr "bdver1_decode" "*")])
14088 (define_expand "sqrt<mode>2"
14089   [(set (match_operand:MODEF 0 "register_operand")
14090         (sqrt:MODEF
14091           (match_operand:MODEF 1 "nonimmediate_operand")))]
14092   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14093    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14095   if (<MODE>mode == SFmode
14096       && TARGET_SSE_MATH
14097       && TARGET_RECIP_SQRT
14098       && !optimize_function_for_size_p (cfun)
14099       && flag_finite_math_only && !flag_trapping_math
14100       && flag_unsafe_math_optimizations)
14101     {
14102       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14103       DONE;
14104     }
14106   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14107     {
14108       rtx op0 = gen_reg_rtx (XFmode);
14109       rtx op1 = force_reg (<MODE>mode, operands[1]);
14111       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14112       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14113       DONE;
14114    }
14117 (define_insn "fpremxf4_i387"
14118   [(set (match_operand:XF 0 "register_operand" "=f")
14119         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14120                     (match_operand:XF 3 "register_operand" "1")]
14121                    UNSPEC_FPREM_F))
14122    (set (match_operand:XF 1 "register_operand" "=u")
14123         (unspec:XF [(match_dup 2) (match_dup 3)]
14124                    UNSPEC_FPREM_U))
14125    (set (reg:CCFP FPSR_REG)
14126         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14127                      UNSPEC_C2_FLAG))]
14128   "TARGET_USE_FANCY_MATH_387
14129    && flag_finite_math_only"
14130   "fprem"
14131   [(set_attr "type" "fpspc")
14132    (set_attr "mode" "XF")])
14134 (define_expand "fmodxf3"
14135   [(use (match_operand:XF 0 "register_operand"))
14136    (use (match_operand:XF 1 "general_operand"))
14137    (use (match_operand:XF 2 "general_operand"))]
14138   "TARGET_USE_FANCY_MATH_387
14139    && flag_finite_math_only"
14141   rtx_code_label *label = gen_label_rtx ();
14143   rtx op1 = gen_reg_rtx (XFmode);
14144   rtx op2 = gen_reg_rtx (XFmode);
14146   emit_move_insn (op2, operands[2]);
14147   emit_move_insn (op1, operands[1]);
14149   emit_label (label);
14150   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14151   ix86_emit_fp_unordered_jump (label);
14152   LABEL_NUSES (label) = 1;
14154   emit_move_insn (operands[0], op1);
14155   DONE;
14158 (define_expand "fmod<mode>3"
14159   [(use (match_operand:MODEF 0 "register_operand"))
14160    (use (match_operand:MODEF 1 "general_operand"))
14161    (use (match_operand:MODEF 2 "general_operand"))]
14162   "TARGET_USE_FANCY_MATH_387
14163    && flag_finite_math_only"
14165   rtx (*gen_truncxf) (rtx, rtx);
14167   rtx_code_label *label = gen_label_rtx ();
14169   rtx op1 = gen_reg_rtx (XFmode);
14170   rtx op2 = gen_reg_rtx (XFmode);
14172   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14173   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14175   emit_label (label);
14176   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14177   ix86_emit_fp_unordered_jump (label);
14178   LABEL_NUSES (label) = 1;
14180   /* Truncate the result properly for strict SSE math.  */
14181   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14182       && !TARGET_MIX_SSE_I387)
14183     gen_truncxf = gen_truncxf<mode>2;
14184   else
14185     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14187   emit_insn (gen_truncxf (operands[0], op1));
14188   DONE;
14191 (define_insn "fprem1xf4_i387"
14192   [(set (match_operand:XF 0 "register_operand" "=f")
14193         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14194                     (match_operand:XF 3 "register_operand" "1")]
14195                    UNSPEC_FPREM1_F))
14196    (set (match_operand:XF 1 "register_operand" "=u")
14197         (unspec:XF [(match_dup 2) (match_dup 3)]
14198                    UNSPEC_FPREM1_U))
14199    (set (reg:CCFP FPSR_REG)
14200         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14201                      UNSPEC_C2_FLAG))]
14202   "TARGET_USE_FANCY_MATH_387
14203    && flag_finite_math_only"
14204   "fprem1"
14205   [(set_attr "type" "fpspc")
14206    (set_attr "mode" "XF")])
14208 (define_expand "remainderxf3"
14209   [(use (match_operand:XF 0 "register_operand"))
14210    (use (match_operand:XF 1 "general_operand"))
14211    (use (match_operand:XF 2 "general_operand"))]
14212   "TARGET_USE_FANCY_MATH_387
14213    && flag_finite_math_only"
14215   rtx_code_label *label = gen_label_rtx ();
14217   rtx op1 = gen_reg_rtx (XFmode);
14218   rtx op2 = gen_reg_rtx (XFmode);
14220   emit_move_insn (op2, operands[2]);
14221   emit_move_insn (op1, operands[1]);
14223   emit_label (label);
14224   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14225   ix86_emit_fp_unordered_jump (label);
14226   LABEL_NUSES (label) = 1;
14228   emit_move_insn (operands[0], op1);
14229   DONE;
14232 (define_expand "remainder<mode>3"
14233   [(use (match_operand:MODEF 0 "register_operand"))
14234    (use (match_operand:MODEF 1 "general_operand"))
14235    (use (match_operand:MODEF 2 "general_operand"))]
14236   "TARGET_USE_FANCY_MATH_387
14237    && flag_finite_math_only"
14239   rtx (*gen_truncxf) (rtx, rtx);
14241   rtx_code_label *label = gen_label_rtx ();
14243   rtx op1 = gen_reg_rtx (XFmode);
14244   rtx op2 = gen_reg_rtx (XFmode);
14246   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14247   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14249   emit_label (label);
14251   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14252   ix86_emit_fp_unordered_jump (label);
14253   LABEL_NUSES (label) = 1;
14255   /* Truncate the result properly for strict SSE math.  */
14256   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14257       && !TARGET_MIX_SSE_I387)
14258     gen_truncxf = gen_truncxf<mode>2;
14259   else
14260     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14262   emit_insn (gen_truncxf (operands[0], op1));
14263   DONE;
14266 (define_int_iterator SINCOS
14267         [UNSPEC_SIN
14268          UNSPEC_COS])
14270 (define_int_attr sincos
14271         [(UNSPEC_SIN "sin")
14272          (UNSPEC_COS "cos")])
14274 (define_insn "*<sincos>xf2_i387"
14275   [(set (match_operand:XF 0 "register_operand" "=f")
14276         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14277                    SINCOS))]
14278   "TARGET_USE_FANCY_MATH_387
14279    && flag_unsafe_math_optimizations"
14280   "f<sincos>"
14281   [(set_attr "type" "fpspc")
14282    (set_attr "mode" "XF")])
14284 (define_insn "*<sincos>_extend<mode>xf2_i387"
14285   [(set (match_operand:XF 0 "register_operand" "=f")
14286         (unspec:XF [(float_extend:XF
14287                       (match_operand:MODEF 1 "register_operand" "0"))]
14288                    SINCOS))]
14289   "TARGET_USE_FANCY_MATH_387
14290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14291        || TARGET_MIX_SSE_I387)
14292    && flag_unsafe_math_optimizations"
14293   "f<sincos>"
14294   [(set_attr "type" "fpspc")
14295    (set_attr "mode" "XF")])
14297 ;; When sincos pattern is defined, sin and cos builtin functions will be
14298 ;; expanded to sincos pattern with one of its outputs left unused.
14299 ;; CSE pass will figure out if two sincos patterns can be combined,
14300 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14301 ;; depending on the unused output.
14303 (define_insn "sincosxf3"
14304   [(set (match_operand:XF 0 "register_operand" "=f")
14305         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14306                    UNSPEC_SINCOS_COS))
14307    (set (match_operand:XF 1 "register_operand" "=u")
14308         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14309   "TARGET_USE_FANCY_MATH_387
14310    && flag_unsafe_math_optimizations"
14311   "fsincos"
14312   [(set_attr "type" "fpspc")
14313    (set_attr "mode" "XF")])
14315 (define_split
14316   [(set (match_operand:XF 0 "register_operand")
14317         (unspec:XF [(match_operand:XF 2 "register_operand")]
14318                    UNSPEC_SINCOS_COS))
14319    (set (match_operand:XF 1 "register_operand")
14320         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14321   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14322    && can_create_pseudo_p ()"
14323   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14325 (define_split
14326   [(set (match_operand:XF 0 "register_operand")
14327         (unspec:XF [(match_operand:XF 2 "register_operand")]
14328                    UNSPEC_SINCOS_COS))
14329    (set (match_operand:XF 1 "register_operand")
14330         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14331   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14332    && can_create_pseudo_p ()"
14333   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14335 (define_insn "sincos_extend<mode>xf3_i387"
14336   [(set (match_operand:XF 0 "register_operand" "=f")
14337         (unspec:XF [(float_extend:XF
14338                       (match_operand:MODEF 2 "register_operand" "0"))]
14339                    UNSPEC_SINCOS_COS))
14340    (set (match_operand:XF 1 "register_operand" "=u")
14341         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14342   "TARGET_USE_FANCY_MATH_387
14343    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344        || TARGET_MIX_SSE_I387)
14345    && flag_unsafe_math_optimizations"
14346   "fsincos"
14347   [(set_attr "type" "fpspc")
14348    (set_attr "mode" "XF")])
14350 (define_split
14351   [(set (match_operand:XF 0 "register_operand")
14352         (unspec:XF [(float_extend:XF
14353                       (match_operand:MODEF 2 "register_operand"))]
14354                    UNSPEC_SINCOS_COS))
14355    (set (match_operand:XF 1 "register_operand")
14356         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14357   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14358    && can_create_pseudo_p ()"
14359   [(set (match_dup 1)
14360         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14362 (define_split
14363   [(set (match_operand:XF 0 "register_operand")
14364         (unspec:XF [(float_extend:XF
14365                       (match_operand:MODEF 2 "register_operand"))]
14366                    UNSPEC_SINCOS_COS))
14367    (set (match_operand:XF 1 "register_operand")
14368         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14369   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14370    && can_create_pseudo_p ()"
14371   [(set (match_dup 0)
14372         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14374 (define_expand "sincos<mode>3"
14375   [(use (match_operand:MODEF 0 "register_operand"))
14376    (use (match_operand:MODEF 1 "register_operand"))
14377    (use (match_operand:MODEF 2 "register_operand"))]
14378   "TARGET_USE_FANCY_MATH_387
14379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380        || TARGET_MIX_SSE_I387)
14381    && flag_unsafe_math_optimizations"
14383   rtx op0 = gen_reg_rtx (XFmode);
14384   rtx op1 = gen_reg_rtx (XFmode);
14386   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14387   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14388   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14389   DONE;
14392 (define_insn "fptanxf4_i387"
14393   [(set (match_operand:XF 0 "register_operand" "=f")
14394         (match_operand:XF 3 "const_double_operand" "F"))
14395    (set (match_operand:XF 1 "register_operand" "=u")
14396         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14397                    UNSPEC_TAN))]
14398   "TARGET_USE_FANCY_MATH_387
14399    && flag_unsafe_math_optimizations
14400    && standard_80387_constant_p (operands[3]) == 2"
14401   "fptan"
14402   [(set_attr "type" "fpspc")
14403    (set_attr "mode" "XF")])
14405 (define_insn "fptan_extend<mode>xf4_i387"
14406   [(set (match_operand:MODEF 0 "register_operand" "=f")
14407         (match_operand:MODEF 3 "const_double_operand" "F"))
14408    (set (match_operand:XF 1 "register_operand" "=u")
14409         (unspec:XF [(float_extend:XF
14410                       (match_operand:MODEF 2 "register_operand" "0"))]
14411                    UNSPEC_TAN))]
14412   "TARGET_USE_FANCY_MATH_387
14413    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14414        || TARGET_MIX_SSE_I387)
14415    && flag_unsafe_math_optimizations
14416    && standard_80387_constant_p (operands[3]) == 2"
14417   "fptan"
14418   [(set_attr "type" "fpspc")
14419    (set_attr "mode" "XF")])
14421 (define_expand "tanxf2"
14422   [(use (match_operand:XF 0 "register_operand"))
14423    (use (match_operand:XF 1 "register_operand"))]
14424   "TARGET_USE_FANCY_MATH_387
14425    && flag_unsafe_math_optimizations"
14427   rtx one = gen_reg_rtx (XFmode);
14428   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14430   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14431   DONE;
14434 (define_expand "tan<mode>2"
14435   [(use (match_operand:MODEF 0 "register_operand"))
14436    (use (match_operand:MODEF 1 "register_operand"))]
14437   "TARGET_USE_FANCY_MATH_387
14438    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14439        || TARGET_MIX_SSE_I387)
14440    && flag_unsafe_math_optimizations"
14442   rtx op0 = gen_reg_rtx (XFmode);
14444   rtx one = gen_reg_rtx (<MODE>mode);
14445   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14447   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14448                                              operands[1], op2));
14449   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14450   DONE;
14453 (define_insn "*fpatanxf3_i387"
14454   [(set (match_operand:XF 0 "register_operand" "=f")
14455         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14456                     (match_operand:XF 2 "register_operand" "u")]
14457                    UNSPEC_FPATAN))
14458    (clobber (match_scratch:XF 3 "=2"))]
14459   "TARGET_USE_FANCY_MATH_387
14460    && flag_unsafe_math_optimizations"
14461   "fpatan"
14462   [(set_attr "type" "fpspc")
14463    (set_attr "mode" "XF")])
14465 (define_insn "fpatan_extend<mode>xf3_i387"
14466   [(set (match_operand:XF 0 "register_operand" "=f")
14467         (unspec:XF [(float_extend:XF
14468                       (match_operand:MODEF 1 "register_operand" "0"))
14469                     (float_extend:XF
14470                       (match_operand:MODEF 2 "register_operand" "u"))]
14471                    UNSPEC_FPATAN))
14472    (clobber (match_scratch:XF 3 "=2"))]
14473   "TARGET_USE_FANCY_MATH_387
14474    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14475        || TARGET_MIX_SSE_I387)
14476    && flag_unsafe_math_optimizations"
14477   "fpatan"
14478   [(set_attr "type" "fpspc")
14479    (set_attr "mode" "XF")])
14481 (define_expand "atan2xf3"
14482   [(parallel [(set (match_operand:XF 0 "register_operand")
14483                    (unspec:XF [(match_operand:XF 2 "register_operand")
14484                                (match_operand:XF 1 "register_operand")]
14485                               UNSPEC_FPATAN))
14486               (clobber (match_scratch:XF 3))])]
14487   "TARGET_USE_FANCY_MATH_387
14488    && flag_unsafe_math_optimizations")
14490 (define_expand "atan2<mode>3"
14491   [(use (match_operand:MODEF 0 "register_operand"))
14492    (use (match_operand:MODEF 1 "register_operand"))
14493    (use (match_operand:MODEF 2 "register_operand"))]
14494   "TARGET_USE_FANCY_MATH_387
14495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14496        || TARGET_MIX_SSE_I387)
14497    && flag_unsafe_math_optimizations"
14499   rtx op0 = gen_reg_rtx (XFmode);
14501   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14503   DONE;
14506 (define_expand "atanxf2"
14507   [(parallel [(set (match_operand:XF 0 "register_operand")
14508                    (unspec:XF [(match_dup 2)
14509                                (match_operand:XF 1 "register_operand")]
14510                               UNSPEC_FPATAN))
14511               (clobber (match_scratch:XF 3))])]
14512   "TARGET_USE_FANCY_MATH_387
14513    && flag_unsafe_math_optimizations"
14515   operands[2] = gen_reg_rtx (XFmode);
14516   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14519 (define_expand "atan<mode>2"
14520   [(use (match_operand:MODEF 0 "register_operand"))
14521    (use (match_operand:MODEF 1 "register_operand"))]
14522   "TARGET_USE_FANCY_MATH_387
14523    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14524        || TARGET_MIX_SSE_I387)
14525    && flag_unsafe_math_optimizations"
14527   rtx op0 = gen_reg_rtx (XFmode);
14529   rtx op2 = gen_reg_rtx (<MODE>mode);
14530   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14532   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14533   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14534   DONE;
14537 (define_expand "asinxf2"
14538   [(set (match_dup 2)
14539         (mult:XF (match_operand:XF 1 "register_operand")
14540                  (match_dup 1)))
14541    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14542    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14543    (parallel [(set (match_operand:XF 0 "register_operand")
14544                    (unspec:XF [(match_dup 5) (match_dup 1)]
14545                               UNSPEC_FPATAN))
14546               (clobber (match_scratch:XF 6))])]
14547   "TARGET_USE_FANCY_MATH_387
14548    && flag_unsafe_math_optimizations"
14550   int i;
14552   if (optimize_insn_for_size_p ())
14553     FAIL;
14555   for (i = 2; i < 6; i++)
14556     operands[i] = gen_reg_rtx (XFmode);
14558   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14561 (define_expand "asin<mode>2"
14562   [(use (match_operand:MODEF 0 "register_operand"))
14563    (use (match_operand:MODEF 1 "general_operand"))]
14564  "TARGET_USE_FANCY_MATH_387
14565    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14566        || TARGET_MIX_SSE_I387)
14567    && flag_unsafe_math_optimizations"
14569   rtx op0 = gen_reg_rtx (XFmode);
14570   rtx op1 = gen_reg_rtx (XFmode);
14572   if (optimize_insn_for_size_p ())
14573     FAIL;
14575   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14576   emit_insn (gen_asinxf2 (op0, op1));
14577   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14578   DONE;
14581 (define_expand "acosxf2"
14582   [(set (match_dup 2)
14583         (mult:XF (match_operand:XF 1 "register_operand")
14584                  (match_dup 1)))
14585    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14586    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14587    (parallel [(set (match_operand:XF 0 "register_operand")
14588                    (unspec:XF [(match_dup 1) (match_dup 5)]
14589                               UNSPEC_FPATAN))
14590               (clobber (match_scratch:XF 6))])]
14591   "TARGET_USE_FANCY_MATH_387
14592    && flag_unsafe_math_optimizations"
14594   int i;
14596   if (optimize_insn_for_size_p ())
14597     FAIL;
14599   for (i = 2; i < 6; i++)
14600     operands[i] = gen_reg_rtx (XFmode);
14602   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14605 (define_expand "acos<mode>2"
14606   [(use (match_operand:MODEF 0 "register_operand"))
14607    (use (match_operand:MODEF 1 "general_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);
14614   rtx op1 = gen_reg_rtx (XFmode);
14616   if (optimize_insn_for_size_p ())
14617     FAIL;
14619   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620   emit_insn (gen_acosxf2 (op0, op1));
14621   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14622   DONE;
14625 (define_insn "fyl2xxf3_i387"
14626   [(set (match_operand:XF 0 "register_operand" "=f")
14627         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14628                     (match_operand:XF 2 "register_operand" "u")]
14629                    UNSPEC_FYL2X))
14630    (clobber (match_scratch:XF 3 "=2"))]
14631   "TARGET_USE_FANCY_MATH_387
14632    && flag_unsafe_math_optimizations"
14633   "fyl2x"
14634   [(set_attr "type" "fpspc")
14635    (set_attr "mode" "XF")])
14637 (define_insn "fyl2x_extend<mode>xf3_i387"
14638   [(set (match_operand:XF 0 "register_operand" "=f")
14639         (unspec:XF [(float_extend:XF
14640                       (match_operand:MODEF 1 "register_operand" "0"))
14641                     (match_operand:XF 2 "register_operand" "u")]
14642                    UNSPEC_FYL2X))
14643    (clobber (match_scratch:XF 3 "=2"))]
14644   "TARGET_USE_FANCY_MATH_387
14645    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14646        || TARGET_MIX_SSE_I387)
14647    && flag_unsafe_math_optimizations"
14648   "fyl2x"
14649   [(set_attr "type" "fpspc")
14650    (set_attr "mode" "XF")])
14652 (define_expand "logxf2"
14653   [(parallel [(set (match_operand:XF 0 "register_operand")
14654                    (unspec:XF [(match_operand:XF 1 "register_operand")
14655                                (match_dup 2)] UNSPEC_FYL2X))
14656               (clobber (match_scratch:XF 3))])]
14657   "TARGET_USE_FANCY_MATH_387
14658    && flag_unsafe_math_optimizations"
14660   operands[2] = gen_reg_rtx (XFmode);
14661   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14664 (define_expand "log<mode>2"
14665   [(use (match_operand:MODEF 0 "register_operand"))
14666    (use (match_operand:MODEF 1 "register_operand"))]
14667   "TARGET_USE_FANCY_MATH_387
14668    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14669        || TARGET_MIX_SSE_I387)
14670    && flag_unsafe_math_optimizations"
14672   rtx op0 = gen_reg_rtx (XFmode);
14674   rtx op2 = gen_reg_rtx (XFmode);
14675   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14677   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14678   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14679   DONE;
14682 (define_expand "log10xf2"
14683   [(parallel [(set (match_operand:XF 0 "register_operand")
14684                    (unspec:XF [(match_operand:XF 1 "register_operand")
14685                                (match_dup 2)] UNSPEC_FYL2X))
14686               (clobber (match_scratch:XF 3))])]
14687   "TARGET_USE_FANCY_MATH_387
14688    && flag_unsafe_math_optimizations"
14690   operands[2] = gen_reg_rtx (XFmode);
14691   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14694 (define_expand "log10<mode>2"
14695   [(use (match_operand:MODEF 0 "register_operand"))
14696    (use (match_operand:MODEF 1 "register_operand"))]
14697   "TARGET_USE_FANCY_MATH_387
14698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14699        || TARGET_MIX_SSE_I387)
14700    && flag_unsafe_math_optimizations"
14702   rtx op0 = gen_reg_rtx (XFmode);
14704   rtx op2 = gen_reg_rtx (XFmode);
14705   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14707   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14708   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14709   DONE;
14712 (define_expand "log2xf2"
14713   [(parallel [(set (match_operand:XF 0 "register_operand")
14714                    (unspec:XF [(match_operand:XF 1 "register_operand")
14715                                (match_dup 2)] UNSPEC_FYL2X))
14716               (clobber (match_scratch:XF 3))])]
14717   "TARGET_USE_FANCY_MATH_387
14718    && flag_unsafe_math_optimizations"
14720   operands[2] = gen_reg_rtx (XFmode);
14721   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14724 (define_expand "log2<mode>2"
14725   [(use (match_operand:MODEF 0 "register_operand"))
14726    (use (match_operand:MODEF 1 "register_operand"))]
14727   "TARGET_USE_FANCY_MATH_387
14728    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14729        || TARGET_MIX_SSE_I387)
14730    && flag_unsafe_math_optimizations"
14732   rtx op0 = gen_reg_rtx (XFmode);
14734   rtx op2 = gen_reg_rtx (XFmode);
14735   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14737   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14738   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14739   DONE;
14742 (define_insn "fyl2xp1xf3_i387"
14743   [(set (match_operand:XF 0 "register_operand" "=f")
14744         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14745                     (match_operand:XF 2 "register_operand" "u")]
14746                    UNSPEC_FYL2XP1))
14747    (clobber (match_scratch:XF 3 "=2"))]
14748   "TARGET_USE_FANCY_MATH_387
14749    && flag_unsafe_math_optimizations"
14750   "fyl2xp1"
14751   [(set_attr "type" "fpspc")
14752    (set_attr "mode" "XF")])
14754 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14755   [(set (match_operand:XF 0 "register_operand" "=f")
14756         (unspec:XF [(float_extend:XF
14757                       (match_operand:MODEF 1 "register_operand" "0"))
14758                     (match_operand:XF 2 "register_operand" "u")]
14759                    UNSPEC_FYL2XP1))
14760    (clobber (match_scratch:XF 3 "=2"))]
14761   "TARGET_USE_FANCY_MATH_387
14762    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14763        || TARGET_MIX_SSE_I387)
14764    && flag_unsafe_math_optimizations"
14765   "fyl2xp1"
14766   [(set_attr "type" "fpspc")
14767    (set_attr "mode" "XF")])
14769 (define_expand "log1pxf2"
14770   [(use (match_operand:XF 0 "register_operand"))
14771    (use (match_operand:XF 1 "register_operand"))]
14772   "TARGET_USE_FANCY_MATH_387
14773    && flag_unsafe_math_optimizations"
14775   if (optimize_insn_for_size_p ())
14776     FAIL;
14778   ix86_emit_i387_log1p (operands[0], operands[1]);
14779   DONE;
14782 (define_expand "log1p<mode>2"
14783   [(use (match_operand:MODEF 0 "register_operand"))
14784    (use (match_operand:MODEF 1 "register_operand"))]
14785   "TARGET_USE_FANCY_MATH_387
14786    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14787        || TARGET_MIX_SSE_I387)
14788    && flag_unsafe_math_optimizations"
14790   rtx op0;
14792   if (optimize_insn_for_size_p ())
14793     FAIL;
14795   op0 = gen_reg_rtx (XFmode);
14797   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14799   ix86_emit_i387_log1p (op0, operands[1]);
14800   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14801   DONE;
14804 (define_insn "fxtractxf3_i387"
14805   [(set (match_operand:XF 0 "register_operand" "=f")
14806         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14807                    UNSPEC_XTRACT_FRACT))
14808    (set (match_operand:XF 1 "register_operand" "=u")
14809         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14810   "TARGET_USE_FANCY_MATH_387
14811    && flag_unsafe_math_optimizations"
14812   "fxtract"
14813   [(set_attr "type" "fpspc")
14814    (set_attr "mode" "XF")])
14816 (define_insn "fxtract_extend<mode>xf3_i387"
14817   [(set (match_operand:XF 0 "register_operand" "=f")
14818         (unspec:XF [(float_extend:XF
14819                       (match_operand:MODEF 2 "register_operand" "0"))]
14820                    UNSPEC_XTRACT_FRACT))
14821    (set (match_operand:XF 1 "register_operand" "=u")
14822         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14823   "TARGET_USE_FANCY_MATH_387
14824    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14825        || TARGET_MIX_SSE_I387)
14826    && flag_unsafe_math_optimizations"
14827   "fxtract"
14828   [(set_attr "type" "fpspc")
14829    (set_attr "mode" "XF")])
14831 (define_expand "logbxf2"
14832   [(parallel [(set (match_dup 2)
14833                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14834                               UNSPEC_XTRACT_FRACT))
14835               (set (match_operand:XF 0 "register_operand")
14836                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14837   "TARGET_USE_FANCY_MATH_387
14838    && flag_unsafe_math_optimizations"
14839   "operands[2] = gen_reg_rtx (XFmode);")
14841 (define_expand "logb<mode>2"
14842   [(use (match_operand:MODEF 0 "register_operand"))
14843    (use (match_operand:MODEF 1 "register_operand"))]
14844   "TARGET_USE_FANCY_MATH_387
14845    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14846        || TARGET_MIX_SSE_I387)
14847    && flag_unsafe_math_optimizations"
14849   rtx op0 = gen_reg_rtx (XFmode);
14850   rtx op1 = gen_reg_rtx (XFmode);
14852   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14853   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14854   DONE;
14857 (define_expand "ilogbxf2"
14858   [(use (match_operand:SI 0 "register_operand"))
14859    (use (match_operand:XF 1 "register_operand"))]
14860   "TARGET_USE_FANCY_MATH_387
14861    && flag_unsafe_math_optimizations"
14863   rtx op0, op1;
14865   if (optimize_insn_for_size_p ())
14866     FAIL;
14868   op0 = gen_reg_rtx (XFmode);
14869   op1 = gen_reg_rtx (XFmode);
14871   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14872   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14873   DONE;
14876 (define_expand "ilogb<mode>2"
14877   [(use (match_operand:SI 0 "register_operand"))
14878    (use (match_operand:MODEF 1 "register_operand"))]
14879   "TARGET_USE_FANCY_MATH_387
14880    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14881        || TARGET_MIX_SSE_I387)
14882    && flag_unsafe_math_optimizations"
14884   rtx op0, op1;
14886   if (optimize_insn_for_size_p ())
14887     FAIL;
14889   op0 = gen_reg_rtx (XFmode);
14890   op1 = gen_reg_rtx (XFmode);
14892   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14893   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14894   DONE;
14897 (define_insn "*f2xm1xf2_i387"
14898   [(set (match_operand:XF 0 "register_operand" "=f")
14899         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14900                    UNSPEC_F2XM1))]
14901   "TARGET_USE_FANCY_MATH_387
14902    && flag_unsafe_math_optimizations"
14903   "f2xm1"
14904   [(set_attr "type" "fpspc")
14905    (set_attr "mode" "XF")])
14907 (define_insn "fscalexf4_i387"
14908   [(set (match_operand:XF 0 "register_operand" "=f")
14909         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14910                     (match_operand:XF 3 "register_operand" "1")]
14911                    UNSPEC_FSCALE_FRACT))
14912    (set (match_operand:XF 1 "register_operand" "=u")
14913         (unspec:XF [(match_dup 2) (match_dup 3)]
14914                    UNSPEC_FSCALE_EXP))]
14915   "TARGET_USE_FANCY_MATH_387
14916    && flag_unsafe_math_optimizations"
14917   "fscale"
14918   [(set_attr "type" "fpspc")
14919    (set_attr "mode" "XF")])
14921 (define_expand "expNcorexf3"
14922   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14923                                (match_operand:XF 2 "register_operand")))
14924    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14925    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14926    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14927    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14928    (parallel [(set (match_operand:XF 0 "register_operand")
14929                    (unspec:XF [(match_dup 8) (match_dup 4)]
14930                               UNSPEC_FSCALE_FRACT))
14931               (set (match_dup 9)
14932                    (unspec:XF [(match_dup 8) (match_dup 4)]
14933                               UNSPEC_FSCALE_EXP))])]
14934   "TARGET_USE_FANCY_MATH_387
14935    && flag_unsafe_math_optimizations"
14937   int i;
14939   if (optimize_insn_for_size_p ())
14940     FAIL;
14942   for (i = 3; i < 10; i++)
14943     operands[i] = gen_reg_rtx (XFmode);
14945   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14948 (define_expand "expxf2"
14949   [(use (match_operand:XF 0 "register_operand"))
14950    (use (match_operand:XF 1 "register_operand"))]
14951   "TARGET_USE_FANCY_MATH_387
14952    && flag_unsafe_math_optimizations"
14954   rtx op2;
14956   if (optimize_insn_for_size_p ())
14957     FAIL;
14959   op2 = gen_reg_rtx (XFmode);
14960   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14962   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14963   DONE;
14966 (define_expand "exp<mode>2"
14967   [(use (match_operand:MODEF 0 "register_operand"))
14968    (use (match_operand:MODEF 1 "general_operand"))]
14969  "TARGET_USE_FANCY_MATH_387
14970    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14971        || TARGET_MIX_SSE_I387)
14972    && flag_unsafe_math_optimizations"
14974   rtx op0, op1;
14976   if (optimize_insn_for_size_p ())
14977     FAIL;
14979   op0 = gen_reg_rtx (XFmode);
14980   op1 = gen_reg_rtx (XFmode);
14982   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14983   emit_insn (gen_expxf2 (op0, op1));
14984   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14985   DONE;
14988 (define_expand "exp10xf2"
14989   [(use (match_operand:XF 0 "register_operand"))
14990    (use (match_operand:XF 1 "register_operand"))]
14991   "TARGET_USE_FANCY_MATH_387
14992    && flag_unsafe_math_optimizations"
14994   rtx op2;
14996   if (optimize_insn_for_size_p ())
14997     FAIL;
14999   op2 = gen_reg_rtx (XFmode);
15000   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15002   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15003   DONE;
15006 (define_expand "exp10<mode>2"
15007   [(use (match_operand:MODEF 0 "register_operand"))
15008    (use (match_operand:MODEF 1 "general_operand"))]
15009  "TARGET_USE_FANCY_MATH_387
15010    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15011        || TARGET_MIX_SSE_I387)
15012    && flag_unsafe_math_optimizations"
15014   rtx op0, op1;
15016   if (optimize_insn_for_size_p ())
15017     FAIL;
15019   op0 = gen_reg_rtx (XFmode);
15020   op1 = gen_reg_rtx (XFmode);
15022   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15023   emit_insn (gen_exp10xf2 (op0, op1));
15024   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15025   DONE;
15028 (define_expand "exp2xf2"
15029   [(use (match_operand:XF 0 "register_operand"))
15030    (use (match_operand:XF 1 "register_operand"))]
15031   "TARGET_USE_FANCY_MATH_387
15032    && flag_unsafe_math_optimizations"
15034   rtx op2;
15036   if (optimize_insn_for_size_p ())
15037     FAIL;
15039   op2 = gen_reg_rtx (XFmode);
15040   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15042   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15043   DONE;
15046 (define_expand "exp2<mode>2"
15047   [(use (match_operand:MODEF 0 "register_operand"))
15048    (use (match_operand:MODEF 1 "general_operand"))]
15049  "TARGET_USE_FANCY_MATH_387
15050    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15051        || TARGET_MIX_SSE_I387)
15052    && flag_unsafe_math_optimizations"
15054   rtx op0, op1;
15056   if (optimize_insn_for_size_p ())
15057     FAIL;
15059   op0 = gen_reg_rtx (XFmode);
15060   op1 = gen_reg_rtx (XFmode);
15062   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15063   emit_insn (gen_exp2xf2 (op0, op1));
15064   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15065   DONE;
15068 (define_expand "expm1xf2"
15069   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15070                                (match_dup 2)))
15071    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15072    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15073    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15074    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15075    (parallel [(set (match_dup 7)
15076                    (unspec:XF [(match_dup 6) (match_dup 4)]
15077                               UNSPEC_FSCALE_FRACT))
15078               (set (match_dup 8)
15079                    (unspec:XF [(match_dup 6) (match_dup 4)]
15080                               UNSPEC_FSCALE_EXP))])
15081    (parallel [(set (match_dup 10)
15082                    (unspec:XF [(match_dup 9) (match_dup 8)]
15083                               UNSPEC_FSCALE_FRACT))
15084               (set (match_dup 11)
15085                    (unspec:XF [(match_dup 9) (match_dup 8)]
15086                               UNSPEC_FSCALE_EXP))])
15087    (set (match_dup 12) (minus:XF (match_dup 10)
15088                                  (float_extend:XF (match_dup 13))))
15089    (set (match_operand:XF 0 "register_operand")
15090         (plus:XF (match_dup 12) (match_dup 7)))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && flag_unsafe_math_optimizations"
15094   int i;
15096   if (optimize_insn_for_size_p ())
15097     FAIL;
15099   for (i = 2; i < 13; i++)
15100     operands[i] = gen_reg_rtx (XFmode);
15102   operands[13]
15103     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15105   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15108 (define_expand "expm1<mode>2"
15109   [(use (match_operand:MODEF 0 "register_operand"))
15110    (use (match_operand:MODEF 1 "general_operand"))]
15111  "TARGET_USE_FANCY_MATH_387
15112    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15113        || TARGET_MIX_SSE_I387)
15114    && flag_unsafe_math_optimizations"
15116   rtx op0, op1;
15118   if (optimize_insn_for_size_p ())
15119     FAIL;
15121   op0 = gen_reg_rtx (XFmode);
15122   op1 = gen_reg_rtx (XFmode);
15124   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15125   emit_insn (gen_expm1xf2 (op0, op1));
15126   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15127   DONE;
15130 (define_expand "ldexpxf3"
15131   [(match_operand:XF 0 "register_operand")
15132    (match_operand:XF 1 "register_operand")
15133    (match_operand:SI 2 "register_operand")]
15134   "TARGET_USE_FANCY_MATH_387
15135    && flag_unsafe_math_optimizations"
15137   rtx tmp1, tmp2;
15138   if (optimize_insn_for_size_p ())
15139     FAIL;
15141   tmp1 = gen_reg_rtx (XFmode);
15142   tmp2 = gen_reg_rtx (XFmode);
15144   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15145   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15146                                  operands[1], tmp1));
15147   DONE;
15150 (define_expand "ldexp<mode>3"
15151   [(use (match_operand:MODEF 0 "register_operand"))
15152    (use (match_operand:MODEF 1 "general_operand"))
15153    (use (match_operand:SI 2 "register_operand"))]
15154  "TARGET_USE_FANCY_MATH_387
15155    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15156        || TARGET_MIX_SSE_I387)
15157    && flag_unsafe_math_optimizations"
15159   rtx op0, op1;
15161   if (optimize_insn_for_size_p ())
15162     FAIL;
15164   op0 = gen_reg_rtx (XFmode);
15165   op1 = gen_reg_rtx (XFmode);
15167   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15168   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15169   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15170   DONE;
15173 (define_expand "scalbxf3"
15174   [(parallel [(set (match_operand:XF 0 " register_operand")
15175                    (unspec:XF [(match_operand:XF 1 "register_operand")
15176                                (match_operand:XF 2 "register_operand")]
15177                               UNSPEC_FSCALE_FRACT))
15178               (set (match_dup 3)
15179                    (unspec:XF [(match_dup 1) (match_dup 2)]
15180                               UNSPEC_FSCALE_EXP))])]
15181   "TARGET_USE_FANCY_MATH_387
15182    && flag_unsafe_math_optimizations"
15184   if (optimize_insn_for_size_p ())
15185     FAIL;
15187   operands[3] = gen_reg_rtx (XFmode);
15190 (define_expand "scalb<mode>3"
15191   [(use (match_operand:MODEF 0 "register_operand"))
15192    (use (match_operand:MODEF 1 "general_operand"))
15193    (use (match_operand:MODEF 2 "general_operand"))]
15194  "TARGET_USE_FANCY_MATH_387
15195    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15196        || TARGET_MIX_SSE_I387)
15197    && flag_unsafe_math_optimizations"
15199   rtx op0, op1, op2;
15201   if (optimize_insn_for_size_p ())
15202     FAIL;
15204   op0 = gen_reg_rtx (XFmode);
15205   op1 = gen_reg_rtx (XFmode);
15206   op2 = gen_reg_rtx (XFmode);
15208   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15209   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15210   emit_insn (gen_scalbxf3 (op0, op1, op2));
15211   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15212   DONE;
15215 (define_expand "significandxf2"
15216   [(parallel [(set (match_operand:XF 0 "register_operand")
15217                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15218                               UNSPEC_XTRACT_FRACT))
15219               (set (match_dup 2)
15220                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15221   "TARGET_USE_FANCY_MATH_387
15222    && flag_unsafe_math_optimizations"
15223   "operands[2] = gen_reg_rtx (XFmode);")
15225 (define_expand "significand<mode>2"
15226   [(use (match_operand:MODEF 0 "register_operand"))
15227    (use (match_operand:MODEF 1 "register_operand"))]
15228   "TARGET_USE_FANCY_MATH_387
15229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15230        || TARGET_MIX_SSE_I387)
15231    && flag_unsafe_math_optimizations"
15233   rtx op0 = gen_reg_rtx (XFmode);
15234   rtx op1 = gen_reg_rtx (XFmode);
15236   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15237   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15238   DONE;
15242 (define_insn "sse4_1_round<mode>2"
15243   [(set (match_operand:MODEF 0 "register_operand" "=x")
15244         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15245                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
15246                       UNSPEC_ROUND))]
15247   "TARGET_ROUND"
15248   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15249   [(set_attr "type" "ssecvt")
15250    (set_attr "prefix_extra" "1")
15251    (set_attr "prefix" "maybe_vex")
15252    (set_attr "mode" "<MODE>")])
15254 (define_insn "rintxf2"
15255   [(set (match_operand:XF 0 "register_operand" "=f")
15256         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15257                    UNSPEC_FRNDINT))]
15258   "TARGET_USE_FANCY_MATH_387
15259    && flag_unsafe_math_optimizations"
15260   "frndint"
15261   [(set_attr "type" "fpspc")
15262    (set_attr "mode" "XF")])
15264 (define_expand "rint<mode>2"
15265   [(use (match_operand:MODEF 0 "register_operand"))
15266    (use (match_operand:MODEF 1 "register_operand"))]
15267   "(TARGET_USE_FANCY_MATH_387
15268     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15269         || TARGET_MIX_SSE_I387)
15270     && flag_unsafe_math_optimizations)
15271    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15272        && !flag_trapping_math)"
15274   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15275       && !flag_trapping_math)
15276     {
15277       if (TARGET_ROUND)
15278         emit_insn (gen_sse4_1_round<mode>2
15279                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15280       else if (optimize_insn_for_size_p ())
15281         FAIL;
15282       else
15283         ix86_expand_rint (operands[0], operands[1]);
15284     }
15285   else
15286     {
15287       rtx op0 = gen_reg_rtx (XFmode);
15288       rtx op1 = gen_reg_rtx (XFmode);
15290       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15291       emit_insn (gen_rintxf2 (op0, op1));
15293       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15294     }
15295   DONE;
15298 (define_expand "round<mode>2"
15299   [(match_operand:X87MODEF 0 "register_operand")
15300    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15301   "(TARGET_USE_FANCY_MATH_387
15302     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15303         || TARGET_MIX_SSE_I387)
15304     && flag_unsafe_math_optimizations)
15305    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15306        && !flag_trapping_math && !flag_rounding_math)"
15308   if (optimize_insn_for_size_p ())
15309     FAIL;
15311   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15312       && !flag_trapping_math && !flag_rounding_math)
15313     {
15314       if (TARGET_ROUND)
15315         {
15316           operands[1] = force_reg (<MODE>mode, operands[1]);
15317           ix86_expand_round_sse4 (operands[0], operands[1]);
15318         }
15319       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15320         ix86_expand_round (operands[0], operands[1]);
15321       else
15322         ix86_expand_rounddf_32 (operands[0], operands[1]);
15323     }
15324   else
15325     {
15326       operands[1] = force_reg (<MODE>mode, operands[1]);
15327       ix86_emit_i387_round (operands[0], operands[1]);
15328     }
15329   DONE;
15332 (define_insn_and_split "*fistdi2_1"
15333   [(set (match_operand:DI 0 "nonimmediate_operand")
15334         (unspec:DI [(match_operand:XF 1 "register_operand")]
15335                    UNSPEC_FIST))]
15336   "TARGET_USE_FANCY_MATH_387
15337    && can_create_pseudo_p ()"
15338   "#"
15339   "&& 1"
15340   [(const_int 0)]
15342   if (memory_operand (operands[0], VOIDmode))
15343     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15344   else
15345     {
15346       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15347       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15348                                          operands[2]));
15349     }
15350   DONE;
15352   [(set_attr "type" "fpspc")
15353    (set_attr "mode" "DI")])
15355 (define_insn "fistdi2"
15356   [(set (match_operand:DI 0 "memory_operand" "=m")
15357         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15358                    UNSPEC_FIST))
15359    (clobber (match_scratch:XF 2 "=&1f"))]
15360   "TARGET_USE_FANCY_MATH_387"
15361   "* return output_fix_trunc (insn, operands, false);"
15362   [(set_attr "type" "fpspc")
15363    (set_attr "mode" "DI")])
15365 (define_insn "fistdi2_with_temp"
15366   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15367         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15368                    UNSPEC_FIST))
15369    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15370    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15371   "TARGET_USE_FANCY_MATH_387"
15372   "#"
15373   [(set_attr "type" "fpspc")
15374    (set_attr "mode" "DI")])
15376 (define_split
15377   [(set (match_operand:DI 0 "register_operand")
15378         (unspec:DI [(match_operand:XF 1 "register_operand")]
15379                    UNSPEC_FIST))
15380    (clobber (match_operand:DI 2 "memory_operand"))
15381    (clobber (match_scratch 3))]
15382   "reload_completed"
15383   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15384               (clobber (match_dup 3))])
15385    (set (match_dup 0) (match_dup 2))])
15387 (define_split
15388   [(set (match_operand:DI 0 "memory_operand")
15389         (unspec:DI [(match_operand:XF 1 "register_operand")]
15390                    UNSPEC_FIST))
15391    (clobber (match_operand:DI 2 "memory_operand"))
15392    (clobber (match_scratch 3))]
15393   "reload_completed"
15394   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15395               (clobber (match_dup 3))])])
15397 (define_insn_and_split "*fist<mode>2_1"
15398   [(set (match_operand:SWI24 0 "register_operand")
15399         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15400                       UNSPEC_FIST))]
15401   "TARGET_USE_FANCY_MATH_387
15402    && can_create_pseudo_p ()"
15403   "#"
15404   "&& 1"
15405   [(const_int 0)]
15407   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15408   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15409                                         operands[2]));
15410   DONE;
15412   [(set_attr "type" "fpspc")
15413    (set_attr "mode" "<MODE>")])
15415 (define_insn "fist<mode>2"
15416   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15417         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15418                       UNSPEC_FIST))]
15419   "TARGET_USE_FANCY_MATH_387"
15420   "* return output_fix_trunc (insn, operands, false);"
15421   [(set_attr "type" "fpspc")
15422    (set_attr "mode" "<MODE>")])
15424 (define_insn "fist<mode>2_with_temp"
15425   [(set (match_operand:SWI24 0 "register_operand" "=r")
15426         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15427                       UNSPEC_FIST))
15428    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15429   "TARGET_USE_FANCY_MATH_387"
15430   "#"
15431   [(set_attr "type" "fpspc")
15432    (set_attr "mode" "<MODE>")])
15434 (define_split
15435   [(set (match_operand:SWI24 0 "register_operand")
15436         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15437                       UNSPEC_FIST))
15438    (clobber (match_operand:SWI24 2 "memory_operand"))]
15439   "reload_completed"
15440   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15441    (set (match_dup 0) (match_dup 2))])
15443 (define_split
15444   [(set (match_operand:SWI24 0 "memory_operand")
15445         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15446                       UNSPEC_FIST))
15447    (clobber (match_operand:SWI24 2 "memory_operand"))]
15448   "reload_completed"
15449   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15451 (define_expand "lrintxf<mode>2"
15452   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15453      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15454                      UNSPEC_FIST))]
15455   "TARGET_USE_FANCY_MATH_387")
15457 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15458   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15459      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15460                    UNSPEC_FIX_NOTRUNC))]
15461   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15463 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15464   [(match_operand:SWI248x 0 "nonimmediate_operand")
15465    (match_operand:X87MODEF 1 "register_operand")]
15466   "(TARGET_USE_FANCY_MATH_387
15467     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15468         || TARGET_MIX_SSE_I387)
15469     && flag_unsafe_math_optimizations)
15470    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15471        && <SWI248x:MODE>mode != HImode 
15472        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15473        && !flag_trapping_math && !flag_rounding_math)"
15475   if (optimize_insn_for_size_p ())
15476     FAIL;
15478   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15479       && <SWI248x:MODE>mode != HImode
15480       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15481       && !flag_trapping_math && !flag_rounding_math)
15482     ix86_expand_lround (operands[0], operands[1]);
15483   else
15484     ix86_emit_i387_round (operands[0], operands[1]);
15485   DONE;
15488 (define_int_iterator FRNDINT_ROUNDING
15489         [UNSPEC_FRNDINT_FLOOR
15490          UNSPEC_FRNDINT_CEIL
15491          UNSPEC_FRNDINT_TRUNC])
15493 (define_int_iterator FIST_ROUNDING
15494         [UNSPEC_FIST_FLOOR
15495          UNSPEC_FIST_CEIL])
15497 ;; Base name for define_insn
15498 (define_int_attr rounding_insn
15499         [(UNSPEC_FRNDINT_FLOOR "floor")
15500          (UNSPEC_FRNDINT_CEIL "ceil")
15501          (UNSPEC_FRNDINT_TRUNC "btrunc")
15502          (UNSPEC_FIST_FLOOR "floor")
15503          (UNSPEC_FIST_CEIL "ceil")])
15505 (define_int_attr rounding
15506         [(UNSPEC_FRNDINT_FLOOR "floor")
15507          (UNSPEC_FRNDINT_CEIL "ceil")
15508          (UNSPEC_FRNDINT_TRUNC "trunc")
15509          (UNSPEC_FIST_FLOOR "floor")
15510          (UNSPEC_FIST_CEIL "ceil")])
15512 (define_int_attr ROUNDING
15513         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15514          (UNSPEC_FRNDINT_CEIL "CEIL")
15515          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15516          (UNSPEC_FIST_FLOOR "FLOOR")
15517          (UNSPEC_FIST_CEIL "CEIL")])
15519 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15520 (define_insn_and_split "frndintxf2_<rounding>"
15521   [(set (match_operand:XF 0 "register_operand")
15522         (unspec:XF [(match_operand:XF 1 "register_operand")]
15523                    FRNDINT_ROUNDING))
15524    (clobber (reg:CC FLAGS_REG))]
15525   "TARGET_USE_FANCY_MATH_387
15526    && flag_unsafe_math_optimizations
15527    && can_create_pseudo_p ()"
15528   "#"
15529   "&& 1"
15530   [(const_int 0)]
15532   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15534   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15535   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15537   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15538                                              operands[2], operands[3]));
15539   DONE;
15541   [(set_attr "type" "frndint")
15542    (set_attr "i387_cw" "<rounding>")
15543    (set_attr "mode" "XF")])
15545 (define_insn "frndintxf2_<rounding>_i387"
15546   [(set (match_operand:XF 0 "register_operand" "=f")
15547         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15548                    FRNDINT_ROUNDING))
15549    (use (match_operand:HI 2 "memory_operand" "m"))
15550    (use (match_operand:HI 3 "memory_operand" "m"))]
15551   "TARGET_USE_FANCY_MATH_387
15552    && flag_unsafe_math_optimizations"
15553   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15554   [(set_attr "type" "frndint")
15555    (set_attr "i387_cw" "<rounding>")
15556    (set_attr "mode" "XF")])
15558 (define_expand "<rounding_insn>xf2"
15559   [(parallel [(set (match_operand:XF 0 "register_operand")
15560                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15561                               FRNDINT_ROUNDING))
15562               (clobber (reg:CC FLAGS_REG))])]
15563   "TARGET_USE_FANCY_MATH_387
15564    && flag_unsafe_math_optimizations
15565    && !optimize_insn_for_size_p ()")
15567 (define_expand "<rounding_insn><mode>2"
15568   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15569                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15570                                  FRNDINT_ROUNDING))
15571               (clobber (reg:CC FLAGS_REG))])]
15572   "(TARGET_USE_FANCY_MATH_387
15573     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15574         || TARGET_MIX_SSE_I387)
15575     && flag_unsafe_math_optimizations)
15576    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15577        && !flag_trapping_math)"
15579   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15580       && !flag_trapping_math)
15581     {
15582       if (TARGET_ROUND)
15583         emit_insn (gen_sse4_1_round<mode>2
15584                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15585       else if (optimize_insn_for_size_p ())
15586         FAIL;
15587       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15588         {
15589           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15590             ix86_expand_floorceil (operands[0], operands[1], true);
15591           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15592             ix86_expand_floorceil (operands[0], operands[1], false);
15593           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15594             ix86_expand_trunc (operands[0], operands[1]);
15595           else
15596             gcc_unreachable ();
15597         }
15598       else
15599         {
15600           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15601             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15602           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15603             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15604           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15605             ix86_expand_truncdf_32 (operands[0], operands[1]);
15606           else
15607             gcc_unreachable ();
15608         }
15609     }
15610   else
15611     {
15612       rtx op0, op1;
15614       if (optimize_insn_for_size_p ())
15615         FAIL;
15617       op0 = gen_reg_rtx (XFmode);
15618       op1 = gen_reg_rtx (XFmode);
15619       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15620       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15622       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15623     }
15624   DONE;
15627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15628 (define_insn_and_split "frndintxf2_mask_pm"
15629   [(set (match_operand:XF 0 "register_operand")
15630         (unspec:XF [(match_operand:XF 1 "register_operand")]
15631                    UNSPEC_FRNDINT_MASK_PM))
15632    (clobber (reg:CC FLAGS_REG))]
15633   "TARGET_USE_FANCY_MATH_387
15634    && flag_unsafe_math_optimizations
15635    && can_create_pseudo_p ()"
15636   "#"
15637   "&& 1"
15638   [(const_int 0)]
15640   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15642   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15643   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15645   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15646                                           operands[2], operands[3]));
15647   DONE;
15649   [(set_attr "type" "frndint")
15650    (set_attr "i387_cw" "mask_pm")
15651    (set_attr "mode" "XF")])
15653 (define_insn "frndintxf2_mask_pm_i387"
15654   [(set (match_operand:XF 0 "register_operand" "=f")
15655         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15656                    UNSPEC_FRNDINT_MASK_PM))
15657    (use (match_operand:HI 2 "memory_operand" "m"))
15658    (use (match_operand:HI 3 "memory_operand" "m"))]
15659   "TARGET_USE_FANCY_MATH_387
15660    && flag_unsafe_math_optimizations"
15661   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15662   [(set_attr "type" "frndint")
15663    (set_attr "i387_cw" "mask_pm")
15664    (set_attr "mode" "XF")])
15666 (define_expand "nearbyintxf2"
15667   [(parallel [(set (match_operand:XF 0 "register_operand")
15668                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15669                               UNSPEC_FRNDINT_MASK_PM))
15670               (clobber (reg:CC FLAGS_REG))])]
15671   "TARGET_USE_FANCY_MATH_387
15672    && flag_unsafe_math_optimizations")
15674 (define_expand "nearbyint<mode>2"
15675   [(use (match_operand:MODEF 0 "register_operand"))
15676    (use (match_operand:MODEF 1 "register_operand"))]
15677   "TARGET_USE_FANCY_MATH_387
15678    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15679        || TARGET_MIX_SSE_I387)
15680    && flag_unsafe_math_optimizations"
15682   rtx op0 = gen_reg_rtx (XFmode);
15683   rtx op1 = gen_reg_rtx (XFmode);
15685   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15686   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15688   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15689   DONE;
15692 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15693 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15694   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15695         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15696                         FIST_ROUNDING))
15697    (clobber (reg:CC FLAGS_REG))]
15698   "TARGET_USE_FANCY_MATH_387
15699    && flag_unsafe_math_optimizations
15700    && can_create_pseudo_p ()"
15701   "#"
15702   "&& 1"
15703   [(const_int 0)]
15705   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15707   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15708   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15709   if (memory_operand (operands[0], VOIDmode))
15710     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15711                                            operands[2], operands[3]));
15712   else
15713     {
15714       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15715       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15716                   (operands[0], operands[1], operands[2],
15717                    operands[3], operands[4]));
15718     }
15719   DONE;
15721   [(set_attr "type" "fistp")
15722    (set_attr "i387_cw" "<rounding>")
15723    (set_attr "mode" "<MODE>")])
15725 (define_insn "fistdi2_<rounding>"
15726   [(set (match_operand:DI 0 "memory_operand" "=m")
15727         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15728                    FIST_ROUNDING))
15729    (use (match_operand:HI 2 "memory_operand" "m"))
15730    (use (match_operand:HI 3 "memory_operand" "m"))
15731    (clobber (match_scratch:XF 4 "=&1f"))]
15732   "TARGET_USE_FANCY_MATH_387
15733    && flag_unsafe_math_optimizations"
15734   "* return output_fix_trunc (insn, operands, false);"
15735   [(set_attr "type" "fistp")
15736    (set_attr "i387_cw" "<rounding>")
15737    (set_attr "mode" "DI")])
15739 (define_insn "fistdi2_<rounding>_with_temp"
15740   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15741         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15742                    FIST_ROUNDING))
15743    (use (match_operand:HI 2 "memory_operand" "m,m"))
15744    (use (match_operand:HI 3 "memory_operand" "m,m"))
15745    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15746    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15747   "TARGET_USE_FANCY_MATH_387
15748    && flag_unsafe_math_optimizations"
15749   "#"
15750   [(set_attr "type" "fistp")
15751    (set_attr "i387_cw" "<rounding>")
15752    (set_attr "mode" "DI")])
15754 (define_split
15755   [(set (match_operand:DI 0 "register_operand")
15756         (unspec:DI [(match_operand:XF 1 "register_operand")]
15757                    FIST_ROUNDING))
15758    (use (match_operand:HI 2 "memory_operand"))
15759    (use (match_operand:HI 3 "memory_operand"))
15760    (clobber (match_operand:DI 4 "memory_operand"))
15761    (clobber (match_scratch 5))]
15762   "reload_completed"
15763   [(parallel [(set (match_dup 4)
15764                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15765               (use (match_dup 2))
15766               (use (match_dup 3))
15767               (clobber (match_dup 5))])
15768    (set (match_dup 0) (match_dup 4))])
15770 (define_split
15771   [(set (match_operand:DI 0 "memory_operand")
15772         (unspec:DI [(match_operand:XF 1 "register_operand")]
15773                    FIST_ROUNDING))
15774    (use (match_operand:HI 2 "memory_operand"))
15775    (use (match_operand:HI 3 "memory_operand"))
15776    (clobber (match_operand:DI 4 "memory_operand"))
15777    (clobber (match_scratch 5))]
15778   "reload_completed"
15779   [(parallel [(set (match_dup 0)
15780                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15781               (use (match_dup 2))
15782               (use (match_dup 3))
15783               (clobber (match_dup 5))])])
15785 (define_insn "fist<mode>2_<rounding>"
15786   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15787         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15788                       FIST_ROUNDING))
15789    (use (match_operand:HI 2 "memory_operand" "m"))
15790    (use (match_operand:HI 3 "memory_operand" "m"))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15793   "* return output_fix_trunc (insn, operands, false);"
15794   [(set_attr "type" "fistp")
15795    (set_attr "i387_cw" "<rounding>")
15796    (set_attr "mode" "<MODE>")])
15798 (define_insn "fist<mode>2_<rounding>_with_temp"
15799   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15800         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15801                       FIST_ROUNDING))
15802    (use (match_operand:HI 2 "memory_operand" "m,m"))
15803    (use (match_operand:HI 3 "memory_operand" "m,m"))
15804    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15805   "TARGET_USE_FANCY_MATH_387
15806    && flag_unsafe_math_optimizations"
15807   "#"
15808   [(set_attr "type" "fistp")
15809    (set_attr "i387_cw" "<rounding>")
15810    (set_attr "mode" "<MODE>")])
15812 (define_split
15813   [(set (match_operand:SWI24 0 "register_operand")
15814         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15815                       FIST_ROUNDING))
15816    (use (match_operand:HI 2 "memory_operand"))
15817    (use (match_operand:HI 3 "memory_operand"))
15818    (clobber (match_operand:SWI24 4 "memory_operand"))]
15819   "reload_completed"
15820   [(parallel [(set (match_dup 4)
15821                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15822               (use (match_dup 2))
15823               (use (match_dup 3))])
15824    (set (match_dup 0) (match_dup 4))])
15826 (define_split
15827   [(set (match_operand:SWI24 0 "memory_operand")
15828         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15829                       FIST_ROUNDING))
15830    (use (match_operand:HI 2 "memory_operand"))
15831    (use (match_operand:HI 3 "memory_operand"))
15832    (clobber (match_operand:SWI24 4 "memory_operand"))]
15833   "reload_completed"
15834   [(parallel [(set (match_dup 0)
15835                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15836               (use (match_dup 2))
15837               (use (match_dup 3))])])
15839 (define_expand "l<rounding_insn>xf<mode>2"
15840   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15841                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15842                                    FIST_ROUNDING))
15843               (clobber (reg:CC FLAGS_REG))])]
15844   "TARGET_USE_FANCY_MATH_387
15845    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15846    && flag_unsafe_math_optimizations")
15848 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15849   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15850                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15851                                  FIST_ROUNDING))
15852               (clobber (reg:CC FLAGS_REG))])]
15853   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15854    && !flag_trapping_math"
15856   if (TARGET_64BIT && optimize_insn_for_size_p ())
15857     FAIL;
15859   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15860     ix86_expand_lfloorceil (operands[0], operands[1], true);
15861   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15862     ix86_expand_lfloorceil (operands[0], operands[1], false);
15863   else
15864     gcc_unreachable ();
15866   DONE;
15869 (define_insn "fxam<mode>2_i387"
15870   [(set (match_operand:HI 0 "register_operand" "=a")
15871         (unspec:HI
15872           [(match_operand:X87MODEF 1 "register_operand" "f")]
15873           UNSPEC_FXAM))]
15874   "TARGET_USE_FANCY_MATH_387"
15875   "fxam\n\tfnstsw\t%0"
15876   [(set_attr "type" "multi")
15877    (set_attr "length" "4")
15878    (set_attr "unit" "i387")
15879    (set_attr "mode" "<MODE>")])
15881 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15882   [(set (match_operand:HI 0 "register_operand")
15883         (unspec:HI
15884           [(match_operand:MODEF 1 "memory_operand")]
15885           UNSPEC_FXAM_MEM))]
15886   "TARGET_USE_FANCY_MATH_387
15887    && can_create_pseudo_p ()"
15888   "#"
15889   "&& 1"
15890   [(set (match_dup 2)(match_dup 1))
15891    (set (match_dup 0)
15892         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15894   operands[2] = gen_reg_rtx (<MODE>mode);
15896   MEM_VOLATILE_P (operands[1]) = 1;
15898   [(set_attr "type" "multi")
15899    (set_attr "unit" "i387")
15900    (set_attr "mode" "<MODE>")])
15902 (define_expand "isinfxf2"
15903   [(use (match_operand:SI 0 "register_operand"))
15904    (use (match_operand:XF 1 "register_operand"))]
15905   "TARGET_USE_FANCY_MATH_387
15906    && ix86_libc_has_function (function_c99_misc)"
15908   rtx mask = GEN_INT (0x45);
15909   rtx val = GEN_INT (0x05);
15911   rtx cond;
15913   rtx scratch = gen_reg_rtx (HImode);
15914   rtx res = gen_reg_rtx (QImode);
15916   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15918   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15919   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15920   cond = gen_rtx_fmt_ee (EQ, QImode,
15921                          gen_rtx_REG (CCmode, FLAGS_REG),
15922                          const0_rtx);
15923   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15924   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15925   DONE;
15928 (define_expand "isinf<mode>2"
15929   [(use (match_operand:SI 0 "register_operand"))
15930    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15931   "TARGET_USE_FANCY_MATH_387
15932    && ix86_libc_has_function (function_c99_misc)
15933    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15935   rtx mask = GEN_INT (0x45);
15936   rtx val = GEN_INT (0x05);
15938   rtx cond;
15940   rtx scratch = gen_reg_rtx (HImode);
15941   rtx res = gen_reg_rtx (QImode);
15943   /* Remove excess precision by forcing value through memory. */
15944   if (memory_operand (operands[1], VOIDmode))
15945     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15946   else
15947     {
15948       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15950       emit_move_insn (temp, operands[1]);
15951       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15952     }
15954   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15955   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15956   cond = gen_rtx_fmt_ee (EQ, QImode,
15957                          gen_rtx_REG (CCmode, FLAGS_REG),
15958                          const0_rtx);
15959   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15960   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15961   DONE;
15964 (define_expand "signbitxf2"
15965   [(use (match_operand:SI 0 "register_operand"))
15966    (use (match_operand:XF 1 "register_operand"))]
15967   "TARGET_USE_FANCY_MATH_387"
15969   rtx scratch = gen_reg_rtx (HImode);
15971   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15972   emit_insn (gen_andsi3 (operands[0],
15973              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15974   DONE;
15977 (define_insn "movmsk_df"
15978   [(set (match_operand:SI 0 "register_operand" "=r")
15979         (unspec:SI
15980           [(match_operand:DF 1 "register_operand" "x")]
15981           UNSPEC_MOVMSK))]
15982   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15983   "%vmovmskpd\t{%1, %0|%0, %1}"
15984   [(set_attr "type" "ssemov")
15985    (set_attr "prefix" "maybe_vex")
15986    (set_attr "mode" "DF")])
15988 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15989 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15990 (define_expand "signbitdf2"
15991   [(use (match_operand:SI 0 "register_operand"))
15992    (use (match_operand:DF 1 "register_operand"))]
15993   "TARGET_USE_FANCY_MATH_387
15994    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15996   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15997     {
15998       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15999       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16000     }
16001   else
16002     {
16003       rtx scratch = gen_reg_rtx (HImode);
16005       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16006       emit_insn (gen_andsi3 (operands[0],
16007                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16008     }
16009   DONE;
16012 (define_expand "signbitsf2"
16013   [(use (match_operand:SI 0 "register_operand"))
16014    (use (match_operand:SF 1 "register_operand"))]
16015   "TARGET_USE_FANCY_MATH_387
16016    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16018   rtx scratch = gen_reg_rtx (HImode);
16020   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16021   emit_insn (gen_andsi3 (operands[0],
16022              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16023   DONE;
16026 ;; Block operation instructions
16028 (define_insn "cld"
16029   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16030   ""
16031   "cld"
16032   [(set_attr "length" "1")
16033    (set_attr "length_immediate" "0")
16034    (set_attr "modrm" "0")])
16036 (define_expand "movmem<mode>"
16037   [(use (match_operand:BLK 0 "memory_operand"))
16038    (use (match_operand:BLK 1 "memory_operand"))
16039    (use (match_operand:SWI48 2 "nonmemory_operand"))
16040    (use (match_operand:SWI48 3 "const_int_operand"))
16041    (use (match_operand:SI 4 "const_int_operand"))
16042    (use (match_operand:SI 5 "const_int_operand"))
16043    (use (match_operand:SI 6 ""))
16044    (use (match_operand:SI 7 ""))
16045    (use (match_operand:SI 8 ""))]
16046   ""
16048  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16049                                 operands[2], NULL, operands[3],
16050                                 operands[4], operands[5],
16051                                 operands[6], operands[7],
16052                                 operands[8], false))
16053    DONE;
16054  else
16055    FAIL;
16058 ;; Most CPUs don't like single string operations
16059 ;; Handle this case here to simplify previous expander.
16061 (define_expand "strmov"
16062   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16063    (set (match_operand 1 "memory_operand") (match_dup 4))
16064    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16065               (clobber (reg:CC FLAGS_REG))])
16066    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16067               (clobber (reg:CC FLAGS_REG))])]
16068   ""
16070   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16072   /* If .md ever supports :P for Pmode, these can be directly
16073      in the pattern above.  */
16074   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16075   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16077   /* Can't use this if the user has appropriated esi or edi.  */
16078   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16079       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16080     {
16081       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16082                                       operands[2], operands[3],
16083                                       operands[5], operands[6]));
16084       DONE;
16085     }
16087   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16090 (define_expand "strmov_singleop"
16091   [(parallel [(set (match_operand 1 "memory_operand")
16092                    (match_operand 3 "memory_operand"))
16093               (set (match_operand 0 "register_operand")
16094                    (match_operand 4))
16095               (set (match_operand 2 "register_operand")
16096                    (match_operand 5))])]
16097   ""
16098   "ix86_current_function_needs_cld = 1;")
16100 (define_insn "*strmovdi_rex_1"
16101   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16102         (mem:DI (match_operand:P 3 "register_operand" "1")))
16103    (set (match_operand:P 0 "register_operand" "=D")
16104         (plus:P (match_dup 2)
16105                 (const_int 8)))
16106    (set (match_operand:P 1 "register_operand" "=S")
16107         (plus:P (match_dup 3)
16108                 (const_int 8)))]
16109   "TARGET_64BIT
16110    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16111   "%^movsq"
16112   [(set_attr "type" "str")
16113    (set_attr "memory" "both")
16114    (set_attr "mode" "DI")])
16116 (define_insn "*strmovsi_1"
16117   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16118         (mem:SI (match_operand:P 3 "register_operand" "1")))
16119    (set (match_operand:P 0 "register_operand" "=D")
16120         (plus:P (match_dup 2)
16121                 (const_int 4)))
16122    (set (match_operand:P 1 "register_operand" "=S")
16123         (plus:P (match_dup 3)
16124                 (const_int 4)))]
16125   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16126   "%^movs{l|d}"
16127   [(set_attr "type" "str")
16128    (set_attr "memory" "both")
16129    (set_attr "mode" "SI")])
16131 (define_insn "*strmovhi_1"
16132   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16133         (mem:HI (match_operand:P 3 "register_operand" "1")))
16134    (set (match_operand:P 0 "register_operand" "=D")
16135         (plus:P (match_dup 2)
16136                 (const_int 2)))
16137    (set (match_operand:P 1 "register_operand" "=S")
16138         (plus:P (match_dup 3)
16139                 (const_int 2)))]
16140   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16141   "%^movsw"
16142   [(set_attr "type" "str")
16143    (set_attr "memory" "both")
16144    (set_attr "mode" "HI")])
16146 (define_insn "*strmovqi_1"
16147   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16148         (mem:QI (match_operand:P 3 "register_operand" "1")))
16149    (set (match_operand:P 0 "register_operand" "=D")
16150         (plus:P (match_dup 2)
16151                 (const_int 1)))
16152    (set (match_operand:P 1 "register_operand" "=S")
16153         (plus:P (match_dup 3)
16154                 (const_int 1)))]
16155   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16156   "%^movsb"
16157   [(set_attr "type" "str")
16158    (set_attr "memory" "both")
16159    (set (attr "prefix_rex")
16160         (if_then_else
16161           (match_test "<P:MODE>mode == DImode")
16162           (const_string "0")
16163           (const_string "*")))
16164    (set_attr "mode" "QI")])
16166 (define_expand "rep_mov"
16167   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16168               (set (match_operand 0 "register_operand")
16169                    (match_operand 5))
16170               (set (match_operand 2 "register_operand")
16171                    (match_operand 6))
16172               (set (match_operand 1 "memory_operand")
16173                    (match_operand 3 "memory_operand"))
16174               (use (match_dup 4))])]
16175   ""
16176   "ix86_current_function_needs_cld = 1;")
16178 (define_insn "*rep_movdi_rex64"
16179   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16180    (set (match_operand:P 0 "register_operand" "=D")
16181         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16182                           (const_int 3))
16183                 (match_operand:P 3 "register_operand" "0")))
16184    (set (match_operand:P 1 "register_operand" "=S")
16185         (plus:P (ashift:P (match_dup 5) (const_int 3))
16186                 (match_operand:P 4 "register_operand" "1")))
16187    (set (mem:BLK (match_dup 3))
16188         (mem:BLK (match_dup 4)))
16189    (use (match_dup 5))]
16190   "TARGET_64BIT
16191    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16192   "%^rep{%;} movsq"
16193   [(set_attr "type" "str")
16194    (set_attr "prefix_rep" "1")
16195    (set_attr "memory" "both")
16196    (set_attr "mode" "DI")])
16198 (define_insn "*rep_movsi"
16199   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16200    (set (match_operand:P 0 "register_operand" "=D")
16201         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16202                           (const_int 2))
16203                  (match_operand:P 3 "register_operand" "0")))
16204    (set (match_operand:P 1 "register_operand" "=S")
16205         (plus:P (ashift:P (match_dup 5) (const_int 2))
16206                 (match_operand:P 4 "register_operand" "1")))
16207    (set (mem:BLK (match_dup 3))
16208         (mem:BLK (match_dup 4)))
16209    (use (match_dup 5))]
16210   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16211   "%^rep{%;} movs{l|d}"
16212   [(set_attr "type" "str")
16213    (set_attr "prefix_rep" "1")
16214    (set_attr "memory" "both")
16215    (set_attr "mode" "SI")])
16217 (define_insn "*rep_movqi"
16218   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16219    (set (match_operand:P 0 "register_operand" "=D")
16220         (plus:P (match_operand:P 3 "register_operand" "0")
16221                 (match_operand:P 5 "register_operand" "2")))
16222    (set (match_operand:P 1 "register_operand" "=S")
16223         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16224    (set (mem:BLK (match_dup 3))
16225         (mem:BLK (match_dup 4)))
16226    (use (match_dup 5))]
16227   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16228   "%^rep{%;} movsb"
16229   [(set_attr "type" "str")
16230    (set_attr "prefix_rep" "1")
16231    (set_attr "memory" "both")
16232    (set_attr "mode" "QI")])
16234 (define_expand "setmem<mode>"
16235    [(use (match_operand:BLK 0 "memory_operand"))
16236     (use (match_operand:SWI48 1 "nonmemory_operand"))
16237     (use (match_operand:QI 2 "nonmemory_operand"))
16238     (use (match_operand 3 "const_int_operand"))
16239     (use (match_operand:SI 4 "const_int_operand"))
16240     (use (match_operand:SI 5 "const_int_operand"))
16241     (use (match_operand:SI 6 ""))
16242     (use (match_operand:SI 7 ""))
16243     (use (match_operand:SI 8 ""))]
16244   ""
16246  if (ix86_expand_set_or_movmem (operands[0], NULL,
16247                                 operands[1], operands[2],
16248                                 operands[3], operands[4],
16249                                 operands[5], operands[6],
16250                                 operands[7], operands[8], true))
16251    DONE;
16252  else
16253    FAIL;
16256 ;; Most CPUs don't like single string operations
16257 ;; Handle this case here to simplify previous expander.
16259 (define_expand "strset"
16260   [(set (match_operand 1 "memory_operand")
16261         (match_operand 2 "register_operand"))
16262    (parallel [(set (match_operand 0 "register_operand")
16263                    (match_dup 3))
16264               (clobber (reg:CC FLAGS_REG))])]
16265   ""
16267   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16268     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16270   /* If .md ever supports :P for Pmode, this can be directly
16271      in the pattern above.  */
16272   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16273                               GEN_INT (GET_MODE_SIZE (GET_MODE
16274                                                       (operands[2]))));
16275   /* Can't use this if the user has appropriated eax or edi.  */
16276   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16277       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16278     {
16279       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16280                                       operands[3]));
16281       DONE;
16282     }
16285 (define_expand "strset_singleop"
16286   [(parallel [(set (match_operand 1 "memory_operand")
16287                    (match_operand 2 "register_operand"))
16288               (set (match_operand 0 "register_operand")
16289                    (match_operand 3))
16290               (unspec [(const_int 0)] UNSPEC_STOS)])]
16291   ""
16292   "ix86_current_function_needs_cld = 1;")
16294 (define_insn "*strsetdi_rex_1"
16295   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16296         (match_operand:DI 2 "register_operand" "a"))
16297    (set (match_operand:P 0 "register_operand" "=D")
16298         (plus:P (match_dup 1)
16299                 (const_int 8)))
16300    (unspec [(const_int 0)] UNSPEC_STOS)]
16301   "TARGET_64BIT
16302    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16303   "%^stosq"
16304   [(set_attr "type" "str")
16305    (set_attr "memory" "store")
16306    (set_attr "mode" "DI")])
16308 (define_insn "*strsetsi_1"
16309   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16310         (match_operand:SI 2 "register_operand" "a"))
16311    (set (match_operand:P 0 "register_operand" "=D")
16312         (plus:P (match_dup 1)
16313                 (const_int 4)))
16314    (unspec [(const_int 0)] UNSPEC_STOS)]
16315   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16316   "%^stos{l|d}"
16317   [(set_attr "type" "str")
16318    (set_attr "memory" "store")
16319    (set_attr "mode" "SI")])
16321 (define_insn "*strsethi_1"
16322   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16323         (match_operand:HI 2 "register_operand" "a"))
16324    (set (match_operand:P 0 "register_operand" "=D")
16325         (plus:P (match_dup 1)
16326                 (const_int 2)))
16327    (unspec [(const_int 0)] UNSPEC_STOS)]
16328   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16329   "%^stosw"
16330   [(set_attr "type" "str")
16331    (set_attr "memory" "store")
16332    (set_attr "mode" "HI")])
16334 (define_insn "*strsetqi_1"
16335   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16336         (match_operand:QI 2 "register_operand" "a"))
16337    (set (match_operand:P 0 "register_operand" "=D")
16338         (plus:P (match_dup 1)
16339                 (const_int 1)))
16340    (unspec [(const_int 0)] UNSPEC_STOS)]
16341   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16342   "%^stosb"
16343   [(set_attr "type" "str")
16344    (set_attr "memory" "store")
16345    (set (attr "prefix_rex")
16346         (if_then_else
16347           (match_test "<P:MODE>mode == DImode")
16348           (const_string "0")
16349           (const_string "*")))
16350    (set_attr "mode" "QI")])
16352 (define_expand "rep_stos"
16353   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16354               (set (match_operand 0 "register_operand")
16355                    (match_operand 4))
16356               (set (match_operand 2 "memory_operand") (const_int 0))
16357               (use (match_operand 3 "register_operand"))
16358               (use (match_dup 1))])]
16359   ""
16360   "ix86_current_function_needs_cld = 1;")
16362 (define_insn "*rep_stosdi_rex64"
16363   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16364    (set (match_operand:P 0 "register_operand" "=D")
16365         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16366                           (const_int 3))
16367                  (match_operand:P 3 "register_operand" "0")))
16368    (set (mem:BLK (match_dup 3))
16369         (const_int 0))
16370    (use (match_operand:DI 2 "register_operand" "a"))
16371    (use (match_dup 4))]
16372   "TARGET_64BIT
16373    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16374   "%^rep{%;} stosq"
16375   [(set_attr "type" "str")
16376    (set_attr "prefix_rep" "1")
16377    (set_attr "memory" "store")
16378    (set_attr "mode" "DI")])
16380 (define_insn "*rep_stossi"
16381   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16382    (set (match_operand:P 0 "register_operand" "=D")
16383         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16384                           (const_int 2))
16385                  (match_operand:P 3 "register_operand" "0")))
16386    (set (mem:BLK (match_dup 3))
16387         (const_int 0))
16388    (use (match_operand:SI 2 "register_operand" "a"))
16389    (use (match_dup 4))]
16390   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16391   "%^rep{%;} stos{l|d}"
16392   [(set_attr "type" "str")
16393    (set_attr "prefix_rep" "1")
16394    (set_attr "memory" "store")
16395    (set_attr "mode" "SI")])
16397 (define_insn "*rep_stosqi"
16398   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16399    (set (match_operand:P 0 "register_operand" "=D")
16400         (plus:P (match_operand:P 3 "register_operand" "0")
16401                 (match_operand:P 4 "register_operand" "1")))
16402    (set (mem:BLK (match_dup 3))
16403         (const_int 0))
16404    (use (match_operand:QI 2 "register_operand" "a"))
16405    (use (match_dup 4))]
16406   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16407   "%^rep{%;} stosb"
16408   [(set_attr "type" "str")
16409    (set_attr "prefix_rep" "1")
16410    (set_attr "memory" "store")
16411    (set (attr "prefix_rex")
16412         (if_then_else
16413           (match_test "<P:MODE>mode == DImode")
16414           (const_string "0")
16415           (const_string "*")))
16416    (set_attr "mode" "QI")])
16418 (define_expand "cmpstrnsi"
16419   [(set (match_operand:SI 0 "register_operand")
16420         (compare:SI (match_operand:BLK 1 "general_operand")
16421                     (match_operand:BLK 2 "general_operand")))
16422    (use (match_operand 3 "general_operand"))
16423    (use (match_operand 4 "immediate_operand"))]
16424   ""
16426   rtx addr1, addr2, out, outlow, count, countreg, align;
16428   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16429     FAIL;
16431   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16432   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16433     FAIL;
16435   out = operands[0];
16436   if (!REG_P (out))
16437     out = gen_reg_rtx (SImode);
16439   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16440   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16441   if (addr1 != XEXP (operands[1], 0))
16442     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16443   if (addr2 != XEXP (operands[2], 0))
16444     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16446   count = operands[3];
16447   countreg = ix86_zero_extend_to_Pmode (count);
16449   /* %%% Iff we are testing strict equality, we can use known alignment
16450      to good advantage.  This may be possible with combine, particularly
16451      once cc0 is dead.  */
16452   align = operands[4];
16454   if (CONST_INT_P (count))
16455     {
16456       if (INTVAL (count) == 0)
16457         {
16458           emit_move_insn (operands[0], const0_rtx);
16459           DONE;
16460         }
16461       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16462                                      operands[1], operands[2]));
16463     }
16464   else
16465     {
16466       rtx (*gen_cmp) (rtx, rtx);
16468       gen_cmp = (TARGET_64BIT
16469                  ? gen_cmpdi_1 : gen_cmpsi_1);
16471       emit_insn (gen_cmp (countreg, countreg));
16472       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16473                                   operands[1], operands[2]));
16474     }
16476   outlow = gen_lowpart (QImode, out);
16477   emit_insn (gen_cmpintqi (outlow));
16478   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16480   if (operands[0] != out)
16481     emit_move_insn (operands[0], out);
16483   DONE;
16486 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16488 (define_expand "cmpintqi"
16489   [(set (match_dup 1)
16490         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16491    (set (match_dup 2)
16492         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16493    (parallel [(set (match_operand:QI 0 "register_operand")
16494                    (minus:QI (match_dup 1)
16495                              (match_dup 2)))
16496               (clobber (reg:CC FLAGS_REG))])]
16497   ""
16499   operands[1] = gen_reg_rtx (QImode);
16500   operands[2] = gen_reg_rtx (QImode);
16503 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16504 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16506 (define_expand "cmpstrnqi_nz_1"
16507   [(parallel [(set (reg:CC FLAGS_REG)
16508                    (compare:CC (match_operand 4 "memory_operand")
16509                                (match_operand 5 "memory_operand")))
16510               (use (match_operand 2 "register_operand"))
16511               (use (match_operand:SI 3 "immediate_operand"))
16512               (clobber (match_operand 0 "register_operand"))
16513               (clobber (match_operand 1 "register_operand"))
16514               (clobber (match_dup 2))])]
16515   ""
16516   "ix86_current_function_needs_cld = 1;")
16518 (define_insn "*cmpstrnqi_nz_1"
16519   [(set (reg:CC FLAGS_REG)
16520         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16521                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16522    (use (match_operand:P 6 "register_operand" "2"))
16523    (use (match_operand:SI 3 "immediate_operand" "i"))
16524    (clobber (match_operand:P 0 "register_operand" "=S"))
16525    (clobber (match_operand:P 1 "register_operand" "=D"))
16526    (clobber (match_operand:P 2 "register_operand" "=c"))]
16527   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16528   "%^repz{%;} cmpsb"
16529   [(set_attr "type" "str")
16530    (set_attr "mode" "QI")
16531    (set (attr "prefix_rex")
16532         (if_then_else
16533           (match_test "<P:MODE>mode == DImode")
16534           (const_string "0")
16535           (const_string "*")))
16536    (set_attr "prefix_rep" "1")])
16538 ;; The same, but the count is not known to not be zero.
16540 (define_expand "cmpstrnqi_1"
16541   [(parallel [(set (reg:CC FLAGS_REG)
16542                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16543                                      (const_int 0))
16544                   (compare:CC (match_operand 4 "memory_operand")
16545                               (match_operand 5 "memory_operand"))
16546                   (const_int 0)))
16547               (use (match_operand:SI 3 "immediate_operand"))
16548               (use (reg:CC FLAGS_REG))
16549               (clobber (match_operand 0 "register_operand"))
16550               (clobber (match_operand 1 "register_operand"))
16551               (clobber (match_dup 2))])]
16552   ""
16553   "ix86_current_function_needs_cld = 1;")
16555 (define_insn "*cmpstrnqi_1"
16556   [(set (reg:CC FLAGS_REG)
16557         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16558                              (const_int 0))
16559           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16560                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16561           (const_int 0)))
16562    (use (match_operand:SI 3 "immediate_operand" "i"))
16563    (use (reg:CC FLAGS_REG))
16564    (clobber (match_operand:P 0 "register_operand" "=S"))
16565    (clobber (match_operand:P 1 "register_operand" "=D"))
16566    (clobber (match_operand:P 2 "register_operand" "=c"))]
16567   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16568   "%^repz{%;} cmpsb"
16569   [(set_attr "type" "str")
16570    (set_attr "mode" "QI")
16571    (set (attr "prefix_rex")
16572         (if_then_else
16573           (match_test "<P:MODE>mode == DImode")
16574           (const_string "0")
16575           (const_string "*")))
16576    (set_attr "prefix_rep" "1")])
16578 (define_expand "strlen<mode>"
16579   [(set (match_operand:P 0 "register_operand")
16580         (unspec:P [(match_operand:BLK 1 "general_operand")
16581                    (match_operand:QI 2 "immediate_operand")
16582                    (match_operand 3 "immediate_operand")]
16583                   UNSPEC_SCAS))]
16584   ""
16586  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16587    DONE;
16588  else
16589    FAIL;
16592 (define_expand "strlenqi_1"
16593   [(parallel [(set (match_operand 0 "register_operand")
16594                    (match_operand 2))
16595               (clobber (match_operand 1 "register_operand"))
16596               (clobber (reg:CC FLAGS_REG))])]
16597   ""
16598   "ix86_current_function_needs_cld = 1;")
16600 (define_insn "*strlenqi_1"
16601   [(set (match_operand:P 0 "register_operand" "=&c")
16602         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16603                    (match_operand:QI 2 "register_operand" "a")
16604                    (match_operand:P 3 "immediate_operand" "i")
16605                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16606    (clobber (match_operand:P 1 "register_operand" "=D"))
16607    (clobber (reg:CC FLAGS_REG))]
16608   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16609   "%^repnz{%;} scasb"
16610   [(set_attr "type" "str")
16611    (set_attr "mode" "QI")
16612    (set (attr "prefix_rex")
16613         (if_then_else
16614           (match_test "<P:MODE>mode == DImode")
16615           (const_string "0")
16616           (const_string "*")))
16617    (set_attr "prefix_rep" "1")])
16619 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16620 ;; handled in combine, but it is not currently up to the task.
16621 ;; When used for their truth value, the cmpstrn* expanders generate
16622 ;; code like this:
16624 ;;   repz cmpsb
16625 ;;   seta       %al
16626 ;;   setb       %dl
16627 ;;   cmpb       %al, %dl
16628 ;;   jcc        label
16630 ;; The intermediate three instructions are unnecessary.
16632 ;; This one handles cmpstrn*_nz_1...
16633 (define_peephole2
16634   [(parallel[
16635      (set (reg:CC FLAGS_REG)
16636           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16637                       (mem:BLK (match_operand 5 "register_operand"))))
16638      (use (match_operand 6 "register_operand"))
16639      (use (match_operand:SI 3 "immediate_operand"))
16640      (clobber (match_operand 0 "register_operand"))
16641      (clobber (match_operand 1 "register_operand"))
16642      (clobber (match_operand 2 "register_operand"))])
16643    (set (match_operand:QI 7 "register_operand")
16644         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16645    (set (match_operand:QI 8 "register_operand")
16646         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16647    (set (reg FLAGS_REG)
16648         (compare (match_dup 7) (match_dup 8)))
16649   ]
16650   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16651   [(parallel[
16652      (set (reg:CC FLAGS_REG)
16653           (compare:CC (mem:BLK (match_dup 4))
16654                       (mem:BLK (match_dup 5))))
16655      (use (match_dup 6))
16656      (use (match_dup 3))
16657      (clobber (match_dup 0))
16658      (clobber (match_dup 1))
16659      (clobber (match_dup 2))])])
16661 ;; ...and this one handles cmpstrn*_1.
16662 (define_peephole2
16663   [(parallel[
16664      (set (reg:CC FLAGS_REG)
16665           (if_then_else:CC (ne (match_operand 6 "register_operand")
16666                                (const_int 0))
16667             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16668                         (mem:BLK (match_operand 5 "register_operand")))
16669             (const_int 0)))
16670      (use (match_operand:SI 3 "immediate_operand"))
16671      (use (reg:CC FLAGS_REG))
16672      (clobber (match_operand 0 "register_operand"))
16673      (clobber (match_operand 1 "register_operand"))
16674      (clobber (match_operand 2 "register_operand"))])
16675    (set (match_operand:QI 7 "register_operand")
16676         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16677    (set (match_operand:QI 8 "register_operand")
16678         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16679    (set (reg FLAGS_REG)
16680         (compare (match_dup 7) (match_dup 8)))
16681   ]
16682   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16683   [(parallel[
16684      (set (reg:CC FLAGS_REG)
16685           (if_then_else:CC (ne (match_dup 6)
16686                                (const_int 0))
16687             (compare:CC (mem:BLK (match_dup 4))
16688                         (mem:BLK (match_dup 5)))
16689             (const_int 0)))
16690      (use (match_dup 3))
16691      (use (reg:CC FLAGS_REG))
16692      (clobber (match_dup 0))
16693      (clobber (match_dup 1))
16694      (clobber (match_dup 2))])])
16696 ;; Conditional move instructions.
16698 (define_expand "mov<mode>cc"
16699   [(set (match_operand:SWIM 0 "register_operand")
16700         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16701                            (match_operand:SWIM 2 "<general_operand>")
16702                            (match_operand:SWIM 3 "<general_operand>")))]
16703   ""
16704   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16706 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16707 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16708 ;; So just document what we're doing explicitly.
16710 (define_expand "x86_mov<mode>cc_0_m1"
16711   [(parallel
16712     [(set (match_operand:SWI48 0 "register_operand")
16713           (if_then_else:SWI48
16714             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16715              [(match_operand 1 "flags_reg_operand")
16716               (const_int 0)])
16717             (const_int -1)
16718             (const_int 0)))
16719      (clobber (reg:CC FLAGS_REG))])])
16721 (define_insn "*x86_mov<mode>cc_0_m1"
16722   [(set (match_operand:SWI48 0 "register_operand" "=r")
16723         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16724                              [(reg FLAGS_REG) (const_int 0)])
16725           (const_int -1)
16726           (const_int 0)))
16727    (clobber (reg:CC FLAGS_REG))]
16728   ""
16729   "sbb{<imodesuffix>}\t%0, %0"
16730   ; Since we don't have the proper number of operands for an alu insn,
16731   ; fill in all the blanks.
16732   [(set_attr "type" "alu")
16733    (set_attr "use_carry" "1")
16734    (set_attr "pent_pair" "pu")
16735    (set_attr "memory" "none")
16736    (set_attr "imm_disp" "false")
16737    (set_attr "mode" "<MODE>")
16738    (set_attr "length_immediate" "0")])
16740 (define_insn "*x86_mov<mode>cc_0_m1_se"
16741   [(set (match_operand:SWI48 0 "register_operand" "=r")
16742         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16743                              [(reg FLAGS_REG) (const_int 0)])
16744                             (const_int 1)
16745                             (const_int 0)))
16746    (clobber (reg:CC FLAGS_REG))]
16747   ""
16748   "sbb{<imodesuffix>}\t%0, %0"
16749   [(set_attr "type" "alu")
16750    (set_attr "use_carry" "1")
16751    (set_attr "pent_pair" "pu")
16752    (set_attr "memory" "none")
16753    (set_attr "imm_disp" "false")
16754    (set_attr "mode" "<MODE>")
16755    (set_attr "length_immediate" "0")])
16757 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16758   [(set (match_operand:SWI48 0 "register_operand" "=r")
16759         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16760                     [(reg FLAGS_REG) (const_int 0)])))
16761    (clobber (reg:CC FLAGS_REG))]
16762   ""
16763   "sbb{<imodesuffix>}\t%0, %0"
16764   [(set_attr "type" "alu")
16765    (set_attr "use_carry" "1")
16766    (set_attr "pent_pair" "pu")
16767    (set_attr "memory" "none")
16768    (set_attr "imm_disp" "false")
16769    (set_attr "mode" "<MODE>")
16770    (set_attr "length_immediate" "0")])
16772 (define_insn "*mov<mode>cc_noc"
16773   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16774         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16775                                [(reg FLAGS_REG) (const_int 0)])
16776           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16777           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16778   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16779   "@
16780    cmov%O2%C1\t{%2, %0|%0, %2}
16781    cmov%O2%c1\t{%3, %0|%0, %3}"
16782   [(set_attr "type" "icmov")
16783    (set_attr "mode" "<MODE>")])
16785 ;; Don't do conditional moves with memory inputs.  This splitter helps
16786 ;; register starved x86_32 by forcing inputs into registers before reload.
16787 (define_split
16788   [(set (match_operand:SWI248 0 "register_operand")
16789         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16790                                [(reg FLAGS_REG) (const_int 0)])
16791           (match_operand:SWI248 2 "nonimmediate_operand")
16792           (match_operand:SWI248 3 "nonimmediate_operand")))]
16793   "!TARGET_64BIT && TARGET_CMOVE
16794    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16795    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16796    && can_create_pseudo_p ()
16797    && optimize_insn_for_speed_p ()"
16798   [(set (match_dup 0)
16799         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16801   if (MEM_P (operands[2]))
16802     operands[2] = force_reg (<MODE>mode, operands[2]);
16803   if (MEM_P (operands[3]))
16804     operands[3] = force_reg (<MODE>mode, operands[3]);
16807 (define_insn "*movqicc_noc"
16808   [(set (match_operand:QI 0 "register_operand" "=r,r")
16809         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16810                            [(reg FLAGS_REG) (const_int 0)])
16811                       (match_operand:QI 2 "register_operand" "r,0")
16812                       (match_operand:QI 3 "register_operand" "0,r")))]
16813   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16814   "#"
16815   [(set_attr "type" "icmov")
16816    (set_attr "mode" "QI")])
16818 (define_split
16819   [(set (match_operand:SWI12 0 "register_operand")
16820         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16821                               [(reg FLAGS_REG) (const_int 0)])
16822                       (match_operand:SWI12 2 "register_operand")
16823                       (match_operand:SWI12 3 "register_operand")))]
16824   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16825    && reload_completed"
16826   [(set (match_dup 0)
16827         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16829   operands[0] = gen_lowpart (SImode, operands[0]);
16830   operands[2] = gen_lowpart (SImode, operands[2]);
16831   operands[3] = gen_lowpart (SImode, operands[3]);
16834 ;; Don't do conditional moves with memory inputs
16835 (define_peephole2
16836   [(match_scratch:SWI248 2 "r")
16837    (set (match_operand:SWI248 0 "register_operand")
16838         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16839                                [(reg FLAGS_REG) (const_int 0)])
16840           (match_dup 0)
16841           (match_operand:SWI248 3 "memory_operand")))]
16842   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16843    && optimize_insn_for_speed_p ()"
16844   [(set (match_dup 2) (match_dup 3))
16845    (set (match_dup 0)
16846         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16848 (define_peephole2
16849   [(match_scratch:SWI248 2 "r")
16850    (set (match_operand:SWI248 0 "register_operand")
16851         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16852                                [(reg FLAGS_REG) (const_int 0)])
16853           (match_operand:SWI248 3 "memory_operand")
16854           (match_dup 0)))]
16855   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16856    && optimize_insn_for_speed_p ()"
16857   [(set (match_dup 2) (match_dup 3))
16858    (set (match_dup 0)
16859         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16861 (define_expand "mov<mode>cc"
16862   [(set (match_operand:X87MODEF 0 "register_operand")
16863         (if_then_else:X87MODEF
16864           (match_operand 1 "comparison_operator")
16865           (match_operand:X87MODEF 2 "register_operand")
16866           (match_operand:X87MODEF 3 "register_operand")))]
16867   "(TARGET_80387 && TARGET_CMOVE)
16868    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16869   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16871 (define_insn "*movxfcc_1"
16872   [(set (match_operand:XF 0 "register_operand" "=f,f")
16873         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16874                                 [(reg FLAGS_REG) (const_int 0)])
16875                       (match_operand:XF 2 "register_operand" "f,0")
16876                       (match_operand:XF 3 "register_operand" "0,f")))]
16877   "TARGET_80387 && TARGET_CMOVE"
16878   "@
16879    fcmov%F1\t{%2, %0|%0, %2}
16880    fcmov%f1\t{%3, %0|%0, %3}"
16881   [(set_attr "type" "fcmov")
16882    (set_attr "mode" "XF")])
16884 (define_insn "*movdfcc_1"
16885   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16886         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16887                                 [(reg FLAGS_REG) (const_int 0)])
16888                       (match_operand:DF 2 "nonimmediate_operand"
16889                                                "f ,0,rm,0 ,rm,0")
16890                       (match_operand:DF 3 "nonimmediate_operand"
16891                                                "0 ,f,0 ,rm,0, rm")))]
16892   "TARGET_80387 && TARGET_CMOVE
16893    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16894   "@
16895    fcmov%F1\t{%2, %0|%0, %2}
16896    fcmov%f1\t{%3, %0|%0, %3}
16897    #
16898    #
16899    cmov%O2%C1\t{%2, %0|%0, %2}
16900    cmov%O2%c1\t{%3, %0|%0, %3}"
16901   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16902    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16903    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16905 (define_split
16906   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16907         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16908                                 [(reg FLAGS_REG) (const_int 0)])
16909                       (match_operand:DF 2 "nonimmediate_operand")
16910                       (match_operand:DF 3 "nonimmediate_operand")))]
16911   "!TARGET_64BIT && reload_completed"
16912   [(set (match_dup 2)
16913         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16914    (set (match_dup 3)
16915         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16917   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16918   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16921 (define_insn "*movsfcc_1_387"
16922   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16923         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16924                                 [(reg FLAGS_REG) (const_int 0)])
16925                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16926                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16927   "TARGET_80387 && TARGET_CMOVE
16928    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16929   "@
16930    fcmov%F1\t{%2, %0|%0, %2}
16931    fcmov%f1\t{%3, %0|%0, %3}
16932    cmov%O2%C1\t{%2, %0|%0, %2}
16933    cmov%O2%c1\t{%3, %0|%0, %3}"
16934   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16935    (set_attr "mode" "SF,SF,SI,SI")])
16937 ;; Don't do conditional moves with memory inputs.  This splitter helps
16938 ;; register starved x86_32 by forcing inputs into registers before reload.
16939 (define_split
16940   [(set (match_operand:MODEF 0 "register_operand")
16941         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16942                               [(reg FLAGS_REG) (const_int 0)])
16943           (match_operand:MODEF 2 "nonimmediate_operand")
16944           (match_operand:MODEF 3 "nonimmediate_operand")))]
16945   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16946    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16947    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16948    && can_create_pseudo_p ()
16949    && optimize_insn_for_speed_p ()"
16950   [(set (match_dup 0)
16951         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16953   if (MEM_P (operands[2]))
16954     operands[2] = force_reg (<MODE>mode, operands[2]);
16955   if (MEM_P (operands[3]))
16956     operands[3] = force_reg (<MODE>mode, operands[3]);
16959 ;; Don't do conditional moves with memory inputs
16960 (define_peephole2
16961   [(match_scratch:MODEF 2 "r")
16962    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16963         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16964                               [(reg FLAGS_REG) (const_int 0)])
16965           (match_dup 0)
16966           (match_operand:MODEF 3 "memory_operand")))]
16967   "(<MODE>mode != DFmode || TARGET_64BIT)
16968    && TARGET_80387 && TARGET_CMOVE
16969    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16970    && optimize_insn_for_speed_p ()"
16971   [(set (match_dup 2) (match_dup 3))
16972    (set (match_dup 0)
16973         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16975 (define_peephole2
16976   [(match_scratch:MODEF 2 "r")
16977    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16978         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16979                               [(reg FLAGS_REG) (const_int 0)])
16980           (match_operand:MODEF 3 "memory_operand")
16981           (match_dup 0)))]
16982   "(<MODE>mode != DFmode || TARGET_64BIT)
16983    && TARGET_80387 && TARGET_CMOVE
16984    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16985    && optimize_insn_for_speed_p ()"
16986   [(set (match_dup 2) (match_dup 3))
16987    (set (match_dup 0)
16988         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16990 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16991 ;; the scalar versions to have only XMM registers as operands.
16993 ;; XOP conditional move
16994 (define_insn "*xop_pcmov_<mode>"
16995   [(set (match_operand:MODEF 0 "register_operand" "=x")
16996         (if_then_else:MODEF
16997           (match_operand:MODEF 1 "register_operand" "x")
16998           (match_operand:MODEF 2 "register_operand" "x")
16999           (match_operand:MODEF 3 "register_operand" "x")))]
17000   "TARGET_XOP"
17001   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17002   [(set_attr "type" "sse4arg")])
17004 ;; These versions of the min/max patterns are intentionally ignorant of
17005 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17006 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17007 ;; are undefined in this condition, we're certain this is correct.
17009 (define_insn "<code><mode>3"
17010   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17011         (smaxmin:MODEF
17012           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17013           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17014   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17015   "@
17016    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17017    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17018   [(set_attr "isa" "noavx,avx")
17019    (set_attr "prefix" "orig,vex")
17020    (set_attr "type" "sseadd")
17021    (set_attr "mode" "<MODE>")])
17023 ;; These versions of the min/max patterns implement exactly the operations
17024 ;;   min = (op1 < op2 ? op1 : op2)
17025 ;;   max = (!(op1 < op2) ? op1 : op2)
17026 ;; Their operands are not commutative, and thus they may be used in the
17027 ;; presence of -0.0 and NaN.
17029 (define_int_iterator IEEE_MAXMIN
17030         [UNSPEC_IEEE_MAX
17031          UNSPEC_IEEE_MIN])
17033 (define_int_attr ieee_maxmin
17034         [(UNSPEC_IEEE_MAX "max")
17035          (UNSPEC_IEEE_MIN "min")])
17037 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17038   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17039         (unspec:MODEF
17040           [(match_operand:MODEF 1 "register_operand" "0,x")
17041            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17042           IEEE_MAXMIN))]
17043   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17044   "@
17045    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17046    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17047   [(set_attr "isa" "noavx,avx")
17048    (set_attr "prefix" "orig,vex")
17049    (set_attr "type" "sseadd")
17050    (set_attr "mode" "<MODE>")])
17052 ;; Make two stack loads independent:
17053 ;;   fld aa              fld aa
17054 ;;   fld %st(0)     ->   fld bb
17055 ;;   fmul bb             fmul %st(1), %st
17057 ;; Actually we only match the last two instructions for simplicity.
17058 (define_peephole2
17059   [(set (match_operand 0 "fp_register_operand")
17060         (match_operand 1 "fp_register_operand"))
17061    (set (match_dup 0)
17062         (match_operator 2 "binary_fp_operator"
17063            [(match_dup 0)
17064             (match_operand 3 "memory_operand")]))]
17065   "REGNO (operands[0]) != REGNO (operands[1])"
17066   [(set (match_dup 0) (match_dup 3))
17067    (set (match_dup 0) (match_dup 4))]
17069   ;; The % modifier is not operational anymore in peephole2's, so we have to
17070   ;; swap the operands manually in the case of addition and multiplication.
17072   rtx op0, op1;
17074   if (COMMUTATIVE_ARITH_P (operands[2]))
17075     op0 = operands[0], op1 = operands[1];
17076   else
17077     op0 = operands[1], op1 = operands[0];
17079   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17080                                 GET_MODE (operands[2]),
17081                                 op0, op1);
17084 ;; Conditional addition patterns
17085 (define_expand "add<mode>cc"
17086   [(match_operand:SWI 0 "register_operand")
17087    (match_operand 1 "ordered_comparison_operator")
17088    (match_operand:SWI 2 "register_operand")
17089    (match_operand:SWI 3 "const_int_operand")]
17090   ""
17091   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17093 ;; Misc patterns (?)
17095 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17096 ;; Otherwise there will be nothing to keep
17098 ;; [(set (reg ebp) (reg esp))]
17099 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17100 ;;  (clobber (eflags)]
17101 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17103 ;; in proper program order.
17105 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17106   [(set (match_operand:P 0 "register_operand" "=r,r")
17107         (plus:P (match_operand:P 1 "register_operand" "0,r")
17108                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17109    (clobber (reg:CC FLAGS_REG))
17110    (clobber (mem:BLK (scratch)))]
17111   ""
17113   switch (get_attr_type (insn))
17114     {
17115     case TYPE_IMOV:
17116       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17118     case TYPE_ALU:
17119       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17120       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17121         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17123       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17125     default:
17126       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17127       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17128     }
17130   [(set (attr "type")
17131         (cond [(and (eq_attr "alternative" "0")
17132                     (not (match_test "TARGET_OPT_AGU")))
17133                  (const_string "alu")
17134                (match_operand:<MODE> 2 "const0_operand")
17135                  (const_string "imov")
17136               ]
17137               (const_string "lea")))
17138    (set (attr "length_immediate")
17139         (cond [(eq_attr "type" "imov")
17140                  (const_string "0")
17141                (and (eq_attr "type" "alu")
17142                     (match_operand 2 "const128_operand"))
17143                  (const_string "1")
17144               ]
17145               (const_string "*")))
17146    (set_attr "mode" "<MODE>")])
17148 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17149   [(set (match_operand:P 0 "register_operand" "=r")
17150         (minus:P (match_operand:P 1 "register_operand" "0")
17151                  (match_operand:P 2 "register_operand" "r")))
17152    (clobber (reg:CC FLAGS_REG))
17153    (clobber (mem:BLK (scratch)))]
17154   ""
17155   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17156   [(set_attr "type" "alu")
17157    (set_attr "mode" "<MODE>")])
17159 (define_insn "allocate_stack_worker_probe_<mode>"
17160   [(set (match_operand:P 0 "register_operand" "=a")
17161         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17162                             UNSPECV_STACK_PROBE))
17163    (clobber (reg:CC FLAGS_REG))]
17164   "ix86_target_stack_probe ()"
17165   "call\t___chkstk_ms"
17166   [(set_attr "type" "multi")
17167    (set_attr "length" "5")])
17169 (define_expand "allocate_stack"
17170   [(match_operand 0 "register_operand")
17171    (match_operand 1 "general_operand")]
17172   "ix86_target_stack_probe ()"
17174   rtx x;
17176 #ifndef CHECK_STACK_LIMIT
17177 #define CHECK_STACK_LIMIT 0
17178 #endif
17180   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17181       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17182     x = operands[1];
17183   else
17184     {
17185       rtx (*insn) (rtx, rtx);
17187       x = copy_to_mode_reg (Pmode, operands[1]);
17189       insn = (TARGET_64BIT
17190               ? gen_allocate_stack_worker_probe_di
17191               : gen_allocate_stack_worker_probe_si);
17193       emit_insn (insn (x, x));
17194     }
17196   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17197                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17199   if (x != stack_pointer_rtx)
17200     emit_move_insn (stack_pointer_rtx, x);
17202   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17203   DONE;
17206 ;; Use IOR for stack probes, this is shorter.
17207 (define_expand "probe_stack"
17208   [(match_operand 0 "memory_operand")]
17209   ""
17211   rtx (*gen_ior3) (rtx, rtx, rtx);
17213   gen_ior3 = (GET_MODE (operands[0]) == DImode
17214               ? gen_iordi3 : gen_iorsi3);
17216   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17217   DONE;
17220 (define_insn "adjust_stack_and_probe<mode>"
17221   [(set (match_operand:P 0 "register_operand" "=r")
17222         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17223                             UNSPECV_PROBE_STACK_RANGE))
17224    (set (reg:P SP_REG)
17225         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17226    (clobber (reg:CC FLAGS_REG))
17227    (clobber (mem:BLK (scratch)))]
17228   ""
17229   "* return output_adjust_stack_and_probe (operands[0]);"
17230   [(set_attr "type" "multi")])
17232 (define_insn "probe_stack_range<mode>"
17233   [(set (match_operand:P 0 "register_operand" "=r")
17234         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17235                             (match_operand:P 2 "const_int_operand" "n")]
17236                             UNSPECV_PROBE_STACK_RANGE))
17237    (clobber (reg:CC FLAGS_REG))]
17238   ""
17239   "* return output_probe_stack_range (operands[0], operands[2]);"
17240   [(set_attr "type" "multi")])
17242 (define_expand "builtin_setjmp_receiver"
17243   [(label_ref (match_operand 0))]
17244   "!TARGET_64BIT && flag_pic"
17246 #if TARGET_MACHO
17247   if (TARGET_MACHO)
17248     {
17249       rtx xops[3];
17250       rtx_code_label *label_rtx = gen_label_rtx ();
17251       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17252       xops[0] = xops[1] = pic_offset_table_rtx;
17253       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17254       ix86_expand_binary_operator (MINUS, SImode, xops);
17255     }
17256   else
17257 #endif
17258     emit_insn (gen_set_got (pic_offset_table_rtx));
17259   DONE;
17262 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17263 ;; Do not split instructions with mask registers.
17264 (define_split
17265   [(set (match_operand 0 "general_reg_operand")
17266         (match_operator 3 "promotable_binary_operator"
17267            [(match_operand 1 "general_reg_operand")
17268             (match_operand 2 "aligned_operand")]))
17269    (clobber (reg:CC FLAGS_REG))]
17270   "! TARGET_PARTIAL_REG_STALL && reload_completed
17271    && ((GET_MODE (operands[0]) == HImode
17272         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17273             /* ??? next two lines just !satisfies_constraint_K (...) */
17274             || !CONST_INT_P (operands[2])
17275             || satisfies_constraint_K (operands[2])))
17276        || (GET_MODE (operands[0]) == QImode
17277            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17278   [(parallel [(set (match_dup 0)
17279                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17280               (clobber (reg:CC FLAGS_REG))])]
17282   operands[0] = gen_lowpart (SImode, operands[0]);
17283   operands[1] = gen_lowpart (SImode, operands[1]);
17284   if (GET_CODE (operands[3]) != ASHIFT)
17285     operands[2] = gen_lowpart (SImode, operands[2]);
17286   operands[3] = shallow_copy_rtx (operands[3]);
17287   PUT_MODE (operands[3], SImode);
17290 ; Promote the QImode tests, as i386 has encoding of the AND
17291 ; instruction with 32-bit sign-extended immediate and thus the
17292 ; instruction size is unchanged, except in the %eax case for
17293 ; which it is increased by one byte, hence the ! optimize_size.
17294 (define_split
17295   [(set (match_operand 0 "flags_reg_operand")
17296         (match_operator 2 "compare_operator"
17297           [(and (match_operand 3 "aligned_operand")
17298                 (match_operand 4 "const_int_operand"))
17299            (const_int 0)]))
17300    (set (match_operand 1 "register_operand")
17301         (and (match_dup 3) (match_dup 4)))]
17302   "! TARGET_PARTIAL_REG_STALL && reload_completed
17303    && optimize_insn_for_speed_p ()
17304    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17305        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17306    /* Ensure that the operand will remain sign-extended immediate.  */
17307    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17308   [(parallel [(set (match_dup 0)
17309                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17310                                     (const_int 0)]))
17311               (set (match_dup 1)
17312                    (and:SI (match_dup 3) (match_dup 4)))])]
17314   operands[4]
17315     = gen_int_mode (INTVAL (operands[4])
17316                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17317   operands[1] = gen_lowpart (SImode, operands[1]);
17318   operands[3] = gen_lowpart (SImode, operands[3]);
17321 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17322 ; the TEST instruction with 32-bit sign-extended immediate and thus
17323 ; the instruction size would at least double, which is not what we
17324 ; want even with ! optimize_size.
17325 (define_split
17326   [(set (match_operand 0 "flags_reg_operand")
17327         (match_operator 1 "compare_operator"
17328           [(and (match_operand:HI 2 "aligned_operand")
17329                 (match_operand:HI 3 "const_int_operand"))
17330            (const_int 0)]))]
17331   "! TARGET_PARTIAL_REG_STALL && reload_completed
17332    && ! TARGET_FAST_PREFIX
17333    && optimize_insn_for_speed_p ()
17334    /* Ensure that the operand will remain sign-extended immediate.  */
17335    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17336   [(set (match_dup 0)
17337         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17338                          (const_int 0)]))]
17340   operands[3]
17341     = gen_int_mode (INTVAL (operands[3])
17342                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17343   operands[2] = gen_lowpart (SImode, operands[2]);
17346 (define_split
17347   [(set (match_operand 0 "register_operand")
17348         (neg (match_operand 1 "register_operand")))
17349    (clobber (reg:CC FLAGS_REG))]
17350   "! TARGET_PARTIAL_REG_STALL && reload_completed
17351    && (GET_MODE (operands[0]) == HImode
17352        || (GET_MODE (operands[0]) == QImode
17353            && (TARGET_PROMOTE_QImode
17354                || optimize_insn_for_size_p ())))"
17355   [(parallel [(set (match_dup 0)
17356                    (neg:SI (match_dup 1)))
17357               (clobber (reg:CC FLAGS_REG))])]
17359   operands[0] = gen_lowpart (SImode, operands[0]);
17360   operands[1] = gen_lowpart (SImode, operands[1]);
17363 ;; Do not split instructions with mask regs.
17364 (define_split
17365   [(set (match_operand 0 "general_reg_operand")
17366         (not (match_operand 1 "general_reg_operand")))]
17367   "! TARGET_PARTIAL_REG_STALL && reload_completed
17368    && (GET_MODE (operands[0]) == HImode
17369        || (GET_MODE (operands[0]) == QImode
17370            && (TARGET_PROMOTE_QImode
17371                || optimize_insn_for_size_p ())))"
17372   [(set (match_dup 0)
17373         (not:SI (match_dup 1)))]
17375   operands[0] = gen_lowpart (SImode, operands[0]);
17376   operands[1] = gen_lowpart (SImode, operands[1]);
17379 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17380 ;; transform a complex memory operation into two memory to register operations.
17382 ;; Don't push memory operands
17383 (define_peephole2
17384   [(set (match_operand:SWI 0 "push_operand")
17385         (match_operand:SWI 1 "memory_operand"))
17386    (match_scratch:SWI 2 "<r>")]
17387   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17388    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17389   [(set (match_dup 2) (match_dup 1))
17390    (set (match_dup 0) (match_dup 2))])
17392 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17393 ;; SImode pushes.
17394 (define_peephole2
17395   [(set (match_operand:SF 0 "push_operand")
17396         (match_operand:SF 1 "memory_operand"))
17397    (match_scratch:SF 2 "r")]
17398   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17399    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17400   [(set (match_dup 2) (match_dup 1))
17401    (set (match_dup 0) (match_dup 2))])
17403 ;; Don't move an immediate directly to memory when the instruction
17404 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17405 (define_peephole2
17406   [(match_scratch:SWI124 1 "<r>")
17407    (set (match_operand:SWI124 0 "memory_operand")
17408         (const_int 0))]
17409   "optimize_insn_for_speed_p ()
17410    && ((<MODE>mode == HImode
17411        && TARGET_LCP_STALL)
17412        || (!TARGET_USE_MOV0
17413           && TARGET_SPLIT_LONG_MOVES
17414           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17415    && peep2_regno_dead_p (0, FLAGS_REG)"
17416   [(parallel [(set (match_dup 2) (const_int 0))
17417               (clobber (reg:CC FLAGS_REG))])
17418    (set (match_dup 0) (match_dup 1))]
17419   "operands[2] = gen_lowpart (SImode, operands[1]);")
17421 (define_peephole2
17422   [(match_scratch:SWI124 2 "<r>")
17423    (set (match_operand:SWI124 0 "memory_operand")
17424         (match_operand:SWI124 1 "immediate_operand"))]
17425   "optimize_insn_for_speed_p ()
17426    && ((<MODE>mode == HImode
17427        && TARGET_LCP_STALL)
17428        || (TARGET_SPLIT_LONG_MOVES
17429           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17430   [(set (match_dup 2) (match_dup 1))
17431    (set (match_dup 0) (match_dup 2))])
17433 ;; Don't compare memory with zero, load and use a test instead.
17434 (define_peephole2
17435   [(set (match_operand 0 "flags_reg_operand")
17436         (match_operator 1 "compare_operator"
17437           [(match_operand:SI 2 "memory_operand")
17438            (const_int 0)]))
17439    (match_scratch:SI 3 "r")]
17440   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17441   [(set (match_dup 3) (match_dup 2))
17442    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17444 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17445 ;; Don't split NOTs with a displacement operand, because resulting XOR
17446 ;; will not be pairable anyway.
17448 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17449 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17450 ;; so this split helps here as well.
17452 ;; Note: Can't do this as a regular split because we can't get proper
17453 ;; lifetime information then.
17455 (define_peephole2
17456   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17457         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17458   "optimize_insn_for_speed_p ()
17459    && ((TARGET_NOT_UNPAIRABLE
17460         && (!MEM_P (operands[0])
17461             || !memory_displacement_operand (operands[0], <MODE>mode)))
17462        || (TARGET_NOT_VECTORMODE
17463            && long_memory_operand (operands[0], <MODE>mode)))
17464    && peep2_regno_dead_p (0, FLAGS_REG)"
17465   [(parallel [(set (match_dup 0)
17466                    (xor:SWI124 (match_dup 1) (const_int -1)))
17467               (clobber (reg:CC FLAGS_REG))])])
17469 ;; Non pairable "test imm, reg" instructions can be translated to
17470 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17471 ;; byte opcode instead of two, have a short form for byte operands),
17472 ;; so do it for other CPUs as well.  Given that the value was dead,
17473 ;; this should not create any new dependencies.  Pass on the sub-word
17474 ;; versions if we're concerned about partial register stalls.
17476 (define_peephole2
17477   [(set (match_operand 0 "flags_reg_operand")
17478         (match_operator 1 "compare_operator"
17479           [(and:SI (match_operand:SI 2 "register_operand")
17480                    (match_operand:SI 3 "immediate_operand"))
17481            (const_int 0)]))]
17482   "ix86_match_ccmode (insn, CCNOmode)
17483    && (true_regnum (operands[2]) != AX_REG
17484        || satisfies_constraint_K (operands[3]))
17485    && peep2_reg_dead_p (1, operands[2])"
17486   [(parallel
17487      [(set (match_dup 0)
17488            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17489                             (const_int 0)]))
17490       (set (match_dup 2)
17491            (and:SI (match_dup 2) (match_dup 3)))])])
17493 ;; We don't need to handle HImode case, because it will be promoted to SImode
17494 ;; on ! TARGET_PARTIAL_REG_STALL
17496 (define_peephole2
17497   [(set (match_operand 0 "flags_reg_operand")
17498         (match_operator 1 "compare_operator"
17499           [(and:QI (match_operand:QI 2 "register_operand")
17500                    (match_operand:QI 3 "immediate_operand"))
17501            (const_int 0)]))]
17502   "! TARGET_PARTIAL_REG_STALL
17503    && ix86_match_ccmode (insn, CCNOmode)
17504    && true_regnum (operands[2]) != AX_REG
17505    && peep2_reg_dead_p (1, operands[2])"
17506   [(parallel
17507      [(set (match_dup 0)
17508            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17509                             (const_int 0)]))
17510       (set (match_dup 2)
17511            (and:QI (match_dup 2) (match_dup 3)))])])
17513 (define_peephole2
17514   [(set (match_operand 0 "flags_reg_operand")
17515         (match_operator 1 "compare_operator"
17516           [(and:SI
17517              (zero_extract:SI
17518                (match_operand 2 "ext_register_operand")
17519                (const_int 8)
17520                (const_int 8))
17521              (match_operand 3 "const_int_operand"))
17522            (const_int 0)]))]
17523   "! TARGET_PARTIAL_REG_STALL
17524    && ix86_match_ccmode (insn, CCNOmode)
17525    && true_regnum (operands[2]) != AX_REG
17526    && peep2_reg_dead_p (1, operands[2])"
17527   [(parallel [(set (match_dup 0)
17528                    (match_op_dup 1
17529                      [(and:SI
17530                         (zero_extract:SI
17531                           (match_dup 2)
17532                           (const_int 8)
17533                           (const_int 8))
17534                         (match_dup 3))
17535                       (const_int 0)]))
17536               (set (zero_extract:SI (match_dup 2)
17537                                     (const_int 8)
17538                                     (const_int 8))
17539                    (and:SI
17540                      (zero_extract:SI
17541                        (match_dup 2)
17542                        (const_int 8)
17543                        (const_int 8))
17544                      (match_dup 3)))])])
17546 ;; Don't do logical operations with memory inputs.
17547 (define_peephole2
17548   [(match_scratch:SI 2 "r")
17549    (parallel [(set (match_operand:SI 0 "register_operand")
17550                    (match_operator:SI 3 "arith_or_logical_operator"
17551                      [(match_dup 0)
17552                       (match_operand:SI 1 "memory_operand")]))
17553               (clobber (reg:CC FLAGS_REG))])]
17554   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17555   [(set (match_dup 2) (match_dup 1))
17556    (parallel [(set (match_dup 0)
17557                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17558               (clobber (reg:CC FLAGS_REG))])])
17560 (define_peephole2
17561   [(match_scratch:SI 2 "r")
17562    (parallel [(set (match_operand:SI 0 "register_operand")
17563                    (match_operator:SI 3 "arith_or_logical_operator"
17564                      [(match_operand:SI 1 "memory_operand")
17565                       (match_dup 0)]))
17566               (clobber (reg:CC FLAGS_REG))])]
17567   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17568   [(set (match_dup 2) (match_dup 1))
17569    (parallel [(set (match_dup 0)
17570                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17571               (clobber (reg:CC FLAGS_REG))])])
17573 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17574 ;; refers to the destination of the load!
17576 (define_peephole2
17577   [(set (match_operand:SI 0 "register_operand")
17578         (match_operand:SI 1 "register_operand"))
17579    (parallel [(set (match_dup 0)
17580                    (match_operator:SI 3 "commutative_operator"
17581                      [(match_dup 0)
17582                       (match_operand:SI 2 "memory_operand")]))
17583               (clobber (reg:CC FLAGS_REG))])]
17584   "REGNO (operands[0]) != REGNO (operands[1])
17585    && GENERAL_REGNO_P (REGNO (operands[0]))
17586    && GENERAL_REGNO_P (REGNO (operands[1]))"
17587   [(set (match_dup 0) (match_dup 4))
17588    (parallel [(set (match_dup 0)
17589                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17590               (clobber (reg:CC FLAGS_REG))])]
17591   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17593 (define_peephole2
17594   [(set (match_operand 0 "register_operand")
17595         (match_operand 1 "register_operand"))
17596    (set (match_dup 0)
17597                    (match_operator 3 "commutative_operator"
17598                      [(match_dup 0)
17599                       (match_operand 2 "memory_operand")]))]
17600   "REGNO (operands[0]) != REGNO (operands[1])
17601    && ((MMX_REGNO_P (REGNO (operands[0]))
17602         && MMX_REGNO_P (REGNO (operands[1]))) 
17603        || (SSE_REGNO_P (REGNO (operands[0]))
17604            && SSE_REGNO_P (REGNO (operands[1]))))"
17605   [(set (match_dup 0) (match_dup 2))
17606    (set (match_dup 0)
17607         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17609 ; Don't do logical operations with memory outputs
17611 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17612 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17613 ; the same decoder scheduling characteristics as the original.
17615 (define_peephole2
17616   [(match_scratch:SI 2 "r")
17617    (parallel [(set (match_operand:SI 0 "memory_operand")
17618                    (match_operator:SI 3 "arith_or_logical_operator"
17619                      [(match_dup 0)
17620                       (match_operand:SI 1 "nonmemory_operand")]))
17621               (clobber (reg:CC FLAGS_REG))])]
17622   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17623    /* Do not split stack checking probes.  */
17624    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17625   [(set (match_dup 2) (match_dup 0))
17626    (parallel [(set (match_dup 2)
17627                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17628               (clobber (reg:CC FLAGS_REG))])
17629    (set (match_dup 0) (match_dup 2))])
17631 (define_peephole2
17632   [(match_scratch:SI 2 "r")
17633    (parallel [(set (match_operand:SI 0 "memory_operand")
17634                    (match_operator:SI 3 "arith_or_logical_operator"
17635                      [(match_operand:SI 1 "nonmemory_operand")
17636                       (match_dup 0)]))
17637               (clobber (reg:CC FLAGS_REG))])]
17638   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17639    /* Do not split stack checking probes.  */
17640    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17641   [(set (match_dup 2) (match_dup 0))
17642    (parallel [(set (match_dup 2)
17643                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17644               (clobber (reg:CC FLAGS_REG))])
17645    (set (match_dup 0) (match_dup 2))])
17647 ;; Attempt to use arith or logical operations with memory outputs with
17648 ;; setting of flags.
17649 (define_peephole2
17650   [(set (match_operand:SWI 0 "register_operand")
17651         (match_operand:SWI 1 "memory_operand"))
17652    (parallel [(set (match_dup 0)
17653                    (match_operator:SWI 3 "plusminuslogic_operator"
17654                      [(match_dup 0)
17655                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17656               (clobber (reg:CC FLAGS_REG))])
17657    (set (match_dup 1) (match_dup 0))
17658    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17659   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17660    && peep2_reg_dead_p (4, operands[0])
17661    && !reg_overlap_mentioned_p (operands[0], operands[1])
17662    && !reg_overlap_mentioned_p (operands[0], operands[2])
17663    && (<MODE>mode != QImode
17664        || immediate_operand (operands[2], QImode)
17665        || q_regs_operand (operands[2], QImode))
17666    && ix86_match_ccmode (peep2_next_insn (3),
17667                          (GET_CODE (operands[3]) == PLUS
17668                           || GET_CODE (operands[3]) == MINUS)
17669                          ? CCGOCmode : CCNOmode)"
17670   [(parallel [(set (match_dup 4) (match_dup 5))
17671               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17672                                                   (match_dup 2)]))])]
17674   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17675   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17676                                 copy_rtx (operands[1]),
17677                                 copy_rtx (operands[2]));
17678   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17679                                  operands[5], const0_rtx);
17682 (define_peephole2
17683   [(parallel [(set (match_operand:SWI 0 "register_operand")
17684                    (match_operator:SWI 2 "plusminuslogic_operator"
17685                      [(match_dup 0)
17686                       (match_operand:SWI 1 "memory_operand")]))
17687               (clobber (reg:CC FLAGS_REG))])
17688    (set (match_dup 1) (match_dup 0))
17689    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17690   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17691    && GET_CODE (operands[2]) != MINUS
17692    && peep2_reg_dead_p (3, operands[0])
17693    && !reg_overlap_mentioned_p (operands[0], operands[1])
17694    && ix86_match_ccmode (peep2_next_insn (2),
17695                          GET_CODE (operands[2]) == PLUS
17696                          ? CCGOCmode : CCNOmode)"
17697   [(parallel [(set (match_dup 3) (match_dup 4))
17698               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17699                                                   (match_dup 0)]))])]
17701   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17702   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17703                                 copy_rtx (operands[1]),
17704                                 copy_rtx (operands[0]));
17705   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17706                                  operands[4], const0_rtx);
17709 (define_peephole2
17710   [(set (match_operand:SWI12 0 "register_operand")
17711         (match_operand:SWI12 1 "memory_operand"))
17712    (parallel [(set (match_operand:SI 4 "register_operand")
17713                    (match_operator:SI 3 "plusminuslogic_operator"
17714                      [(match_dup 4)
17715                       (match_operand:SI 2 "nonmemory_operand")]))
17716               (clobber (reg:CC FLAGS_REG))])
17717    (set (match_dup 1) (match_dup 0))
17718    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17719   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17720    && REG_P (operands[0]) && REG_P (operands[4])
17721    && REGNO (operands[0]) == REGNO (operands[4])
17722    && peep2_reg_dead_p (4, operands[0])
17723    && (<MODE>mode != QImode
17724        || immediate_operand (operands[2], SImode)
17725        || q_regs_operand (operands[2], SImode))
17726    && !reg_overlap_mentioned_p (operands[0], operands[1])
17727    && !reg_overlap_mentioned_p (operands[0], operands[2])
17728    && ix86_match_ccmode (peep2_next_insn (3),
17729                          (GET_CODE (operands[3]) == PLUS
17730                           || GET_CODE (operands[3]) == MINUS)
17731                          ? CCGOCmode : CCNOmode)"
17732   [(parallel [(set (match_dup 4) (match_dup 5))
17733               (set (match_dup 1) (match_dup 6))])]
17735   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17736   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17737   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17738                                 copy_rtx (operands[1]), operands[2]);
17739   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17740                                  operands[5], const0_rtx);
17741   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17742                                 copy_rtx (operands[1]),
17743                                 copy_rtx (operands[2]));
17746 ;; Attempt to always use XOR for zeroing registers.
17747 (define_peephole2
17748   [(set (match_operand 0 "register_operand")
17749         (match_operand 1 "const0_operand"))]
17750   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17751    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17752    && GENERAL_REGNO_P (REGNO (operands[0]))
17753    && peep2_regno_dead_p (0, FLAGS_REG)"
17754   [(parallel [(set (match_dup 0) (const_int 0))
17755               (clobber (reg:CC FLAGS_REG))])]
17756   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17758 (define_peephole2
17759   [(set (strict_low_part (match_operand 0 "register_operand"))
17760         (const_int 0))]
17761   "(GET_MODE (operands[0]) == QImode
17762     || GET_MODE (operands[0]) == HImode)
17763    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17764    && peep2_regno_dead_p (0, FLAGS_REG)"
17765   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17766               (clobber (reg:CC FLAGS_REG))])])
17768 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17769 (define_peephole2
17770   [(set (match_operand:SWI248 0 "register_operand")
17771         (const_int -1))]
17772   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17773    && GENERAL_REGNO_P (REGNO (operands[0]))
17774    && peep2_regno_dead_p (0, FLAGS_REG)"
17775   [(parallel [(set (match_dup 0) (const_int -1))
17776               (clobber (reg:CC FLAGS_REG))])]
17778   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17779     operands[0] = gen_lowpart (SImode, operands[0]);
17782 ;; Attempt to convert simple lea to add/shift.
17783 ;; These can be created by move expanders.
17784 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17785 ;; relevant lea instructions were already split.
17787 (define_peephole2
17788   [(set (match_operand:SWI48 0 "register_operand")
17789         (plus:SWI48 (match_dup 0)
17790                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17791   "!TARGET_OPT_AGU
17792    && peep2_regno_dead_p (0, FLAGS_REG)"
17793   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17794               (clobber (reg:CC FLAGS_REG))])])
17796 (define_peephole2
17797   [(set (match_operand:SWI48 0 "register_operand")
17798         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17799                     (match_dup 0)))]
17800   "!TARGET_OPT_AGU
17801    && peep2_regno_dead_p (0, FLAGS_REG)"
17802   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17803               (clobber (reg:CC FLAGS_REG))])])
17805 (define_peephole2
17806   [(set (match_operand:DI 0 "register_operand")
17807         (zero_extend:DI
17808           (plus:SI (match_operand:SI 1 "register_operand")
17809                    (match_operand:SI 2 "nonmemory_operand"))))]
17810   "TARGET_64BIT && !TARGET_OPT_AGU
17811    && REGNO (operands[0]) == REGNO (operands[1])
17812    && peep2_regno_dead_p (0, FLAGS_REG)"
17813   [(parallel [(set (match_dup 0)
17814                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17815               (clobber (reg:CC FLAGS_REG))])])
17817 (define_peephole2
17818   [(set (match_operand:DI 0 "register_operand")
17819         (zero_extend:DI
17820           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17821                    (match_operand:SI 2 "register_operand"))))]
17822   "TARGET_64BIT && !TARGET_OPT_AGU
17823    && REGNO (operands[0]) == REGNO (operands[2])
17824    && peep2_regno_dead_p (0, FLAGS_REG)"
17825   [(parallel [(set (match_dup 0)
17826                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17827               (clobber (reg:CC FLAGS_REG))])])
17829 (define_peephole2
17830   [(set (match_operand:SWI48 0 "register_operand")
17831         (mult:SWI48 (match_dup 0)
17832                     (match_operand:SWI48 1 "const_int_operand")))]
17833   "exact_log2 (INTVAL (operands[1])) >= 0
17834    && peep2_regno_dead_p (0, FLAGS_REG)"
17835   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17836               (clobber (reg:CC FLAGS_REG))])]
17837   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17839 (define_peephole2
17840   [(set (match_operand:DI 0 "register_operand")
17841         (zero_extend:DI
17842           (mult:SI (match_operand:SI 1 "register_operand")
17843                    (match_operand:SI 2 "const_int_operand"))))]
17844   "TARGET_64BIT
17845    && exact_log2 (INTVAL (operands[2])) >= 0
17846    && REGNO (operands[0]) == REGNO (operands[1])
17847    && peep2_regno_dead_p (0, FLAGS_REG)"
17848   [(parallel [(set (match_dup 0)
17849                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17850               (clobber (reg:CC FLAGS_REG))])]
17851   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17853 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17854 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17855 ;; On many CPUs it is also faster, since special hardware to avoid esp
17856 ;; dependencies is present.
17858 ;; While some of these conversions may be done using splitters, we use
17859 ;; peepholes in order to allow combine_stack_adjustments pass to see
17860 ;; nonobfuscated RTL.
17862 ;; Convert prologue esp subtractions to push.
17863 ;; We need register to push.  In order to keep verify_flow_info happy we have
17864 ;; two choices
17865 ;; - use scratch and clobber it in order to avoid dependencies
17866 ;; - use already live register
17867 ;; We can't use the second way right now, since there is no reliable way how to
17868 ;; verify that given register is live.  First choice will also most likely in
17869 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17870 ;; call clobbered registers are dead.  We may want to use base pointer as an
17871 ;; alternative when no register is available later.
17873 (define_peephole2
17874   [(match_scratch:W 1 "r")
17875    (parallel [(set (reg:P SP_REG)
17876                    (plus:P (reg:P SP_REG)
17877                            (match_operand:P 0 "const_int_operand")))
17878               (clobber (reg:CC FLAGS_REG))
17879               (clobber (mem:BLK (scratch)))])]
17880   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17881    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17882   [(clobber (match_dup 1))
17883    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17884               (clobber (mem:BLK (scratch)))])])
17886 (define_peephole2
17887   [(match_scratch:W 1 "r")
17888    (parallel [(set (reg:P SP_REG)
17889                    (plus:P (reg:P SP_REG)
17890                            (match_operand:P 0 "const_int_operand")))
17891               (clobber (reg:CC FLAGS_REG))
17892               (clobber (mem:BLK (scratch)))])]
17893   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17894    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17895   [(clobber (match_dup 1))
17896    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17897    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17898               (clobber (mem:BLK (scratch)))])])
17900 ;; Convert esp subtractions to push.
17901 (define_peephole2
17902   [(match_scratch:W 1 "r")
17903    (parallel [(set (reg:P SP_REG)
17904                    (plus:P (reg:P SP_REG)
17905                            (match_operand:P 0 "const_int_operand")))
17906               (clobber (reg:CC FLAGS_REG))])]
17907   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17908    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17909   [(clobber (match_dup 1))
17910    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17912 (define_peephole2
17913   [(match_scratch:W 1 "r")
17914    (parallel [(set (reg:P SP_REG)
17915                    (plus:P (reg:P SP_REG)
17916                            (match_operand:P 0 "const_int_operand")))
17917               (clobber (reg:CC FLAGS_REG))])]
17918   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17919    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17920   [(clobber (match_dup 1))
17921    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17922    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17924 ;; Convert epilogue deallocator to pop.
17925 (define_peephole2
17926   [(match_scratch:W 1 "r")
17927    (parallel [(set (reg:P SP_REG)
17928                    (plus:P (reg:P SP_REG)
17929                            (match_operand:P 0 "const_int_operand")))
17930               (clobber (reg:CC FLAGS_REG))
17931               (clobber (mem:BLK (scratch)))])]
17932   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17933    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17934   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17935               (clobber (mem:BLK (scratch)))])])
17937 ;; Two pops case is tricky, since pop causes dependency
17938 ;; on destination register.  We use two registers if available.
17939 (define_peephole2
17940   [(match_scratch:W 1 "r")
17941    (match_scratch:W 2 "r")
17942    (parallel [(set (reg:P SP_REG)
17943                    (plus:P (reg:P SP_REG)
17944                            (match_operand:P 0 "const_int_operand")))
17945               (clobber (reg:CC FLAGS_REG))
17946               (clobber (mem:BLK (scratch)))])]
17947   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17948    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17949   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17950               (clobber (mem:BLK (scratch)))])
17951    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17953 (define_peephole2
17954   [(match_scratch:W 1 "r")
17955    (parallel [(set (reg:P SP_REG)
17956                    (plus:P (reg:P SP_REG)
17957                            (match_operand:P 0 "const_int_operand")))
17958               (clobber (reg:CC FLAGS_REG))
17959               (clobber (mem:BLK (scratch)))])]
17960   "optimize_insn_for_size_p ()
17961    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17962   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17963               (clobber (mem:BLK (scratch)))])
17964    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17966 ;; Convert esp additions to pop.
17967 (define_peephole2
17968   [(match_scratch:W 1 "r")
17969    (parallel [(set (reg:P SP_REG)
17970                    (plus:P (reg:P SP_REG)
17971                            (match_operand:P 0 "const_int_operand")))
17972               (clobber (reg:CC FLAGS_REG))])]
17973   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17974   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17976 ;; Two pops case is tricky, since pop causes dependency
17977 ;; on destination register.  We use two registers if available.
17978 (define_peephole2
17979   [(match_scratch:W 1 "r")
17980    (match_scratch:W 2 "r")
17981    (parallel [(set (reg:P SP_REG)
17982                    (plus:P (reg:P SP_REG)
17983                            (match_operand:P 0 "const_int_operand")))
17984               (clobber (reg:CC FLAGS_REG))])]
17985   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17986   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17987    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17989 (define_peephole2
17990   [(match_scratch:W 1 "r")
17991    (parallel [(set (reg:P SP_REG)
17992                    (plus:P (reg:P SP_REG)
17993                            (match_operand:P 0 "const_int_operand")))
17994               (clobber (reg:CC FLAGS_REG))])]
17995   "optimize_insn_for_size_p ()
17996    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17997   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17998    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18000 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18001 ;; required and register dies.  Similarly for 128 to -128.
18002 (define_peephole2
18003   [(set (match_operand 0 "flags_reg_operand")
18004         (match_operator 1 "compare_operator"
18005           [(match_operand 2 "register_operand")
18006            (match_operand 3 "const_int_operand")]))]
18007   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18008      && incdec_operand (operands[3], GET_MODE (operands[3])))
18009     || (!TARGET_FUSE_CMP_AND_BRANCH
18010         && INTVAL (operands[3]) == 128))
18011    && ix86_match_ccmode (insn, CCGCmode)
18012    && peep2_reg_dead_p (1, operands[2])"
18013   [(parallel [(set (match_dup 0)
18014                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18015               (clobber (match_dup 2))])])
18017 ;; Convert imul by three, five and nine into lea
18018 (define_peephole2
18019   [(parallel
18020     [(set (match_operand:SWI48 0 "register_operand")
18021           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18022                       (match_operand:SWI48 2 "const359_operand")))
18023      (clobber (reg:CC FLAGS_REG))])]
18024   "!TARGET_PARTIAL_REG_STALL
18025    || <MODE>mode == SImode
18026    || optimize_function_for_size_p (cfun)"
18027   [(set (match_dup 0)
18028         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18029                     (match_dup 1)))]
18030   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18032 (define_peephole2
18033   [(parallel
18034     [(set (match_operand:SWI48 0 "register_operand")
18035           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18036                       (match_operand:SWI48 2 "const359_operand")))
18037      (clobber (reg:CC FLAGS_REG))])]
18038   "optimize_insn_for_speed_p ()
18039    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18040   [(set (match_dup 0) (match_dup 1))
18041    (set (match_dup 0)
18042         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18043                     (match_dup 0)))]
18044   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18046 ;; imul $32bit_imm, mem, reg is vector decoded, while
18047 ;; imul $32bit_imm, reg, reg is direct decoded.
18048 (define_peephole2
18049   [(match_scratch:SWI48 3 "r")
18050    (parallel [(set (match_operand:SWI48 0 "register_operand")
18051                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18052                                (match_operand:SWI48 2 "immediate_operand")))
18053               (clobber (reg:CC FLAGS_REG))])]
18054   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18055    && !satisfies_constraint_K (operands[2])"
18056   [(set (match_dup 3) (match_dup 1))
18057    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18058               (clobber (reg:CC FLAGS_REG))])])
18060 (define_peephole2
18061   [(match_scratch:SI 3 "r")
18062    (parallel [(set (match_operand:DI 0 "register_operand")
18063                    (zero_extend:DI
18064                      (mult:SI (match_operand:SI 1 "memory_operand")
18065                               (match_operand:SI 2 "immediate_operand"))))
18066               (clobber (reg:CC FLAGS_REG))])]
18067   "TARGET_64BIT
18068    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18069    && !satisfies_constraint_K (operands[2])"
18070   [(set (match_dup 3) (match_dup 1))
18071    (parallel [(set (match_dup 0)
18072                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18073               (clobber (reg:CC FLAGS_REG))])])
18075 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18076 ;; Convert it into imul reg, reg
18077 ;; It would be better to force assembler to encode instruction using long
18078 ;; immediate, but there is apparently no way to do so.
18079 (define_peephole2
18080   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18081                    (mult:SWI248
18082                     (match_operand:SWI248 1 "nonimmediate_operand")
18083                     (match_operand:SWI248 2 "const_int_operand")))
18084               (clobber (reg:CC FLAGS_REG))])
18085    (match_scratch:SWI248 3 "r")]
18086   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18087    && satisfies_constraint_K (operands[2])"
18088   [(set (match_dup 3) (match_dup 2))
18089    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18090               (clobber (reg:CC FLAGS_REG))])]
18092   if (!rtx_equal_p (operands[0], operands[1]))
18093     emit_move_insn (operands[0], operands[1]);
18096 ;; After splitting up read-modify operations, array accesses with memory
18097 ;; operands might end up in form:
18098 ;;  sall    $2, %eax
18099 ;;  movl    4(%esp), %edx
18100 ;;  addl    %edx, %eax
18101 ;; instead of pre-splitting:
18102 ;;  sall    $2, %eax
18103 ;;  addl    4(%esp), %eax
18104 ;; Turn it into:
18105 ;;  movl    4(%esp), %edx
18106 ;;  leal    (%edx,%eax,4), %eax
18108 (define_peephole2
18109   [(match_scratch:W 5 "r")
18110    (parallel [(set (match_operand 0 "register_operand")
18111                    (ashift (match_operand 1 "register_operand")
18112                            (match_operand 2 "const_int_operand")))
18113                (clobber (reg:CC FLAGS_REG))])
18114    (parallel [(set (match_operand 3 "register_operand")
18115                    (plus (match_dup 0)
18116                          (match_operand 4 "x86_64_general_operand")))
18117                    (clobber (reg:CC FLAGS_REG))])]
18118   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18119    /* Validate MODE for lea.  */
18120    && ((!TARGET_PARTIAL_REG_STALL
18121         && (GET_MODE (operands[0]) == QImode
18122             || GET_MODE (operands[0]) == HImode))
18123        || GET_MODE (operands[0]) == SImode
18124        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18125    && (rtx_equal_p (operands[0], operands[3])
18126        || peep2_reg_dead_p (2, operands[0]))
18127    /* We reorder load and the shift.  */
18128    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18129   [(set (match_dup 5) (match_dup 4))
18130    (set (match_dup 0) (match_dup 1))]
18132   machine_mode op1mode = GET_MODE (operands[1]);
18133   machine_mode mode = op1mode == DImode ? DImode : SImode;
18134   int scale = 1 << INTVAL (operands[2]);
18135   rtx index = gen_lowpart (word_mode, operands[1]);
18136   rtx base = gen_lowpart (word_mode, operands[5]);
18137   rtx dest = gen_lowpart (mode, operands[3]);
18139   operands[1] = gen_rtx_PLUS (word_mode, base,
18140                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18141   if (mode != word_mode)
18142     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18144   operands[5] = base;
18145   if (op1mode != word_mode)
18146     operands[5] = gen_lowpart (op1mode, operands[5]);
18148   operands[0] = dest;
18151 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18152 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18153 ;; caught for use by garbage collectors and the like.  Using an insn that
18154 ;; maps to SIGILL makes it more likely the program will rightfully die.
18155 ;; Keeping with tradition, "6" is in honor of #UD.
18156 (define_insn "trap"
18157   [(trap_if (const_int 1) (const_int 6))]
18158   ""
18160 #ifdef HAVE_AS_IX86_UD2
18161   return "ud2";
18162 #else
18163   return ASM_SHORT "0x0b0f";
18164 #endif
18166   [(set_attr "length" "2")])
18168 (define_expand "prefetch"
18169   [(prefetch (match_operand 0 "address_operand")
18170              (match_operand:SI 1 "const_int_operand")
18171              (match_operand:SI 2 "const_int_operand"))]
18172   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18174   bool write = INTVAL (operands[1]) != 0;
18175   int locality = INTVAL (operands[2]);
18177   gcc_assert (IN_RANGE (locality, 0, 3));
18179   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18180      supported by SSE counterpart or the SSE prefetch is not available
18181      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18182      of locality.  */
18183   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18184     operands[2] = const2_rtx;
18185   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18186     operands[2] = GEN_INT (3);
18187   else
18188     operands[1] = const0_rtx;
18191 (define_insn "*prefetch_sse"
18192   [(prefetch (match_operand 0 "address_operand" "p")
18193              (const_int 0)
18194              (match_operand:SI 1 "const_int_operand"))]
18195   "TARGET_PREFETCH_SSE"
18197   static const char * const patterns[4] = {
18198    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18199   };
18201   int locality = INTVAL (operands[1]);
18202   gcc_assert (IN_RANGE (locality, 0, 3));
18204   return patterns[locality];
18206   [(set_attr "type" "sse")
18207    (set_attr "atom_sse_attr" "prefetch")
18208    (set (attr "length_address")
18209         (symbol_ref "memory_address_length (operands[0], false)"))
18210    (set_attr "memory" "none")])
18212 (define_insn "*prefetch_3dnow"
18213   [(prefetch (match_operand 0 "address_operand" "p")
18214              (match_operand:SI 1 "const_int_operand" "n")
18215              (const_int 3))]
18216   "TARGET_PRFCHW"
18218   if (INTVAL (operands[1]) == 0)
18219     return "prefetch\t%a0";
18220   else
18221     return "prefetchw\t%a0";
18223   [(set_attr "type" "mmx")
18224    (set (attr "length_address")
18225         (symbol_ref "memory_address_length (operands[0], false)"))
18226    (set_attr "memory" "none")])
18228 (define_insn "*prefetch_prefetchwt1"
18229   [(prefetch (match_operand 0 "address_operand" "p")
18230              (const_int 1)
18231              (const_int 2))]
18232   "TARGET_PREFETCHWT1"
18233   "prefetchwt1\t%a0";
18234   [(set_attr "type" "sse")
18235    (set (attr "length_address")
18236         (symbol_ref "memory_address_length (operands[0], false)"))
18237    (set_attr "memory" "none")])
18239 (define_expand "stack_protect_set"
18240   [(match_operand 0 "memory_operand")
18241    (match_operand 1 "memory_operand")]
18242   "TARGET_SSP_TLS_GUARD"
18244   rtx (*insn)(rtx, rtx);
18246 #ifdef TARGET_THREAD_SSP_OFFSET
18247   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18248   insn = (TARGET_LP64
18249           ? gen_stack_tls_protect_set_di
18250           : gen_stack_tls_protect_set_si);
18251 #else
18252   insn = (TARGET_LP64
18253           ? gen_stack_protect_set_di
18254           : gen_stack_protect_set_si);
18255 #endif
18257   emit_insn (insn (operands[0], operands[1]));
18258   DONE;
18261 (define_insn "stack_protect_set_<mode>"
18262   [(set (match_operand:PTR 0 "memory_operand" "=m")
18263         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18264                     UNSPEC_SP_SET))
18265    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18266    (clobber (reg:CC FLAGS_REG))]
18267   "TARGET_SSP_TLS_GUARD"
18268   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18269   [(set_attr "type" "multi")])
18271 (define_insn "stack_tls_protect_set_<mode>"
18272   [(set (match_operand:PTR 0 "memory_operand" "=m")
18273         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18274                     UNSPEC_SP_TLS_SET))
18275    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18276    (clobber (reg:CC FLAGS_REG))]
18277   ""
18278   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18279   [(set_attr "type" "multi")])
18281 (define_expand "stack_protect_test"
18282   [(match_operand 0 "memory_operand")
18283    (match_operand 1 "memory_operand")
18284    (match_operand 2)]
18285   "TARGET_SSP_TLS_GUARD"
18287   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18289   rtx (*insn)(rtx, rtx, rtx);
18291 #ifdef TARGET_THREAD_SSP_OFFSET
18292   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18293   insn = (TARGET_LP64
18294           ? gen_stack_tls_protect_test_di
18295           : gen_stack_tls_protect_test_si);
18296 #else
18297   insn = (TARGET_LP64
18298           ? gen_stack_protect_test_di
18299           : gen_stack_protect_test_si);
18300 #endif
18302   emit_insn (insn (flags, operands[0], operands[1]));
18304   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18305                                   flags, const0_rtx, operands[2]));
18306   DONE;
18309 (define_insn "stack_protect_test_<mode>"
18310   [(set (match_operand:CCZ 0 "flags_reg_operand")
18311         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18312                      (match_operand:PTR 2 "memory_operand" "m")]
18313                     UNSPEC_SP_TEST))
18314    (clobber (match_scratch:PTR 3 "=&r"))]
18315   "TARGET_SSP_TLS_GUARD"
18316   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18317   [(set_attr "type" "multi")])
18319 (define_insn "stack_tls_protect_test_<mode>"
18320   [(set (match_operand:CCZ 0 "flags_reg_operand")
18321         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18322                      (match_operand:PTR 2 "const_int_operand" "i")]
18323                     UNSPEC_SP_TLS_TEST))
18324    (clobber (match_scratch:PTR 3 "=r"))]
18325   ""
18326   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18327   [(set_attr "type" "multi")])
18329 (define_insn "sse4_2_crc32<mode>"
18330   [(set (match_operand:SI 0 "register_operand" "=r")
18331         (unspec:SI
18332           [(match_operand:SI 1 "register_operand" "0")
18333            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18334           UNSPEC_CRC32))]
18335   "TARGET_SSE4_2 || TARGET_CRC32"
18336   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18337   [(set_attr "type" "sselog1")
18338    (set_attr "prefix_rep" "1")
18339    (set_attr "prefix_extra" "1")
18340    (set (attr "prefix_data16")
18341      (if_then_else (match_operand:HI 2)
18342        (const_string "1")
18343        (const_string "*")))
18344    (set (attr "prefix_rex")
18345      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18346        (const_string "1")
18347        (const_string "*")))
18348    (set_attr "mode" "SI")])
18350 (define_insn "sse4_2_crc32di"
18351   [(set (match_operand:DI 0 "register_operand" "=r")
18352         (unspec:DI
18353           [(match_operand:DI 1 "register_operand" "0")
18354            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18355           UNSPEC_CRC32))]
18356   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18357   "crc32{q}\t{%2, %0|%0, %2}"
18358   [(set_attr "type" "sselog1")
18359    (set_attr "prefix_rep" "1")
18360    (set_attr "prefix_extra" "1")
18361    (set_attr "mode" "DI")])
18363 (define_insn "rdpmc"
18364   [(set (match_operand:DI 0 "register_operand" "=A")
18365         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18366                             UNSPECV_RDPMC))]
18367   "!TARGET_64BIT"
18368   "rdpmc"
18369   [(set_attr "type" "other")
18370    (set_attr "length" "2")])
18372 (define_insn "rdpmc_rex64"
18373   [(set (match_operand:DI 0 "register_operand" "=a")
18374         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18375                             UNSPECV_RDPMC))
18376    (set (match_operand:DI 1 "register_operand" "=d")
18377         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18378   "TARGET_64BIT"
18379   "rdpmc"
18380   [(set_attr "type" "other")
18381    (set_attr "length" "2")])
18383 (define_insn "rdtsc"
18384   [(set (match_operand:DI 0 "register_operand" "=A")
18385         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18386   "!TARGET_64BIT"
18387   "rdtsc"
18388   [(set_attr "type" "other")
18389    (set_attr "length" "2")])
18391 (define_insn "rdtsc_rex64"
18392   [(set (match_operand:DI 0 "register_operand" "=a")
18393         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18394    (set (match_operand:DI 1 "register_operand" "=d")
18395         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18396   "TARGET_64BIT"
18397   "rdtsc"
18398   [(set_attr "type" "other")
18399    (set_attr "length" "2")])
18401 (define_insn "rdtscp"
18402   [(set (match_operand:DI 0 "register_operand" "=A")
18403         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18404    (set (match_operand:SI 1 "register_operand" "=c")
18405         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18406   "!TARGET_64BIT"
18407   "rdtscp"
18408   [(set_attr "type" "other")
18409    (set_attr "length" "3")])
18411 (define_insn "rdtscp_rex64"
18412   [(set (match_operand:DI 0 "register_operand" "=a")
18413         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18414    (set (match_operand:DI 1 "register_operand" "=d")
18415         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18416    (set (match_operand:SI 2 "register_operand" "=c")
18417         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18418   "TARGET_64BIT"
18419   "rdtscp"
18420   [(set_attr "type" "other")
18421    (set_attr "length" "3")])
18423 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18425 ;; FXSR, XSAVE and XSAVEOPT instructions
18427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18429 (define_insn "fxsave"
18430   [(set (match_operand:BLK 0 "memory_operand" "=m")
18431         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18432   "TARGET_FXSR"
18433   "fxsave\t%0"
18434   [(set_attr "type" "other")
18435    (set_attr "memory" "store")
18436    (set (attr "length")
18437         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18439 (define_insn "fxsave64"
18440   [(set (match_operand:BLK 0 "memory_operand" "=m")
18441         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18442   "TARGET_64BIT && TARGET_FXSR"
18443   "fxsave64\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) + 4"))])
18449 (define_insn "fxrstor"
18450   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18451                     UNSPECV_FXRSTOR)]
18452   "TARGET_FXSR"
18453   "fxrstor\t%0"
18454   [(set_attr "type" "other")
18455    (set_attr "memory" "load")
18456    (set (attr "length")
18457         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18459 (define_insn "fxrstor64"
18460   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18461                     UNSPECV_FXRSTOR64)]
18462   "TARGET_64BIT && TARGET_FXSR"
18463   "fxrstor64\t%0"
18464   [(set_attr "type" "other")
18465    (set_attr "memory" "load")
18466    (set (attr "length")
18467         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18469 (define_int_iterator ANY_XSAVE
18470         [UNSPECV_XSAVE
18471          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18472          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18473          (UNSPECV_XSAVES "TARGET_XSAVES")])
18475 (define_int_iterator ANY_XSAVE64
18476         [UNSPECV_XSAVE64
18477          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18478          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18479          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18481 (define_int_attr xsave
18482         [(UNSPECV_XSAVE "xsave")
18483          (UNSPECV_XSAVE64 "xsave64")
18484          (UNSPECV_XSAVEOPT "xsaveopt")
18485          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18486          (UNSPECV_XSAVEC "xsavec")
18487          (UNSPECV_XSAVEC64 "xsavec64")
18488          (UNSPECV_XSAVES "xsaves")
18489          (UNSPECV_XSAVES64 "xsaves64")])
18491 (define_int_iterator ANY_XRSTOR
18492         [UNSPECV_XRSTOR
18493          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18495 (define_int_iterator ANY_XRSTOR64
18496         [UNSPECV_XRSTOR64
18497          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18499 (define_int_attr xrstor
18500         [(UNSPECV_XRSTOR "xrstor")
18501          (UNSPECV_XRSTOR64 "xrstor")
18502          (UNSPECV_XRSTORS "xrstors")
18503          (UNSPECV_XRSTORS64 "xrstors")])
18505 (define_insn "<xsave>"
18506   [(set (match_operand:BLK 0 "memory_operand" "=m")
18507         (unspec_volatile:BLK
18508          [(match_operand:DI 1 "register_operand" "A")]
18509          ANY_XSAVE))]
18510   "!TARGET_64BIT && TARGET_XSAVE"
18511   "<xsave>\t%0"
18512   [(set_attr "type" "other")
18513    (set_attr "memory" "store")
18514    (set (attr "length")
18515         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18517 (define_insn "<xsave>_rex64"
18518   [(set (match_operand:BLK 0 "memory_operand" "=m")
18519         (unspec_volatile:BLK
18520          [(match_operand:SI 1 "register_operand" "a")
18521           (match_operand:SI 2 "register_operand" "d")]
18522          ANY_XSAVE))]
18523   "TARGET_64BIT && TARGET_XSAVE"
18524   "<xsave>\t%0"
18525   [(set_attr "type" "other")
18526    (set_attr "memory" "store")
18527    (set (attr "length")
18528         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18530 (define_insn "<xsave>"
18531   [(set (match_operand:BLK 0 "memory_operand" "=m")
18532         (unspec_volatile:BLK
18533          [(match_operand:SI 1 "register_operand" "a")
18534           (match_operand:SI 2 "register_operand" "d")]
18535          ANY_XSAVE64))]
18536   "TARGET_64BIT && TARGET_XSAVE"
18537   "<xsave>\t%0"
18538   [(set_attr "type" "other")
18539    (set_attr "memory" "store")
18540    (set (attr "length")
18541         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18543 (define_insn "<xrstor>"
18544    [(unspec_volatile:BLK
18545      [(match_operand:BLK 0 "memory_operand" "m")
18546       (match_operand:DI 1 "register_operand" "A")]
18547      ANY_XRSTOR)]
18548   "!TARGET_64BIT && TARGET_XSAVE"
18549   "<xrstor>\t%0"
18550   [(set_attr "type" "other")
18551    (set_attr "memory" "load")
18552    (set (attr "length")
18553         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18555 (define_insn "<xrstor>_rex64"
18556    [(unspec_volatile:BLK
18557      [(match_operand:BLK 0 "memory_operand" "m")
18558       (match_operand:SI 1 "register_operand" "a")
18559       (match_operand:SI 2 "register_operand" "d")]
18560      ANY_XRSTOR)]
18561   "TARGET_64BIT && TARGET_XSAVE"
18562   "<xrstor>\t%0"
18563   [(set_attr "type" "other")
18564    (set_attr "memory" "load")
18565    (set (attr "length")
18566         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18568 (define_insn "<xrstor>64"
18569    [(unspec_volatile:BLK
18570      [(match_operand:BLK 0 "memory_operand" "m")
18571       (match_operand:SI 1 "register_operand" "a")
18572       (match_operand:SI 2 "register_operand" "d")]
18573      ANY_XRSTOR64)]
18574   "TARGET_64BIT && TARGET_XSAVE"
18575   "<xrstor>64\t%0"
18576   [(set_attr "type" "other")
18577    (set_attr "memory" "load")
18578    (set (attr "length")
18579         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18581 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18583 ;; Floating-point instructions for atomic compound assignments
18585 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18587 ; Clobber all floating-point registers on environment save and restore
18588 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18589 (define_insn "fnstenv"
18590   [(set (match_operand:BLK 0 "memory_operand" "=m")
18591         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18592    (clobber (reg:HI FPCR_REG))
18593    (clobber (reg:XF ST0_REG))
18594    (clobber (reg:XF ST1_REG))
18595    (clobber (reg:XF ST2_REG))
18596    (clobber (reg:XF ST3_REG))
18597    (clobber (reg:XF ST4_REG))
18598    (clobber (reg:XF ST5_REG))
18599    (clobber (reg:XF ST6_REG))
18600    (clobber (reg:XF ST7_REG))]
18601   "TARGET_80387"
18602   "fnstenv\t%0"
18603   [(set_attr "type" "other")
18604    (set_attr "memory" "store")
18605    (set (attr "length")
18606         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18608 (define_insn "fldenv"
18609   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18610                     UNSPECV_FLDENV)
18611    (clobber (reg:CCFP FPSR_REG))
18612    (clobber (reg:HI FPCR_REG))
18613    (clobber (reg:XF ST0_REG))
18614    (clobber (reg:XF ST1_REG))
18615    (clobber (reg:XF ST2_REG))
18616    (clobber (reg:XF ST3_REG))
18617    (clobber (reg:XF ST4_REG))
18618    (clobber (reg:XF ST5_REG))
18619    (clobber (reg:XF ST6_REG))
18620    (clobber (reg:XF ST7_REG))]
18621   "TARGET_80387"
18622   "fldenv\t%0"
18623   [(set_attr "type" "other")
18624    (set_attr "memory" "load")
18625    (set (attr "length")
18626         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18628 (define_insn "fnstsw"
18629   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18630         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18631   "TARGET_80387"
18632   "fnstsw\t%0"
18633   [(set_attr "type" "other,other")
18634    (set_attr "memory" "none,store")
18635    (set (attr "length")
18636         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18638 (define_insn "fnclex"
18639   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18640   "TARGET_80387"
18641   "fnclex"
18642   [(set_attr "type" "other")
18643    (set_attr "memory" "none")
18644    (set_attr "length" "2")])
18646 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18648 ;; LWP instructions
18650 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18652 (define_expand "lwp_llwpcb"
18653   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18654                     UNSPECV_LLWP_INTRINSIC)]
18655   "TARGET_LWP")
18657 (define_insn "*lwp_llwpcb<mode>1"
18658   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18659                     UNSPECV_LLWP_INTRINSIC)]
18660   "TARGET_LWP"
18661   "llwpcb\t%0"
18662   [(set_attr "type" "lwp")
18663    (set_attr "mode" "<MODE>")
18664    (set_attr "length" "5")])
18666 (define_expand "lwp_slwpcb"
18667   [(set (match_operand 0 "register_operand" "=r")
18668         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18669   "TARGET_LWP"
18671   rtx (*insn)(rtx);
18673   insn = (Pmode == DImode
18674           ? gen_lwp_slwpcbdi
18675           : gen_lwp_slwpcbsi);
18677   emit_insn (insn (operands[0]));
18678   DONE;
18681 (define_insn "lwp_slwpcb<mode>"
18682   [(set (match_operand:P 0 "register_operand" "=r")
18683         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18684   "TARGET_LWP"
18685   "slwpcb\t%0"
18686   [(set_attr "type" "lwp")
18687    (set_attr "mode" "<MODE>")
18688    (set_attr "length" "5")])
18690 (define_expand "lwp_lwpval<mode>3"
18691   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18692                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18693                      (match_operand:SI 3 "const_int_operand" "i")]
18694                     UNSPECV_LWPVAL_INTRINSIC)]
18695   "TARGET_LWP"
18696   ;; Avoid unused variable warning.
18697   "(void) operands[0];")
18699 (define_insn "*lwp_lwpval<mode>3_1"
18700   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18701                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18702                      (match_operand:SI 2 "const_int_operand" "i")]
18703                     UNSPECV_LWPVAL_INTRINSIC)]
18704   "TARGET_LWP"
18705   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18706   [(set_attr "type" "lwp")
18707    (set_attr "mode" "<MODE>")
18708    (set (attr "length")
18709         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18711 (define_expand "lwp_lwpins<mode>3"
18712   [(set (reg:CCC FLAGS_REG)
18713         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18714                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18715                               (match_operand:SI 3 "const_int_operand" "i")]
18716                              UNSPECV_LWPINS_INTRINSIC))
18717    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18718         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18719   "TARGET_LWP")
18721 (define_insn "*lwp_lwpins<mode>3_1"
18722   [(set (reg:CCC FLAGS_REG)
18723         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18724                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18725                               (match_operand:SI 2 "const_int_operand" "i")]
18726                              UNSPECV_LWPINS_INTRINSIC))]
18727   "TARGET_LWP"
18728   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18729   [(set_attr "type" "lwp")
18730    (set_attr "mode" "<MODE>")
18731    (set (attr "length")
18732         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18734 (define_int_iterator RDFSGSBASE
18735         [UNSPECV_RDFSBASE
18736          UNSPECV_RDGSBASE])
18738 (define_int_iterator WRFSGSBASE
18739         [UNSPECV_WRFSBASE
18740          UNSPECV_WRGSBASE])
18742 (define_int_attr fsgs
18743         [(UNSPECV_RDFSBASE "fs")
18744          (UNSPECV_RDGSBASE "gs")
18745          (UNSPECV_WRFSBASE "fs")
18746          (UNSPECV_WRGSBASE "gs")])
18748 (define_insn "rd<fsgs>base<mode>"
18749   [(set (match_operand:SWI48 0 "register_operand" "=r")
18750         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18751   "TARGET_64BIT && TARGET_FSGSBASE"
18752   "rd<fsgs>base\t%0"
18753   [(set_attr "type" "other")
18754    (set_attr "prefix_extra" "2")])
18756 (define_insn "wr<fsgs>base<mode>"
18757   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18758                     WRFSGSBASE)]
18759   "TARGET_64BIT && TARGET_FSGSBASE"
18760   "wr<fsgs>base\t%0"
18761   [(set_attr "type" "other")
18762    (set_attr "prefix_extra" "2")])
18764 (define_insn "rdrand<mode>_1"
18765   [(set (match_operand:SWI248 0 "register_operand" "=r")
18766         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18767    (set (reg:CCC FLAGS_REG)
18768         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18769   "TARGET_RDRND"
18770   "rdrand\t%0"
18771   [(set_attr "type" "other")
18772    (set_attr "prefix_extra" "1")])
18774 (define_insn "rdseed<mode>_1"
18775   [(set (match_operand:SWI248 0 "register_operand" "=r")
18776         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18777    (set (reg:CCC FLAGS_REG)
18778         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18779   "TARGET_RDSEED"
18780   "rdseed\t%0"
18781   [(set_attr "type" "other")
18782    (set_attr "prefix_extra" "1")])
18784 (define_expand "pause"
18785   [(set (match_dup 0)
18786         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18787   ""
18789   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18790   MEM_VOLATILE_P (operands[0]) = 1;
18793 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18794 ;; They have the same encoding.
18795 (define_insn "*pause"
18796   [(set (match_operand:BLK 0)
18797         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18798   ""
18799   "rep%; nop"
18800   [(set_attr "length" "2")
18801    (set_attr "memory" "unknown")])
18803 (define_expand "xbegin"
18804   [(set (match_operand:SI 0 "register_operand")
18805         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18806   "TARGET_RTM"
18808   rtx_code_label *label = gen_label_rtx ();
18810   /* xbegin is emitted as jump_insn, so reload won't be able
18811      to reload its operand.  Force the value into AX hard register.  */
18812   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18813   emit_move_insn (ax_reg, constm1_rtx);
18815   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18817   emit_label (label);
18818   LABEL_NUSES (label) = 1;
18820   emit_move_insn (operands[0], ax_reg);
18822   DONE;
18825 (define_insn "xbegin_1"
18826   [(set (pc)
18827         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18828                           (const_int 0))
18829                       (label_ref (match_operand 1))
18830                       (pc)))
18831    (set (match_operand:SI 0 "register_operand" "+a")
18832         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18833   "TARGET_RTM"
18834   "xbegin\t%l1"
18835   [(set_attr "type" "other")
18836    (set_attr "length" "6")])
18838 (define_insn "xend"
18839   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18840   "TARGET_RTM"
18841   "xend"
18842   [(set_attr "type" "other")
18843    (set_attr "length" "3")])
18845 (define_insn "xabort"
18846   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18847                     UNSPECV_XABORT)]
18848   "TARGET_RTM"
18849   "xabort\t%0"
18850   [(set_attr "type" "other")
18851    (set_attr "length" "3")])
18853 (define_expand "xtest"
18854   [(set (match_operand:QI 0 "register_operand")
18855         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18856   "TARGET_RTM"
18858   emit_insn (gen_xtest_1 ());
18860   ix86_expand_setcc (operands[0], NE,
18861                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18862   DONE;
18865 (define_insn "xtest_1"
18866   [(set (reg:CCZ FLAGS_REG)
18867         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18868   "TARGET_RTM"
18869   "xtest"
18870   [(set_attr "type" "other")
18871    (set_attr "length" "3")])
18873 (define_insn "pcommit"
18874   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18875   "TARGET_PCOMMIT"
18876   "pcommit"
18877   [(set_attr "type" "other")
18878    (set_attr "length" "4")])
18880 (define_insn "clwb"
18881   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18882                    UNSPECV_CLWB)]
18883   "TARGET_CLWB"
18884   "clwb\t%a0"
18885   [(set_attr "type" "sse")
18886    (set_attr "atom_sse_attr" "fence")
18887    (set_attr "memory" "unknown")])
18889 (define_insn "clflushopt"
18890   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18891                    UNSPECV_CLFLUSHOPT)]
18892   "TARGET_CLFLUSHOPT"
18893   "clflushopt\t%a0"
18894   [(set_attr "type" "sse")
18895    (set_attr "atom_sse_attr" "fence")
18896    (set_attr "memory" "unknown")])
18898 ;; MONITORX and MWAITX
18899 (define_insn "mwaitx"
18900   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18901                      (match_operand:SI 1 "register_operand" "a")
18902                      (match_operand:SI 2 "register_operand" "b")]
18903                    UNSPECV_MWAITX)]
18904   "TARGET_MWAITX"
18905 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18906 ;; Since 32bit register operands are implicitly zero extended to 64bit,
18907 ;; we only need to set up 32bit registers.
18908   "mwaitx"
18909   [(set_attr "length" "3")])
18911 (define_insn "monitorx_<mode>"
18912   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18913                      (match_operand:SI 1 "register_operand" "c")
18914                      (match_operand:SI 2 "register_operand" "d")]
18915                    UNSPECV_MONITORX)]
18916   "TARGET_MWAITX"
18917 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18918 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
18919 ;; zero extended to 64bit, we only need to set up 32bit registers.
18920   "%^monitorx"
18921   [(set (attr "length")
18922      (symbol_ref ("(Pmode != word_mode) + 3")))])
18924 ;; MPX instructions
18926 (define_expand "<mode>_mk"
18927   [(set (match_operand:BND 0 "register_operand")
18928     (unspec:BND
18929       [(mem:<bnd_ptr>
18930        (match_par_dup 3
18931         [(match_operand:<bnd_ptr> 1 "register_operand")
18932          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18933       UNSPEC_BNDMK))]
18934   "TARGET_MPX"
18936   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18937                                                   operands[2]),
18938                                 UNSPEC_BNDMK_ADDR);
18941 (define_insn "*<mode>_mk"
18942   [(set (match_operand:BND 0 "register_operand" "=w")
18943     (unspec:BND
18944       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18945         [(unspec:<bnd_ptr>
18946            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18947             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18948            UNSPEC_BNDMK_ADDR)])]
18949       UNSPEC_BNDMK))]
18950   "TARGET_MPX"
18951   "bndmk\t{%3, %0|%0, %3}"
18952   [(set_attr "type" "mpxmk")])
18954 (define_expand "mov<mode>"
18955   [(set (match_operand:BND 0 "general_operand")
18956         (match_operand:BND 1 "general_operand"))]
18957   "TARGET_MPX"
18959   ix86_expand_move (<MODE>mode, operands);DONE;
18962 (define_insn "*mov<mode>_internal_mpx"
18963   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18964         (match_operand:BND 1 "general_operand" "wm,w"))]
18965   "TARGET_MPX"
18966   "bndmov\t{%1, %0|%0, %1}"
18967   [(set_attr "type" "mpxmov")])
18969 (define_expand "<mode>_<bndcheck>"
18970   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18971                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18972               (set (match_dup 2)
18973                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18974   "TARGET_MPX"
18976   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18977   MEM_VOLATILE_P (operands[2]) = 1;
18980 (define_insn "*<mode>_<bndcheck>"
18981   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18982                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18983               (set (match_operand:BLK 2 "bnd_mem_operator")
18984                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18985   "TARGET_MPX"
18986   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18987   [(set_attr "type" "mpxchk")])
18989 (define_expand "<mode>_ldx"
18990   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18991                        (unspec:BND
18992                          [(mem:<bnd_ptr>
18993                            (match_par_dup 3
18994                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18995                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18996                          UNSPEC_BNDLDX))
18997               (use (mem:BLK (match_dup 1)))])]
18998   "TARGET_MPX"
19000   /* Avoid registers which connot be used as index.  */
19001   if (!index_register_operand (operands[2], Pmode))
19002     {
19003       rtx temp = gen_reg_rtx (Pmode);
19004       emit_move_insn (temp, operands[2]);
19005       operands[2] = temp;
19006     }
19008   /* If it was a register originally then it may have
19009      mode other than Pmode.  We need to extend in such
19010      case because bndldx may work only with Pmode regs.  */
19011   if (GET_MODE (operands[2]) != Pmode)
19012     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
19014   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19015                                                   operands[2]),
19016                                 UNSPEC_BNDLDX_ADDR);
19019 (define_insn "*<mode>_ldx"
19020   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
19021                        (unspec:BND
19022                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19023                            [(unspec:<bnd_ptr>
19024                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19025                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19026                             UNSPEC_BNDLDX_ADDR)])]
19027                          UNSPEC_BNDLDX))
19028               (use (mem:BLK (match_dup 1)))])]
19029   "TARGET_MPX"
19030   "bndldx\t{%3, %0|%0, %3}"
19031   [(set_attr "type" "mpxld")])
19033 (define_expand "<mode>_stx"
19034   [(parallel [(unspec [(mem:<bnd_ptr>
19035                          (match_par_dup 3
19036                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19037                             (match_operand:<bnd_ptr> 1 "register_operand")]))
19038                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
19039               (set (match_dup 4)
19040                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19041   "TARGET_MPX"
19043   /* Avoid registers which connot be used as index.  */
19044   if (!index_register_operand (operands[1], Pmode))
19045     {
19046       rtx temp = gen_reg_rtx (Pmode);
19047       emit_move_insn (temp, operands[1]);
19048       operands[1] = temp;
19049     }
19051   /* If it was a register originally then it may have
19052      mode other than Pmode.  We need to extend in such
19053      case because bndstx may work only with Pmode regs.  */
19054   if (GET_MODE (operands[1]) != Pmode)
19055     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
19057   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19058                                                   operands[1]),
19059                                 UNSPEC_BNDLDX_ADDR);
19060   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19061   MEM_VOLATILE_P (operands[4]) = 1;
19064 (define_insn "*<mode>_stx"
19065   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19066                          [(unspec:<bnd_ptr>
19067                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19068                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19069                          UNSPEC_BNDLDX_ADDR)])
19070                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
19071               (set (match_operand:BLK 4 "bnd_mem_operator")
19072                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19073   "TARGET_MPX"
19074   "bndstx\t{%2, %3|%3, %2}"
19075   [(set_attr "type" "mpxst")])
19077 (define_insn "move_size_reloc_<mode>"
19078   [(set (match_operand:SWI48 0 "register_operand" "=r")
19079        (unspec:SWI48
19080         [(match_operand:SWI48 1 "symbol_operand")]
19081         UNSPEC_SIZEOF))]
19082   "TARGET_MPX"
19084   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19085     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19086   else
19087     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19089   [(set_attr "type" "imov")
19090    (set_attr "mode" "<MODE>")])
19092 (include "mmx.md")
19093 (include "sse.md")
19094 (include "sync.md")