* config/i386/i386.md (*x86_mov<mode>cc_0_m1): Use type "alu1" rather
[official-gcc.git] / gcc / config / i386 / i386.md
blob1db95f0bb2b8106b43e38626a95b0d69431b70ae
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 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 addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68   ;; Relocation specifiers
69   UNSPEC_GOT
70   UNSPEC_GOTOFF
71   UNSPEC_GOTPCREL
72   UNSPEC_GOTTPOFF
73   UNSPEC_TPOFF
74   UNSPEC_NTPOFF
75   UNSPEC_DTPOFF
76   UNSPEC_GOTNTPOFF
77   UNSPEC_INDNTPOFF
78   UNSPEC_PLTOFF
79   UNSPEC_MACHOPIC_OFFSET
80   UNSPEC_PCREL
81   UNSPEC_SIZEOF
83   ;; Prologue support
84   UNSPEC_STACK_ALLOC
85   UNSPEC_SET_GOT
86   UNSPEC_SET_RIP
87   UNSPEC_SET_GOT_OFFSET
88   UNSPEC_MEMORY_BLOCKAGE
89   UNSPEC_PROBE_STACK
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
98   ;; Other random patterns
99   UNSPEC_SCAS
100   UNSPEC_FNSTSW
101   UNSPEC_SAHF
102   UNSPEC_NOTRAP
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
116   UNSPEC_SBB
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
170   ;; For ROUND support
171   UNSPEC_ROUND
173   ;; For CRC32 support
174   UNSPEC_CRC32
176   ;; For LZCNT suppoprt
177   UNSPEC_LZCNT
179   ;; For BMI support
180   UNSPEC_TZCNT
181   UNSPEC_BEXTR
183   ;; For BMI2 support
184   UNSPEC_PDEP
185   UNSPEC_PEXT
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
197   ;; IRET support
198   UNSPEC_INTERRUPT_RETURN
201 (define_c_enum "unspecv" [
202   UNSPECV_UD2
203   UNSPECV_BLOCKAGE
204   UNSPECV_STACK_PROBE
205   UNSPECV_PROBE_STACK_RANGE
206   UNSPECV_ALIGN
207   UNSPECV_PROLOGUE_USE
208   UNSPECV_SPLIT_STACK_RETURN
209   UNSPECV_CLD
210   UNSPECV_NOPS
211   UNSPECV_RDTSC
212   UNSPECV_RDTSCP
213   UNSPECV_RDPMC
214   UNSPECV_LLWP_INTRINSIC
215   UNSPECV_SLWP_INTRINSIC
216   UNSPECV_LWPVAL_INTRINSIC
217   UNSPECV_LWPINS_INTRINSIC
218   UNSPECV_RDFSBASE
219   UNSPECV_RDGSBASE
220   UNSPECV_WRFSBASE
221   UNSPECV_WRGSBASE
222   UNSPECV_FXSAVE
223   UNSPECV_FXRSTOR
224   UNSPECV_FXSAVE64
225   UNSPECV_FXRSTOR64
226   UNSPECV_XSAVE
227   UNSPECV_XRSTOR
228   UNSPECV_XSAVE64
229   UNSPECV_XRSTOR64
230   UNSPECV_XSAVEOPT
231   UNSPECV_XSAVEOPT64
232   UNSPECV_XSAVES
233   UNSPECV_XRSTORS
234   UNSPECV_XSAVES64
235   UNSPECV_XRSTORS64
236   UNSPECV_XSAVEC
237   UNSPECV_XSAVEC64
238   UNSPECV_XGETBV
239   UNSPECV_XSETBV
240   UNSPECV_WBINVD
241   UNSPECV_WBNOINVD
243   ;; For atomic compound assignments.
244   UNSPECV_FNSTENV
245   UNSPECV_FLDENV
246   UNSPECV_FNSTSW
247   UNSPECV_FNCLEX
249   ;; For RDRAND support
250   UNSPECV_RDRAND
252   ;; For RDSEED support
253   UNSPECV_RDSEED
255   ;; For RTM support
256   UNSPECV_XBEGIN
257   UNSPECV_XEND
258   UNSPECV_XABORT
259   UNSPECV_XTEST
261   UNSPECV_NLGR
263   ;; For CLWB support
264   UNSPECV_CLWB
266   ;; For CLFLUSHOPT support
267   UNSPECV_CLFLUSHOPT
269   ;; For MONITORX and MWAITX support 
270   UNSPECV_MONITORX
271   UNSPECV_MWAITX
273   ;; For CLZERO support
274   UNSPECV_CLZERO
276   ;; For RDPKRU and WRPKRU support
277   UNSPECV_PKU
279   ;; For RDPID support
280   UNSPECV_RDPID
282   ;; For CET support
283   UNSPECV_NOP_ENDBR
284   UNSPECV_NOP_RDSSP
285   UNSPECV_INCSSP
286   UNSPECV_SAVEPREVSSP
287   UNSPECV_RSTORSSP
288   UNSPECV_WRSS
289   UNSPECV_WRUSS
290   UNSPECV_SETSSBSY
291   UNSPECV_CLRSSBSY
292   UNSPECV_MOVDIRI
293   UNSPECV_MOVDIR64B
296 ;; Constants to represent rounding modes in the ROUND instruction
297 (define_constants
298   [(ROUND_FLOOR                 0x1)
299    (ROUND_CEIL                  0x2)
300    (ROUND_TRUNC                 0x3)
301    (ROUND_MXCSR                 0x4)
302    (ROUND_NO_EXC                0x8)
303   ])
305 ;; Constants to represent AVX512F embeded rounding
306 (define_constants
307   [(ROUND_NEAREST_INT                   0)
308    (ROUND_NEG_INF                       1)
309    (ROUND_POS_INF                       2)
310    (ROUND_ZERO                          3)
311    (NO_ROUND                            4)
312    (ROUND_SAE                           8)
313   ])
315 ;; Constants to represent pcomtrue/pcomfalse variants
316 (define_constants
317   [(PCOM_FALSE                  0)
318    (PCOM_TRUE                   1)
319    (COM_FALSE_S                 2)
320    (COM_FALSE_P                 3)
321    (COM_TRUE_S                  4)
322    (COM_TRUE_P                  5)
323   ])
325 ;; Constants used in the XOP pperm instruction
326 (define_constants
327   [(PPERM_SRC                   0x00)   /* copy source */
328    (PPERM_INVERT                0x20)   /* invert source */
329    (PPERM_REVERSE               0x40)   /* bit reverse source */
330    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
331    (PPERM_ZERO                  0x80)   /* all 0's */
332    (PPERM_ONES                  0xa0)   /* all 1's */
333    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
334    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
335    (PPERM_SRC1                  0x00)   /* use first source byte */
336    (PPERM_SRC2                  0x10)   /* use second source byte */
337    ])
339 ;; Registers by name.
340 (define_constants
341   [(AX_REG                       0)
342    (DX_REG                       1)
343    (CX_REG                       2)
344    (BX_REG                       3)
345    (SI_REG                       4)
346    (DI_REG                       5)
347    (BP_REG                       6)
348    (SP_REG                       7)
349    (ST0_REG                      8)
350    (ST1_REG                      9)
351    (ST2_REG                     10)
352    (ST3_REG                     11)
353    (ST4_REG                     12)
354    (ST5_REG                     13)
355    (ST6_REG                     14)
356    (ST7_REG                     15)
357    (ARGP_REG                    16)
358    (FLAGS_REG                   17)
359    (FPSR_REG                    18)
360    (FPCR_REG                    19)
361    (FRAME_REG                   20)
362    (XMM0_REG                    21)
363    (XMM1_REG                    22)
364    (XMM2_REG                    23)
365    (XMM3_REG                    24)
366    (XMM4_REG                    25)
367    (XMM5_REG                    26)
368    (XMM6_REG                    27)
369    (XMM7_REG                    28)
370    (MM0_REG                     29)
371    (MM1_REG                     30)
372    (MM2_REG                     31)
373    (MM3_REG                     32)
374    (MM4_REG                     33)
375    (MM5_REG                     34)
376    (MM6_REG                     35)
377    (MM7_REG                     36)
378    (R8_REG                      37)
379    (R9_REG                      38)
380    (R10_REG                     39)
381    (R11_REG                     40)
382    (R12_REG                     41)
383    (R13_REG                     42)
384    (R14_REG                     43)
385    (R15_REG                     44)
386    (XMM8_REG                    45)
387    (XMM9_REG                    46)
388    (XMM10_REG                   47)
389    (XMM11_REG                   48)
390    (XMM12_REG                   49)
391    (XMM13_REG                   50)
392    (XMM14_REG                   51)
393    (XMM15_REG                   52)
394    (XMM16_REG                   53)
395    (XMM17_REG                   54)
396    (XMM18_REG                   55)
397    (XMM19_REG                   56)
398    (XMM20_REG                   57)
399    (XMM21_REG                   58)
400    (XMM22_REG                   59)
401    (XMM23_REG                   60)
402    (XMM24_REG                   61)
403    (XMM25_REG                   62)
404    (XMM26_REG                   63)
405    (XMM27_REG                   64)
406    (XMM28_REG                   65)
407    (XMM29_REG                   66)
408    (XMM30_REG                   67)
409    (XMM31_REG                   68)
410    (MASK0_REG                   69)
411    (MASK1_REG                   70)
412    (MASK2_REG                   71)
413    (MASK3_REG                   72)
414    (MASK4_REG                   73)
415    (MASK5_REG                   74)
416    (MASK6_REG                   75)
417    (MASK7_REG                   76)
418    (BND0_REG                    77)
419    (BND1_REG                    78)
420    (BND2_REG                    79)
421    (BND3_REG                    80)
422    (FIRST_PSEUDO_REG            81)
423   ])
425 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
426 ;; from i386.c.
428 ;; In C guard expressions, put expressions which may be compile-time
429 ;; constants first.  This allows for better optimization.  For
430 ;; example, write "TARGET_64BIT && reload_completed", not
431 ;; "reload_completed && TARGET_64BIT".
434 ;; Processor type.
435 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
436                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
437                     bdver4,btver2,znver1"
438   (const (symbol_ref "ix86_schedule")))
440 ;; A basic instruction type.  Refinements due to arguments to be
441 ;; provided in other attributes.
442 (define_attr "type"
443   "other,multi,
444    alu,alu1,negnot,imov,imovx,lea,
445    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
446    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
447    push,pop,call,callv,leave,
448    str,bitmanip,
449    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
450    fxch,fistp,fisttp,frndint,
451    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452    ssemul,sseimul,ssediv,sselog,sselog1,
453    sseishft,sseishft1,ssecmp,ssecomi,
454    ssecvt,ssecvt1,sseicvt,sseins,
455    sseshuf,sseshuf1,ssemuladd,sse4arg,
456    lwp,mskmov,msklog,
457    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
458    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
459   (const_string "other"))
461 ;; Main data type used by the insn
462 (define_attr "mode"
463   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
464   V2DF,V2SF,V1DF,V8DF"
465   (const_string "unknown"))
467 ;; The CPU unit operations uses.
468 (define_attr "unit" "integer,i387,sse,mmx,unknown"
469   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
470                           fxch,fistp,fisttp,frndint")
471            (const_string "i387")
472          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
473                           ssemul,sseimul,ssediv,sselog,sselog1,
474                           sseishft,sseishft1,ssecmp,ssecomi,
475                           ssecvt,ssecvt1,sseicvt,sseins,
476                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
477            (const_string "sse")
478          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
479            (const_string "mmx")
480          (eq_attr "type" "other")
481            (const_string "unknown")]
482          (const_string "integer")))
484 ;; The (bounding maximum) length of an instruction immediate.
485 (define_attr "length_immediate" ""
486   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
487                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
488                           mpxld,mpxst")
489            (const_int 0)
490          (eq_attr "unit" "i387,sse,mmx")
491            (const_int 0)
492          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
493                           rotate,rotatex,rotate1,imul,icmp,push,pop")
494            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
495          (eq_attr "type" "imov,test")
496            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
497          (eq_attr "type" "call")
498            (if_then_else (match_operand 0 "constant_call_address_operand")
499              (const_int 4)
500              (const_int 0))
501          (eq_attr "type" "callv")
502            (if_then_else (match_operand 1 "constant_call_address_operand")
503              (const_int 4)
504              (const_int 0))
505          ;; We don't know the size before shorten_branches.  Expect
506          ;; the instruction to fit for better scheduling.
507          (eq_attr "type" "ibr")
508            (const_int 1)
509          ]
510          (symbol_ref "/* Update immediate_length and other attributes! */
511                       gcc_unreachable (),1")))
513 ;; The (bounding maximum) length of an instruction address.
514 (define_attr "length_address" ""
515   (cond [(eq_attr "type" "str,other,multi,fxch")
516            (const_int 0)
517          (and (eq_attr "type" "call")
518               (match_operand 0 "constant_call_address_operand"))
519              (const_int 0)
520          (and (eq_attr "type" "callv")
521               (match_operand 1 "constant_call_address_operand"))
522              (const_int 0)
523          ]
524          (symbol_ref "ix86_attr_length_address_default (insn)")))
526 ;; Set when length prefix is used.
527 (define_attr "prefix_data16" ""
528   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
529            (const_int 0)
530          (eq_attr "mode" "HI")
531            (const_int 1)
532          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
533            (const_int 1)
534         ]
535         (const_int 0)))
537 ;; Set when string REP prefix is used.
538 (define_attr "prefix_rep" ""
539   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
540            (const_int 0)
541          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
542            (const_int 1)
543          (and (eq_attr "type" "ibr,call,callv")
544               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
545            (const_int 1)
546         ]
547         (const_int 0)))
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
551   (if_then_else
552     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
553                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
554          (eq_attr "unit" "sse,mmx"))
555     (const_int 1)
556     (const_int 0)))
558 ;; Set when REX opcode prefix is used.
559 (define_attr "prefix_rex" ""
560   (cond [(not (match_test "TARGET_64BIT"))
561            (const_int 0)
562          (and (eq_attr "mode" "DI")
563               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
564                    (eq_attr "unit" "!mmx")))
565            (const_int 1)
566          (and (eq_attr "mode" "QI")
567               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
568            (const_int 1)
569          (match_test "x86_extended_reg_mentioned_p (insn)")
570            (const_int 1)
571          (and (eq_attr "type" "imovx")
572               (match_operand:QI 1 "ext_QIreg_operand"))
573            (const_int 1)
574         ]
575         (const_int 0)))
577 ;; There are also additional prefixes in 3DNOW, SSSE3.
578 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
579 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
580 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
581 (define_attr "prefix_extra" ""
582   (cond [(eq_attr "type" "ssemuladd,sse4arg")
583            (const_int 2)
584          (eq_attr "type" "sseiadd1,ssecvt1")
585            (const_int 1)
586         ]
587         (const_int 0)))
589 ;; Set when BND opcode prefix may be used.
590 (define_attr "maybe_prefix_bnd" "" (const_int 0))
592 ;; Prefix used: original, VEX or maybe VEX.
593 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
594   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
595            (const_string "vex")
596          (eq_attr "mode" "XI,V16SF,V8DF")
597            (const_string "evex")
598         ]
599         (const_string "orig")))
601 ;; VEX W bit is used.
602 (define_attr "prefix_vex_w" "" (const_int 0))
604 ;; The length of VEX prefix
605 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
606 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
607 ;; still prefix_0f 1, with prefix_extra 1.
608 (define_attr "length_vex" ""
609   (if_then_else (and (eq_attr "prefix_0f" "1")
610                      (eq_attr "prefix_extra" "0"))
611     (if_then_else (eq_attr "prefix_vex_w" "1")
612       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
613       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
614     (if_then_else (eq_attr "prefix_vex_w" "1")
615       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
616       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
618 ;; 4-bytes evex prefix and 1 byte opcode.
619 (define_attr "length_evex" "" (const_int 5))
621 ;; Set when modrm byte is used.
622 (define_attr "modrm" ""
623   (cond [(eq_attr "type" "str,leave")
624            (const_int 0)
625          (eq_attr "unit" "i387")
626            (const_int 0)
627          (and (eq_attr "type" "incdec")
628               (and (not (match_test "TARGET_64BIT"))
629                    (ior (match_operand:SI 1 "register_operand")
630                         (match_operand:HI 1 "register_operand"))))
631            (const_int 0)
632          (and (eq_attr "type" "push")
633               (not (match_operand 1 "memory_operand")))
634            (const_int 0)
635          (and (eq_attr "type" "pop")
636               (not (match_operand 0 "memory_operand")))
637            (const_int 0)
638          (and (eq_attr "type" "imov")
639               (and (not (eq_attr "mode" "DI"))
640                    (ior (and (match_operand 0 "register_operand")
641                              (match_operand 1 "immediate_operand"))
642                         (ior (and (match_operand 0 "ax_reg_operand")
643                                   (match_operand 1 "memory_displacement_only_operand"))
644                              (and (match_operand 0 "memory_displacement_only_operand")
645                                   (match_operand 1 "ax_reg_operand"))))))
646            (const_int 0)
647          (and (eq_attr "type" "call")
648               (match_operand 0 "constant_call_address_operand"))
649              (const_int 0)
650          (and (eq_attr "type" "callv")
651               (match_operand 1 "constant_call_address_operand"))
652              (const_int 0)
653          (and (eq_attr "type" "alu,alu1,icmp,test")
654               (match_operand 0 "ax_reg_operand"))
655              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
656          ]
657          (const_int 1)))
659 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
660   (cond [(eq_attr "modrm" "0")
661            (const_string "none")
662          (eq_attr "type" "alu,imul,ishift")
663            (const_string "op02")
664          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
665            (const_string "op01")
666          (eq_attr "type" "incdec")
667            (const_string "incdec")
668          (eq_attr "type" "push,pop")
669            (const_string "pushpop")]
670          (const_string "unknown")))
672 ;; The (bounding maximum) length of an instruction in bytes.
673 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
674 ;; Later we may want to split them and compute proper length as for
675 ;; other insns.
676 (define_attr "length" ""
677   (cond [(eq_attr "type" "other,multi,fistp,frndint")
678            (const_int 16)
679          (eq_attr "type" "fcmp")
680            (const_int 4)
681          (eq_attr "unit" "i387")
682            (plus (const_int 2)
683                  (plus (attr "prefix_data16")
684                        (attr "length_address")))
685          (ior (eq_attr "prefix" "evex")
686               (and (ior (eq_attr "prefix" "maybe_evex")
687                         (eq_attr "prefix" "maybe_vex"))
688                    (match_test "TARGET_AVX512F")))
689            (plus (attr "length_evex")
690                  (plus (attr "length_immediate")
691                        (plus (attr "modrm")
692                              (attr "length_address"))))
693          (ior (eq_attr "prefix" "vex")
694               (and (ior (eq_attr "prefix" "maybe_vex")
695                         (eq_attr "prefix" "maybe_evex"))
696                    (match_test "TARGET_AVX")))
697            (plus (attr "length_vex")
698                  (plus (attr "length_immediate")
699                        (plus (attr "modrm")
700                              (attr "length_address"))))]
701          (plus (plus (attr "modrm")
702                      (plus (attr "prefix_0f")
703                            (plus (attr "prefix_rex")
704                                  (plus (attr "prefix_extra")
705                                        (const_int 1)))))
706                (plus (attr "prefix_rep")
707                      (plus (attr "prefix_data16")
708                            (plus (attr "length_immediate")
709                                  (attr "length_address")))))))
711 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
712 ;; `store' if there is a simple memory reference therein, or `unknown'
713 ;; if the instruction is complex.
715 (define_attr "memory" "none,load,store,both,unknown"
716   (cond [(eq_attr "type" "other,multi,str,lwp")
717            (const_string "unknown")
718          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
719            (const_string "none")
720          (eq_attr "type" "fistp,leave")
721            (const_string "both")
722          (eq_attr "type" "frndint")
723            (const_string "load")
724          (eq_attr "type" "mpxld")
725            (const_string "load")
726          (eq_attr "type" "mpxst")
727            (const_string "store")
728          (eq_attr "type" "push")
729            (if_then_else (match_operand 1 "memory_operand")
730              (const_string "both")
731              (const_string "store"))
732          (eq_attr "type" "pop")
733            (if_then_else (match_operand 0 "memory_operand")
734              (const_string "both")
735              (const_string "load"))
736          (eq_attr "type" "setcc")
737            (if_then_else (match_operand 0 "memory_operand")
738              (const_string "store")
739              (const_string "none"))
740          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
741            (if_then_else (ior (match_operand 0 "memory_operand")
742                               (match_operand 1 "memory_operand"))
743              (const_string "load")
744              (const_string "none"))
745          (eq_attr "type" "ibr")
746            (if_then_else (match_operand 0 "memory_operand")
747              (const_string "load")
748              (const_string "none"))
749          (eq_attr "type" "call")
750            (if_then_else (match_operand 0 "constant_call_address_operand")
751              (const_string "none")
752              (const_string "load"))
753          (eq_attr "type" "callv")
754            (if_then_else (match_operand 1 "constant_call_address_operand")
755              (const_string "none")
756              (const_string "load"))
757          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
758               (match_operand 1 "memory_operand"))
759            (const_string "both")
760          (and (match_operand 0 "memory_operand")
761               (match_operand 1 "memory_operand"))
762            (const_string "both")
763          (match_operand 0 "memory_operand")
764            (const_string "store")
765          (match_operand 1 "memory_operand")
766            (const_string "load")
767          (and (eq_attr "type"
768                  "!alu1,negnot,ishift1,rotate1,
769                    imov,imovx,icmp,test,bitmanip,
770                    fmov,fcmp,fsgn,
771                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
772                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
773                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
774               (match_operand 2 "memory_operand"))
775            (const_string "load")
776          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
777               (match_operand 3 "memory_operand"))
778            (const_string "load")
779         ]
780         (const_string "none")))
782 ;; Indicates if an instruction has both an immediate and a displacement.
784 (define_attr "imm_disp" "false,true,unknown"
785   (cond [(eq_attr "type" "other,multi")
786            (const_string "unknown")
787          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
788               (and (match_operand 0 "memory_displacement_operand")
789                    (match_operand 1 "immediate_operand")))
790            (const_string "true")
791          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
792               (and (match_operand 0 "memory_displacement_operand")
793                    (match_operand 2 "immediate_operand")))
794            (const_string "true")
795         ]
796         (const_string "false")))
798 ;; Indicates if an FP operation has an integer source.
800 (define_attr "fp_int_src" "false,true"
801   (const_string "false"))
803 ;; Defines rounding mode of an FP operation.
805 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
806   (const_string "any"))
808 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
809 (define_attr "use_carry" "0,1" (const_string "0"))
811 ;; Define attribute to indicate unaligned ssemov insns
812 (define_attr "movu" "0,1" (const_string "0"))
814 ;; Used to control the "enabled" attribute on a per-instruction basis.
815 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
816                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
817                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
818                     avx512bw,noavx512bw,avx512dq,noavx512dq,
819                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
820   (const_string "base"))
822 (define_attr "enabled" ""
823   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
824          (eq_attr "isa" "x64_sse4")
825            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
826          (eq_attr "isa" "x64_sse4_noavx")
827            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
828          (eq_attr "isa" "x64_avx")
829            (symbol_ref "TARGET_64BIT && TARGET_AVX")
830          (eq_attr "isa" "x64_avx512dq")
831            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
832          (eq_attr "isa" "x64_avx512bw")
833            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
834          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
835          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
836          (eq_attr "isa" "sse2_noavx")
837            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
838          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
839          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
840          (eq_attr "isa" "sse4_noavx")
841            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
842          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
843          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
844          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
845          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
846          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
847          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
848          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
849          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
850          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
851          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
852          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
853          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
854          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
855          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
856          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
857          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
858         ]
859         (const_int 1)))
861 (define_attr "preferred_for_size" "" (const_int 1))
862 (define_attr "preferred_for_speed" "" (const_int 1))
864 ;; Describe a user's asm statement.
865 (define_asm_attributes
866   [(set_attr "length" "128")
867    (set_attr "type" "multi")])
869 (define_code_iterator plusminus [plus minus])
871 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
873 (define_code_iterator multdiv [mult div])
875 ;; Base name for define_insn
876 (define_code_attr plusminus_insn
877   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
878    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
880 ;; Base name for insn mnemonic.
881 (define_code_attr plusminus_mnemonic
882   [(plus "add") (ss_plus "adds") (us_plus "addus")
883    (minus "sub") (ss_minus "subs") (us_minus "subus")])
884 (define_code_attr multdiv_mnemonic
885   [(mult "mul") (div "div")])
887 ;; Mark commutative operators as such in constraints.
888 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
889                         (minus "") (ss_minus "") (us_minus "")])
891 ;; Mapping of max and min
892 (define_code_iterator maxmin [smax smin umax umin])
894 ;; Mapping of signed max and min
895 (define_code_iterator smaxmin [smax smin])
897 ;; Mapping of unsigned max and min
898 (define_code_iterator umaxmin [umax umin])
900 ;; Base name for integer and FP insn mnemonic
901 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
902                               (umax "maxu") (umin "minu")])
903 (define_code_attr maxmin_float [(smax "max") (smin "min")])
905 (define_int_iterator IEEE_MAXMIN
906         [UNSPEC_IEEE_MAX
907          UNSPEC_IEEE_MIN])
909 (define_int_attr ieee_maxmin
910         [(UNSPEC_IEEE_MAX "max")
911          (UNSPEC_IEEE_MIN "min")])
913 ;; Mapping of logic operators
914 (define_code_iterator any_logic [and ior xor])
915 (define_code_iterator any_or [ior xor])
916 (define_code_iterator fpint_logic [and xor])
918 ;; Base name for insn mnemonic.
919 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
921 ;; Mapping of logic-shift operators
922 (define_code_iterator any_lshift [ashift lshiftrt])
924 ;; Mapping of shift-right operators
925 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
927 ;; Mapping of all shift operators
928 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
930 ;; Base name for define_insn
931 (define_code_attr shift_insn
932   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
934 ;; Base name for insn mnemonic.
935 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
936 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
938 ;; Mapping of rotate operators
939 (define_code_iterator any_rotate [rotate rotatert])
941 ;; Base name for define_insn
942 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
944 ;; Base name for insn mnemonic.
945 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
947 ;; Mapping of abs neg operators
948 (define_code_iterator absneg [abs neg])
950 ;; Base name for x87 insn mnemonic.
951 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
953 ;; Used in signed and unsigned widening multiplications.
954 (define_code_iterator any_extend [sign_extend zero_extend])
956 ;; Prefix for insn menmonic.
957 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
959 ;; Prefix for define_insn
960 (define_code_attr u [(sign_extend "") (zero_extend "u")])
961 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
962 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
964 ;; Used in signed and unsigned truncations.
965 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
966 ;; Instruction suffix for truncations.
967 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
969 ;; Used in signed and unsigned fix.
970 (define_code_iterator any_fix [fix unsigned_fix])
971 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
973 ;; Used in signed and unsigned float.
974 (define_code_iterator any_float [float unsigned_float])
975 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
977 ;; All integer modes.
978 (define_mode_iterator SWI1248x [QI HI SI DI])
980 ;; All integer modes without QImode.
981 (define_mode_iterator SWI248x [HI SI DI])
983 ;; All integer modes without QImode and HImode.
984 (define_mode_iterator SWI48x [SI DI])
986 ;; All integer modes without SImode and DImode.
987 (define_mode_iterator SWI12 [QI HI])
989 ;; All integer modes without DImode.
990 (define_mode_iterator SWI124 [QI HI SI])
992 ;; All integer modes without QImode and DImode.
993 (define_mode_iterator SWI24 [HI SI])
995 ;; Single word integer modes.
996 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
998 ;; Single word integer modes without QImode.
999 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1001 ;; Single word integer modes without QImode and HImode.
1002 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1004 ;; All math-dependant single and double word integer modes.
1005 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1006                              (HI "TARGET_HIMODE_MATH")
1007                              SI DI (TI "TARGET_64BIT")])
1009 ;; Math-dependant single word integer modes.
1010 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1011                             (HI "TARGET_HIMODE_MATH")
1012                             SI (DI "TARGET_64BIT")])
1014 ;; Math-dependant integer modes without DImode.
1015 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1016                                (HI "TARGET_HIMODE_MATH")
1017                                SI])
1019 ;; Math-dependant integer modes with DImode.
1020 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1021                                  (HI "TARGET_HIMODE_MATH")
1022                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1024 ;; Math-dependant single word integer modes without QImode.
1025 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1026                                SI (DI "TARGET_64BIT")])
1028 ;; Double word integer modes.
1029 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1030                            (TI "TARGET_64BIT")])
1032 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1033 ;; compile time constant, it is faster to use <MODE_SIZE> than
1034 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1035 ;; command line options just use GET_MODE_SIZE macro.
1036 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1037                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1038                              (V16QI "16") (V32QI "32") (V64QI "64")
1039                              (V8HI "16") (V16HI "32") (V32HI "64")
1040                              (V4SI "16") (V8SI "32") (V16SI "64")
1041                              (V2DI "16") (V4DI "32") (V8DI "64")
1042                              (V1TI "16") (V2TI "32") (V4TI "64")
1043                              (V2DF "16") (V4DF "32") (V8DF "64")
1044                              (V4SF "16") (V8SF "32") (V16SF "64")])
1046 ;; Double word integer modes as mode attribute.
1047 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1048 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1050 ;; LEA mode corresponding to an integer mode
1051 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1053 ;; Half mode for double word integer modes.
1054 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1055                             (DI "TARGET_64BIT")])
1057 ;; Bound modes.
1058 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1059                            (BND64 "TARGET_LP64")])
1061 ;; Pointer mode corresponding to bound mode.
1062 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1064 ;; MPX check types
1065 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1067 ;; Check name
1068 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1069                            (UNSPEC_BNDCU "cu")
1070                            (UNSPEC_BNDCN "cn")])
1072 ;; Instruction suffix for integer modes.
1073 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1075 ;; Instruction suffix for masks.
1076 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1078 ;; Pointer size prefix for integer modes (Intel asm dialect)
1079 (define_mode_attr iptrsize [(QI "BYTE")
1080                             (HI "WORD")
1081                             (SI "DWORD")
1082                             (DI "QWORD")])
1084 ;; Register class for integer modes.
1085 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1087 ;; Immediate operand constraint for integer modes.
1088 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1090 ;; General operand constraint for word modes.
1091 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1093 ;; Immediate operand constraint for double integer modes.
1094 (define_mode_attr di [(SI "nF") (DI "Wd")])
1096 ;; Immediate operand constraint for shifts.
1097 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1099 ;; Print register name in the specified mode.
1100 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1102 ;; General operand predicate for integer modes.
1103 (define_mode_attr general_operand
1104         [(QI "general_operand")
1105          (HI "general_operand")
1106          (SI "x86_64_general_operand")
1107          (DI "x86_64_general_operand")
1108          (TI "x86_64_general_operand")])
1110 ;; General operand predicate for integer modes, where for TImode
1111 ;; we need both words of the operand to be general operands.
1112 (define_mode_attr general_hilo_operand
1113         [(QI "general_operand")
1114          (HI "general_operand")
1115          (SI "x86_64_general_operand")
1116          (DI "x86_64_general_operand")
1117          (TI "x86_64_hilo_general_operand")])
1119 ;; General sign extend operand predicate for integer modes,
1120 ;; which disallows VOIDmode operands and thus it is suitable
1121 ;; for use inside sign_extend.
1122 (define_mode_attr general_sext_operand
1123         [(QI "sext_operand")
1124          (HI "sext_operand")
1125          (SI "x86_64_sext_operand")
1126          (DI "x86_64_sext_operand")])
1128 ;; General sign/zero extend operand predicate for integer modes.
1129 (define_mode_attr general_szext_operand
1130         [(QI "general_operand")
1131          (HI "general_operand")
1132          (SI "x86_64_szext_general_operand")
1133          (DI "x86_64_szext_general_operand")])
1135 ;; Immediate operand predicate for integer modes.
1136 (define_mode_attr immediate_operand
1137         [(QI "immediate_operand")
1138          (HI "immediate_operand")
1139          (SI "x86_64_immediate_operand")
1140          (DI "x86_64_immediate_operand")])
1142 ;; Nonmemory operand predicate for integer modes.
1143 (define_mode_attr nonmemory_operand
1144         [(QI "nonmemory_operand")
1145          (HI "nonmemory_operand")
1146          (SI "x86_64_nonmemory_operand")
1147          (DI "x86_64_nonmemory_operand")])
1149 ;; Operand predicate for shifts.
1150 (define_mode_attr shift_operand
1151         [(QI "nonimmediate_operand")
1152          (HI "nonimmediate_operand")
1153          (SI "nonimmediate_operand")
1154          (DI "shiftdi_operand")
1155          (TI "register_operand")])
1157 ;; Operand predicate for shift argument.
1158 (define_mode_attr shift_immediate_operand
1159         [(QI "const_1_to_31_operand")
1160          (HI "const_1_to_31_operand")
1161          (SI "const_1_to_31_operand")
1162          (DI "const_1_to_63_operand")])
1164 ;; Input operand predicate for arithmetic left shifts.
1165 (define_mode_attr ashl_input_operand
1166         [(QI "nonimmediate_operand")
1167          (HI "nonimmediate_operand")
1168          (SI "nonimmediate_operand")
1169          (DI "ashldi_input_operand")
1170          (TI "reg_or_pm1_operand")])
1172 ;; SSE and x87 SFmode and DFmode floating point modes
1173 (define_mode_iterator MODEF [SF DF])
1175 ;; All x87 floating point modes
1176 (define_mode_iterator X87MODEF [SF DF XF])
1178 ;; SSE instruction suffix for various modes
1179 (define_mode_attr ssemodesuffix
1180   [(SF "ss") (DF "sd")
1181    (V16SF "ps") (V8DF "pd")
1182    (V8SF "ps") (V4DF "pd")
1183    (V4SF "ps") (V2DF "pd")
1184    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1185    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1186    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1188 ;; SSE vector suffix for floating point modes
1189 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1191 ;; SSE vector mode corresponding to a scalar mode
1192 (define_mode_attr ssevecmode
1193   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1194 (define_mode_attr ssevecmodelower
1195   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1197 ;; AVX512F vector mode corresponding to a scalar mode
1198 (define_mode_attr avx512fvecmode
1199   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1201 ;; Instruction suffix for REX 64bit operators.
1202 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1204 ;; This mode iterator allows :P to be used for patterns that operate on
1205 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1206 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1208 ;; This mode iterator allows :W to be used for patterns that operate on
1209 ;; word_mode sized quantities.
1210 (define_mode_iterator W
1211   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1213 ;; This mode iterator allows :PTR to be used for patterns that operate on
1214 ;; ptr_mode sized quantities.
1215 (define_mode_iterator PTR
1216   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1218 ;; Scheduling descriptions
1220 (include "pentium.md")
1221 (include "ppro.md")
1222 (include "k6.md")
1223 (include "athlon.md")
1224 (include "bdver1.md")
1225 (include "bdver3.md")
1226 (include "btver2.md")
1227 (include "znver1.md")
1228 (include "geode.md")
1229 (include "atom.md")
1230 (include "slm.md")
1231 (include "core2.md")
1232 (include "haswell.md")
1235 ;; Operand and operator predicates and constraints
1237 (include "predicates.md")
1238 (include "constraints.md")
1241 ;; Compare and branch/compare and store instructions.
1243 (define_expand "cbranch<mode>4"
1244   [(set (reg:CC FLAGS_REG)
1245         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1246                     (match_operand:SDWIM 2 "<general_operand>")))
1247    (set (pc) (if_then_else
1248                (match_operator 0 "ordered_comparison_operator"
1249                 [(reg:CC FLAGS_REG) (const_int 0)])
1250                (label_ref (match_operand 3))
1251                (pc)))]
1252   ""
1254   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1255     operands[1] = force_reg (<MODE>mode, operands[1]);
1256   ix86_expand_branch (GET_CODE (operands[0]),
1257                       operands[1], operands[2], operands[3]);
1258   DONE;
1261 (define_expand "cstore<mode>4"
1262   [(set (reg:CC FLAGS_REG)
1263         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1264                     (match_operand:SWIM 3 "<general_operand>")))
1265    (set (match_operand:QI 0 "register_operand")
1266         (match_operator 1 "ordered_comparison_operator"
1267           [(reg:CC FLAGS_REG) (const_int 0)]))]
1268   ""
1270   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1271     operands[2] = force_reg (<MODE>mode, operands[2]);
1272   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1273                      operands[2], operands[3]);
1274   DONE;
1277 (define_expand "cmp<mode>_1"
1278   [(set (reg:CC FLAGS_REG)
1279         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1280                     (match_operand:SWI48 1 "<general_operand>")))])
1282 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1283   [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1284    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1286 (define_insn "*cmp<mode>_ccz_1"
1287   [(set (reg FLAGS_REG)
1288         (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1289                         "nonimmediate_operand" "<r>,?m<r>,$k")
1290                  (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1291   "ix86_match_ccmode (insn, CCZmode)"
1292   "@
1293    test{<imodesuffix>}\t%0, %0
1294    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1295    ktest<mskmodesuffix>\t%0, %0"
1296   [(set_attr "type" "test,icmp,msklog")
1297    (set_attr "length_immediate" "0,1,*")
1298    (set_attr "modrm_class" "op0,unknown,*")
1299    (set_attr "prefix" "*,*,vex")
1300    (set_attr "mode" "<MODE>")])
1302 (define_insn "*cmp<mode>_ccno_1"
1303   [(set (reg FLAGS_REG)
1304         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1305                  (match_operand:SWI 1 "const0_operand")))]
1306   "ix86_match_ccmode (insn, CCNOmode)"
1307   "@
1308    test{<imodesuffix>}\t%0, %0
1309    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1310   [(set_attr "type" "test,icmp")
1311    (set_attr "length_immediate" "0,1")
1312    (set_attr "modrm_class" "op0,unknown")
1313    (set_attr "mode" "<MODE>")])
1315 (define_insn "*cmp<mode>_1"
1316   [(set (reg FLAGS_REG)
1317         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1318                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1319   "ix86_match_ccmode (insn, CCmode)"
1320   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1321   [(set_attr "type" "icmp")
1322    (set_attr "mode" "<MODE>")])
1324 (define_insn "*cmp<mode>_minus_1"
1325   [(set (reg FLAGS_REG)
1326         (compare
1327           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1328                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1329           (const_int 0)))]
1330   "ix86_match_ccmode (insn, CCGOCmode)"
1331   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1332   [(set_attr "type" "icmp")
1333    (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmpqi_ext_1"
1336   [(set (reg FLAGS_REG)
1337         (compare
1338           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1339           (subreg:QI
1340             (zero_extract:SI
1341               (match_operand 1 "ext_register_operand" "Q,Q")
1342               (const_int 8)
1343               (const_int 8)) 0)))]
1344   "ix86_match_ccmode (insn, CCmode)"
1345   "cmp{b}\t{%h1, %0|%0, %h1}"
1346   [(set_attr "isa" "*,nox64")
1347    (set_attr "type" "icmp")
1348    (set_attr "mode" "QI")])
1350 (define_insn "*cmpqi_ext_2"
1351   [(set (reg FLAGS_REG)
1352         (compare
1353           (subreg:QI
1354             (zero_extract:SI
1355               (match_operand 0 "ext_register_operand" "Q")
1356               (const_int 8)
1357               (const_int 8)) 0)
1358           (match_operand:QI 1 "const0_operand")))]
1359   "ix86_match_ccmode (insn, CCNOmode)"
1360   "test{b}\t%h0, %h0"
1361   [(set_attr "type" "test")
1362    (set_attr "length_immediate" "0")
1363    (set_attr "mode" "QI")])
1365 (define_expand "cmpqi_ext_3"
1366   [(set (reg:CC FLAGS_REG)
1367         (compare:CC
1368           (subreg:QI
1369             (zero_extract:SI
1370               (match_operand 0 "ext_register_operand")
1371               (const_int 8)
1372               (const_int 8)) 0)
1373           (match_operand:QI 1 "const_int_operand")))])
1375 (define_insn "*cmpqi_ext_3"
1376   [(set (reg FLAGS_REG)
1377         (compare
1378           (subreg:QI
1379             (zero_extract:SI
1380               (match_operand 0 "ext_register_operand" "Q,Q")
1381               (const_int 8)
1382               (const_int 8)) 0)
1383           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1384   "ix86_match_ccmode (insn, CCmode)"
1385   "cmp{b}\t{%1, %h0|%h0, %1}"
1386   [(set_attr "isa" "*,nox64")
1387    (set_attr "type" "icmp")
1388    (set_attr "mode" "QI")])
1390 (define_insn "*cmpqi_ext_4"
1391   [(set (reg FLAGS_REG)
1392         (compare
1393           (subreg:QI
1394             (zero_extract:SI
1395               (match_operand 0 "ext_register_operand" "Q")
1396               (const_int 8)
1397               (const_int 8)) 0)
1398           (subreg:QI
1399             (zero_extract:SI
1400               (match_operand 1 "ext_register_operand" "Q")
1401               (const_int 8)
1402               (const_int 8)) 0)))]
1403   "ix86_match_ccmode (insn, CCmode)"
1404   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1405   [(set_attr "type" "icmp")
1406    (set_attr "mode" "QI")])
1408 ;; These implement float point compares.
1409 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1410 ;; which would allow mix and match FP modes on the compares.  Which is what
1411 ;; the old patterns did, but with many more of them.
1413 (define_expand "cbranchxf4"
1414   [(set (reg:CC FLAGS_REG)
1415         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1416                     (match_operand:XF 2 "nonmemory_operand")))
1417    (set (pc) (if_then_else
1418               (match_operator 0 "ix86_fp_comparison_operator"
1419                [(reg:CC FLAGS_REG)
1420                 (const_int 0)])
1421               (label_ref (match_operand 3))
1422               (pc)))]
1423   "TARGET_80387"
1425   ix86_expand_branch (GET_CODE (operands[0]),
1426                       operands[1], operands[2], operands[3]);
1427   DONE;
1430 (define_expand "cstorexf4"
1431   [(set (reg:CC FLAGS_REG)
1432         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1433                     (match_operand:XF 3 "nonmemory_operand")))
1434    (set (match_operand:QI 0 "register_operand")
1435               (match_operator 1 "ix86_fp_comparison_operator"
1436                [(reg:CC FLAGS_REG)
1437                 (const_int 0)]))]
1438   "TARGET_80387"
1440   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1441                      operands[2], operands[3]);
1442   DONE;
1445 (define_expand "cbranch<mode>4"
1446   [(set (reg:CC FLAGS_REG)
1447         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1448                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1449    (set (pc) (if_then_else
1450               (match_operator 0 "ix86_fp_comparison_operator"
1451                [(reg:CC FLAGS_REG)
1452                 (const_int 0)])
1453               (label_ref (match_operand 3))
1454               (pc)))]
1455   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1457   ix86_expand_branch (GET_CODE (operands[0]),
1458                       operands[1], operands[2], operands[3]);
1459   DONE;
1462 (define_expand "cstore<mode>4"
1463   [(set (reg:CC FLAGS_REG)
1464         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1465                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1466    (set (match_operand:QI 0 "register_operand")
1467               (match_operator 1 "ix86_fp_comparison_operator"
1468                [(reg:CC FLAGS_REG)
1469                 (const_int 0)]))]
1470   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1472   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1473                      operands[2], operands[3]);
1474   DONE;
1477 (define_expand "cbranchcc4"
1478   [(set (pc) (if_then_else
1479               (match_operator 0 "comparison_operator"
1480                [(match_operand 1 "flags_reg_operand")
1481                 (match_operand 2 "const0_operand")])
1482               (label_ref (match_operand 3))
1483               (pc)))]
1484   ""
1486   ix86_expand_branch (GET_CODE (operands[0]),
1487                       operands[1], operands[2], operands[3]);
1488   DONE;
1491 (define_expand "cstorecc4"
1492   [(set (match_operand:QI 0 "register_operand")
1493               (match_operator 1 "comparison_operator"
1494                [(match_operand 2 "flags_reg_operand")
1495                 (match_operand 3 "const0_operand")]))]
1496   ""
1498   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1499                      operands[2], operands[3]);
1500   DONE;
1504 ;; FP compares, step 1:
1505 ;; Set the FP condition codes.
1507 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1508 ;; used to manage the reg stack popping would not be preserved.
1510 (define_insn "*cmp<mode>_0_i387"
1511   [(set (match_operand:HI 0 "register_operand" "=a")
1512         (unspec:HI
1513           [(compare:CCFP
1514              (match_operand:X87MODEF 1 "register_operand" "f")
1515              (match_operand:X87MODEF 2 "const0_operand"))]
1516         UNSPEC_FNSTSW))]
1517   "TARGET_80387"
1518   "* return output_fp_compare (insn, operands, false, false);"
1519   [(set_attr "type" "multi")
1520    (set_attr "unit" "i387")
1521    (set_attr "mode" "<MODE>")])
1523 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1524   [(set (reg:CCFP FLAGS_REG)
1525         (compare:CCFP
1526           (match_operand:X87MODEF 1 "register_operand" "f")
1527           (match_operand:X87MODEF 2 "const0_operand")))
1528    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1529   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1530   "#"
1531   "&& reload_completed"
1532   [(set (match_dup 0)
1533         (unspec:HI
1534           [(compare:CCFP (match_dup 1)(match_dup 2))]
1535         UNSPEC_FNSTSW))
1536    (set (reg:CC FLAGS_REG)
1537         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1538   ""
1539   [(set_attr "type" "multi")
1540    (set_attr "unit" "i387")
1541    (set_attr "mode" "<MODE>")])
1543 (define_insn "*cmpxf_i387"
1544   [(set (match_operand:HI 0 "register_operand" "=a")
1545         (unspec:HI
1546           [(compare:CCFP
1547              (match_operand:XF 1 "register_operand" "f")
1548              (match_operand:XF 2 "register_operand" "f"))]
1549           UNSPEC_FNSTSW))]
1550   "TARGET_80387"
1551   "* return output_fp_compare (insn, operands, false, false);"
1552   [(set_attr "type" "multi")
1553    (set_attr "unit" "i387")
1554    (set_attr "mode" "XF")])
1556 (define_insn_and_split "*cmpxf_cc_i387"
1557   [(set (reg:CCFP FLAGS_REG)
1558         (compare:CCFP
1559           (match_operand:XF 1 "register_operand" "f")
1560           (match_operand:XF 2 "register_operand" "f")))
1561    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1562   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1563   "#"
1564   "&& reload_completed"
1565   [(set (match_dup 0)
1566         (unspec:HI
1567           [(compare:CCFP (match_dup 1)(match_dup 2))]
1568         UNSPEC_FNSTSW))
1569    (set (reg:CC FLAGS_REG)
1570         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1571   ""
1572   [(set_attr "type" "multi")
1573    (set_attr "unit" "i387")
1574    (set_attr "mode" "XF")])
1576 (define_insn "*cmp<mode>_i387"
1577   [(set (match_operand:HI 0 "register_operand" "=a")
1578         (unspec:HI
1579           [(compare:CCFP
1580              (match_operand:MODEF 1 "register_operand" "f")
1581              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1582           UNSPEC_FNSTSW))]
1583   "TARGET_80387"
1584   "* return output_fp_compare (insn, operands, false, false);"
1585   [(set_attr "type" "multi")
1586    (set_attr "unit" "i387")
1587    (set_attr "mode" "<MODE>")])
1589 (define_insn_and_split "*cmp<mode>_cc_i387"
1590   [(set (reg:CCFP FLAGS_REG)
1591         (compare:CCFP
1592           (match_operand:MODEF 1 "register_operand" "f")
1593           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1594    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1595   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1596   "#"
1597   "&& reload_completed"
1598   [(set (match_dup 0)
1599         (unspec:HI
1600           [(compare:CCFP (match_dup 1)(match_dup 2))]
1601         UNSPEC_FNSTSW))
1602    (set (reg:CC FLAGS_REG)
1603         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1604   ""
1605   [(set_attr "type" "multi")
1606    (set_attr "unit" "i387")
1607    (set_attr "mode" "<MODE>")])
1609 (define_insn "*cmpu<mode>_i387"
1610   [(set (match_operand:HI 0 "register_operand" "=a")
1611         (unspec:HI
1612           [(unspec:CCFP
1613              [(compare:CCFP
1614                 (match_operand:X87MODEF 1 "register_operand" "f")
1615                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1616              UNSPEC_NOTRAP)]
1617           UNSPEC_FNSTSW))]
1618   "TARGET_80387"
1619   "* return output_fp_compare (insn, operands, false, true);"
1620   [(set_attr "type" "multi")
1621    (set_attr "unit" "i387")
1622    (set_attr "mode" "<MODE>")])
1624 (define_insn_and_split "*cmpu<mode>_cc_i387"
1625   [(set (reg:CCFP FLAGS_REG)
1626         (unspec:CCFP
1627           [(compare:CCFP
1628              (match_operand:X87MODEF 1 "register_operand" "f")
1629              (match_operand:X87MODEF 2 "register_operand" "f"))]
1630           UNSPEC_NOTRAP))
1631    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1632   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1633   "#"
1634   "&& reload_completed"
1635   [(set (match_dup 0)
1636         (unspec:HI
1637           [(unspec:CCFP
1638              [(compare:CCFP (match_dup 1)(match_dup 2))]
1639              UNSPEC_NOTRAP)]
1640           UNSPEC_FNSTSW))
1641    (set (reg:CC FLAGS_REG)
1642         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1643   ""
1644   [(set_attr "type" "multi")
1645    (set_attr "unit" "i387")
1646    (set_attr "mode" "<MODE>")])
1648 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1649   [(set (match_operand:HI 0 "register_operand" "=a")
1650         (unspec:HI
1651           [(compare:CCFP
1652              (match_operand:X87MODEF 1 "register_operand" "f")
1653              (float:X87MODEF
1654                (match_operand:SWI24 2 "memory_operand" "m")))]
1655           UNSPEC_FNSTSW))]
1656   "TARGET_80387
1657    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1658        || optimize_function_for_size_p (cfun))"
1659   "* return output_fp_compare (insn, operands, false, false);"
1660   [(set_attr "type" "multi")
1661    (set_attr "unit" "i387")
1662    (set_attr "fp_int_src" "true")
1663    (set_attr "mode" "<SWI24:MODE>")])
1665 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1666   [(set (reg:CCFP FLAGS_REG)
1667         (compare:CCFP
1668           (match_operand:X87MODEF 1 "register_operand" "f")
1669           (float:X87MODEF
1670             (match_operand:SWI24 2 "memory_operand" "m"))))
1671    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1672   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1673    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1674        || optimize_function_for_size_p (cfun))"
1675   "#"
1676   "&& reload_completed"
1677   [(set (match_dup 0)
1678         (unspec:HI
1679           [(compare:CCFP
1680              (match_dup 1)
1681              (float:X87MODEF (match_dup 2)))]
1682         UNSPEC_FNSTSW))
1683    (set (reg:CC FLAGS_REG)
1684         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1685   ""
1686   [(set_attr "type" "multi")
1687    (set_attr "unit" "i387")
1688    (set_attr "fp_int_src" "true")
1689    (set_attr "mode" "<SWI24:MODE>")])
1691 ;; FP compares, step 2
1692 ;; Move the fpsw to ax.
1694 (define_insn "x86_fnstsw_1"
1695   [(set (match_operand:HI 0 "register_operand" "=a")
1696         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1697   "TARGET_80387"
1698   "fnstsw\t%0"
1699   [(set_attr "length" "2")
1700    (set_attr "mode" "SI")
1701    (set_attr "unit" "i387")])
1703 ;; FP compares, step 3
1704 ;; Get ax into flags, general case.
1706 (define_insn "x86_sahf_1"
1707   [(set (reg:CC FLAGS_REG)
1708         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1709                    UNSPEC_SAHF))]
1710   "TARGET_SAHF"
1712 #ifndef HAVE_AS_IX86_SAHF
1713   if (TARGET_64BIT)
1714     return ASM_BYTE "0x9e";
1715   else
1716 #endif
1717   return "sahf";
1719   [(set_attr "length" "1")
1720    (set_attr "athlon_decode" "vector")
1721    (set_attr "amdfam10_decode" "direct")
1722    (set_attr "bdver1_decode" "direct")
1723    (set_attr "mode" "SI")])
1725 ;; Pentium Pro can do steps 1 through 3 in one go.
1726 ;; (these instructions set flags directly)
1728 (define_subst_attr "unord" "unord_subst" "" "u")
1729 (define_subst_attr "unordered" "unord_subst" "false" "true")
1731 (define_subst "unord_subst"
1732   [(set (match_operand:CCFP 0)
1733         (match_operand:CCFP 1))]
1734   ""
1735   [(set (match_dup 0)
1736         (unspec:CCFP
1737           [(match_dup 1)]
1738           UNSPEC_NOTRAP))])
1740 (define_insn "*cmpi<unord><MODEF:mode>"
1741   [(set (reg:CCFP FLAGS_REG)
1742         (compare:CCFP
1743           (match_operand:MODEF 0 "register_operand" "f,v")
1744           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1745   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1746    || (TARGET_80387 && TARGET_CMOVE)"
1747   "@
1748    * return output_fp_compare (insn, operands, true, <unordered>);
1749    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1750   [(set_attr "type" "fcmp,ssecomi")
1751    (set_attr "prefix" "orig,maybe_vex")
1752    (set_attr "mode" "<MODEF:MODE>")
1753    (set_attr "prefix_rep" "*,0")
1754    (set (attr "prefix_data16")
1755         (cond [(eq_attr "alternative" "0")
1756                  (const_string "*")
1757                (eq_attr "mode" "DF")
1758                  (const_string "1")
1759               ]
1760               (const_string "0")))
1761    (set_attr "athlon_decode" "vector")
1762    (set_attr "amdfam10_decode" "direct")
1763    (set_attr "bdver1_decode" "double")
1764    (set_attr "znver1_decode" "double")
1765    (set (attr "enabled")
1766      (if_then_else
1767        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1768        (if_then_else
1769          (eq_attr "alternative" "0")
1770          (symbol_ref "TARGET_MIX_SSE_I387")
1771          (symbol_ref "true"))
1772        (if_then_else
1773          (eq_attr "alternative" "0")
1774          (symbol_ref "true")
1775          (symbol_ref "false"))))])
1777 (define_insn "*cmpi<unord>xf_i387"
1778   [(set (reg:CCFP FLAGS_REG)
1779         (compare:CCFP
1780           (match_operand:XF 0 "register_operand" "f")
1781           (match_operand:XF 1 "register_operand" "f")))]
1782   "TARGET_80387 && TARGET_CMOVE"
1783   "* return output_fp_compare (insn, operands, true, <unordered>);"
1784   [(set_attr "type" "fcmp")
1785    (set_attr "mode" "XF")
1786    (set_attr "athlon_decode" "vector")
1787    (set_attr "amdfam10_decode" "direct")
1788    (set_attr "bdver1_decode" "double")
1789    (set_attr "znver1_decode" "double")])
1791 ;; Push/pop instructions.
1793 (define_insn "*push<mode>2"
1794   [(set (match_operand:DWI 0 "push_operand" "=<")
1795         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1796   ""
1797   "#"
1798   [(set_attr "type" "multi")
1799    (set_attr "mode" "<MODE>")])
1801 (define_split
1802   [(set (match_operand:DWI 0 "push_operand")
1803         (match_operand:DWI 1 "general_gr_operand"))]
1804   "reload_completed"
1805   [(const_int 0)]
1806   "ix86_split_long_move (operands); DONE;")
1808 (define_insn "*pushdi2_rex64"
1809   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1810         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1811   "TARGET_64BIT"
1812   "@
1813    push{q}\t%1
1814    #"
1815   [(set_attr "type" "push,multi")
1816    (set_attr "mode" "DI")])
1818 ;; Convert impossible pushes of immediate to existing instructions.
1819 ;; First try to get scratch register and go through it.  In case this
1820 ;; fails, push sign extended lower part first and then overwrite
1821 ;; upper part by 32bit move.
1822 (define_peephole2
1823   [(match_scratch:DI 2 "r")
1824    (set (match_operand:DI 0 "push_operand")
1825         (match_operand:DI 1 "immediate_operand"))]
1826   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1827    && !x86_64_immediate_operand (operands[1], DImode)"
1828   [(set (match_dup 2) (match_dup 1))
1829    (set (match_dup 0) (match_dup 2))])
1831 ;; We need to define this as both peepholer and splitter for case
1832 ;; peephole2 pass is not run.
1833 ;; "&& 1" is needed to keep it from matching the previous pattern.
1834 (define_peephole2
1835   [(set (match_operand:DI 0 "push_operand")
1836         (match_operand:DI 1 "immediate_operand"))]
1837   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1839   [(set (match_dup 0) (match_dup 1))
1840    (set (match_dup 2) (match_dup 3))]
1842   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1844   operands[1] = gen_lowpart (DImode, operands[2]);
1845   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1846                                                    GEN_INT (4)));
1849 (define_split
1850   [(set (match_operand:DI 0 "push_operand")
1851         (match_operand:DI 1 "immediate_operand"))]
1852   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1853                     ? epilogue_completed : reload_completed)
1854    && !symbolic_operand (operands[1], DImode)
1855    && !x86_64_immediate_operand (operands[1], DImode)"
1856   [(set (match_dup 0) (match_dup 1))
1857    (set (match_dup 2) (match_dup 3))]
1859   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1861   operands[1] = gen_lowpart (DImode, operands[2]);
1862   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1863                                                    GEN_INT (4)));
1866 (define_insn "*pushsi2"
1867   [(set (match_operand:SI 0 "push_operand" "=<")
1868         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1869   "!TARGET_64BIT"
1870   "push{l}\t%1"
1871   [(set_attr "type" "push")
1872    (set_attr "mode" "SI")])
1874 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1875 ;; "push a byte/word".  But actually we use pushl, which has the effect
1876 ;; of rounding the amount pushed up to a word.
1878 ;; For TARGET_64BIT we always round up to 8 bytes.
1879 (define_insn "*push<mode>2_rex64"
1880   [(set (match_operand:SWI124 0 "push_operand" "=X")
1881         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1882   "TARGET_64BIT"
1883   "push{q}\t%q1"
1884   [(set_attr "type" "push")
1885    (set_attr "mode" "DI")])
1887 (define_insn "*push<mode>2"
1888   [(set (match_operand:SWI12 0 "push_operand" "=X")
1889         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1890   "!TARGET_64BIT"
1891   "push{l}\t%k1"
1892   [(set_attr "type" "push")
1893    (set_attr "mode" "SI")])
1895 (define_insn "*push<mode>2_prologue"
1896   [(set (match_operand:W 0 "push_operand" "=<")
1897         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1898    (clobber (mem:BLK (scratch)))]
1899   ""
1900   "push{<imodesuffix>}\t%1"
1901   [(set_attr "type" "push")
1902    (set_attr "mode" "<MODE>")])
1904 (define_insn "*pop<mode>1"
1905   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1906         (match_operand:W 1 "pop_operand" ">"))]
1907   ""
1908   "pop{<imodesuffix>}\t%0"
1909   [(set_attr "type" "pop")
1910    (set_attr "mode" "<MODE>")])
1912 (define_insn "*pop<mode>1_epilogue"
1913   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1914         (match_operand:W 1 "pop_operand" ">"))
1915    (clobber (mem:BLK (scratch)))]
1916   ""
1917   "pop{<imodesuffix>}\t%0"
1918   [(set_attr "type" "pop")
1919    (set_attr "mode" "<MODE>")])
1921 (define_insn "*pushfl<mode>2"
1922   [(set (match_operand:W 0 "push_operand" "=<")
1923         (match_operand:W 1 "flags_reg_operand"))]
1924   ""
1925   "pushf{<imodesuffix>}"
1926   [(set_attr "type" "push")
1927    (set_attr "mode" "<MODE>")])
1929 (define_insn "*popfl<mode>1"
1930   [(set (match_operand:W 0 "flags_reg_operand")
1931         (match_operand:W 1 "pop_operand" ">"))]
1932   ""
1933   "popf{<imodesuffix>}"
1934   [(set_attr "type" "pop")
1935    (set_attr "mode" "<MODE>")])
1938 ;; Reload patterns to support multi-word load/store
1939 ;; with non-offsetable address.
1940 (define_expand "reload_noff_store"
1941   [(parallel [(match_operand 0 "memory_operand" "=m")
1942               (match_operand 1 "register_operand" "r")
1943               (match_operand:DI 2 "register_operand" "=&r")])]
1944   "TARGET_64BIT"
1946   rtx mem = operands[0];
1947   rtx addr = XEXP (mem, 0);
1949   emit_move_insn (operands[2], addr);
1950   mem = replace_equiv_address_nv (mem, operands[2]);
1952   emit_insn (gen_rtx_SET (mem, operands[1]));
1953   DONE;
1956 (define_expand "reload_noff_load"
1957   [(parallel [(match_operand 0 "register_operand" "=r")
1958               (match_operand 1 "memory_operand" "m")
1959               (match_operand:DI 2 "register_operand" "=r")])]
1960   "TARGET_64BIT"
1962   rtx mem = operands[1];
1963   rtx addr = XEXP (mem, 0);
1965   emit_move_insn (operands[2], addr);
1966   mem = replace_equiv_address_nv (mem, operands[2]);
1968   emit_insn (gen_rtx_SET (operands[0], mem));
1969   DONE;
1972 ;; Move instructions.
1974 (define_expand "movxi"
1975   [(set (match_operand:XI 0 "nonimmediate_operand")
1976         (match_operand:XI 1 "general_operand"))]
1977   "TARGET_AVX512F"
1978   "ix86_expand_vector_move (XImode, operands); DONE;")
1980 (define_expand "movoi"
1981   [(set (match_operand:OI 0 "nonimmediate_operand")
1982         (match_operand:OI 1 "general_operand"))]
1983   "TARGET_AVX"
1984   "ix86_expand_vector_move (OImode, operands); DONE;")
1986 (define_expand "movti"
1987   [(set (match_operand:TI 0 "nonimmediate_operand")
1988         (match_operand:TI 1 "general_operand"))]
1989   "TARGET_64BIT || TARGET_SSE"
1991   if (TARGET_64BIT)
1992     ix86_expand_move (TImode, operands);
1993   else
1994     ix86_expand_vector_move (TImode, operands);
1995   DONE;
1998 ;; This expands to what emit_move_complex would generate if we didn't
1999 ;; have a movti pattern.  Having this avoids problems with reload on
2000 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2001 ;; to have around all the time.
2002 (define_expand "movcdi"
2003   [(set (match_operand:CDI 0 "nonimmediate_operand")
2004         (match_operand:CDI 1 "general_operand"))]
2005   ""
2007   if (push_operand (operands[0], CDImode))
2008     emit_move_complex_push (CDImode, operands[0], operands[1]);
2009   else
2010     emit_move_complex_parts (operands[0], operands[1]);
2011   DONE;
2014 (define_expand "mov<mode>"
2015   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2016         (match_operand:SWI1248x 1 "general_operand"))]
2017   ""
2018   "ix86_expand_move (<MODE>mode, operands); DONE;")
2020 (define_insn "*mov<mode>_xor"
2021   [(set (match_operand:SWI48 0 "register_operand" "=r")
2022         (match_operand:SWI48 1 "const0_operand"))
2023    (clobber (reg:CC FLAGS_REG))]
2024   "reload_completed"
2025   "xor{l}\t%k0, %k0"
2026   [(set_attr "type" "alu1")
2027    (set_attr "modrm_class" "op0")
2028    (set_attr "mode" "SI")
2029    (set_attr "length_immediate" "0")])
2031 (define_insn "*mov<mode>_or"
2032   [(set (match_operand:SWI48 0 "register_operand" "=r")
2033         (match_operand:SWI48 1 "constm1_operand"))
2034    (clobber (reg:CC FLAGS_REG))]
2035   "reload_completed"
2036   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2037   [(set_attr "type" "alu1")
2038    (set_attr "mode" "<MODE>")
2039    (set_attr "length_immediate" "1")])
2041 (define_insn "*movxi_internal_avx512f"
2042   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2043         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2044   "TARGET_AVX512F
2045    && (register_operand (operands[0], XImode)
2046        || register_operand (operands[1], XImode))"
2048   switch (get_attr_type (insn))
2049     {
2050     case TYPE_SSELOG1:
2051       return standard_sse_constant_opcode (insn, operands);
2053     case TYPE_SSEMOV:
2054       if (misaligned_operand (operands[0], XImode)
2055           || misaligned_operand (operands[1], XImode))
2056         return "vmovdqu32\t{%1, %0|%0, %1}";
2057       else
2058         return "vmovdqa32\t{%1, %0|%0, %1}";
2060     default:
2061       gcc_unreachable ();
2062     }
2064   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2065    (set_attr "prefix" "evex")
2066    (set_attr "mode" "XI")])
2068 (define_insn "*movoi_internal_avx"
2069   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2070         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2071   "TARGET_AVX
2072    && (register_operand (operands[0], OImode)
2073        || register_operand (operands[1], OImode))"
2075   switch (get_attr_type (insn))
2076     {
2077     case TYPE_SSELOG1:
2078       return standard_sse_constant_opcode (insn, operands);
2080     case TYPE_SSEMOV:
2081       if (misaligned_operand (operands[0], OImode)
2082           || misaligned_operand (operands[1], OImode))
2083         {
2084           if (get_attr_mode (insn) == MODE_V8SF)
2085             return "vmovups\t{%1, %0|%0, %1}";
2086           else if (get_attr_mode (insn) == MODE_XI)
2087             return "vmovdqu32\t{%1, %0|%0, %1}";
2088           else
2089             return "vmovdqu\t{%1, %0|%0, %1}";
2090         }
2091       else
2092         {
2093           if (get_attr_mode (insn) == MODE_V8SF)
2094             return "vmovaps\t{%1, %0|%0, %1}";
2095           else if (get_attr_mode (insn) == MODE_XI)
2096             return "vmovdqa32\t{%1, %0|%0, %1}";
2097           else
2098             return "vmovdqa\t{%1, %0|%0, %1}";
2099         }
2101     default:
2102       gcc_unreachable ();
2103     }
2105   [(set_attr "isa" "*,avx2,*,*")
2106    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2107    (set_attr "prefix" "vex")
2108    (set (attr "mode")
2109         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2110                     (match_operand 1 "ext_sse_reg_operand"))
2111                  (const_string "XI")
2112                (and (eq_attr "alternative" "1")
2113                     (match_test "TARGET_AVX512VL"))
2114                  (const_string "XI")
2115                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2116                     (and (eq_attr "alternative" "3")
2117                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2118                  (const_string "V8SF")
2119               ]
2120               (const_string "OI")))])
2122 (define_insn "*movti_internal"
2123   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2124         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Ye,r"))]
2125   "(TARGET_64BIT
2126     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2127    || (TARGET_SSE
2128        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2129        && (register_operand (operands[0], TImode)
2130            || register_operand (operands[1], TImode)))"
2132   switch (get_attr_type (insn))
2133     {
2134     case TYPE_MULTI:
2135       return "#";
2137     case TYPE_SSELOG1:
2138       return standard_sse_constant_opcode (insn, operands);
2140     case TYPE_SSEMOV:
2141       /* TDmode values are passed as TImode on the stack.  Moving them
2142          to stack may result in unaligned memory access.  */
2143       if (misaligned_operand (operands[0], TImode)
2144           || misaligned_operand (operands[1], TImode))
2145         {
2146           if (get_attr_mode (insn) == MODE_V4SF)
2147             return "%vmovups\t{%1, %0|%0, %1}";
2148           else if (get_attr_mode (insn) == MODE_XI)
2149             return "vmovdqu32\t{%1, %0|%0, %1}";
2150           else
2151             return "%vmovdqu\t{%1, %0|%0, %1}";
2152         }
2153       else
2154         {
2155           if (get_attr_mode (insn) == MODE_V4SF)
2156             return "%vmovaps\t{%1, %0|%0, %1}";
2157           else if (get_attr_mode (insn) == MODE_XI)
2158             return "vmovdqa32\t{%1, %0|%0, %1}";
2159           else
2160             return "%vmovdqa\t{%1, %0|%0, %1}";
2161         }
2163     default:
2164       gcc_unreachable ();
2165     }
2167   [(set (attr "isa")
2168      (cond [(eq_attr "alternative" "0,1,6,7")
2169               (const_string "x64")
2170             (eq_attr "alternative" "3")
2171               (const_string "sse2")
2172            ]
2173            (const_string "*")))
2174    (set (attr "type")
2175      (cond [(eq_attr "alternative" "0,1,6,7")
2176               (const_string "multi")
2177             (eq_attr "alternative" "2,3")
2178               (const_string "sselog1")
2179            ]
2180            (const_string "ssemov")))
2181    (set (attr "prefix")
2182      (if_then_else (eq_attr "type" "sselog1,ssemov")
2183        (const_string "maybe_vex")
2184        (const_string "orig")))
2185    (set (attr "mode")
2186         (cond [(eq_attr "alternative" "0,1")
2187                  (const_string "DI")
2188                (ior (match_operand 0 "ext_sse_reg_operand")
2189                     (match_operand 1 "ext_sse_reg_operand"))
2190                  (const_string "XI")
2191                (and (eq_attr "alternative" "3")
2192                     (match_test "TARGET_AVX512VL"))
2193                  (const_string "XI")
2194                (ior (not (match_test "TARGET_SSE2"))
2195                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2196                          (and (eq_attr "alternative" "5")
2197                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2198                  (const_string "V4SF")
2199                (match_test "TARGET_AVX")
2200                  (const_string "TI")
2201                (match_test "optimize_function_for_size_p (cfun)")
2202                  (const_string "V4SF")
2203                ]
2204                (const_string "TI")))])
2206 (define_split
2207   [(set (match_operand:TI 0 "sse_reg_operand")
2208         (match_operand:TI 1 "general_reg_operand"))]
2209   "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2210    && reload_completed"
2211   [(set (match_dup 2)
2212         (vec_merge:V2DI
2213           (vec_duplicate:V2DI (match_dup 3))
2214           (match_dup 2)
2215           (const_int 2)))]
2217   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2218   operands[3] = gen_highpart (DImode, operands[1]);
2220   emit_move_insn (gen_lowpart (DImode, operands[0]),
2221                   gen_lowpart (DImode, operands[1]));
2224 (define_insn "*movdi_internal"
2225   [(set (match_operand:DI 0 "nonimmediate_operand"
2226     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2227         (match_operand:DI 1 "general_operand"
2228     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Ye,r   ,*Yj,r   ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2229   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2231   switch (get_attr_type (insn))
2232     {
2233     case TYPE_MSKMOV:
2234       return "kmovq\t{%1, %0|%0, %1}";
2236     case TYPE_MULTI:
2237       return "#";
2239     case TYPE_MMX:
2240       return "pxor\t%0, %0";
2242     case TYPE_MMXMOV:
2243       /* Handle broken assemblers that require movd instead of movq.  */
2244       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2245           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2246         return "movd\t{%1, %0|%0, %1}";
2247       return "movq\t{%1, %0|%0, %1}";
2249     case TYPE_SSELOG1:
2250       return standard_sse_constant_opcode (insn, operands);
2252     case TYPE_SSEMOV:
2253       switch (get_attr_mode (insn))
2254         {
2255         case MODE_DI:
2256           /* Handle broken assemblers that require movd instead of movq.  */
2257           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2258               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2259             return "%vmovd\t{%1, %0|%0, %1}";
2260           return "%vmovq\t{%1, %0|%0, %1}";
2262         case MODE_TI:
2263           /* Handle AVX512 registers set.  */
2264           if (EXT_REX_SSE_REG_P (operands[0])
2265               || EXT_REX_SSE_REG_P (operands[1]))
2266             return "vmovdqa64\t{%1, %0|%0, %1}";
2267           return "%vmovdqa\t{%1, %0|%0, %1}";
2269         case MODE_V2SF:
2270           gcc_assert (!TARGET_AVX);
2271           return "movlps\t{%1, %0|%0, %1}";
2272         case MODE_V4SF:
2273           return "%vmovaps\t{%1, %0|%0, %1}";
2275         default:
2276           gcc_unreachable ();
2277         }
2279     case TYPE_SSECVT:
2280       if (SSE_REG_P (operands[0]))
2281         return "movq2dq\t{%1, %0|%0, %1}";
2282       else
2283         return "movdq2q\t{%1, %0|%0, %1}";
2285     case TYPE_LEA:
2286       return "lea{q}\t{%E1, %0|%0, %E1}";
2288     case TYPE_IMOV:
2289       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2290       if (get_attr_mode (insn) == MODE_SI)
2291         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2292       else if (which_alternative == 4)
2293         return "movabs{q}\t{%1, %0|%0, %1}";
2294       else if (ix86_use_lea_for_mov (insn, operands))
2295         return "lea{q}\t{%E1, %0|%0, %E1}";
2296       else
2297         return "mov{q}\t{%1, %0|%0, %1}";
2299     default:
2300       gcc_unreachable ();
2301     }
2303   [(set (attr "isa")
2304      (cond [(eq_attr "alternative" "0,1,17,18")
2305               (const_string "nox64")
2306             (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2307               (const_string "x64")
2308            ]
2309            (const_string "*")))
2310    (set (attr "type")
2311      (cond [(eq_attr "alternative" "0,1,17,18")
2312               (const_string "multi")
2313             (eq_attr "alternative" "6")
2314               (const_string "mmx")
2315             (eq_attr "alternative" "7,8,9,10,11")
2316               (const_string "mmxmov")
2317             (eq_attr "alternative" "12")
2318               (const_string "sselog1")
2319             (eq_attr "alternative" "13,14,15,16,19,20")
2320               (const_string "ssemov")
2321             (eq_attr "alternative" "21,22")
2322               (const_string "ssecvt")
2323             (eq_attr "alternative" "23,24,25,26")
2324               (const_string "mskmov")
2325             (and (match_operand 0 "register_operand")
2326                  (match_operand 1 "pic_32bit_operand"))
2327               (const_string "lea")
2328            ]
2329            (const_string "imov")))
2330    (set (attr "modrm")
2331      (if_then_else
2332        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2333        (const_string "0")
2334        (const_string "*")))
2335    (set (attr "length_immediate")
2336      (if_then_else
2337        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2338        (const_string "8")
2339        (const_string "*")))
2340    (set (attr "prefix_rex")
2341      (if_then_else
2342        (eq_attr "alternative" "10,11,19,20")
2343        (const_string "1")
2344        (const_string "*")))
2345    (set (attr "prefix")
2346      (if_then_else (eq_attr "type" "sselog1,ssemov")
2347        (const_string "maybe_vex")
2348        (const_string "orig")))
2349    (set (attr "prefix_data16")
2350      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2351        (const_string "1")
2352        (const_string "*")))
2353    (set (attr "mode")
2354      (cond [(eq_attr "alternative" "2")
2355               (const_string "SI")
2356             (eq_attr "alternative" "12,13")
2357               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2358                           (match_operand 1 "ext_sse_reg_operand"))
2359                        (const_string "TI")
2360                      (ior (not (match_test "TARGET_SSE2"))
2361                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2362                        (const_string "V4SF")
2363                      (match_test "TARGET_AVX")
2364                        (const_string "TI")
2365                      (match_test "optimize_function_for_size_p (cfun)")
2366                        (const_string "V4SF")
2367                     ]
2368                     (const_string "TI"))
2370             (and (eq_attr "alternative" "14,15,16")
2371                  (not (match_test "TARGET_SSE2")))
2372               (const_string "V2SF")
2373            ]
2374            (const_string "DI")))
2375    (set (attr "enabled")
2376      (cond [(eq_attr "alternative" "15")
2377               (if_then_else
2378                 (match_test "TARGET_STV && TARGET_SSE2")
2379                 (symbol_ref "false")
2380                 (const_string "*"))
2381             (eq_attr "alternative" "16")
2382               (if_then_else
2383                 (match_test "TARGET_STV && TARGET_SSE2")
2384                 (symbol_ref "true")
2385                 (symbol_ref "false"))
2386            ]
2387            (const_string "*")))])
2389 (define_split
2390   [(set (match_operand:<DWI> 0 "general_reg_operand")
2391         (match_operand:<DWI> 1 "sse_reg_operand"))]
2392   "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2393    && reload_completed"
2394   [(set (match_dup 2)
2395         (vec_select:DWIH
2396           (match_dup 3)
2397           (parallel [(const_int 1)])))]
2399   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2400   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2402   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2403                   gen_lowpart (<MODE>mode, operands[1]));
2406 (define_split
2407   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2408         (match_operand:DWI 1 "general_gr_operand"))]
2409   "reload_completed"
2410   [(const_int 0)]
2411   "ix86_split_long_move (operands); DONE;")
2413 (define_split
2414   [(set (match_operand:DI 0 "sse_reg_operand")
2415         (match_operand:DI 1 "general_reg_operand"))]
2416   "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2417    && reload_completed"
2418   [(set (match_dup 2)
2419         (vec_merge:V4SI
2420           (vec_duplicate:V4SI (match_dup 3))
2421           (match_dup 2)
2422           (const_int 2)))]
2424   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2425   operands[3] = gen_highpart (SImode, operands[1]);
2427   emit_move_insn (gen_lowpart (SImode, operands[0]),
2428                   gen_lowpart (SImode, operands[1]));
2431 ;; movabsq $0x0012345678000000, %rax is longer
2432 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2433 (define_peephole2
2434   [(set (match_operand:DI 0 "register_operand")
2435         (match_operand:DI 1 "const_int_operand"))]
2436   "TARGET_64BIT
2437    && optimize_insn_for_size_p ()
2438    && LEGACY_INT_REG_P (operands[0])
2439    && !x86_64_immediate_operand (operands[1], DImode)
2440    && !x86_64_zext_immediate_operand (operands[1], DImode)
2441    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2442         & ~(HOST_WIDE_INT) 0xffffffff)
2443    && peep2_regno_dead_p (0, FLAGS_REG)"
2444   [(set (match_dup 0) (match_dup 1))
2445    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2446               (clobber (reg:CC FLAGS_REG))])]
2448   int shift = ctz_hwi (UINTVAL (operands[1]));
2449   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2450   operands[2] = gen_int_mode (shift, QImode);
2453 (define_insn "*movsi_internal"
2454   [(set (match_operand:SI 0 "nonimmediate_operand"
2455     "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2456         (match_operand:SI 1 "general_operand"
2457     "g ,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,r   ,*r,*km,*k"))]
2458   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460   switch (get_attr_type (insn))
2461     {
2462     case TYPE_SSELOG1:
2463       return standard_sse_constant_opcode (insn, operands);
2465     case TYPE_MSKMOV:
2466       return "kmovd\t{%1, %0|%0, %1}";
2468     case TYPE_SSEMOV:
2469       switch (get_attr_mode (insn))
2470         {
2471         case MODE_SI:
2472           return "%vmovd\t{%1, %0|%0, %1}";
2473         case MODE_TI:
2474           return "%vmovdqa\t{%1, %0|%0, %1}";
2475         case MODE_XI:
2476           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2478         case MODE_V4SF:
2479           return "%vmovaps\t{%1, %0|%0, %1}";
2481         case MODE_SF:
2482           gcc_assert (!TARGET_AVX);
2483           return "movss\t{%1, %0|%0, %1}";
2485         default:
2486           gcc_unreachable ();
2487         }
2489     case TYPE_MMX:
2490       return "pxor\t%0, %0";
2492     case TYPE_MMXMOV:
2493       switch (get_attr_mode (insn))
2494         {
2495         case MODE_DI:
2496           return "movq\t{%1, %0|%0, %1}";
2497         case MODE_SI:
2498           return "movd\t{%1, %0|%0, %1}";
2500         default:
2501           gcc_unreachable ();
2502         }
2504     case TYPE_LEA:
2505       return "lea{l}\t{%E1, %0|%0, %E1}";
2507     case TYPE_IMOV:
2508       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2509       if (ix86_use_lea_for_mov (insn, operands))
2510         return "lea{l}\t{%E1, %0|%0, %E1}";
2511       else
2512         return "mov{l}\t{%1, %0|%0, %1}";
2514     default:
2515       gcc_unreachable ();
2516     }
2518   [(set (attr "type")
2519      (cond [(eq_attr "alternative" "2")
2520               (const_string "mmx")
2521             (eq_attr "alternative" "3,4,5,6,7")
2522               (const_string "mmxmov")
2523             (eq_attr "alternative" "8")
2524               (const_string "sselog1")
2525             (eq_attr "alternative" "9,10,11,12,13")
2526               (const_string "ssemov")
2527             (eq_attr "alternative" "14,15,16")
2528               (const_string "mskmov")
2529             (and (match_operand 0 "register_operand")
2530                  (match_operand 1 "pic_32bit_operand"))
2531               (const_string "lea")
2532            ]
2533            (const_string "imov")))
2534    (set (attr "prefix")
2535      (if_then_else (eq_attr "type" "sselog1,ssemov")
2536        (const_string "maybe_vex")
2537        (const_string "orig")))
2538    (set (attr "prefix_data16")
2539      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2540        (const_string "1")
2541        (const_string "*")))
2542    (set (attr "mode")
2543      (cond [(eq_attr "alternative" "2,3")
2544               (const_string "DI")
2545             (eq_attr "alternative" "8,9")
2546               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2547                           (match_operand 1 "ext_sse_reg_operand"))
2548                        (const_string "XI")
2549                      (ior (not (match_test "TARGET_SSE2"))
2550                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2551                        (const_string "V4SF")
2552                      (match_test "TARGET_AVX")
2553                        (const_string "TI")
2554                      (match_test "optimize_function_for_size_p (cfun)")
2555                        (const_string "V4SF")
2556                     ]
2557                     (const_string "TI"))
2559             (and (eq_attr "alternative" "10,11")
2560                  (not (match_test "TARGET_SSE2")))
2561               (const_string "SF")
2562            ]
2563            (const_string "SI")))])
2565 (define_insn "*movhi_internal"
2566   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2567         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2568   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2570   switch (get_attr_type (insn))
2571     {
2572     case TYPE_IMOVX:
2573       /* movzwl is faster than movw on p2 due to partial word stalls,
2574          though not as fast as an aligned movl.  */
2575       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2577     case TYPE_MSKMOV:
2578       switch (which_alternative)
2579         {
2580         case 4:
2581           return "kmovw\t{%k1, %0|%0, %k1}";
2582         case 6:
2583           return "kmovw\t{%1, %k0|%k0, %1}";
2584         case 5:
2585         case 7:
2586           return "kmovw\t{%1, %0|%0, %1}";
2587         default:
2588           gcc_unreachable ();
2589         }
2591     default:
2592       if (get_attr_mode (insn) == MODE_SI)
2593         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2594       else
2595         return "mov{w}\t{%1, %0|%0, %1}";
2596     }
2598   [(set (attr "type")
2599      (cond [(eq_attr "alternative" "4,5,6,7")
2600               (const_string "mskmov")
2601             (match_test "optimize_function_for_size_p (cfun)")
2602               (const_string "imov")
2603             (and (eq_attr "alternative" "0")
2604                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2605                       (not (match_test "TARGET_HIMODE_MATH"))))
2606               (const_string "imov")
2607             (and (eq_attr "alternative" "1,2")
2608                  (match_operand:HI 1 "aligned_operand"))
2609               (const_string "imov")
2610             (and (match_test "TARGET_MOVX")
2611                  (eq_attr "alternative" "0,2"))
2612               (const_string "imovx")
2613            ]
2614            (const_string "imov")))
2615     (set (attr "prefix")
2616       (if_then_else (eq_attr "alternative" "4,5,6,7")
2617         (const_string "vex")
2618         (const_string "orig")))
2619     (set (attr "mode")
2620       (cond [(eq_attr "type" "imovx")
2621                (const_string "SI")
2622              (and (eq_attr "alternative" "1,2")
2623                   (match_operand:HI 1 "aligned_operand"))
2624                (const_string "SI")
2625              (and (eq_attr "alternative" "0")
2626                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2627                        (not (match_test "TARGET_HIMODE_MATH"))))
2628                (const_string "SI")
2629             ]
2630             (const_string "HI")))])
2632 ;; Situation is quite tricky about when to choose full sized (SImode) move
2633 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2634 ;; partial register dependency machines (such as AMD Athlon), where QImode
2635 ;; moves issue extra dependency and for partial register stalls machines
2636 ;; that don't use QImode patterns (and QImode move cause stall on the next
2637 ;; instruction).
2639 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2640 ;; register stall machines with, where we use QImode instructions, since
2641 ;; partial register stall can be caused there.  Then we use movzx.
2643 (define_insn "*movqi_internal"
2644   [(set (match_operand:QI 0 "nonimmediate_operand"
2645                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2646         (match_operand:QI 1 "general_operand"
2647                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2648   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2650   static char buf[128];
2651   const char *ops;
2652   const char *suffix;
2654   switch (get_attr_type (insn))
2655     {
2656     case TYPE_IMOVX:
2657       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2658       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2660     case TYPE_MSKMOV:
2661       switch (which_alternative)
2662         {
2663         case 9:
2664           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2665           break;
2666         case 11:
2667           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2668           break;
2669         case 12:
2670         case 13:
2671           gcc_assert (TARGET_AVX512DQ);
2672           /* FALLTHRU */
2673         case 10:
2674           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2675           break;
2676         default:
2677           gcc_unreachable ();
2678         }
2680       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2682       snprintf (buf, sizeof (buf), ops, suffix);
2683       return buf;
2685     default:
2686       if (get_attr_mode (insn) == MODE_SI)
2687         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2688       else
2689         return "mov{b}\t{%1, %0|%0, %1}";
2690     }
2692   [(set (attr "isa")
2693      (cond [(eq_attr "alternative" "1,2")
2694               (const_string "x64")
2695             (eq_attr "alternative" "12,13")
2696               (const_string "avx512dq")
2697            ]
2698            (const_string "*")))
2699    (set (attr "type")
2700      (cond [(eq_attr "alternative" "9,10,11,12,13")
2701               (const_string "mskmov")
2702             (and (eq_attr "alternative" "7")
2703                  (not (match_operand:QI 1 "aligned_operand")))
2704               (const_string "imovx")
2705             (match_test "optimize_function_for_size_p (cfun)")
2706               (const_string "imov")
2707             (and (eq_attr "alternative" "5")
2708                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2709                       (not (match_test "TARGET_QIMODE_MATH"))))
2710               (const_string "imov")
2711             (eq_attr "alternative" "5,7")
2712               (const_string "imovx")
2713             (and (match_test "TARGET_MOVX")
2714                  (eq_attr "alternative" "4"))
2715               (const_string "imovx")
2716            ]
2717            (const_string "imov")))
2718    (set (attr "prefix")
2719      (if_then_else (eq_attr "alternative" "9,10,11")
2720        (const_string "vex")
2721        (const_string "orig")))
2722    (set (attr "mode")
2723       (cond [(eq_attr "alternative" "5,6,7")
2724                (const_string "SI")
2725              (eq_attr "alternative" "8")
2726                (const_string "QI")
2727              (and (eq_attr "alternative" "9,10,11")
2728                   (not (match_test "TARGET_AVX512DQ")))
2729                (const_string "HI")
2730              (eq_attr "type" "imovx")
2731                (const_string "SI")
2732              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2733              ;; ones.
2734              (and (eq_attr "type" "imov")
2735                   (and (eq_attr "alternative" "3")
2736                        (match_test "optimize_function_for_size_p (cfun)")))
2737                (const_string "QI")
2738              ;; For -Os, movl where one or both operands are NON_Q_REGS
2739              ;; and both are LEGACY_REGS is shorter than movb.
2740              ;; Otherwise movb and movl sizes are the same, so decide purely
2741              ;; based on speed factors.
2742              (and (eq_attr "type" "imov")
2743                   (and (eq_attr "alternative" "1")
2744                        (match_test "optimize_function_for_size_p (cfun)")))
2745                (const_string "SI")
2746              (and (eq_attr "type" "imov")
2747                   (and (eq_attr "alternative" "0,1,2,3")
2748                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2749                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2750                (const_string "SI")
2751              ;; Avoid partial register stalls when not using QImode arithmetic
2752              (and (eq_attr "type" "imov")
2753                   (and (eq_attr "alternative" "0,1,2,3")
2754                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2755                             (not (match_test "TARGET_QIMODE_MATH")))))
2756                (const_string "SI")
2757            ]
2758            (const_string "QI")))])
2760 ;; Stores and loads of ax to arbitrary constant address.
2761 ;; We fake an second form of instruction to force reload to load address
2762 ;; into register when rax is not available
2763 (define_insn "*movabs<mode>_1"
2764   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2765         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2766   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2768   /* Recover the full memory rtx.  */
2769   operands[0] = SET_DEST (PATTERN (insn));
2770   switch (which_alternative)
2771     {
2772     case 0:
2773       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2774     case 1:
2775       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2776     default:
2777       gcc_unreachable ();
2778     }
2780   [(set_attr "type" "imov")
2781    (set_attr "modrm" "0,*")
2782    (set_attr "length_address" "8,0")
2783    (set_attr "length_immediate" "0,*")
2784    (set_attr "memory" "store")
2785    (set_attr "mode" "<MODE>")])
2787 (define_insn "*movabs<mode>_2"
2788   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2789         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2790   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2792   /* Recover the full memory rtx.  */
2793   operands[1] = SET_SRC (PATTERN (insn));
2794   switch (which_alternative)
2795     {
2796     case 0:
2797       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2798     case 1:
2799       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2800     default:
2801       gcc_unreachable ();
2802     }
2804   [(set_attr "type" "imov")
2805    (set_attr "modrm" "0,*")
2806    (set_attr "length_address" "8,0")
2807    (set_attr "length_immediate" "0")
2808    (set_attr "memory" "load")
2809    (set_attr "mode" "<MODE>")])
2811 (define_insn "*swap<mode>"
2812   [(set (match_operand:SWI48 0 "register_operand" "+r")
2813         (match_operand:SWI48 1 "register_operand" "+r"))
2814    (set (match_dup 1)
2815         (match_dup 0))]
2816   ""
2817   "xchg{<imodesuffix>}\t%1, %0"
2818   [(set_attr "type" "imov")
2819    (set_attr "mode" "<MODE>")
2820    (set_attr "pent_pair" "np")
2821    (set_attr "athlon_decode" "vector")
2822    (set_attr "amdfam10_decode" "double")
2823    (set_attr "bdver1_decode" "double")])
2825 (define_insn "*swap<mode>"
2826   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2827         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2828    (set (match_dup 1)
2829         (match_dup 0))]
2830   ""
2831   "@
2832    xchg{<imodesuffix>}\t%1, %0
2833    xchg{l}\t%k1, %k0"
2834   [(set_attr "type" "imov")
2835    (set_attr "mode" "<MODE>,SI")
2836    (set (attr "preferred_for_size")
2837      (cond [(eq_attr "alternative" "0")
2838               (symbol_ref "false")]
2839            (symbol_ref "true")))
2840    ;; Potential partial reg stall on alternative 1.
2841    (set (attr "preferred_for_speed")
2842      (cond [(eq_attr "alternative" "1")
2843               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2844            (symbol_ref "true")))
2845    (set_attr "pent_pair" "np")
2846    (set_attr "athlon_decode" "vector")
2847    (set_attr "amdfam10_decode" "double")
2848    (set_attr "bdver1_decode" "double")])
2850 (define_expand "movstrict<mode>"
2851   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2852         (match_operand:SWI12 1 "general_operand"))]
2853   ""
2855   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2856     FAIL;
2857   if (SUBREG_P (operands[0])
2858       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2859     FAIL;
2860   /* Don't generate memory->memory moves, go through a register */
2861   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2862     operands[1] = force_reg (<MODE>mode, operands[1]);
2865 (define_insn "*movstrict<mode>_1"
2866   [(set (strict_low_part
2867           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2868         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2869   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2871   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2872   [(set_attr "type" "imov")
2873    (set_attr "mode" "<MODE>")])
2875 (define_insn "*movstrict<mode>_xor"
2876   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2877         (match_operand:SWI12 1 "const0_operand"))
2878    (clobber (reg:CC FLAGS_REG))]
2879   "reload_completed"
2880   "xor{<imodesuffix>}\t%0, %0"
2881   [(set_attr "type" "alu1")
2882    (set_attr "modrm_class" "op0")
2883    (set_attr "mode" "<MODE>")
2884    (set_attr "length_immediate" "0")])
2886 (define_expand "extv<mode>"
2887   [(set (match_operand:SWI24 0 "register_operand")
2888         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2889                             (match_operand:SI 2 "const_int_operand")
2890                             (match_operand:SI 3 "const_int_operand")))]
2891   ""
2893   /* Handle extractions from %ah et al.  */
2894   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2895     FAIL;
2897   unsigned int regno = reg_or_subregno (operands[1]);
2899   /* Be careful to expand only with registers having upper parts.  */
2900   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2901     operands[1] = copy_to_reg (operands[1]);
2904 (define_insn "*extv<mode>"
2905   [(set (match_operand:SWI24 0 "register_operand" "=R")
2906         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2907                             (const_int 8)
2908                             (const_int 8)))]
2909   ""
2910   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2911   [(set_attr "type" "imovx")
2912    (set_attr "mode" "SI")])
2914 (define_expand "extzv<mode>"
2915   [(set (match_operand:SWI248 0 "register_operand")
2916         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2917                              (match_operand:SI 2 "const_int_operand")
2918                              (match_operand:SI 3 "const_int_operand")))]
2919   ""
2921   if (ix86_expand_pextr (operands))
2922     DONE;
2924   /* Handle extractions from %ah et al.  */
2925   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2926     FAIL;
2928   unsigned int regno = reg_or_subregno (operands[1]);
2930   /* Be careful to expand only with registers having upper parts.  */
2931   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932     operands[1] = copy_to_reg (operands[1]);
2935 (define_insn "*extzvqi_mem_rex64"
2936   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2937         (subreg:QI
2938           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2939                            (const_int 8)
2940                            (const_int 8)) 0))]
2941   "TARGET_64BIT && reload_completed"
2942   "mov{b}\t{%h1, %0|%0, %h1}"
2943   [(set_attr "type" "imov")
2944    (set_attr "mode" "QI")])
2946 (define_insn "*extzv<mode>"
2947   [(set (match_operand:SWI248 0 "register_operand" "=R")
2948         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2949                              (const_int 8)
2950                              (const_int 8)))]
2951   ""
2952   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2953   [(set_attr "type" "imovx")
2954    (set_attr "mode" "SI")])
2956 (define_insn "*extzvqi"
2957   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2958         (subreg:QI
2959           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2960                            (const_int 8)
2961                            (const_int 8)) 0))]
2962   ""
2964   switch (get_attr_type (insn))
2965     {
2966     case TYPE_IMOVX:
2967       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2968     default:
2969       return "mov{b}\t{%h1, %0|%0, %h1}";
2970     }
2972   [(set_attr "isa" "*,*,nox64")
2973    (set (attr "type")
2974      (if_then_else (and (match_operand:QI 0 "register_operand")
2975                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2976                              (match_test "TARGET_MOVX")))
2977         (const_string "imovx")
2978         (const_string "imov")))
2979    (set (attr "mode")
2980      (if_then_else (eq_attr "type" "imovx")
2981         (const_string "SI")
2982         (const_string "QI")))])
2984 (define_peephole2
2985   [(set (match_operand:QI 0 "register_operand")
2986         (subreg:QI
2987           (zero_extract:SI (match_operand 1 "ext_register_operand")
2988                            (const_int 8)
2989                            (const_int 8)) 0))
2990    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2991   "TARGET_64BIT
2992    && peep2_reg_dead_p (2, operands[0])"
2993   [(set (match_dup 2)
2994         (subreg:QI
2995           (zero_extract:SI (match_dup 1)
2996                            (const_int 8)
2997                            (const_int 8)) 0))])
2999 (define_expand "insv<mode>"
3000   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3001                              (match_operand:SI 1 "const_int_operand")
3002                              (match_operand:SI 2 "const_int_operand"))
3003         (match_operand:SWI248 3 "register_operand"))]
3004   ""
3006   rtx dst;
3008   if (ix86_expand_pinsr (operands))
3009     DONE;
3011   /* Handle insertions to %ah et al.  */
3012   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3013     FAIL;
3015   unsigned int regno = reg_or_subregno (operands[0]);
3017   /* Be careful to expand only with registers having upper parts.  */
3018   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3019     dst = copy_to_reg (operands[0]);
3020   else
3021     dst = operands[0];
3023   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3025   /* Fix up the destination if needed.  */
3026   if (dst != operands[0])
3027     emit_move_insn (operands[0], dst);
3029   DONE;
3032 (define_insn "*insvqi_1_mem_rex64"
3033   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3034                          (const_int 8)
3035                          (const_int 8))
3036         (subreg:SI
3037           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3038   "TARGET_64BIT && reload_completed"
3039   "mov{b}\t{%1, %h0|%h0, %1}"
3040   [(set_attr "type" "imov")
3041    (set_attr "mode" "QI")])
3043 (define_insn "insv<mode>_1"
3044   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3045                              (const_int 8)
3046                              (const_int 8))
3047         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3048   ""
3050   if (CONST_INT_P (operands[1]))
3051     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3052   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3054   [(set_attr "isa" "*,nox64")
3055    (set_attr "type" "imov")
3056    (set_attr "mode" "QI")])
3058 (define_insn "*insvqi_1"
3059   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3060                          (const_int 8)
3061                          (const_int 8))
3062         (subreg:SI
3063           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3064   ""
3065   "mov{b}\t{%1, %h0|%h0, %1}"
3066   [(set_attr "isa" "*,nox64")
3067    (set_attr "type" "imov")
3068    (set_attr "mode" "QI")])
3070 (define_peephole2
3071   [(set (match_operand:QI 0 "register_operand")
3072         (match_operand:QI 1 "norex_memory_operand"))
3073    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3074                          (const_int 8)
3075                          (const_int 8))
3076         (subreg:SI (match_dup 0) 0))]
3077   "TARGET_64BIT
3078    && peep2_reg_dead_p (2, operands[0])"
3079   [(set (zero_extract:SI (match_dup 2)
3080                          (const_int 8)
3081                          (const_int 8))
3082            (subreg:SI (match_dup 1) 0))])
3084 (define_code_iterator any_extract [sign_extract zero_extract])
3086 (define_insn "*insvqi_2"
3087   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3088                          (const_int 8)
3089                          (const_int 8))
3090         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3091                         (const_int 8)
3092                         (const_int 8)))]
3093   ""
3094   "mov{b}\t{%h1, %h0|%h0, %h1}"
3095   [(set_attr "type" "imov")
3096    (set_attr "mode" "QI")])
3098 (define_insn "*insvqi_3"
3099   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3100                          (const_int 8)
3101                          (const_int 8))
3102         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3103                         (const_int 8)))]
3104   ""
3105   "mov{b}\t{%h1, %h0|%h0, %h1}"
3106   [(set_attr "type" "imov")
3107    (set_attr "mode" "QI")])
3109 ;; Floating point push instructions.
3111 (define_insn "*pushtf"
3112   [(set (match_operand:TF 0 "push_operand" "=<,<")
3113         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3114   "TARGET_64BIT || TARGET_SSE"
3116   /* This insn should be already split before reg-stack.  */
3117   gcc_unreachable ();
3119   [(set_attr "isa" "*,x64")
3120    (set_attr "type" "multi")
3121    (set_attr "unit" "sse,*")
3122    (set_attr "mode" "TF,DI")])
3124 ;; %%% Kill this when call knows how to work this out.
3125 (define_split
3126   [(set (match_operand:TF 0 "push_operand")
3127         (match_operand:TF 1 "sse_reg_operand"))]
3128   "TARGET_SSE && reload_completed"
3129   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3130    (set (match_dup 0) (match_dup 1))]
3132   /* Preserve memory attributes. */
3133   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3136 (define_insn_and_split "*pushxf_rounded"
3137   [(set (mem:XF
3138           (pre_modify:P
3139             (reg:P SP_REG)
3140             (plus:P (reg:P SP_REG) (const_int -16))))
3141         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3142   "TARGET_64BIT"
3143   "#"
3144   "&& 1"
3145   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3146    (set (match_dup 1) (match_dup 0))]
3148   rtx pat = PATTERN (curr_insn);
3149   operands[1] = SET_DEST (pat);
3151   /* Preserve memory attributes. */
3152   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3154   [(set_attr "type" "multi")
3155    (set_attr "unit" "i387,*,*,*")
3156    (set (attr "mode")
3157         (cond [(eq_attr "alternative" "1,2,3")
3158                  (const_string "DI")
3159               ]
3160               (const_string "XF")))
3161    (set (attr "preferred_for_size")
3162      (cond [(eq_attr "alternative" "1")
3163               (symbol_ref "false")]
3164            (symbol_ref "true")))])
3166 (define_insn "*pushxf"
3167   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3168         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3169   ""
3171   /* This insn should be already split before reg-stack.  */
3172   gcc_unreachable ();
3174   [(set_attr "isa" "*,*,*,nox64,x64")
3175    (set_attr "type" "multi")
3176    (set_attr "unit" "i387,*,*,*,*")
3177    (set (attr "mode")
3178         (cond [(eq_attr "alternative" "1,2,3,4")
3179                  (if_then_else (match_test "TARGET_64BIT")
3180                    (const_string "DI")
3181                    (const_string "SI"))
3182               ]
3183               (const_string "XF")))
3184    (set (attr "preferred_for_size")
3185      (cond [(eq_attr "alternative" "1")
3186               (symbol_ref "false")]
3187            (symbol_ref "true")))])
3189 ;; %%% Kill this when call knows how to work this out.
3190 (define_split
3191   [(set (match_operand:XF 0 "push_operand")
3192         (match_operand:XF 1 "fp_register_operand"))]
3193   "reload_completed"
3194   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3195    (set (match_dup 0) (match_dup 1))]
3197   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3198   /* Preserve memory attributes. */
3199   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3202 (define_insn "*pushdf"
3203   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3204         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3205   ""
3207   /* This insn should be already split before reg-stack.  */
3208   gcc_unreachable ();
3210   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3211    (set_attr "type" "multi")
3212    (set_attr "unit" "i387,*,*,*,*,sse")
3213    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3214    (set (attr "preferred_for_size")
3215      (cond [(eq_attr "alternative" "1")
3216               (symbol_ref "false")]
3217            (symbol_ref "true")))
3218    (set (attr "preferred_for_speed")
3219      (cond [(eq_attr "alternative" "1")
3220               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3221            (symbol_ref "true")))])
3222    
3223 ;; %%% Kill this when call knows how to work this out.
3224 (define_split
3225   [(set (match_operand:DF 0 "push_operand")
3226         (match_operand:DF 1 "any_fp_register_operand"))]
3227   "reload_completed"
3228   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3229    (set (match_dup 0) (match_dup 1))]
3231   /* Preserve memory attributes. */
3232   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3235 (define_insn "*pushsf_rex64"
3236   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3237         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3238   "TARGET_64BIT"
3240   /* Anything else should be already split before reg-stack.  */
3241   gcc_assert (which_alternative == 1);
3242   return "push{q}\t%q1";
3244   [(set_attr "type" "multi,push,multi")
3245    (set_attr "unit" "i387,*,*")
3246    (set_attr "mode" "SF,DI,SF")])
3248 (define_insn "*pushsf"
3249   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3250         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3251   "!TARGET_64BIT"
3253   /* Anything else should be already split before reg-stack.  */
3254   gcc_assert (which_alternative == 1);
3255   return "push{l}\t%1";
3257   [(set_attr "type" "multi,push,multi")
3258    (set_attr "unit" "i387,*,*")
3259    (set_attr "mode" "SF,SI,SF")])
3261 ;; %%% Kill this when call knows how to work this out.
3262 (define_split
3263   [(set (match_operand:SF 0 "push_operand")
3264         (match_operand:SF 1 "any_fp_register_operand"))]
3265   "reload_completed"
3266   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3267    (set (match_dup 0) (match_dup 1))]
3269   rtx op = XEXP (operands[0], 0);
3270   if (GET_CODE (op) == PRE_DEC)
3271     {
3272       gcc_assert (!TARGET_64BIT);
3273       op = GEN_INT (-4);
3274     }
3275   else
3276     {
3277       op = XEXP (XEXP (op, 1), 1);
3278       gcc_assert (CONST_INT_P (op));
3279     }
3280   operands[2] = op;
3281   /* Preserve memory attributes. */
3282   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3285 (define_split
3286   [(set (match_operand:SF 0 "push_operand")
3287         (match_operand:SF 1 "memory_operand"))]
3288   "reload_completed
3289    && find_constant_src (insn)"
3290   [(set (match_dup 0) (match_dup 2))]
3291   "operands[2] = find_constant_src (curr_insn);")
3293 (define_split
3294   [(set (match_operand 0 "push_operand")
3295         (match_operand 1 "general_gr_operand"))]
3296   "reload_completed
3297    && (GET_MODE (operands[0]) == TFmode
3298        || GET_MODE (operands[0]) == XFmode
3299        || GET_MODE (operands[0]) == DFmode)"
3300   [(const_int 0)]
3301   "ix86_split_long_move (operands); DONE;")
3303 ;; Floating point move instructions.
3305 (define_expand "movtf"
3306   [(set (match_operand:TF 0 "nonimmediate_operand")
3307         (match_operand:TF 1 "nonimmediate_operand"))]
3308   "TARGET_64BIT || TARGET_SSE"
3309   "ix86_expand_move (TFmode, operands); DONE;")
3311 (define_expand "mov<mode>"
3312   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3313         (match_operand:X87MODEF 1 "general_operand"))]
3314   ""
3315   "ix86_expand_move (<MODE>mode, operands); DONE;")
3317 (define_insn "*movtf_internal"
3318   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3319         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3320   "(TARGET_64BIT || TARGET_SSE)
3321    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3322    && (lra_in_progress || reload_completed
3323        || !CONST_DOUBLE_P (operands[1])
3324        || ((optimize_function_for_size_p (cfun)
3325             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3326            && standard_sse_constant_p (operands[1], TFmode) == 1
3327            && !memory_operand (operands[0], TFmode))
3328        || (!TARGET_MEMORY_MISMATCH_STALL
3329            && memory_operand (operands[0], TFmode)))"
3331   switch (get_attr_type (insn))
3332     {
3333     case TYPE_SSELOG1:
3334       return standard_sse_constant_opcode (insn, operands);
3336     case TYPE_SSEMOV:
3337       /* Handle misaligned load/store since we
3338          don't have movmisaligntf pattern. */
3339       if (misaligned_operand (operands[0], TFmode)
3340           || misaligned_operand (operands[1], TFmode))
3341         {
3342           if (get_attr_mode (insn) == MODE_V4SF)
3343             return "%vmovups\t{%1, %0|%0, %1}";
3344           else if (TARGET_AVX512VL
3345                    && (EXT_REX_SSE_REG_P (operands[0])
3346                        || EXT_REX_SSE_REG_P (operands[1])))
3347             return "vmovdqu64\t{%1, %0|%0, %1}";
3348           else
3349             return "%vmovdqu\t{%1, %0|%0, %1}";
3350         }
3351       else
3352         {
3353           if (get_attr_mode (insn) == MODE_V4SF)
3354             return "%vmovaps\t{%1, %0|%0, %1}";
3355           else if (TARGET_AVX512VL
3356                    && (EXT_REX_SSE_REG_P (operands[0])
3357                        || EXT_REX_SSE_REG_P (operands[1])))
3358             return "vmovdqa64\t{%1, %0|%0, %1}";
3359           else
3360             return "%vmovdqa\t{%1, %0|%0, %1}";
3361         }
3363     case TYPE_MULTI:
3364         return "#";
3366     default:
3367       gcc_unreachable ();
3368     }
3370   [(set_attr "isa" "*,*,*,x64,x64")
3371    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3372    (set (attr "prefix")
3373      (if_then_else (eq_attr "type" "sselog1,ssemov")
3374        (const_string "maybe_vex")
3375        (const_string "orig")))
3376    (set (attr "mode")
3377         (cond [(eq_attr "alternative" "3,4")
3378                  (const_string "DI")
3379                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3380                  (const_string "V4SF")
3381                (and (eq_attr "alternative" "2")
3382                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3383                  (const_string "V4SF")
3384                (match_test "TARGET_AVX")
3385                  (const_string "TI")
3386                (ior (not (match_test "TARGET_SSE2"))
3387                     (match_test "optimize_function_for_size_p (cfun)"))
3388                  (const_string "V4SF")
3389                ]
3390                (const_string "TI")))])
3392 (define_split
3393   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3394         (match_operand:TF 1 "general_gr_operand"))]
3395   "reload_completed"
3396   [(const_int 0)]
3397   "ix86_split_long_move (operands); DONE;")
3399 ;; Possible store forwarding (partial memory) stall
3400 ;; in alternatives 4, 6, 7 and 8.
3401 (define_insn "*movxf_internal"
3402   [(set (match_operand:XF 0 "nonimmediate_operand"
3403          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3404         (match_operand:XF 1 "general_operand"
3405          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3406   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3407    && (lra_in_progress || reload_completed
3408        || !CONST_DOUBLE_P (operands[1])
3409        || ((optimize_function_for_size_p (cfun)
3410             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3411            && standard_80387_constant_p (operands[1]) > 0
3412            && !memory_operand (operands[0], XFmode))
3413        || (!TARGET_MEMORY_MISMATCH_STALL
3414            && memory_operand (operands[0], XFmode))
3415        || !TARGET_HARD_XF_REGS)"
3417   switch (get_attr_type (insn))
3418     {
3419     case TYPE_FMOV:
3420       if (which_alternative == 2)
3421         return standard_80387_constant_opcode (operands[1]);
3422       return output_387_reg_move (insn, operands);
3424     case TYPE_MULTI:
3425       return "#";
3427     default:
3428       gcc_unreachable ();
3429     }
3431   [(set (attr "isa")
3432         (cond [(eq_attr "alternative" "7,10")
3433                  (const_string "nox64")
3434                (eq_attr "alternative" "8,11")
3435                  (const_string "x64")
3436               ]
3437               (const_string "*")))
3438    (set (attr "type")
3439         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3440                  (const_string "multi")
3441               ]
3442               (const_string "fmov")))
3443    (set (attr "mode")
3444         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3445                  (if_then_else (match_test "TARGET_64BIT")
3446                    (const_string "DI")
3447                    (const_string "SI"))
3448               ]
3449               (const_string "XF")))
3450    (set (attr "preferred_for_size")
3451      (cond [(eq_attr "alternative" "3,4")
3452               (symbol_ref "false")]
3453            (symbol_ref "true")))
3454    (set (attr "enabled")
3455      (cond [(eq_attr "alternative" "9,10,11")
3456               (if_then_else
3457                 (match_test "TARGET_HARD_XF_REGS")
3458                 (symbol_ref "false")
3459                 (const_string "*"))
3460             (not (match_test "TARGET_HARD_XF_REGS"))
3461               (symbol_ref "false")
3462            ]
3463            (const_string "*")))])
3464    
3465 (define_split
3466   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3467         (match_operand:XF 1 "general_gr_operand"))]
3468   "reload_completed"
3469   [(const_int 0)]
3470   "ix86_split_long_move (operands); DONE;")
3472 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3473 (define_insn "*movdf_internal"
3474   [(set (match_operand:DF 0 "nonimmediate_operand"
3475     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
3476         (match_operand:DF 1 "general_operand"
3477     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3478   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3479    && (lra_in_progress || reload_completed
3480        || !CONST_DOUBLE_P (operands[1])
3481        || ((optimize_function_for_size_p (cfun)
3482             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3483            && ((IS_STACK_MODE (DFmode)
3484                 && standard_80387_constant_p (operands[1]) > 0)
3485                || (TARGET_SSE2 && TARGET_SSE_MATH
3486                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3487            && !memory_operand (operands[0], DFmode))
3488        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3489            && memory_operand (operands[0], DFmode))
3490        || !TARGET_HARD_DF_REGS)"
3492   switch (get_attr_type (insn))
3493     {
3494     case TYPE_FMOV:
3495       if (which_alternative == 2)
3496         return standard_80387_constant_opcode (operands[1]);
3497       return output_387_reg_move (insn, operands);
3499     case TYPE_MULTI:
3500       return "#";
3502     case TYPE_IMOV:
3503       if (get_attr_mode (insn) == MODE_SI)
3504         return "mov{l}\t{%1, %k0|%k0, %1}";
3505       else if (which_alternative == 11)
3506         return "movabs{q}\t{%1, %0|%0, %1}";
3507       else
3508         return "mov{q}\t{%1, %0|%0, %1}";
3510     case TYPE_SSELOG1:
3511       return standard_sse_constant_opcode (insn, operands);
3513     case TYPE_SSEMOV:
3514       switch (get_attr_mode (insn))
3515         {
3516         case MODE_DF:
3517           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3518             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3519           return "%vmovsd\t{%1, %0|%0, %1}";
3521         case MODE_V4SF:
3522           return "%vmovaps\t{%1, %0|%0, %1}";
3523         case MODE_V8DF:
3524           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3525         case MODE_V2DF:
3526           return "%vmovapd\t{%1, %0|%0, %1}";
3528         case MODE_V2SF:
3529           gcc_assert (!TARGET_AVX);
3530           return "movlps\t{%1, %0|%0, %1}";
3531         case MODE_V1DF:
3532           gcc_assert (!TARGET_AVX);
3533           return "movlpd\t{%1, %0|%0, %1}";
3535         case MODE_DI:
3536           /* Handle broken assemblers that require movd instead of movq.  */
3537           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3538               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3539             return "%vmovd\t{%1, %0|%0, %1}";
3540           return "%vmovq\t{%1, %0|%0, %1}";
3542         default:
3543           gcc_unreachable ();
3544         }
3546     default:
3547       gcc_unreachable ();
3548     }
3550   [(set (attr "isa")
3551         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3552                  (const_string "nox64")
3553                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3554                  (const_string "x64")
3555                (eq_attr "alternative" "12,13,14,15")
3556                  (const_string "sse2")
3557               ]
3558               (const_string "*")))
3559    (set (attr "type")
3560         (cond [(eq_attr "alternative" "0,1,2")
3561                  (const_string "fmov")
3562                (eq_attr "alternative" "3,4,5,6,7,22,23")
3563                  (const_string "multi")
3564                (eq_attr "alternative" "8,9,10,11,24,25")
3565                  (const_string "imov")
3566                (eq_attr "alternative" "12,16")
3567                  (const_string "sselog1")
3568               ]
3569               (const_string "ssemov")))
3570    (set (attr "modrm")
3571      (if_then_else (eq_attr "alternative" "11")
3572        (const_string "0")
3573        (const_string "*")))
3574    (set (attr "length_immediate")
3575      (if_then_else (eq_attr "alternative" "11")
3576        (const_string "8")
3577        (const_string "*")))
3578    (set (attr "prefix")
3579      (if_then_else (eq_attr "type" "sselog1,ssemov")
3580        (const_string "maybe_vex")
3581        (const_string "orig")))
3582    (set (attr "prefix_data16")
3583      (if_then_else
3584        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3585             (eq_attr "mode" "V1DF"))
3586        (const_string "1")
3587        (const_string "*")))
3588    (set (attr "mode")
3589         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3590                  (const_string "SI")
3591                (eq_attr "alternative" "8,9,11,20,21,24,25")
3592                  (const_string "DI")
3594                /* xorps is one byte shorter for non-AVX targets.  */
3595                (eq_attr "alternative" "12,16")
3596                  (cond [(not (match_test "TARGET_SSE2"))
3597                           (const_string "V4SF")
3598                         (and (match_test "TARGET_AVX512F")
3599                           (not (match_test "TARGET_PREFER_AVX256")))
3600                           (const_string "XI")
3601                         (match_test "TARGET_AVX")
3602                           (const_string "V2DF")
3603                         (match_test "optimize_function_for_size_p (cfun)")
3604                           (const_string "V4SF")
3605                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3606                           (const_string "TI")
3607                        ]
3608                        (const_string "V2DF"))
3610                /* For architectures resolving dependencies on
3611                   whole SSE registers use movapd to break dependency
3612                   chains, otherwise use short move to avoid extra work.  */
3614                /* movaps is one byte shorter for non-AVX targets.  */
3615                (eq_attr "alternative" "13,17")
3616                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3617                                   (not (match_test "TARGET_AVX512VL")))
3618                              (ior (match_operand 0 "ext_sse_reg_operand")
3619                                   (match_operand 1 "ext_sse_reg_operand")))
3620                           (const_string "V8DF")
3621                         (ior (not (match_test "TARGET_SSE2"))
3622                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3623                           (const_string "V4SF")
3624                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3625                           (const_string "V2DF")
3626                         (match_test "TARGET_AVX")
3627                           (const_string "DF")
3628                         (match_test "optimize_function_for_size_p (cfun)")
3629                           (const_string "V4SF")
3630                        ]
3631                        (const_string "DF"))
3633                /* For architectures resolving dependencies on register
3634                   parts we may avoid extra work to zero out upper part
3635                   of register.  */
3636                (eq_attr "alternative" "14,18")
3637                  (cond [(not (match_test "TARGET_SSE2"))
3638                           (const_string "V2SF")
3639                         (match_test "TARGET_AVX")
3640                           (const_string "DF")
3641                         (match_test "TARGET_SSE_SPLIT_REGS")
3642                           (const_string "V1DF")
3643                        ]
3644                        (const_string "DF"))
3646                (and (eq_attr "alternative" "15,19")
3647                     (not (match_test "TARGET_SSE2")))
3648                  (const_string "V2SF")
3649               ]
3650               (const_string "DF")))
3651    (set (attr "preferred_for_size")
3652      (cond [(eq_attr "alternative" "3,4")
3653               (symbol_ref "false")]
3654            (symbol_ref "true")))
3655    (set (attr "preferred_for_speed")
3656      (cond [(eq_attr "alternative" "3,4")
3657               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3658            (symbol_ref "true")))
3659    (set (attr "enabled")
3660      (cond [(eq_attr "alternative" "22,23,24,25")
3661               (if_then_else
3662                 (match_test "TARGET_HARD_DF_REGS")
3663                 (symbol_ref "false")
3664                 (const_string "*"))
3665             (not (match_test "TARGET_HARD_DF_REGS"))
3666               (symbol_ref "false")
3667            ]
3668            (const_string "*")))])
3670 (define_split
3671   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3672         (match_operand:DF 1 "general_gr_operand"))]
3673   "!TARGET_64BIT && reload_completed"
3674   [(const_int 0)]
3675   "ix86_split_long_move (operands); DONE;")
3677 (define_insn "*movsf_internal"
3678   [(set (match_operand:SF 0 "nonimmediate_operand"
3679           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3680         (match_operand:SF 1 "general_operand"
3681           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3683    && (lra_in_progress || reload_completed
3684        || !CONST_DOUBLE_P (operands[1])
3685        || ((optimize_function_for_size_p (cfun)
3686             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3687            && ((IS_STACK_MODE (SFmode)
3688                 && standard_80387_constant_p (operands[1]) > 0)
3689                || (TARGET_SSE && TARGET_SSE_MATH
3690                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3691        || memory_operand (operands[0], SFmode)
3692        || !TARGET_HARD_SF_REGS)"
3694   switch (get_attr_type (insn))
3695     {
3696     case TYPE_FMOV:
3697       if (which_alternative == 2)
3698         return standard_80387_constant_opcode (operands[1]);
3699       return output_387_reg_move (insn, operands);
3701     case TYPE_IMOV:
3702       return "mov{l}\t{%1, %0|%0, %1}";
3704     case TYPE_SSELOG1:
3705       return standard_sse_constant_opcode (insn, operands);
3707     case TYPE_SSEMOV:
3708       switch (get_attr_mode (insn))
3709         {
3710         case MODE_SF:
3711           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3712             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3713           return "%vmovss\t{%1, %0|%0, %1}";
3715         case MODE_V16SF:
3716           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3717         case MODE_V4SF:
3718           return "%vmovaps\t{%1, %0|%0, %1}";
3720         case MODE_SI:
3721           return "%vmovd\t{%1, %0|%0, %1}";
3723         default:
3724           gcc_unreachable ();
3725         }
3727     case TYPE_MMXMOV:
3728       switch (get_attr_mode (insn))
3729         {
3730         case MODE_DI:
3731           return "movq\t{%1, %0|%0, %1}";
3732         case MODE_SI:
3733           return "movd\t{%1, %0|%0, %1}";
3735         default:
3736           gcc_unreachable ();
3737         }
3739     default:
3740       gcc_unreachable ();
3741     }
3743   [(set (attr "type")
3744         (cond [(eq_attr "alternative" "0,1,2")
3745                  (const_string "fmov")
3746                (eq_attr "alternative" "3,4,16,17")
3747                  (const_string "imov")
3748                (eq_attr "alternative" "5")
3749                  (const_string "sselog1")
3750                (eq_attr "alternative" "11,12,13,14,15")
3751                  (const_string "mmxmov")
3752               ]
3753               (const_string "ssemov")))
3754    (set (attr "prefix")
3755      (if_then_else (eq_attr "type" "sselog1,ssemov")
3756        (const_string "maybe_vex")
3757        (const_string "orig")))
3758    (set (attr "prefix_data16")
3759      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3760        (const_string "1")
3761        (const_string "*")))
3762    (set (attr "mode")
3763         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3764                  (const_string "SI")
3765                (eq_attr "alternative" "11")
3766                  (const_string "DI")
3767                (eq_attr "alternative" "5")
3768                  (cond [(not (match_test "TARGET_SSE2"))
3769                           (const_string "V4SF")
3770                         (and (match_test "TARGET_AVX512F")
3771                           (not (match_test "TARGET_PREFER_AVX256")))
3772                           (const_string "V16SF")
3773                         (match_test "TARGET_AVX")
3774                           (const_string "V4SF")
3775                         (match_test "optimize_function_for_size_p (cfun)")
3776                           (const_string "V4SF")
3777                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3778                           (const_string "TI")
3779                        ]
3780                        (const_string "V4SF"))
3782                /* For architectures resolving dependencies on
3783                   whole SSE registers use APS move to break dependency
3784                   chains, otherwise use short move to avoid extra work.
3786                   Do the same for architectures resolving dependencies on
3787                   the parts.  While in DF mode it is better to always handle
3788                   just register parts, the SF mode is different due to lack
3789                   of instructions to load just part of the register.  It is
3790                   better to maintain the whole registers in single format
3791                   to avoid problems on using packed logical operations.  */
3792                (eq_attr "alternative" "6")
3793                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3794                                   (not (match_test "TARGET_AVX512VL")))
3795                              (ior (match_operand 0 "ext_sse_reg_operand")
3796                                   (match_operand 1 "ext_sse_reg_operand")))
3797                           (const_string "V16SF")
3798                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3799                              (match_test "TARGET_SSE_SPLIT_REGS"))
3800                           (const_string "V4SF")
3801                        ]
3802                        (const_string "SF"))
3803               ]
3804               (const_string "SF")))
3805    (set (attr "enabled")
3806      (cond [(eq_attr "alternative" "16,17")
3807               (if_then_else
3808                 (match_test "TARGET_HARD_SF_REGS")
3809                 (symbol_ref "false")
3810                 (const_string "*"))
3811             (not (match_test "TARGET_HARD_SF_REGS"))
3812               (symbol_ref "false")
3813            ]
3814            (const_string "*")))])
3816 (define_split
3817   [(set (match_operand 0 "any_fp_register_operand")
3818         (match_operand 1 "nonimmediate_operand"))]
3819   "reload_completed
3820    && (GET_MODE (operands[0]) == TFmode
3821        || GET_MODE (operands[0]) == XFmode
3822        || GET_MODE (operands[0]) == DFmode
3823        || GET_MODE (operands[0]) == SFmode)
3824    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3825   [(set (match_dup 0) (match_dup 2))]
3826   "operands[2] = find_constant_src (curr_insn);")
3828 (define_split
3829   [(set (match_operand 0 "any_fp_register_operand")
3830         (float_extend (match_operand 1 "nonimmediate_operand")))]
3831   "reload_completed
3832    && (GET_MODE (operands[0]) == TFmode
3833        || GET_MODE (operands[0]) == XFmode
3834        || GET_MODE (operands[0]) == DFmode)
3835    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3836   [(set (match_dup 0) (match_dup 2))]
3837   "operands[2] = find_constant_src (curr_insn);")
3839 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3840 (define_split
3841   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3842         (match_operand:X87MODEF 1 "immediate_operand"))]
3843   "reload_completed
3844    && (standard_80387_constant_p (operands[1]) == 8
3845        || standard_80387_constant_p (operands[1]) == 9)"
3846   [(set (match_dup 0)(match_dup 1))
3847    (set (match_dup 0)
3848         (neg:X87MODEF (match_dup 0)))]
3850   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3851     operands[1] = CONST0_RTX (<MODE>mode);
3852   else
3853     operands[1] = CONST1_RTX (<MODE>mode);
3856 (define_insn "swapxf"
3857   [(set (match_operand:XF 0 "register_operand" "+f")
3858         (match_operand:XF 1 "register_operand" "+f"))
3859    (set (match_dup 1)
3860         (match_dup 0))]
3861   "TARGET_80387"
3863   if (STACK_TOP_P (operands[0]))
3864     return "fxch\t%1";
3865   else
3866     return "fxch\t%0";
3868   [(set_attr "type" "fxch")
3869    (set_attr "mode" "XF")])
3871 (define_insn "*swap<mode>"
3872   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3873         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3874    (set (match_dup 1)
3875         (match_dup 0))]
3876   "TARGET_80387 || reload_completed"
3878   if (STACK_TOP_P (operands[0]))
3879     return "fxch\t%1";
3880   else
3881     return "fxch\t%0";
3883   [(set_attr "type" "fxch")
3884    (set_attr "mode" "<MODE>")])
3886 ;; Zero extension instructions
3888 (define_expand "zero_extendsidi2"
3889   [(set (match_operand:DI 0 "nonimmediate_operand")
3890         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3892 (define_insn "*zero_extendsidi2"
3893   [(set (match_operand:DI 0 "nonimmediate_operand"
3894                 "=r,?r,?o,r   ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r")
3895         (zero_extend:DI
3896          (match_operand:SI 1 "x86_64_zext_operand"
3897                 "0 ,rm,r ,rmWz,0,r   ,m   ,Yj,r  ,m ,*x,*v,*k")))]
3898   ""
3900   switch (get_attr_type (insn))
3901     {
3902     case TYPE_IMOVX:
3903       if (ix86_use_lea_for_mov (insn, operands))
3904         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3905       else
3906         return "mov{l}\t{%1, %k0|%k0, %1}";
3908     case TYPE_MULTI:
3909       return "#";
3911     case TYPE_MMXMOV:
3912       return "movd\t{%1, %0|%0, %1}";
3914     case TYPE_SSEMOV:
3915       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3916         {
3917           if (EXT_REX_SSE_REG_P (operands[0])
3918               || EXT_REX_SSE_REG_P (operands[1]))
3919             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3920           else
3921             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3922         }
3924       if (GENERAL_REG_P (operands[0]))
3925         return "%vmovd\t{%1, %k0|%k0, %1}";
3927       return "%vmovd\t{%1, %0|%0, %1}";
3929     case TYPE_MSKMOV:
3930       return "kmovd\t{%1, %k0|%k0, %1}";
3932     default:
3933       gcc_unreachable ();
3934     }
3936   [(set (attr "isa")
3937      (cond [(eq_attr "alternative" "0,1,2")
3938               (const_string "nox64")
3939             (eq_attr "alternative" "3")
3940               (const_string "x64")
3941             (eq_attr "alternative" "9")
3942               (const_string "sse2")
3943             (eq_attr "alternative" "10")
3944               (const_string "sse4")
3945             (eq_attr "alternative" "11")
3946               (const_string "avx512f")
3947             (eq_attr "alternative" "12")
3948               (const_string "x64_avx512bw")
3949            ]
3950            (const_string "*")))
3951    (set (attr "type")
3952      (cond [(eq_attr "alternative" "0,1,2,4")
3953               (const_string "multi")
3954             (eq_attr "alternative" "5,6")
3955               (const_string "mmxmov")
3956             (eq_attr "alternative" "7")
3957               (if_then_else (match_test "TARGET_64BIT")
3958                 (const_string "ssemov")
3959                 (const_string "multi"))
3960             (eq_attr "alternative" "8,9,10,11")
3961               (const_string "ssemov")
3962             (eq_attr "alternative" "12")
3963               (const_string "mskmov")
3964            ]
3965            (const_string "imovx")))
3966    (set (attr "prefix_extra")
3967      (if_then_else (eq_attr "alternative" "10,11")
3968        (const_string "1")
3969        (const_string "*")))
3970    (set (attr "prefix")
3971      (if_then_else (eq_attr "type" "ssemov")
3972        (const_string "maybe_vex")
3973        (const_string "orig")))
3974    (set (attr "prefix_0f")
3975      (if_then_else (eq_attr "type" "imovx")
3976        (const_string "0")
3977        (const_string "*")))
3978    (set (attr "mode")
3979      (cond [(eq_attr "alternative" "5,6")
3980               (const_string "DI")
3981             (and (eq_attr "alternative" "7")
3982                  (match_test "TARGET_64BIT"))
3983               (const_string "TI")
3984             (eq_attr "alternative" "8,10,11")
3985               (const_string "TI")
3986            ]
3987            (const_string "SI")))])
3989 (define_split
3990   [(set (match_operand:DI 0 "memory_operand")
3991         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3992   "reload_completed"
3993   [(set (match_dup 4) (const_int 0))]
3994   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3996 (define_split
3997   [(set (match_operand:DI 0 "general_reg_operand")
3998         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3999   "!TARGET_64BIT && reload_completed
4000    && REGNO (operands[0]) == REGNO (operands[1])"
4001   [(set (match_dup 4) (const_int 0))]
4002   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4004 (define_split
4005   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4006         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4007   "!TARGET_64BIT && reload_completed
4008    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4009   [(set (match_dup 3) (match_dup 1))
4010    (set (match_dup 4) (const_int 0))]
4011   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4013 (define_mode_attr kmov_isa
4014   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4016 (define_insn "zero_extend<mode>di2"
4017   [(set (match_operand:DI 0 "register_operand" "=r,*r")
4018         (zero_extend:DI
4019          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4020   "TARGET_64BIT"
4021   "@
4022    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4023    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4024   [(set_attr "isa" "*,<kmov_isa>")
4025    (set_attr "type" "imovx,mskmov")
4026    (set_attr "mode" "SI,<MODE>")])
4028 (define_expand "zero_extend<mode>si2"
4029   [(set (match_operand:SI 0 "register_operand")
4030         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4031   ""
4033   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4034     {
4035       operands[1] = force_reg (<MODE>mode, operands[1]);
4036       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4037       DONE;
4038     }
4041 (define_insn_and_split "zero_extend<mode>si2_and"
4042   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4043         (zero_extend:SI
4044           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4045    (clobber (reg:CC FLAGS_REG))]
4046   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4047   "#"
4048   "&& reload_completed"
4049   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4050               (clobber (reg:CC FLAGS_REG))])]
4052   if (!REG_P (operands[1])
4053       || REGNO (operands[0]) != REGNO (operands[1]))
4054     {
4055       ix86_expand_clear (operands[0]);
4057       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4058       emit_insn (gen_movstrict<mode>
4059                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4060       DONE;
4061     }
4063   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4065   [(set_attr "type" "alu1")
4066    (set_attr "mode" "SI")])
4068 (define_insn "*zero_extend<mode>si2"
4069   [(set (match_operand:SI 0 "register_operand" "=r,*r")
4070         (zero_extend:SI
4071           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4072   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4073   "@
4074    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4075    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4076   [(set_attr "isa" "*,<kmov_isa>")
4077    (set_attr "type" "imovx,mskmov")
4078    (set_attr "mode" "SI,<MODE>")])
4080 (define_expand "zero_extendqihi2"
4081   [(set (match_operand:HI 0 "register_operand")
4082         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4083   ""
4085   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4086     {
4087       operands[1] = force_reg (QImode, operands[1]);
4088       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4089       DONE;
4090     }
4093 (define_insn_and_split "zero_extendqihi2_and"
4094   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4095         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4096    (clobber (reg:CC FLAGS_REG))]
4097   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4098   "#"
4099   "&& reload_completed"
4100   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4101               (clobber (reg:CC FLAGS_REG))])]
4103   if (!REG_P (operands[1])
4104       || REGNO (operands[0]) != REGNO (operands[1]))
4105     {
4106       ix86_expand_clear (operands[0]);
4108       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4109       emit_insn (gen_movstrictqi
4110                   (gen_lowpart (QImode, operands[0]), operands[1]));
4111       DONE;
4112     }
4114   operands[0] = gen_lowpart (SImode, operands[0]);
4116   [(set_attr "type" "alu1")
4117    (set_attr "mode" "SI")])
4119 ; zero extend to SImode to avoid partial register stalls
4120 (define_insn "*zero_extendqihi2"
4121   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4122         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4123   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4124   "@
4125    movz{bl|x}\t{%1, %k0|%k0, %1}
4126    kmovb\t{%1, %k0|%k0, %1}"
4127   [(set_attr "isa" "*,avx512dq")
4128    (set_attr "type" "imovx,mskmov")
4129    (set_attr "mode" "SI,QI")])
4131 (define_insn_and_split "*zext<mode>_doubleword_and"
4132   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4133         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4134   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4135    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4136   "#"
4137   "&& reload_completed && GENERAL_REG_P (operands[0])"
4138   [(set (match_dup 2) (const_int 0))]
4140   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4142   emit_move_insn (operands[0], const0_rtx);
4144   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4145   emit_insn (gen_movstrict<mode>
4146              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4149 (define_insn_and_split "*zext<mode>_doubleword"
4150   [(set (match_operand:DI 0 "register_operand" "=r")
4151         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4152   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4153    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4154   "#"
4155   "&& reload_completed && GENERAL_REG_P (operands[0])"
4156   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4157    (set (match_dup 2) (const_int 0))]
4158   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4160 (define_insn_and_split "*zextsi_doubleword"
4161   [(set (match_operand:DI 0 "register_operand" "=r")
4162         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4163   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4164   "#"
4165   "&& reload_completed && GENERAL_REG_P (operands[0])"
4166   [(set (match_dup 0) (match_dup 1))
4167    (set (match_dup 2) (const_int 0))]
4168   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4170 ;; Sign extension instructions
4172 (define_expand "extendsidi2"
4173   [(set (match_operand:DI 0 "register_operand")
4174         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4175   ""
4177   if (!TARGET_64BIT)
4178     {
4179       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4180       DONE;
4181     }
4184 (define_insn "*extendsidi2_rex64"
4185   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4186         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4187   "TARGET_64BIT"
4188   "@
4189    {cltq|cdqe}
4190    movs{lq|x}\t{%1, %0|%0, %1}"
4191   [(set_attr "type" "imovx")
4192    (set_attr "mode" "DI")
4193    (set_attr "prefix_0f" "0")
4194    (set_attr "modrm" "0,1")])
4196 (define_insn "extendsidi2_1"
4197   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4198         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4199    (clobber (reg:CC FLAGS_REG))
4200    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4201   "!TARGET_64BIT"
4202   "#")
4204 ;; Split the memory case.  If the source register doesn't die, it will stay
4205 ;; this way, if it does die, following peephole2s take care of it.
4206 (define_split
4207   [(set (match_operand:DI 0 "memory_operand")
4208         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4209    (clobber (reg:CC FLAGS_REG))
4210    (clobber (match_operand:SI 2 "register_operand"))]
4211   "reload_completed"
4212   [(const_int 0)]
4214   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4216   emit_move_insn (operands[3], operands[1]);
4218   /* Generate a cltd if possible and doing so it profitable.  */
4219   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4220       && REGNO (operands[1]) == AX_REG
4221       && REGNO (operands[2]) == DX_REG)
4222     {
4223       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4224     }
4225   else
4226     {
4227       emit_move_insn (operands[2], operands[1]);
4228       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4229     }
4230   emit_move_insn (operands[4], operands[2]);
4231   DONE;
4234 ;; Peepholes for the case where the source register does die, after
4235 ;; being split with the above splitter.
4236 (define_peephole2
4237   [(set (match_operand:SI 0 "memory_operand")
4238         (match_operand:SI 1 "general_reg_operand"))
4239    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4240    (parallel [(set (match_dup 2)
4241                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4242                (clobber (reg:CC FLAGS_REG))])
4243    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4244   "REGNO (operands[1]) != REGNO (operands[2])
4245    && peep2_reg_dead_p (2, operands[1])
4246    && peep2_reg_dead_p (4, operands[2])
4247    && !reg_mentioned_p (operands[2], operands[3])"
4248   [(set (match_dup 0) (match_dup 1))
4249    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4250               (clobber (reg:CC FLAGS_REG))])
4251    (set (match_dup 3) (match_dup 1))])
4253 (define_peephole2
4254   [(set (match_operand:SI 0 "memory_operand")
4255         (match_operand:SI 1 "general_reg_operand"))
4256    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4257                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4258                (clobber (reg:CC FLAGS_REG))])
4259    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4260   "/* cltd is shorter than sarl $31, %eax */
4261    !optimize_function_for_size_p (cfun)
4262    && REGNO (operands[1]) == AX_REG
4263    && REGNO (operands[2]) == DX_REG
4264    && peep2_reg_dead_p (2, operands[1])
4265    && peep2_reg_dead_p (3, operands[2])
4266    && !reg_mentioned_p (operands[2], operands[3])"
4267   [(set (match_dup 0) (match_dup 1))
4268    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4269               (clobber (reg:CC FLAGS_REG))])
4270    (set (match_dup 3) (match_dup 1))])
4272 ;; Extend to register case.  Optimize case where source and destination
4273 ;; registers match and cases where we can use cltd.
4274 (define_split
4275   [(set (match_operand:DI 0 "register_operand")
4276         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4277    (clobber (reg:CC FLAGS_REG))
4278    (clobber (match_scratch:SI 2))]
4279   "reload_completed"
4280   [(const_int 0)]
4282   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4284   if (REGNO (operands[3]) != REGNO (operands[1]))
4285     emit_move_insn (operands[3], operands[1]);
4287   /* Generate a cltd if possible and doing so it profitable.  */
4288   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4289       && REGNO (operands[3]) == AX_REG
4290       && REGNO (operands[4]) == DX_REG)
4291     {
4292       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4293       DONE;
4294     }
4296   if (REGNO (operands[4]) != REGNO (operands[1]))
4297     emit_move_insn (operands[4], operands[1]);
4299   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4300   DONE;
4303 (define_insn "extend<mode>di2"
4304   [(set (match_operand:DI 0 "register_operand" "=r")
4305         (sign_extend:DI
4306          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4307   "TARGET_64BIT"
4308   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4309   [(set_attr "type" "imovx")
4310    (set_attr "mode" "DI")])
4312 (define_insn "extendhisi2"
4313   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4314         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4315   ""
4317   switch (get_attr_prefix_0f (insn))
4318     {
4319     case 0:
4320       return "{cwtl|cwde}";
4321     default:
4322       return "movs{wl|x}\t{%1, %0|%0, %1}";
4323     }
4325   [(set_attr "type" "imovx")
4326    (set_attr "mode" "SI")
4327    (set (attr "prefix_0f")
4328      ;; movsx is short decodable while cwtl is vector decoded.
4329      (if_then_else (and (eq_attr "cpu" "!k6")
4330                         (eq_attr "alternative" "0"))
4331         (const_string "0")
4332         (const_string "1")))
4333    (set (attr "znver1_decode")
4334      (if_then_else (eq_attr "prefix_0f" "0")
4335         (const_string "double")
4336         (const_string "direct")))
4337    (set (attr "modrm")
4338      (if_then_else (eq_attr "prefix_0f" "0")
4339         (const_string "0")
4340         (const_string "1")))])
4342 (define_insn "*extendhisi2_zext"
4343   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4344         (zero_extend:DI
4345          (sign_extend:SI
4346           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4347   "TARGET_64BIT"
4349   switch (get_attr_prefix_0f (insn))
4350     {
4351     case 0:
4352       return "{cwtl|cwde}";
4353     default:
4354       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4355     }
4357   [(set_attr "type" "imovx")
4358    (set_attr "mode" "SI")
4359    (set (attr "prefix_0f")
4360      ;; movsx is short decodable while cwtl is vector decoded.
4361      (if_then_else (and (eq_attr "cpu" "!k6")
4362                         (eq_attr "alternative" "0"))
4363         (const_string "0")
4364         (const_string "1")))
4365    (set (attr "modrm")
4366      (if_then_else (eq_attr "prefix_0f" "0")
4367         (const_string "0")
4368         (const_string "1")))])
4370 (define_insn "extendqisi2"
4371   [(set (match_operand:SI 0 "register_operand" "=r")
4372         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4373   ""
4374   "movs{bl|x}\t{%1, %0|%0, %1}"
4375    [(set_attr "type" "imovx")
4376     (set_attr "mode" "SI")])
4378 (define_insn "*extendqisi2_zext"
4379   [(set (match_operand:DI 0 "register_operand" "=r")
4380         (zero_extend:DI
4381           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4382   "TARGET_64BIT"
4383   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4384    [(set_attr "type" "imovx")
4385     (set_attr "mode" "SI")])
4387 (define_insn "extendqihi2"
4388   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4389         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4390   ""
4392   switch (get_attr_prefix_0f (insn))
4393     {
4394     case 0:
4395       return "{cbtw|cbw}";
4396     default:
4397       return "movs{bw|x}\t{%1, %0|%0, %1}";
4398     }
4400   [(set_attr "type" "imovx")
4401    (set_attr "mode" "HI")
4402    (set (attr "prefix_0f")
4403      ;; movsx is short decodable while cwtl is vector decoded.
4404      (if_then_else (and (eq_attr "cpu" "!k6")
4405                         (eq_attr "alternative" "0"))
4406         (const_string "0")
4407         (const_string "1")))
4408    (set (attr "modrm")
4409      (if_then_else (eq_attr "prefix_0f" "0")
4410         (const_string "0")
4411         (const_string "1")))])
4413 ;; Conversions between float and double.
4415 ;; These are all no-ops in the model used for the 80387.
4416 ;; So just emit moves.
4418 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4419 (define_split
4420   [(set (match_operand:DF 0 "push_operand")
4421         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4422   "reload_completed"
4423   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4424    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4426 (define_split
4427   [(set (match_operand:XF 0 "push_operand")
4428         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4429   "reload_completed"
4430   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4431    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4432   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4434 (define_expand "extendsfdf2"
4435   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4436         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4437   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4439   /* ??? Needed for compress_float_constant since all fp constants
4440      are TARGET_LEGITIMATE_CONSTANT_P.  */
4441   if (CONST_DOUBLE_P (operands[1]))
4442     {
4443       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4444           && standard_80387_constant_p (operands[1]) > 0)
4445         {
4446           operands[1] = simplify_const_unary_operation
4447             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4448           emit_move_insn_1 (operands[0], operands[1]);
4449           DONE;
4450         }
4451       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4452     }
4455 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4456    cvtss2sd:
4457       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4458       cvtps2pd xmm2,xmm1
4459    We do the conversion post reload to avoid producing of 128bit spills
4460    that might lead to ICE on 32bit target.  The sequence unlikely combine
4461    anyway.  */
4462 (define_split
4463   [(set (match_operand:DF 0 "sse_reg_operand")
4464         (float_extend:DF
4465           (match_operand:SF 1 "nonimmediate_operand")))]
4466   "TARGET_USE_VECTOR_FP_CONVERTS
4467    && optimize_insn_for_speed_p ()
4468    && reload_completed
4469    && (!EXT_REX_SSE_REG_P (operands[0])
4470        || TARGET_AVX512VL)"
4471    [(set (match_dup 2)
4472          (float_extend:V2DF
4473            (vec_select:V2SF
4474              (match_dup 3)
4475              (parallel [(const_int 0) (const_int 1)]))))]
4477   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4478   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4479   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4480      Try to avoid move when unpacking can be done in source.  */
4481   if (REG_P (operands[1]))
4482     {
4483       /* If it is unsafe to overwrite upper half of source, we need
4484          to move to destination and unpack there.  */
4485       if (REGNO (operands[0]) != REGNO (operands[1])
4486           || (EXT_REX_SSE_REG_P (operands[1])
4487               && !TARGET_AVX512VL))
4488         {
4489           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4490           emit_move_insn (tmp, operands[1]);
4491         }
4492       else
4493         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4494       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4495          =v, v, then vbroadcastss will be only needed for AVX512F without
4496          AVX512VL.  */
4497       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4498         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4499                                                operands[3]));
4500       else
4501         {
4502           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4503           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4504         }
4505     }
4506   else
4507     emit_insn (gen_vec_setv4sf_0 (operands[3],
4508                                   CONST0_RTX (V4SFmode), operands[1]));
4511 ;; It's more profitable to split and then extend in the same register.
4512 (define_peephole2
4513   [(set (match_operand:DF 0 "sse_reg_operand")
4514         (float_extend:DF
4515           (match_operand:SF 1 "memory_operand")))]
4516   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4517    && optimize_insn_for_speed_p ()"
4518   [(set (match_dup 2) (match_dup 1))
4519    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4520   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4522 (define_insn "*extendsfdf2"
4523   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4524         (float_extend:DF
4525           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4526   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528   switch (which_alternative)
4529     {
4530     case 0:
4531     case 1:
4532       return output_387_reg_move (insn, operands);
4534     case 2:
4535       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4537     default:
4538       gcc_unreachable ();
4539     }
4541   [(set_attr "type" "fmov,fmov,ssecvt")
4542    (set_attr "prefix" "orig,orig,maybe_vex")
4543    (set_attr "mode" "SF,XF,DF")
4544    (set (attr "enabled")
4545      (if_then_else
4546        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4547        (if_then_else
4548          (eq_attr "alternative" "0,1")
4549          (symbol_ref "TARGET_MIX_SSE_I387")
4550          (symbol_ref "true"))
4551        (if_then_else
4552          (eq_attr "alternative" "0,1")
4553          (symbol_ref "true")
4554          (symbol_ref "false"))))])
4556 (define_expand "extend<mode>xf2"
4557   [(set (match_operand:XF 0 "nonimmediate_operand")
4558         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4559   "TARGET_80387"
4561   /* ??? Needed for compress_float_constant since all fp constants
4562      are TARGET_LEGITIMATE_CONSTANT_P.  */
4563   if (CONST_DOUBLE_P (operands[1]))
4564     {
4565       if (standard_80387_constant_p (operands[1]) > 0)
4566         {
4567           operands[1] = simplify_const_unary_operation
4568             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4569           emit_move_insn_1 (operands[0], operands[1]);
4570           DONE;
4571         }
4572       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4573     }
4576 (define_insn "*extend<mode>xf2_i387"
4577   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4578         (float_extend:XF
4579           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4580   "TARGET_80387"
4581   "* return output_387_reg_move (insn, operands);"
4582   [(set_attr "type" "fmov")
4583    (set_attr "mode" "<MODE>,XF")])
4585 ;; %%% This seems like bad news.
4586 ;; This cannot output into an f-reg because there is no way to be sure
4587 ;; of truncating in that case.  Otherwise this is just like a simple move
4588 ;; insn.  So we pretend we can output to a reg in order to get better
4589 ;; register preferencing, but we really use a stack slot.
4591 ;; Conversion from DFmode to SFmode.
4593 (define_expand "truncdfsf2"
4594   [(set (match_operand:SF 0 "nonimmediate_operand")
4595         (float_truncate:SF
4596           (match_operand:DF 1 "nonimmediate_operand")))]
4597   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4599   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4600     ;
4601   else if (flag_unsafe_math_optimizations)
4602     ;
4603   else
4604     {
4605       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4606       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4607       DONE;
4608     }
4611 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4612    cvtsd2ss:
4613       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4614       cvtpd2ps xmm2,xmm1
4615    We do the conversion post reload to avoid producing of 128bit spills
4616    that might lead to ICE on 32bit target.  The sequence unlikely combine
4617    anyway.  */
4618 (define_split
4619   [(set (match_operand:SF 0 "sse_reg_operand")
4620         (float_truncate:SF
4621           (match_operand:DF 1 "nonimmediate_operand")))]
4622   "TARGET_USE_VECTOR_FP_CONVERTS
4623    && optimize_insn_for_speed_p ()
4624    && reload_completed
4625    && (!EXT_REX_SSE_REG_P (operands[0])
4626        || TARGET_AVX512VL)"
4627    [(set (match_dup 2)
4628          (vec_concat:V4SF
4629            (float_truncate:V2SF
4630              (match_dup 4))
4631            (match_dup 3)))]
4633   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4634   operands[3] = CONST0_RTX (V2SFmode);
4635   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4636   /* Use movsd for loading from memory, unpcklpd for registers.
4637      Try to avoid move when unpacking can be done in source, or SSE3
4638      movddup is available.  */
4639   if (REG_P (operands[1]))
4640     {
4641       if (!TARGET_SSE3
4642           && REGNO (operands[0]) != REGNO (operands[1]))
4643         {
4644           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4645           emit_move_insn (tmp, operands[1]);
4646           operands[1] = tmp;
4647         }
4648       else if (!TARGET_SSE3)
4649         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4650       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4651     }
4652   else
4653     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4654                                    CONST0_RTX (DFmode)));
4657 ;; It's more profitable to split and then extend in the same register.
4658 (define_peephole2
4659   [(set (match_operand:SF 0 "sse_reg_operand")
4660         (float_truncate:SF
4661           (match_operand:DF 1 "memory_operand")))]
4662   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4663    && optimize_insn_for_speed_p ()"
4664   [(set (match_dup 2) (match_dup 1))
4665    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4666   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4668 (define_expand "truncdfsf2_with_temp"
4669   [(parallel [(set (match_operand:SF 0)
4670                    (float_truncate:SF (match_operand:DF 1)))
4671               (clobber (match_operand:SF 2))])])
4673 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4674 ;; because nothing we do there is unsafe.
4675 (define_insn "*truncdfsf_fast_mixed"
4676   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4677         (float_truncate:SF
4678           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4679   "TARGET_SSE2 && TARGET_SSE_MATH"
4681   switch (which_alternative)
4682     {
4683     case 0:
4684       return output_387_reg_move (insn, operands);
4685     case 1:
4686       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4687     default:
4688       gcc_unreachable ();
4689     }
4691   [(set_attr "type" "fmov,ssecvt")
4692    (set_attr "prefix" "orig,maybe_vex")
4693    (set_attr "mode" "SF")
4694    (set (attr "enabled")
4695      (cond [(eq_attr "alternative" "0")
4696               (symbol_ref "TARGET_MIX_SSE_I387
4697                            && flag_unsafe_math_optimizations")
4698            ]
4699            (symbol_ref "true")))])
4701 (define_insn "*truncdfsf_fast_i387"
4702   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4703         (float_truncate:SF
4704           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4705   "TARGET_80387 && flag_unsafe_math_optimizations"
4706   "* return output_387_reg_move (insn, operands);"
4707   [(set_attr "type" "fmov")
4708    (set_attr "mode" "SF")])
4710 (define_insn "*truncdfsf_mixed"
4711   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4712         (float_truncate:SF
4713           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4714    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4715   "TARGET_MIX_SSE_I387"
4717   switch (which_alternative)
4718     {
4719     case 0:
4720       return output_387_reg_move (insn, operands);
4721     case 1:
4722       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4724     default:
4725       return "#";
4726     }
4728   [(set_attr "isa" "*,sse2,*,*,*")
4729    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4730    (set_attr "unit" "*,*,i387,i387,i387")
4731    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4732    (set_attr "mode" "SF")])
4734 (define_insn "*truncdfsf_i387"
4735   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4736         (float_truncate:SF
4737           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4738    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4739   "TARGET_80387"
4741   switch (which_alternative)
4742     {
4743     case 0:
4744       return output_387_reg_move (insn, operands);
4746     default:
4747       return "#";
4748     }
4750   [(set_attr "type" "fmov,multi,multi,multi")
4751    (set_attr "unit" "*,i387,i387,i387")
4752    (set_attr "mode" "SF")])
4754 (define_insn "*truncdfsf2_i387_1"
4755   [(set (match_operand:SF 0 "memory_operand" "=m")
4756         (float_truncate:SF
4757           (match_operand:DF 1 "register_operand" "f")))]
4758   "TARGET_80387
4759    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4760    && !TARGET_MIX_SSE_I387"
4761   "* return output_387_reg_move (insn, operands);"
4762   [(set_attr "type" "fmov")
4763    (set_attr "mode" "SF")])
4765 (define_split
4766   [(set (match_operand:SF 0 "register_operand")
4767         (float_truncate:SF
4768          (match_operand:DF 1 "fp_register_operand")))
4769    (clobber (match_operand 2))]
4770   "reload_completed"
4771   [(set (match_dup 2) (match_dup 1))
4772    (set (match_dup 0) (match_dup 2))]
4773   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4775 ;; Conversion from XFmode to {SF,DF}mode
4777 (define_expand "truncxf<mode>2"
4778   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4779                    (float_truncate:MODEF
4780                      (match_operand:XF 1 "register_operand")))
4781               (clobber (match_dup 2))])]
4782   "TARGET_80387"
4784   if (flag_unsafe_math_optimizations)
4785     {
4786       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4787       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4788       if (reg != operands[0])
4789         emit_move_insn (operands[0], reg);
4790       DONE;
4791     }
4792   else
4793     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4796 (define_insn "*truncxfsf2_mixed"
4797   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4798         (float_truncate:SF
4799           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4800    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4801   "TARGET_80387"
4803   gcc_assert (!which_alternative);
4804   return output_387_reg_move (insn, operands);
4806   [(set_attr "type" "fmov,multi,multi,multi")
4807    (set_attr "unit" "*,i387,i387,i387")
4808    (set_attr "mode" "SF")])
4810 (define_insn "*truncxfdf2_mixed"
4811   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4812         (float_truncate:DF
4813           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4814    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4815   "TARGET_80387"
4817   gcc_assert (!which_alternative);
4818   return output_387_reg_move (insn, operands);
4820   [(set_attr "isa" "*,*,sse2,*")
4821    (set_attr "type" "fmov,multi,multi,multi")
4822    (set_attr "unit" "*,i387,i387,i387")
4823    (set_attr "mode" "DF")])
4825 (define_insn "truncxf<mode>2_i387_noop"
4826   [(set (match_operand:MODEF 0 "register_operand" "=f")
4827         (float_truncate:MODEF
4828           (match_operand:XF 1 "register_operand" "f")))]
4829   "TARGET_80387 && flag_unsafe_math_optimizations"
4830   "* return output_387_reg_move (insn, operands);"
4831   [(set_attr "type" "fmov")
4832    (set_attr "mode" "<MODE>")])
4834 (define_insn "*truncxf<mode>2_i387"
4835   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4836         (float_truncate:MODEF
4837           (match_operand:XF 1 "register_operand" "f")))]
4838   "TARGET_80387"
4839   "* return output_387_reg_move (insn, operands);"
4840   [(set_attr "type" "fmov")
4841    (set_attr "mode" "<MODE>")])
4843 (define_split
4844   [(set (match_operand:MODEF 0 "register_operand")
4845         (float_truncate:MODEF
4846           (match_operand:XF 1 "register_operand")))
4847    (clobber (match_operand:MODEF 2 "memory_operand"))]
4848   "TARGET_80387 && reload_completed"
4849   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4850    (set (match_dup 0) (match_dup 2))])
4852 (define_split
4853   [(set (match_operand:MODEF 0 "memory_operand")
4854         (float_truncate:MODEF
4855           (match_operand:XF 1 "register_operand")))
4856    (clobber (match_operand:MODEF 2 "memory_operand"))]
4857   "TARGET_80387"
4858   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4860 ;; Signed conversion to DImode.
4862 (define_expand "fix_truncxfdi2"
4863   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4864                    (fix:DI (match_operand:XF 1 "register_operand")))
4865               (clobber (reg:CC FLAGS_REG))])]
4866   "TARGET_80387"
4868   if (TARGET_FISTTP)
4869    {
4870      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4871      DONE;
4872    }
4875 (define_expand "fix_trunc<mode>di2"
4876   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4877                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4878               (clobber (reg:CC FLAGS_REG))])]
4879   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4881   if (TARGET_FISTTP
4882       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4883    {
4884      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4885      DONE;
4886    }
4887   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4888    {
4889      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4890      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4891      if (out != operands[0])
4892         emit_move_insn (operands[0], out);
4893      DONE;
4894    }
4897 ;; Signed conversion to SImode.
4899 (define_expand "fix_truncxfsi2"
4900   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4901                    (fix:SI (match_operand:XF 1 "register_operand")))
4902               (clobber (reg:CC FLAGS_REG))])]
4903   "TARGET_80387"
4905   if (TARGET_FISTTP)
4906    {
4907      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4908      DONE;
4909    }
4912 (define_expand "fix_trunc<mode>si2"
4913   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4914                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4915               (clobber (reg:CC FLAGS_REG))])]
4916   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4918   if (TARGET_FISTTP
4919       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4920    {
4921      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4922      DONE;
4923    }
4924   if (SSE_FLOAT_MODE_P (<MODE>mode))
4925    {
4926      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4927      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4928      if (out != operands[0])
4929         emit_move_insn (operands[0], out);
4930      DONE;
4931    }
4934 ;; Signed conversion to HImode.
4936 (define_expand "fix_trunc<mode>hi2"
4937   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4938                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4939               (clobber (reg:CC FLAGS_REG))])]
4940   "TARGET_80387
4941    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4943   if (TARGET_FISTTP)
4944    {
4945      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4946      DONE;
4947    }
4950 ;; Unsigned conversion to SImode.
4952 (define_expand "fixuns_trunc<mode>si2"
4953   [(parallel
4954     [(set (match_operand:SI 0 "register_operand")
4955           (unsigned_fix:SI
4956             (match_operand:MODEF 1 "nonimmediate_operand")))
4957      (use (match_dup 2))
4958      (clobber (match_scratch:<ssevecmode> 3))
4959      (clobber (match_scratch:<ssevecmode> 4))])]
4960   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4962   machine_mode mode = <MODE>mode;
4963   machine_mode vecmode = <ssevecmode>mode;
4964   REAL_VALUE_TYPE TWO31r;
4965   rtx two31;
4967   if (optimize_insn_for_size_p ())
4968     FAIL;
4970   real_ldexp (&TWO31r, &dconst1, 31);
4971   two31 = const_double_from_real_value (TWO31r, mode);
4972   two31 = ix86_build_const_vector (vecmode, true, two31);
4973   operands[2] = force_reg (vecmode, two31);
4976 (define_insn_and_split "*fixuns_trunc<mode>_1"
4977   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4978         (unsigned_fix:SI
4979           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4980    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4981    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4982    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4983   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4984    && optimize_function_for_speed_p (cfun)"
4985   "#"
4986   "&& reload_completed"
4987   [(const_int 0)]
4989   ix86_split_convert_uns_si_sse (operands);
4990   DONE;
4993 ;; Unsigned conversion to HImode.
4994 ;; Without these patterns, we'll try the unsigned SI conversion which
4995 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4997 (define_expand "fixuns_trunc<mode>hi2"
4998   [(set (match_dup 2)
4999         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5000    (set (match_operand:HI 0 "nonimmediate_operand")
5001         (subreg:HI (match_dup 2) 0))]
5002   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5003   "operands[2] = gen_reg_rtx (SImode);")
5005 ;; When SSE is available, it is always faster to use it!
5006 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5007   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5008         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5009   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5010    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5011   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5012   [(set_attr "type" "sseicvt")
5013    (set_attr "prefix" "maybe_vex")
5014    (set (attr "prefix_rex")
5015         (if_then_else
5016           (match_test "<SWI48:MODE>mode == DImode")
5017           (const_string "1")
5018           (const_string "*")))
5019    (set_attr "mode" "<MODEF:MODE>")
5020    (set_attr "athlon_decode" "double,vector")
5021    (set_attr "amdfam10_decode" "double,double")
5022    (set_attr "bdver1_decode" "double,double")])
5024 ;; Avoid vector decoded forms of the instruction.
5025 (define_peephole2
5026   [(match_scratch:MODEF 2 "x")
5027    (set (match_operand:SWI48 0 "register_operand")
5028         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5029   "TARGET_AVOID_VECTOR_DECODE
5030    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5031    && optimize_insn_for_speed_p ()"
5032   [(set (match_dup 2) (match_dup 1))
5033    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5035 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5036   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5037         (fix:SWI248x (match_operand 1 "register_operand")))]
5038   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5039    && TARGET_FISTTP
5040    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5041          && (TARGET_64BIT || <MODE>mode != DImode))
5042         && TARGET_SSE_MATH)
5043    && can_create_pseudo_p ()"
5044   "#"
5045   "&& 1"
5046   [(const_int 0)]
5048   if (memory_operand (operands[0], VOIDmode))
5049     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5050   else
5051     {
5052       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5053       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5054                                                             operands[1],
5055                                                             operands[2]));
5056     }
5057   DONE;
5059   [(set_attr "type" "fisttp")
5060    (set_attr "mode" "<MODE>")])
5062 (define_insn "fix_trunc<mode>_i387_fisttp"
5063   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5064         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5065    (clobber (match_scratch:XF 2 "=&1f"))]
5066   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5067    && TARGET_FISTTP
5068    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5069          && (TARGET_64BIT || <MODE>mode != DImode))
5070         && TARGET_SSE_MATH)"
5071   "* return output_fix_trunc (insn, operands, true);"
5072   [(set_attr "type" "fisttp")
5073    (set_attr "mode" "<MODE>")])
5075 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5076   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5077         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5078    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5079    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5080   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5081    && TARGET_FISTTP
5082    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5083         && (TARGET_64BIT || <MODE>mode != DImode))
5084         && TARGET_SSE_MATH)"
5085   "#"
5086   [(set_attr "type" "fisttp")
5087    (set_attr "mode" "<MODE>")])
5089 (define_split
5090   [(set (match_operand:SWI248x 0 "register_operand")
5091         (fix:SWI248x (match_operand 1 "register_operand")))
5092    (clobber (match_operand:SWI248x 2 "memory_operand"))
5093    (clobber (match_scratch 3))]
5094   "reload_completed"
5095   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5096               (clobber (match_dup 3))])
5097    (set (match_dup 0) (match_dup 2))])
5099 (define_split
5100   [(set (match_operand:SWI248x 0 "memory_operand")
5101         (fix:SWI248x (match_operand 1 "register_operand")))
5102    (clobber (match_operand:SWI248x 2 "memory_operand"))
5103    (clobber (match_scratch 3))]
5104   "reload_completed"
5105   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5106               (clobber (match_dup 3))])])
5108 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5109 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5110 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5111 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5112 ;; function in i386.c.
5113 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5114   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5115         (fix:SWI248x (match_operand 1 "register_operand")))
5116    (clobber (reg:CC FLAGS_REG))]
5117   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118    && !TARGET_FISTTP
5119    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120          && (TARGET_64BIT || <MODE>mode != DImode))
5121    && can_create_pseudo_p ()"
5122   "#"
5123   "&& 1"
5124   [(const_int 0)]
5126   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5128   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5129   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5130   if (memory_operand (operands[0], VOIDmode))
5131     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5132                                          operands[2], operands[3]));
5133   else
5134     {
5135       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5136       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5137                                                      operands[2], operands[3],
5138                                                      operands[4]));
5139     }
5140   DONE;
5142   [(set_attr "type" "fistp")
5143    (set_attr "i387_cw" "trunc")
5144    (set_attr "mode" "<MODE>")])
5146 (define_insn "fix_truncdi_i387"
5147   [(set (match_operand:DI 0 "memory_operand" "=m")
5148         (fix:DI (match_operand 1 "register_operand" "f")))
5149    (use (match_operand:HI 2 "memory_operand" "m"))
5150    (use (match_operand:HI 3 "memory_operand" "m"))
5151    (clobber (match_scratch:XF 4 "=&1f"))]
5152   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5153    && !TARGET_FISTTP
5154    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5155   "* return output_fix_trunc (insn, operands, false);"
5156   [(set_attr "type" "fistp")
5157    (set_attr "i387_cw" "trunc")
5158    (set_attr "mode" "DI")])
5160 (define_insn "fix_truncdi_i387_with_temp"
5161   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5162         (fix:DI (match_operand 1 "register_operand" "f,f")))
5163    (use (match_operand:HI 2 "memory_operand" "m,m"))
5164    (use (match_operand:HI 3 "memory_operand" "m,m"))
5165    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5166    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5167   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5168    && !TARGET_FISTTP
5169    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5170   "#"
5171   [(set_attr "type" "fistp")
5172    (set_attr "i387_cw" "trunc")
5173    (set_attr "mode" "DI")])
5175 (define_split
5176   [(set (match_operand:DI 0 "register_operand")
5177         (fix:DI (match_operand 1 "register_operand")))
5178    (use (match_operand:HI 2 "memory_operand"))
5179    (use (match_operand:HI 3 "memory_operand"))
5180    (clobber (match_operand:DI 4 "memory_operand"))
5181    (clobber (match_scratch 5))]
5182   "reload_completed"
5183   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5184               (use (match_dup 2))
5185               (use (match_dup 3))
5186               (clobber (match_dup 5))])
5187    (set (match_dup 0) (match_dup 4))])
5189 (define_split
5190   [(set (match_operand:DI 0 "memory_operand")
5191         (fix:DI (match_operand 1 "register_operand")))
5192    (use (match_operand:HI 2 "memory_operand"))
5193    (use (match_operand:HI 3 "memory_operand"))
5194    (clobber (match_operand:DI 4 "memory_operand"))
5195    (clobber (match_scratch 5))]
5196   "reload_completed"
5197   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5198               (use (match_dup 2))
5199               (use (match_dup 3))
5200               (clobber (match_dup 5))])])
5202 (define_insn "fix_trunc<mode>_i387"
5203   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5204         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5205    (use (match_operand:HI 2 "memory_operand" "m"))
5206    (use (match_operand:HI 3 "memory_operand" "m"))]
5207   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5208    && !TARGET_FISTTP
5209    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5210   "* return output_fix_trunc (insn, operands, false);"
5211   [(set_attr "type" "fistp")
5212    (set_attr "i387_cw" "trunc")
5213    (set_attr "mode" "<MODE>")])
5215 (define_insn "fix_trunc<mode>_i387_with_temp"
5216   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5217         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5218    (use (match_operand:HI 2 "memory_operand" "m,m"))
5219    (use (match_operand:HI 3 "memory_operand" "m,m"))
5220    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5221   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5222    && !TARGET_FISTTP
5223    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5224   "#"
5225   [(set_attr "type" "fistp")
5226    (set_attr "i387_cw" "trunc")
5227    (set_attr "mode" "<MODE>")])
5229 (define_split
5230   [(set (match_operand:SWI24 0 "register_operand")
5231         (fix:SWI24 (match_operand 1 "register_operand")))
5232    (use (match_operand:HI 2 "memory_operand"))
5233    (use (match_operand:HI 3 "memory_operand"))
5234    (clobber (match_operand:SWI24 4 "memory_operand"))]
5235   "reload_completed"
5236   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5237               (use (match_dup 2))
5238               (use (match_dup 3))])
5239    (set (match_dup 0) (match_dup 4))])
5241 (define_split
5242   [(set (match_operand:SWI24 0 "memory_operand")
5243         (fix:SWI24 (match_operand 1 "register_operand")))
5244    (use (match_operand:HI 2 "memory_operand"))
5245    (use (match_operand:HI 3 "memory_operand"))
5246    (clobber (match_operand:SWI24 4 "memory_operand"))]
5247   "reload_completed"
5248   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5249               (use (match_dup 2))
5250               (use (match_dup 3))])])
5252 (define_insn "x86_fnstcw_1"
5253   [(set (match_operand:HI 0 "memory_operand" "=m")
5254         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5255   "TARGET_80387"
5256   "fnstcw\t%0"
5257   [(set (attr "length")
5258         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5259    (set_attr "mode" "HI")
5260    (set_attr "unit" "i387")
5261    (set_attr "bdver1_decode" "vector")])
5263 (define_insn "x86_fldcw_1"
5264   [(set (reg:HI FPCR_REG)
5265         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5266   "TARGET_80387"
5267   "fldcw\t%0"
5268   [(set (attr "length")
5269         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5270    (set_attr "mode" "HI")
5271    (set_attr "unit" "i387")
5272    (set_attr "athlon_decode" "vector")
5273    (set_attr "amdfam10_decode" "vector")
5274    (set_attr "bdver1_decode" "vector")])
5276 ;; Conversion between fixed point and floating point.
5278 ;; Even though we only accept memory inputs, the backend _really_
5279 ;; wants to be able to do this between registers.  Thankfully, LRA
5280 ;; will fix this up for us during register allocation.
5282 (define_insn "floathi<mode>2"
5283   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5285   "TARGET_80387
5286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5287        || TARGET_MIX_SSE_I387)"
5288   "fild%Z1\t%1"
5289   [(set_attr "type" "fmov")
5290    (set_attr "mode" "<MODE>")
5291    (set_attr "znver1_decode" "double")
5292    (set_attr "fp_int_src" "true")])
5294 (define_insn "float<SWI48x:mode>xf2"
5295   [(set (match_operand:XF 0 "register_operand" "=f")
5296         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5297   "TARGET_80387"
5298   "fild%Z1\t%1"
5299   [(set_attr "type" "fmov")
5300    (set_attr "mode" "XF")
5301    (set_attr "znver1_decode" "double")
5302    (set_attr "fp_int_src" "true")])
5304 (define_expand "float<SWI48:mode><MODEF:mode>2"
5305   [(set (match_operand:MODEF 0 "register_operand")
5306         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5307   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5309   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5310       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5311     {
5312       rtx reg = gen_reg_rtx (XFmode);
5313       rtx (*insn)(rtx, rtx);
5315       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5317       if (<MODEF:MODE>mode == SFmode)
5318         insn = gen_truncxfsf2;
5319       else if (<MODEF:MODE>mode == DFmode)
5320         insn = gen_truncxfdf2;
5321       else
5322         gcc_unreachable ();
5324       emit_insn (insn (operands[0], reg));
5325       DONE;
5326     }
5329 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5330   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5331         (float:MODEF
5332           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5333   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5334   "@
5335    fild%Z1\t%1
5336    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5337    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5338   [(set_attr "type" "fmov,sseicvt,sseicvt")
5339    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5340    (set_attr "mode" "<MODEF:MODE>")
5341    (set (attr "prefix_rex")
5342      (if_then_else
5343        (and (eq_attr "prefix" "maybe_vex")
5344             (match_test "<SWI48:MODE>mode == DImode"))
5345        (const_string "1")
5346        (const_string "*")))
5347    (set_attr "unit" "i387,*,*")
5348    (set_attr "athlon_decode" "*,double,direct")
5349    (set_attr "amdfam10_decode" "*,vector,double")
5350    (set_attr "bdver1_decode" "*,double,direct")
5351    (set_attr "znver1_decode" "double,*,*")
5352    (set_attr "fp_int_src" "true")
5353    (set (attr "enabled")
5354      (cond [(eq_attr "alternative" "0")
5355               (symbol_ref "TARGET_MIX_SSE_I387
5356                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5357                                                 <SWI48:MODE>mode)")
5358            ]
5359            (symbol_ref "true")))
5360    (set (attr "preferred_for_speed")
5361      (cond [(eq_attr "alternative" "1")
5362               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5363            (symbol_ref "true")))])
5365 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5366   [(set (match_operand:MODEF 0 "register_operand" "=f")
5367         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5368   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5369   "fild%Z1\t%1"
5370   [(set_attr "type" "fmov")
5371    (set_attr "mode" "<MODEF:MODE>")
5372    (set_attr "znver1_decode" "double")
5373    (set_attr "fp_int_src" "true")])
5375 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5376 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5377 ;; alternative in sse2_loadld.
5378 (define_split
5379   [(set (match_operand:MODEF 0 "sse_reg_operand")
5380         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5381   "TARGET_SSE2
5382    && TARGET_USE_VECTOR_CONVERTS
5383    && optimize_function_for_speed_p (cfun)
5384    && reload_completed
5385    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5386    && (!EXT_REX_SSE_REG_P (operands[0])
5387        || TARGET_AVX512VL)"
5388   [(const_int 0)]
5390   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5391   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5393   emit_insn (gen_sse2_loadld (operands[4],
5394                               CONST0_RTX (V4SImode), operands[1]));
5396   if (<ssevecmode>mode == V4SFmode)
5397     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5398   else
5399     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5400   DONE;
5403 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5404 ;; late in the pass sequence (after register rename pass), so allocated
5405 ;; registers won't change anymore
5407 (define_split
5408   [(set (match_operand:MODEF 0 "sse_reg_operand")
5409         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5410   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5411    && optimize_function_for_speed_p (cfun)
5412    && (!EXT_REX_SSE_REG_P (operands[0])
5413        || TARGET_AVX512VL)"
5414   [(set (match_dup 0)
5415         (vec_merge:<MODEF:ssevecmode>
5416           (vec_duplicate:<MODEF:ssevecmode>
5417             (float:MODEF
5418               (match_dup 1)))
5419           (match_dup 0)
5420           (const_int 1)))]
5422   const machine_mode vmode = <MODEF:ssevecmode>mode;
5424   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5425   emit_move_insn (operands[0], CONST0_RTX (vmode));
5428 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5429 ;; late in the pass sequence (after register rename pass),
5430 ;; so allocated registers won't change anymore.
5432 (define_split
5433   [(set (match_operand:SF 0 "sse_reg_operand")
5434         (float_truncate:SF
5435           (match_operand:DF 1 "nonimmediate_operand")))]
5436   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5437    && optimize_function_for_speed_p (cfun)
5438    && (!REG_P (operands[1])
5439        || REGNO (operands[0]) != REGNO (operands[1]))
5440    && (!EXT_REX_SSE_REG_P (operands[0])
5441        || TARGET_AVX512VL)"
5442   [(set (match_dup 0)
5443         (vec_merge:V4SF
5444           (vec_duplicate:V4SF
5445             (float_truncate:SF
5446               (match_dup 1)))
5447           (match_dup 0)
5448           (const_int 1)))]
5450   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5451   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5454 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5455 ;; late in the pass sequence (after register rename pass),
5456 ;; so allocated registers won't change anymore.
5458 (define_split
5459   [(set (match_operand:DF 0 "sse_reg_operand")
5460         (float_extend:DF
5461           (match_operand:SF 1 "nonimmediate_operand")))]
5462   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5463    && optimize_function_for_speed_p (cfun)
5464    && (!REG_P (operands[1])
5465        || REGNO (operands[0]) != REGNO (operands[1]))
5466    && (!EXT_REX_SSE_REG_P (operands[0])
5467        || TARGET_AVX512VL)"
5468   [(set (match_dup 0)
5469         (vec_merge:V2DF
5470           (vec_duplicate:V2DF
5471             (float_extend:DF
5472               (match_dup 1)))
5473           (match_dup 0)
5474           (const_int 1)))]
5476   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5477   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5480 ;; Avoid store forwarding (partial memory) stall penalty
5481 ;; by passing DImode value through XMM registers.  */
5483 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5484   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5485         (float:X87MODEF
5486           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5487    (clobber (match_scratch:V4SI 3 "=X,x"))
5488    (clobber (match_scratch:V4SI 4 "=X,x"))
5489    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5490   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5491    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5492    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5493   "#"
5494   [(set_attr "type" "multi")
5495    (set_attr "mode" "<X87MODEF:MODE>")
5496    (set_attr "unit" "i387")
5497    (set_attr "fp_int_src" "true")])
5499 (define_split
5500   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5501         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5502    (clobber (match_scratch:V4SI 3))
5503    (clobber (match_scratch:V4SI 4))
5504    (clobber (match_operand:DI 2 "memory_operand"))]
5505   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5506    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5507    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5508    && reload_completed"
5509   [(set (match_dup 2) (match_dup 3))
5510    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5512   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5513      Assemble the 64-bit DImode value in an xmm register.  */
5514   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5515                               gen_lowpart (SImode, operands[1])));
5516   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5517                               gen_highpart (SImode, operands[1])));
5518   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5519                                          operands[4]));
5521   operands[3] = gen_lowpart (DImode, operands[3]);
5524 (define_split
5525   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5526         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5527    (clobber (match_scratch:V4SI 3))
5528    (clobber (match_scratch:V4SI 4))
5529    (clobber (match_operand:DI 2 "memory_operand"))]
5530   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5531    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5532    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5533    && reload_completed"
5534   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5536 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5537   [(set (match_operand:MODEF 0 "register_operand")
5538         (unsigned_float:MODEF
5539           (match_operand:SWI12 1 "nonimmediate_operand")))]
5540   "!TARGET_64BIT
5541    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5543   operands[1] = convert_to_mode (SImode, operands[1], 1);
5544   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5545   DONE;
5548 ;; Avoid store forwarding (partial memory) stall penalty by extending
5549 ;; SImode value to DImode through XMM register instead of pushing two
5550 ;; SImode values to stack. Also note that fild loads from memory only.
5552 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5553   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5554         (unsigned_float:X87MODEF
5555           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5556    (clobber (match_scratch:DI 3 "=x"))
5557    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5558   "!TARGET_64BIT
5559    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5560    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5561   "#"
5562   "&& reload_completed"
5563   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5564    (set (match_dup 2) (match_dup 3))
5565    (set (match_dup 0)
5566         (float:X87MODEF (match_dup 2)))]
5567   ""
5568   [(set_attr "type" "multi")
5569    (set_attr "mode" "<MODE>")])
5571 (define_expand "floatunssi<mode>2"
5572   [(parallel
5573      [(set (match_operand:X87MODEF 0 "register_operand")
5574            (unsigned_float:X87MODEF
5575              (match_operand:SI 1 "nonimmediate_operand")))
5576       (clobber (match_scratch:DI 3))
5577       (clobber (match_dup 2))])]
5578   "!TARGET_64BIT
5579    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5580         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5581        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5583   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5584     {
5585       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5586       DONE;
5587     }
5588   else
5589     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5592 (define_expand "floatunsdisf2"
5593   [(use (match_operand:SF 0 "register_operand"))
5594    (use (match_operand:DI 1 "nonimmediate_operand"))]
5595   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5596   "x86_emit_floatuns (operands); DONE;")
5598 (define_expand "floatunsdidf2"
5599   [(use (match_operand:DF 0 "register_operand"))
5600    (use (match_operand:DI 1 "nonimmediate_operand"))]
5601   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5602    && TARGET_SSE2 && TARGET_SSE_MATH"
5604   if (TARGET_64BIT)
5605     x86_emit_floatuns (operands);
5606   else
5607     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5608   DONE;
5611 ;; Load effective address instructions
5613 (define_insn_and_split "*lea<mode>"
5614   [(set (match_operand:SWI48 0 "register_operand" "=r")
5615         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5616   ""
5618   if (SImode_address_operand (operands[1], VOIDmode))
5619     {
5620       gcc_assert (TARGET_64BIT);
5621       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5622     }
5623   else 
5624     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5626   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5627   [(const_int 0)]
5629   machine_mode mode = <MODE>mode;
5630   rtx pat;
5632   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5633      change operands[] array behind our back.  */
5634   pat = PATTERN (curr_insn);
5636   operands[0] = SET_DEST (pat);
5637   operands[1] = SET_SRC (pat);
5639   /* Emit all operations in SImode for zero-extended addresses.  */
5640   if (SImode_address_operand (operands[1], VOIDmode))
5641     mode = SImode;
5643   ix86_split_lea_for_addr (curr_insn, operands, mode);
5645   /* Zero-extend return register to DImode for zero-extended addresses.  */
5646   if (mode != <MODE>mode)
5647     emit_insn (gen_zero_extendsidi2
5648                (operands[0], gen_lowpart (mode, operands[0])));
5650   DONE;
5652   [(set_attr "type" "lea")
5653    (set (attr "mode")
5654      (if_then_else
5655        (match_operand 1 "SImode_address_operand")
5656        (const_string "SI")
5657        (const_string "<MODE>")))])
5659 ;; Add instructions
5661 (define_expand "add<mode>3"
5662   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5663         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5664                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5665   ""
5666   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5668 (define_insn_and_split "*add<dwi>3_doubleword"
5669   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5670         (plus:<DWI>
5671           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5672           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5673                                                         "ro<di>,r<di>")))
5674    (clobber (reg:CC FLAGS_REG))]
5675   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5676   "#"
5677   "reload_completed"
5678   [(parallel [(set (reg:CCC FLAGS_REG)
5679                    (compare:CCC
5680                      (plus:DWIH (match_dup 1) (match_dup 2))
5681                      (match_dup 1)))
5682               (set (match_dup 0)
5683                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5684    (parallel [(set (match_dup 3)
5685                    (plus:DWIH
5686                      (plus:DWIH
5687                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5688                        (match_dup 4))
5689                      (match_dup 5)))
5690               (clobber (reg:CC FLAGS_REG))])]
5692   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5693   if (operands[2] == const0_rtx)
5694     {
5695       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5696       DONE;
5697     }
5700 (define_insn "*add<mode>_1"
5701   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5702         (plus:SWI48
5703           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5704           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5705    (clobber (reg:CC FLAGS_REG))]
5706   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5708   switch (get_attr_type (insn))
5709     {
5710     case TYPE_LEA:
5711       return "#";
5713     case TYPE_INCDEC:
5714       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715       if (operands[2] == const1_rtx)
5716         return "inc{<imodesuffix>}\t%0";
5717       else
5718         {
5719           gcc_assert (operands[2] == constm1_rtx);
5720           return "dec{<imodesuffix>}\t%0";
5721         }
5723     default:
5724       /* For most processors, ADD is faster than LEA.  This alternative
5725          was added to use ADD as much as possible.  */
5726       if (which_alternative == 2)
5727         std::swap (operands[1], operands[2]);
5728         
5729       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5731         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5733       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5734     }
5736   [(set (attr "type")
5737      (cond [(eq_attr "alternative" "3")
5738               (const_string "lea")
5739             (match_operand:SWI48 2 "incdec_operand")
5740               (const_string "incdec")
5741            ]
5742            (const_string "alu")))
5743    (set (attr "length_immediate")
5744       (if_then_else
5745         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5746         (const_string "1")
5747         (const_string "*")))
5748    (set_attr "mode" "<MODE>")])
5750 ;; It may seem that nonimmediate operand is proper one for operand 1.
5751 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5752 ;; we take care in ix86_binary_operator_ok to not allow two memory
5753 ;; operands so proper swapping will be done in reload.  This allow
5754 ;; patterns constructed from addsi_1 to match.
5756 (define_insn "addsi_1_zext"
5757   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5758         (zero_extend:DI
5759           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5760                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5761    (clobber (reg:CC FLAGS_REG))]
5762   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5764   switch (get_attr_type (insn))
5765     {
5766     case TYPE_LEA:
5767       return "#";
5769     case TYPE_INCDEC:
5770       if (operands[2] == const1_rtx)
5771         return "inc{l}\t%k0";
5772       else
5773         {
5774           gcc_assert (operands[2] == constm1_rtx);
5775           return "dec{l}\t%k0";
5776         }
5778     default:
5779       /* For most processors, ADD is faster than LEA.  This alternative
5780          was added to use ADD as much as possible.  */
5781       if (which_alternative == 1)
5782         std::swap (operands[1], operands[2]);
5784       if (x86_maybe_negate_const_int (&operands[2], SImode))
5785         return "sub{l}\t{%2, %k0|%k0, %2}";
5787       return "add{l}\t{%2, %k0|%k0, %2}";
5788     }
5790   [(set (attr "type")
5791      (cond [(eq_attr "alternative" "2")
5792               (const_string "lea")
5793             (match_operand:SI 2 "incdec_operand")
5794               (const_string "incdec")
5795            ]
5796            (const_string "alu")))
5797    (set (attr "length_immediate")
5798       (if_then_else
5799         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5800         (const_string "1")
5801         (const_string "*")))
5802    (set_attr "mode" "SI")])
5804 (define_insn "*addhi_1"
5805   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5806         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5807                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5808    (clobber (reg:CC FLAGS_REG))]
5809   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5811   switch (get_attr_type (insn))
5812     {
5813     case TYPE_LEA:
5814       return "#";
5816     case TYPE_INCDEC:
5817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818       if (operands[2] == const1_rtx)
5819         return "inc{w}\t%0";
5820       else
5821         {
5822           gcc_assert (operands[2] == constm1_rtx);
5823           return "dec{w}\t%0";
5824         }
5826     default:
5827       /* For most processors, ADD is faster than LEA.  This alternative
5828          was added to use ADD as much as possible.  */
5829       if (which_alternative == 2)
5830         std::swap (operands[1], operands[2]);
5832       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833       if (x86_maybe_negate_const_int (&operands[2], HImode))
5834         return "sub{w}\t{%2, %0|%0, %2}";
5836       return "add{w}\t{%2, %0|%0, %2}";
5837     }
5839   [(set (attr "type")
5840      (cond [(eq_attr "alternative" "3")
5841               (const_string "lea")
5842             (match_operand:HI 2 "incdec_operand")
5843               (const_string "incdec")
5844            ]
5845            (const_string "alu")))
5846    (set (attr "length_immediate")
5847       (if_then_else
5848         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5849         (const_string "1")
5850         (const_string "*")))
5851    (set_attr "mode" "HI,HI,HI,SI")])
5853 (define_insn "*addqi_1"
5854   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5855         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5856                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5860   bool widen = (get_attr_mode (insn) != MODE_QI);
5862   switch (get_attr_type (insn))
5863     {
5864     case TYPE_LEA:
5865       return "#";
5867     case TYPE_INCDEC:
5868       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5869       if (operands[2] == const1_rtx)
5870         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5871       else
5872         {
5873           gcc_assert (operands[2] == constm1_rtx);
5874           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5875         }
5877     default:
5878       /* For most processors, ADD is faster than LEA.  These alternatives
5879          were added to use ADD as much as possible.  */
5880       if (which_alternative == 2 || which_alternative == 4)
5881         std::swap (operands[1], operands[2]);
5883       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5884       if (x86_maybe_negate_const_int (&operands[2], QImode))
5885         {
5886           if (widen)
5887             return "sub{l}\t{%2, %k0|%k0, %2}";
5888           else
5889             return "sub{b}\t{%2, %0|%0, %2}";
5890         }
5891       if (widen)
5892         return "add{l}\t{%k2, %k0|%k0, %k2}";
5893       else
5894         return "add{b}\t{%2, %0|%0, %2}";
5895     }
5897   [(set (attr "type")
5898      (cond [(eq_attr "alternative" "5")
5899               (const_string "lea")
5900             (match_operand:QI 2 "incdec_operand")
5901               (const_string "incdec")
5902            ]
5903            (const_string "alu")))
5904    (set (attr "length_immediate")
5905       (if_then_else
5906         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5907         (const_string "1")
5908         (const_string "*")))
5909    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5910    ;; Potential partial reg stall on alternatives 3 and 4.
5911    (set (attr "preferred_for_speed")
5912      (cond [(eq_attr "alternative" "3,4")
5913               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5914            (symbol_ref "true")))])
5916 (define_insn "*addqi_1_slp"
5917   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5918         (plus:QI (match_dup 0)
5919                  (match_operand:QI 1 "general_operand" "qn,qm")))
5920    (clobber (reg:CC FLAGS_REG))]
5921   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5922    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5924   switch (get_attr_type (insn))
5925     {
5926     case TYPE_INCDEC:
5927       if (operands[1] == const1_rtx)
5928         return "inc{b}\t%0";
5929       else
5930         {
5931           gcc_assert (operands[1] == constm1_rtx);
5932           return "dec{b}\t%0";
5933         }
5935     default:
5936       if (x86_maybe_negate_const_int (&operands[1], QImode))
5937         return "sub{b}\t{%1, %0|%0, %1}";
5939       return "add{b}\t{%1, %0|%0, %1}";
5940     }
5942   [(set (attr "type")
5943      (if_then_else (match_operand:QI 1 "incdec_operand")
5944         (const_string "incdec")
5945         (const_string "alu1")))
5946    (set (attr "memory")
5947      (if_then_else (match_operand 1 "memory_operand")
5948         (const_string "load")
5949         (const_string "none")))
5950    (set_attr "mode" "QI")])
5952 ;; Split non destructive adds if we cannot use lea.
5953 (define_split
5954   [(set (match_operand:SWI48 0 "register_operand")
5955         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5956                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5957    (clobber (reg:CC FLAGS_REG))]
5958   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5959   [(set (match_dup 0) (match_dup 1))
5960    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5961               (clobber (reg:CC FLAGS_REG))])])
5963 ;; Split non destructive adds if we cannot use lea.
5964 (define_split
5965   [(set (match_operand:DI 0 "register_operand")
5966         (zero_extend:DI
5967           (plus:SI (match_operand:SI 1 "register_operand")
5968                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5969    (clobber (reg:CC FLAGS_REG))]
5970   "TARGET_64BIT
5971    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5972   [(set (match_dup 3) (match_dup 1))
5973    (parallel [(set (match_dup 0)
5974                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5975               (clobber (reg:CC FLAGS_REG))])]
5976   "operands[3] = gen_lowpart (SImode, operands[0]);")
5978 ;; Convert add to the lea pattern to avoid flags dependency.
5979 (define_split
5980   [(set (match_operand:SWI 0 "register_operand")
5981         (plus:SWI (match_operand:SWI 1 "register_operand")
5982                   (match_operand:SWI 2 "<nonmemory_operand>")))
5983    (clobber (reg:CC FLAGS_REG))]
5984   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5985   [(set (match_dup 0)
5986         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5988   if (<MODE>mode != <LEAMODE>mode)
5989     {
5990       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5991       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5992       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5993     }
5996 ;; Convert add to the lea pattern to avoid flags dependency.
5997 (define_split
5998   [(set (match_operand:DI 0 "register_operand")
5999         (zero_extend:DI
6000           (plus:SI (match_operand:SI 1 "register_operand")
6001                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6002    (clobber (reg:CC FLAGS_REG))]
6003   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6004   [(set (match_dup 0)
6005         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6007 (define_insn "*add<mode>_2"
6008   [(set (reg FLAGS_REG)
6009         (compare
6010           (plus:SWI
6011             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6012             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6013           (const_int 0)))
6014    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6015         (plus:SWI (match_dup 1) (match_dup 2)))]
6016   "ix86_match_ccmode (insn, CCGOCmode)
6017    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == const1_rtx)
6023         return "inc{<imodesuffix>}\t%0";
6024       else
6025         {
6026           gcc_assert (operands[2] == constm1_rtx);
6027           return "dec{<imodesuffix>}\t%0";
6028         }
6030     default:
6031       if (which_alternative == 2)
6032         std::swap (operands[1], operands[2]);
6033         
6034       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6036         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6038       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6039     }
6041   [(set (attr "type")
6042      (if_then_else (match_operand:SWI 2 "incdec_operand")
6043         (const_string "incdec")
6044         (const_string "alu")))
6045    (set (attr "length_immediate")
6046       (if_then_else
6047         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6048         (const_string "1")
6049         (const_string "*")))
6050    (set_attr "mode" "<MODE>")])
6052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6053 (define_insn "*addsi_2_zext"
6054   [(set (reg FLAGS_REG)
6055         (compare
6056           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6057                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6058           (const_int 0)))
6059    (set (match_operand:DI 0 "register_operand" "=r,r")
6060         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6061   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6062    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6064   switch (get_attr_type (insn))
6065     {
6066     case TYPE_INCDEC:
6067       if (operands[2] == const1_rtx)
6068         return "inc{l}\t%k0";
6069       else
6070         {
6071           gcc_assert (operands[2] == constm1_rtx);
6072           return "dec{l}\t%k0";
6073         }
6075     default:
6076       if (which_alternative == 1)
6077         std::swap (operands[1], operands[2]);
6079       if (x86_maybe_negate_const_int (&operands[2], SImode))
6080         return "sub{l}\t{%2, %k0|%k0, %2}";
6082       return "add{l}\t{%2, %k0|%k0, %2}";
6083     }
6085   [(set (attr "type")
6086      (if_then_else (match_operand:SI 2 "incdec_operand")
6087         (const_string "incdec")
6088         (const_string "alu")))
6089    (set (attr "length_immediate")
6090       (if_then_else
6091         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6092         (const_string "1")
6093         (const_string "*")))
6094    (set_attr "mode" "SI")])
6096 (define_insn "*add<mode>_3"
6097   [(set (reg FLAGS_REG)
6098         (compare
6099           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6100           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6101    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6102   "ix86_match_ccmode (insn, CCZmode)
6103    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6105   switch (get_attr_type (insn))
6106     {
6107     case TYPE_INCDEC:
6108       if (operands[2] == const1_rtx)
6109         return "inc{<imodesuffix>}\t%0";
6110       else
6111         {
6112           gcc_assert (operands[2] == constm1_rtx);
6113           return "dec{<imodesuffix>}\t%0";
6114         }
6116     default:
6117       if (which_alternative == 1)
6118         std::swap (operands[1], operands[2]);
6120       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6121       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6122         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6125     }
6127   [(set (attr "type")
6128      (if_then_else (match_operand:SWI 2 "incdec_operand")
6129         (const_string "incdec")
6130         (const_string "alu")))
6131    (set (attr "length_immediate")
6132       (if_then_else
6133         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6134         (const_string "1")
6135         (const_string "*")))
6136    (set_attr "mode" "<MODE>")])
6138 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6139 (define_insn "*addsi_3_zext"
6140   [(set (reg FLAGS_REG)
6141         (compare
6142           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6143           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6144    (set (match_operand:DI 0 "register_operand" "=r,r")
6145         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6146   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6147    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6149   switch (get_attr_type (insn))
6150     {
6151     case TYPE_INCDEC:
6152       if (operands[2] == const1_rtx)
6153         return "inc{l}\t%k0";
6154       else
6155         {
6156           gcc_assert (operands[2] == constm1_rtx);
6157           return "dec{l}\t%k0";
6158         }
6160     default:
6161       if (which_alternative == 1)
6162         std::swap (operands[1], operands[2]);
6164       if (x86_maybe_negate_const_int (&operands[2], SImode))
6165         return "sub{l}\t{%2, %k0|%k0, %2}";
6167       return "add{l}\t{%2, %k0|%k0, %2}";
6168     }
6170   [(set (attr "type")
6171      (if_then_else (match_operand:SI 2 "incdec_operand")
6172         (const_string "incdec")
6173         (const_string "alu")))
6174    (set (attr "length_immediate")
6175       (if_then_else
6176         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6177         (const_string "1")
6178         (const_string "*")))
6179    (set_attr "mode" "SI")])
6181 ; For comparisons against 1, -1 and 128, we may generate better code
6182 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6183 ; is matched then.  We can't accept general immediate, because for
6184 ; case of overflows,  the result is messed up.
6185 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6186 ; only for comparisons not depending on it.
6188 (define_insn "*adddi_4"
6189   [(set (reg FLAGS_REG)
6190         (compare
6191           (match_operand:DI 1 "nonimmediate_operand" "0")
6192           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6193    (clobber (match_scratch:DI 0 "=rm"))]
6194   "TARGET_64BIT
6195    && ix86_match_ccmode (insn, CCGCmode)"
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       if (operands[2] == constm1_rtx)
6201         return "inc{q}\t%0";
6202       else
6203         {
6204           gcc_assert (operands[2] == const1_rtx);
6205           return "dec{q}\t%0";
6206         }
6208     default:
6209       if (x86_maybe_negate_const_int (&operands[2], DImode))
6210         return "add{q}\t{%2, %0|%0, %2}";
6212       return "sub{q}\t{%2, %0|%0, %2}";
6213     }
6215   [(set (attr "type")
6216      (if_then_else (match_operand:DI 2 "incdec_operand")
6217         (const_string "incdec")
6218         (const_string "alu")))
6219    (set (attr "length_immediate")
6220       (if_then_else
6221         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6222         (const_string "1")
6223         (const_string "*")))
6224    (set_attr "mode" "DI")])
6226 ; For comparisons against 1, -1 and 128, we may generate better code
6227 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6228 ; is matched then.  We can't accept general immediate, because for
6229 ; case of overflows,  the result is messed up.
6230 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6231 ; only for comparisons not depending on it.
6233 (define_insn "*add<mode>_4"
6234   [(set (reg FLAGS_REG)
6235         (compare
6236           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6237           (match_operand:SWI124 2 "const_int_operand" "n")))
6238    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6239   "ix86_match_ccmode (insn, CCGCmode)"
6241   switch (get_attr_type (insn))
6242     {
6243     case TYPE_INCDEC:
6244       if (operands[2] == constm1_rtx)
6245         return "inc{<imodesuffix>}\t%0";
6246       else
6247         {
6248           gcc_assert (operands[2] == const1_rtx);
6249           return "dec{<imodesuffix>}\t%0";
6250         }
6252     default:
6253       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6254         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6256       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6257     }
6259   [(set (attr "type")
6260      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6261         (const_string "incdec")
6262         (const_string "alu")))
6263    (set (attr "length_immediate")
6264       (if_then_else
6265         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6266         (const_string "1")
6267         (const_string "*")))
6268    (set_attr "mode" "<MODE>")])
6270 (define_insn "*add<mode>_5"
6271   [(set (reg FLAGS_REG)
6272         (compare
6273           (plus:SWI
6274             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6275             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6276           (const_int 0)))
6277    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6278   "ix86_match_ccmode (insn, CCGOCmode)
6279    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6281   switch (get_attr_type (insn))
6282     {
6283     case TYPE_INCDEC:
6284       if (operands[2] == const1_rtx)
6285         return "inc{<imodesuffix>}\t%0";
6286       else
6287         {
6288           gcc_assert (operands[2] == constm1_rtx);
6289           return "dec{<imodesuffix>}\t%0";
6290         }
6292     default:
6293       if (which_alternative == 1)
6294         std::swap (operands[1], operands[2]);
6296       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6297       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6298         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6300       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6301     }
6303   [(set (attr "type")
6304      (if_then_else (match_operand:SWI 2 "incdec_operand")
6305         (const_string "incdec")
6306         (const_string "alu")))
6307    (set (attr "length_immediate")
6308       (if_then_else
6309         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6310         (const_string "1")
6311         (const_string "*")))
6312    (set_attr "mode" "<MODE>")])
6314 (define_insn "addqi_ext_1"
6315   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6316                          (const_int 8)
6317                          (const_int 8))
6318         (subreg:SI
6319           (plus:QI
6320             (subreg:QI
6321               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6322                                (const_int 8)
6323                                (const_int 8)) 0)
6324             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6325    (clobber (reg:CC FLAGS_REG))]
6326   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6327    rtx_equal_p (operands[0], operands[1])"
6329   switch (get_attr_type (insn))
6330     {
6331     case TYPE_INCDEC:
6332       if (operands[2] == const1_rtx)
6333         return "inc{b}\t%h0";
6334       else
6335         {
6336           gcc_assert (operands[2] == constm1_rtx);
6337           return "dec{b}\t%h0";
6338         }
6340     default:
6341       return "add{b}\t{%2, %h0|%h0, %2}";
6342     }
6344   [(set_attr "isa" "*,nox64")
6345    (set (attr "type")
6346      (if_then_else (match_operand:QI 2 "incdec_operand")
6347         (const_string "incdec")
6348         (const_string "alu")))
6349    (set_attr "mode" "QI")])
6351 (define_insn "*addqi_ext_2"
6352   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6353                          (const_int 8)
6354                          (const_int 8))
6355         (subreg:SI
6356           (plus:QI
6357             (subreg:QI
6358               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6359                                (const_int 8)
6360                                (const_int 8)) 0)
6361             (subreg:QI
6362               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6363                                (const_int 8)
6364                                (const_int 8)) 0)) 0))
6365   (clobber (reg:CC FLAGS_REG))]
6366   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6367    rtx_equal_p (operands[0], operands[1])
6368    || rtx_equal_p (operands[0], operands[2])"
6369   "add{b}\t{%h2, %h0|%h0, %h2}"
6370   [(set_attr "type" "alu")
6371    (set_attr "mode" "QI")])
6373 ;; Add with jump on overflow.
6374 (define_expand "addv<mode>4"
6375   [(parallel [(set (reg:CCO FLAGS_REG)
6376                    (eq:CCO (plus:<DWI>
6377                               (sign_extend:<DWI>
6378                                  (match_operand:SWI 1 "nonimmediate_operand"))
6379                               (match_dup 4))
6380                            (sign_extend:<DWI>
6381                               (plus:SWI (match_dup 1)
6382                                         (match_operand:SWI 2
6383                                            "<general_operand>")))))
6384               (set (match_operand:SWI 0 "register_operand")
6385                    (plus:SWI (match_dup 1) (match_dup 2)))])
6386    (set (pc) (if_then_else
6387                (eq (reg:CCO FLAGS_REG) (const_int 0))
6388                (label_ref (match_operand 3))
6389                (pc)))]
6390   ""
6392   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6393   if (CONST_INT_P (operands[2]))
6394     operands[4] = operands[2];
6395   else
6396     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6399 (define_insn "*addv<mode>4"
6400   [(set (reg:CCO FLAGS_REG)
6401         (eq:CCO (plus:<DWI>
6402                    (sign_extend:<DWI>
6403                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6404                    (sign_extend:<DWI>
6405                       (match_operand:SWI 2 "<general_sext_operand>"
6406                                            "<r>mWe,<r>We")))
6407                 (sign_extend:<DWI>
6408                    (plus:SWI (match_dup 1) (match_dup 2)))))
6409    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6410         (plus:SWI (match_dup 1) (match_dup 2)))]
6411   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6412   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6413   [(set_attr "type" "alu")
6414    (set_attr "mode" "<MODE>")])
6416 (define_insn "*addv<mode>4_1"
6417   [(set (reg:CCO FLAGS_REG)
6418         (eq:CCO (plus:<DWI>
6419                    (sign_extend:<DWI>
6420                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6421                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6422                 (sign_extend:<DWI>
6423                    (plus:SWI (match_dup 1)
6424                              (match_operand:SWI 2 "x86_64_immediate_operand"
6425                                                   "<i>")))))
6426    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6427         (plus:SWI (match_dup 1) (match_dup 2)))]
6428   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6429    && CONST_INT_P (operands[2])
6430    && INTVAL (operands[2]) == INTVAL (operands[3])"
6431   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "mode" "<MODE>")
6434    (set (attr "length_immediate")
6435         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6436                   (const_string "1")
6437                (match_test "<MODE_SIZE> == 8")
6438                   (const_string "4")]
6439               (const_string "<MODE_SIZE>")))])
6441 (define_expand "uaddv<mode>4"
6442   [(parallel [(set (reg:CCC FLAGS_REG)
6443                    (compare:CCC
6444                      (plus:SWI
6445                        (match_operand:SWI 1 "nonimmediate_operand")
6446                        (match_operand:SWI 2 "<general_operand>"))
6447                      (match_dup 1)))
6448               (set (match_operand:SWI 0 "register_operand")
6449                    (plus:SWI (match_dup 1) (match_dup 2)))])
6450    (set (pc) (if_then_else
6451                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6452                (label_ref (match_operand 3))
6453                (pc)))]
6454   ""
6455   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6457 ;; The lea patterns for modes less than 32 bits need to be matched by
6458 ;; several insns converted to real lea by splitters.
6460 (define_insn_and_split "*lea<mode>_general_1"
6461   [(set (match_operand:SWI12 0 "register_operand" "=r")
6462         (plus:SWI12
6463           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6464                       (match_operand:SWI12 2 "register_operand" "r"))
6465           (match_operand:SWI12 3 "immediate_operand" "i")))]
6466   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6467   "#"
6468   "&& reload_completed"
6469   [(set (match_dup 0)
6470         (plus:SI
6471           (plus:SI (match_dup 1) (match_dup 2))
6472           (match_dup 3)))]
6474   operands[0] = gen_lowpart (SImode, operands[0]);
6475   operands[1] = gen_lowpart (SImode, operands[1]);
6476   operands[2] = gen_lowpart (SImode, operands[2]);
6477   operands[3] = gen_lowpart (SImode, operands[3]);
6479   [(set_attr "type" "lea")
6480    (set_attr "mode" "SI")])
6482 (define_insn_and_split "*lea<mode>_general_2"
6483   [(set (match_operand:SWI12 0 "register_operand" "=r")
6484         (plus:SWI12
6485           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6486                       (match_operand 2 "const248_operand" "n"))
6487           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6488   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6489   "#"
6490   "&& reload_completed"
6491   [(set (match_dup 0)
6492         (plus:SI
6493           (mult:SI (match_dup 1) (match_dup 2))
6494           (match_dup 3)))]
6496   operands[0] = gen_lowpart (SImode, operands[0]);
6497   operands[1] = gen_lowpart (SImode, operands[1]);
6498   operands[3] = gen_lowpart (SImode, operands[3]);
6500   [(set_attr "type" "lea")
6501    (set_attr "mode" "SI")])
6503 (define_insn_and_split "*lea<mode>_general_2b"
6504   [(set (match_operand:SWI12 0 "register_operand" "=r")
6505         (plus:SWI12
6506           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6507                         (match_operand 2 "const123_operand" "n"))
6508           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6509   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6510   "#"
6511   "&& reload_completed"
6512   [(set (match_dup 0)
6513         (plus:SI
6514           (ashift:SI (match_dup 1) (match_dup 2))
6515           (match_dup 3)))]
6517   operands[0] = gen_lowpart (SImode, operands[0]);
6518   operands[1] = gen_lowpart (SImode, operands[1]);
6519   operands[3] = gen_lowpart (SImode, operands[3]);
6521   [(set_attr "type" "lea")
6522    (set_attr "mode" "SI")])
6524 (define_insn_and_split "*lea<mode>_general_3"
6525   [(set (match_operand:SWI12 0 "register_operand" "=r")
6526         (plus:SWI12
6527           (plus:SWI12
6528             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6529                         (match_operand 2 "const248_operand" "n"))
6530             (match_operand:SWI12 3 "register_operand" "r"))
6531           (match_operand:SWI12 4 "immediate_operand" "i")))]
6532   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6533   "#"
6534   "&& reload_completed"
6535   [(set (match_dup 0)
6536         (plus:SI
6537           (plus:SI
6538             (mult:SI (match_dup 1) (match_dup 2))
6539             (match_dup 3))
6540           (match_dup 4)))]
6542   operands[0] = gen_lowpart (SImode, operands[0]);
6543   operands[1] = gen_lowpart (SImode, operands[1]);
6544   operands[3] = gen_lowpart (SImode, operands[3]);
6545   operands[4] = gen_lowpart (SImode, operands[4]);
6547   [(set_attr "type" "lea")
6548    (set_attr "mode" "SI")])
6550 (define_insn_and_split "*lea<mode>_general_3b"
6551   [(set (match_operand:SWI12 0 "register_operand" "=r")
6552         (plus:SWI12
6553           (plus:SWI12
6554             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6555                           (match_operand 2 "const123_operand" "n"))
6556             (match_operand:SWI12 3 "register_operand" "r"))
6557           (match_operand:SWI12 4 "immediate_operand" "i")))]
6558   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6559   "#"
6560   "&& reload_completed"
6561   [(set (match_dup 0)
6562         (plus:SI
6563           (plus:SI
6564             (ashift:SI (match_dup 1) (match_dup 2))
6565             (match_dup 3))
6566           (match_dup 4)))]
6568   operands[0] = gen_lowpart (SImode, operands[0]);
6569   operands[1] = gen_lowpart (SImode, operands[1]);
6570   operands[3] = gen_lowpart (SImode, operands[3]);
6571   operands[4] = gen_lowpart (SImode, operands[4]);
6573   [(set_attr "type" "lea")
6574    (set_attr "mode" "SI")])
6576 (define_insn_and_split "*lea<mode>_general_4"
6577   [(set (match_operand:SWI12 0 "register_operand" "=r")
6578         (any_or:SWI12
6579           (ashift:SWI12
6580             (match_operand:SWI12 1 "index_register_operand" "l")
6581             (match_operand 2 "const_0_to_3_operand" "n"))
6582           (match_operand 3 "const_int_operand" "n")))]
6583   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6584    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6585        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6586   "#"
6587   "&& reload_completed"
6588   [(set (match_dup 0)
6589         (plus:SI
6590           (mult:SI (match_dup 1) (match_dup 2))
6591           (match_dup 3)))]
6593   operands[0] = gen_lowpart (SImode, operands[0]);
6594   operands[1] = gen_lowpart (SImode, operands[1]);
6595   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6597   [(set_attr "type" "lea")
6598    (set_attr "mode" "SI")])
6600 (define_insn_and_split "*lea<mode>_general_4"
6601   [(set (match_operand:SWI48 0 "register_operand" "=r")
6602         (any_or:SWI48
6603           (ashift:SWI48
6604             (match_operand:SWI48 1 "index_register_operand" "l")
6605             (match_operand 2 "const_0_to_3_operand" "n"))
6606           (match_operand 3 "const_int_operand" "n")))]
6607   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6608    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6609   "#"
6610   "&& reload_completed"
6611   [(set (match_dup 0)
6612         (plus:SWI48
6613           (mult:SWI48 (match_dup 1) (match_dup 2))
6614           (match_dup 3)))]
6615   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6616   [(set_attr "type" "lea")
6617    (set_attr "mode" "<MODE>")])
6619 ;; Subtract instructions
6621 (define_expand "sub<mode>3"
6622   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6623         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6624                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6625   ""
6626   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6628 (define_insn_and_split "*sub<dwi>3_doubleword"
6629   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6630         (minus:<DWI>
6631           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6632           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6633                                                         "ro<di>,r<di>")))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6636   "#"
6637   "reload_completed"
6638   [(parallel [(set (reg:CC FLAGS_REG)
6639                    (compare:CC (match_dup 1) (match_dup 2)))
6640               (set (match_dup 0)
6641                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6642    (parallel [(set (match_dup 3)
6643                    (minus:DWIH
6644                      (minus:DWIH
6645                        (match_dup 4)
6646                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6647                      (match_dup 5)))
6648               (clobber (reg:CC FLAGS_REG))])]
6650   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6651   if (operands[2] == const0_rtx)
6652     {
6653       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6654       DONE;
6655     }
6658 (define_insn "*sub<mode>_1"
6659   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6660         (minus:SWI
6661           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6662           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6665   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "<MODE>")])
6669 (define_insn "*subsi_1_zext"
6670   [(set (match_operand:DI 0 "register_operand" "=r")
6671         (zero_extend:DI
6672           (minus:SI (match_operand:SI 1 "register_operand" "0")
6673                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6674    (clobber (reg:CC FLAGS_REG))]
6675   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676   "sub{l}\t{%2, %k0|%k0, %2}"
6677   [(set_attr "type" "alu")
6678    (set_attr "mode" "SI")])
6680 (define_insn "*subqi_1_slp"
6681   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6682         (minus:QI (match_dup 0)
6683                   (match_operand:QI 1 "general_operand" "qn,qm")))
6684    (clobber (reg:CC FLAGS_REG))]
6685   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6686    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6687   "sub{b}\t{%1, %0|%0, %1}"
6688   [(set_attr "type" "alu1")
6689    (set_attr "mode" "QI")])
6691 (define_insn "*sub<mode>_2"
6692   [(set (reg FLAGS_REG)
6693         (compare
6694           (minus:SWI
6695             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6696             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6697           (const_int 0)))
6698    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6699         (minus:SWI (match_dup 1) (match_dup 2)))]
6700   "ix86_match_ccmode (insn, CCGOCmode)
6701    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6702   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "<MODE>")])
6706 (define_insn "*subsi_2_zext"
6707   [(set (reg FLAGS_REG)
6708         (compare
6709           (minus:SI (match_operand:SI 1 "register_operand" "0")
6710                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6711           (const_int 0)))
6712    (set (match_operand:DI 0 "register_operand" "=r")
6713         (zero_extend:DI
6714           (minus:SI (match_dup 1)
6715                     (match_dup 2))))]
6716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6717    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718   "sub{l}\t{%2, %k0|%k0, %2}"
6719   [(set_attr "type" "alu")
6720    (set_attr "mode" "SI")])
6722 ;; Subtract with jump on overflow.
6723 (define_expand "subv<mode>4"
6724   [(parallel [(set (reg:CCO FLAGS_REG)
6725                    (eq:CCO (minus:<DWI>
6726                               (sign_extend:<DWI>
6727                                  (match_operand:SWI 1 "nonimmediate_operand"))
6728                               (match_dup 4))
6729                            (sign_extend:<DWI>
6730                               (minus:SWI (match_dup 1)
6731                                          (match_operand:SWI 2
6732                                             "<general_operand>")))))
6733               (set (match_operand:SWI 0 "register_operand")
6734                    (minus:SWI (match_dup 1) (match_dup 2)))])
6735    (set (pc) (if_then_else
6736                (eq (reg:CCO FLAGS_REG) (const_int 0))
6737                (label_ref (match_operand 3))
6738                (pc)))]
6739   ""
6741   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6742   if (CONST_INT_P (operands[2]))
6743     operands[4] = operands[2];
6744   else
6745     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6748 (define_insn "*subv<mode>4"
6749   [(set (reg:CCO FLAGS_REG)
6750         (eq:CCO (minus:<DWI>
6751                    (sign_extend:<DWI>
6752                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6753                    (sign_extend:<DWI>
6754                       (match_operand:SWI 2 "<general_sext_operand>"
6755                                            "<r>We,<r>m")))
6756                 (sign_extend:<DWI>
6757                    (minus:SWI (match_dup 1) (match_dup 2)))))
6758    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6759         (minus:SWI (match_dup 1) (match_dup 2)))]
6760   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6762   [(set_attr "type" "alu")
6763    (set_attr "mode" "<MODE>")])
6765 (define_insn "*subv<mode>4_1"
6766   [(set (reg:CCO FLAGS_REG)
6767         (eq:CCO (minus:<DWI>
6768                    (sign_extend:<DWI>
6769                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6770                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6771                 (sign_extend:<DWI>
6772                    (minus:SWI (match_dup 1)
6773                               (match_operand:SWI 2 "x86_64_immediate_operand"
6774                                                    "<i>")))))
6775    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6776         (minus:SWI (match_dup 1) (match_dup 2)))]
6777   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6778    && CONST_INT_P (operands[2])
6779    && INTVAL (operands[2]) == INTVAL (operands[3])"
6780   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6781   [(set_attr "type" "alu")
6782    (set_attr "mode" "<MODE>")
6783    (set (attr "length_immediate")
6784         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6785                   (const_string "1")
6786                (match_test "<MODE_SIZE> == 8")
6787                   (const_string "4")]
6788               (const_string "<MODE_SIZE>")))])
6790 (define_expand "usubv<mode>4"
6791   [(parallel [(set (reg:CC FLAGS_REG)
6792                    (compare:CC
6793                      (match_operand:SWI 1 "nonimmediate_operand")
6794                      (match_operand:SWI 2 "<general_operand>")))
6795               (set (match_operand:SWI 0 "register_operand")
6796                    (minus:SWI (match_dup 1) (match_dup 2)))])
6797    (set (pc) (if_then_else
6798                (ltu (reg:CC FLAGS_REG) (const_int 0))
6799                (label_ref (match_operand 3))
6800                (pc)))]
6801   ""
6802   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6804 (define_insn "*sub<mode>_3"
6805   [(set (reg FLAGS_REG)
6806         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6807                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6808    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6809         (minus:SWI (match_dup 1) (match_dup 2)))]
6810   "ix86_match_ccmode (insn, CCmode)
6811    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6812   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6813   [(set_attr "type" "alu")
6814    (set_attr "mode" "<MODE>")])
6816 (define_peephole2
6817   [(parallel
6818      [(set (reg:CC FLAGS_REG)
6819            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6820                        (match_operand:SWI 1 "general_gr_operand")))
6821       (set (match_dup 0)
6822            (minus:SWI (match_dup 0) (match_dup 1)))])]
6823   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6824   [(set (reg:CC FLAGS_REG)
6825         (compare:CC (match_dup 0) (match_dup 1)))])
6827 (define_insn "*subsi_3_zext"
6828   [(set (reg FLAGS_REG)
6829         (compare (match_operand:SI 1 "register_operand" "0")
6830                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6831    (set (match_operand:DI 0 "register_operand" "=r")
6832         (zero_extend:DI
6833           (minus:SI (match_dup 1)
6834                     (match_dup 2))))]
6835   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6836    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6837   "sub{l}\t{%2, %1|%1, %2}"
6838   [(set_attr "type" "alu")
6839    (set_attr "mode" "SI")])
6841 ;; Add with carry and subtract with borrow
6843 (define_insn "add<mode>3_carry"
6844   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6845         (plus:SWI
6846           (plus:SWI
6847             (match_operator:SWI 4 "ix86_carry_flag_operator"
6848              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6849             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6850           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6851    (clobber (reg:CC FLAGS_REG))]
6852   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6853   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6854   [(set_attr "type" "alu")
6855    (set_attr "use_carry" "1")
6856    (set_attr "pent_pair" "pu")
6857    (set_attr "mode" "<MODE>")])
6859 (define_insn "*add<mode>3_carry_0"
6860   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6861         (plus:SWI
6862           (match_operator:SWI 3 "ix86_carry_flag_operator"
6863             [(match_operand 2 "flags_reg_operand") (const_int 0)])
6864           (match_operand:SWI 1 "nonimmediate_operand" "0")))
6865    (clobber (reg:CC FLAGS_REG))]
6866   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6867   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6868   [(set_attr "type" "alu")
6869    (set_attr "use_carry" "1")
6870    (set_attr "pent_pair" "pu")
6871    (set_attr "mode" "<MODE>")])
6873 (define_insn "*addsi3_carry_zext"
6874   [(set (match_operand:DI 0 "register_operand" "=r")
6875         (zero_extend:DI
6876           (plus:SI
6877             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6878                       [(reg FLAGS_REG) (const_int 0)])
6879                      (match_operand:SI 1 "register_operand" "%0"))
6880             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6881    (clobber (reg:CC FLAGS_REG))]
6882   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6883   "adc{l}\t{%2, %k0|%k0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "use_carry" "1")
6886    (set_attr "pent_pair" "pu")
6887    (set_attr "mode" "SI")])
6889 (define_insn "*addsi3_carry_zext_0"
6890   [(set (match_operand:DI 0 "register_operand" "=r")
6891         (zero_extend:DI
6892           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6893                     [(reg FLAGS_REG) (const_int 0)])
6894                    (match_operand:SI 1 "register_operand" "0"))))
6895    (clobber (reg:CC FLAGS_REG))]
6896   "TARGET_64BIT"
6897   "adc{l}\t{$0, %k0|%k0, 0}"
6898   [(set_attr "type" "alu")
6899    (set_attr "use_carry" "1")
6900    (set_attr "pent_pair" "pu")
6901    (set_attr "mode" "SI")])
6903 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6905 (define_insn "addcarry<mode>"
6906   [(set (reg:CCC FLAGS_REG)
6907         (compare:CCC
6908           (zero_extend:<DWI>
6909             (plus:SWI48
6910               (plus:SWI48
6911                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6912                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
6913                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6914               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6915           (plus:<DWI>
6916             (zero_extend:<DWI> (match_dup 2))
6917             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6918               [(match_dup 3) (const_int 0)]))))
6919    (set (match_operand:SWI48 0 "register_operand" "=r")
6920         (plus:SWI48 (plus:SWI48 (match_op_dup 5
6921                                  [(match_dup 3) (const_int 0)])
6922                                 (match_dup 1))
6923                     (match_dup 2)))]
6924   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6925   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6926   [(set_attr "type" "alu")
6927    (set_attr "use_carry" "1")
6928    (set_attr "pent_pair" "pu")
6929    (set_attr "mode" "<MODE>")])
6931 (define_expand "addcarry<mode>_0"
6932   [(parallel
6933      [(set (reg:CCC FLAGS_REG)
6934            (compare:CCC
6935              (plus:SWI48
6936                (match_operand:SWI48 1 "nonimmediate_operand")
6937                (match_operand:SWI48 2 "x86_64_general_operand"))
6938              (match_dup 1)))
6939       (set (match_operand:SWI48 0 "register_operand")
6940            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6941   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6943 (define_insn "sub<mode>3_carry"
6944   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6945         (minus:SWI
6946           (minus:SWI
6947             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6948             (match_operator:SWI 4 "ix86_carry_flag_operator"
6949              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6950           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6951    (clobber (reg:CC FLAGS_REG))]
6952   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6953   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "alu")
6955    (set_attr "use_carry" "1")
6956    (set_attr "pent_pair" "pu")
6957    (set_attr "mode" "<MODE>")])
6959 (define_insn "*sub<mode>3_carry_0"
6960   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6961         (minus:SWI
6962           (match_operand:SWI 1 "nonimmediate_operand" "0")
6963           (match_operator:SWI 3 "ix86_carry_flag_operator"
6964             [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6967   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6968   [(set_attr "type" "alu")
6969    (set_attr "use_carry" "1")
6970    (set_attr "pent_pair" "pu")
6971    (set_attr "mode" "<MODE>")])
6973 (define_insn "*subsi3_carry_zext"
6974   [(set (match_operand:DI 0 "register_operand" "=r")
6975         (zero_extend:DI
6976           (minus:SI
6977             (minus:SI
6978               (match_operand:SI 1 "register_operand" "0")
6979               (match_operator:SI 3 "ix86_carry_flag_operator"
6980                [(reg FLAGS_REG) (const_int 0)]))
6981             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6982    (clobber (reg:CC FLAGS_REG))]
6983   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6984   "sbb{l}\t{%2, %k0|%k0, %2}"
6985   [(set_attr "type" "alu")
6986    (set_attr "use_carry" "1")
6987    (set_attr "pent_pair" "pu")
6988    (set_attr "mode" "SI")])
6990 (define_insn "*subsi3_carry_zext_0"
6991   [(set (match_operand:DI 0 "register_operand" "=r")
6992         (zero_extend:DI
6993           (minus:SI
6994             (match_operand:SI 1 "register_operand" "0")
6995             (match_operator:SI 2 "ix86_carry_flag_operator"
6996               [(reg FLAGS_REG) (const_int 0)]))))
6997    (clobber (reg:CC FLAGS_REG))]
6998   "TARGET_64BIT"
6999   "sbb{l}\t{$0, %k0|%k0, 0}"
7000   [(set_attr "type" "alu")
7001    (set_attr "use_carry" "1")
7002    (set_attr "pent_pair" "pu")
7003    (set_attr "mode" "SI")])
7005 (define_insn "sub<mode>3_carry_ccc"
7006   [(set (reg:CCC FLAGS_REG)
7007         (compare:CCC
7008           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7009           (plus:<DWI>
7010             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7011             (zero_extend:<DWI>
7012               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7013    (clobber (match_scratch:DWIH 0 "=r"))]
7014   ""
7015   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7016   [(set_attr "type" "alu")
7017    (set_attr "mode" "<MODE>")])
7019 (define_insn "*sub<mode>3_carry_ccc_1"
7020   [(set (reg:CCC FLAGS_REG)
7021         (compare:CCC
7022           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7023           (plus:<DWI>
7024             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7025             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7026    (clobber (match_scratch:DWIH 0 "=r"))]
7027   ""
7029   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7030   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7032   [(set_attr "type" "alu")
7033    (set_attr "mode" "<MODE>")])
7035 ;; The sign flag is set from the
7036 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7037 ;; result, the overflow flag likewise, but the overflow flag is also
7038 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7039 (define_insn "sub<mode>3_carry_ccgz"
7040   [(set (reg:CCGZ FLAGS_REG)
7041         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7042                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7043                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7044                      UNSPEC_SBB))
7045    (clobber (match_scratch:DWIH 0 "=r"))]
7046   ""
7047   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7048   [(set_attr "type" "alu")
7049    (set_attr "mode" "<MODE>")])
7051 (define_insn "subborrow<mode>"
7052   [(set (reg:CCC FLAGS_REG)
7053         (compare:CCC
7054           (zero_extend:<DWI>
7055             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7056           (plus:<DWI>
7057             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7058               [(match_operand 3 "flags_reg_operand") (const_int 0)])
7059             (zero_extend:<DWI>
7060               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7061    (set (match_operand:SWI48 0 "register_operand" "=r")
7062         (minus:SWI48 (minus:SWI48
7063                        (match_dup 1)
7064                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
7065                          [(match_dup 3) (const_int 0)]))
7066                      (match_dup 2)))]
7067   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7068   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7069   [(set_attr "type" "alu")
7070    (set_attr "use_carry" "1")
7071    (set_attr "pent_pair" "pu")
7072    (set_attr "mode" "<MODE>")])
7074 (define_expand "subborrow<mode>_0"
7075   [(parallel
7076      [(set (reg:CC FLAGS_REG)
7077            (compare:CC
7078              (match_operand:SWI48 1 "nonimmediate_operand")
7079              (match_operand:SWI48 2 "<general_operand>")))
7080       (set (match_operand:SWI48 0 "register_operand")
7081            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7082   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7084 ;; Overflow setting add instructions
7086 (define_expand "addqi3_cconly_overflow"
7087   [(parallel
7088      [(set (reg:CCC FLAGS_REG)
7089            (compare:CCC
7090              (plus:QI
7091                (match_operand:QI 0 "nonimmediate_operand")
7092                (match_operand:QI 1 "general_operand"))
7093              (match_dup 0)))
7094       (clobber (match_scratch:QI 2))])]
7095   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7097 (define_insn "*add<mode>3_cconly_overflow_1"
7098   [(set (reg:CCC FLAGS_REG)
7099         (compare:CCC
7100           (plus:SWI
7101             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7102             (match_operand:SWI 2 "<general_operand>" "<g>"))
7103           (match_dup 1)))
7104    (clobber (match_scratch:SWI 0 "=<r>"))]
7105   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7106   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7107   [(set_attr "type" "alu")
7108    (set_attr "mode" "<MODE>")])
7110 (define_insn "*add<mode>3_cc_overflow_1"
7111   [(set (reg:CCC FLAGS_REG)
7112         (compare:CCC
7113             (plus:SWI
7114                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7115                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7116             (match_dup 1)))
7117    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7118         (plus:SWI (match_dup 1) (match_dup 2)))]
7119   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7120   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7121   [(set_attr "type" "alu")
7122    (set_attr "mode" "<MODE>")])
7124 (define_insn "*addsi3_zext_cc_overflow_1"
7125   [(set (reg:CCC FLAGS_REG)
7126         (compare:CCC
7127           (plus:SI
7128             (match_operand:SI 1 "nonimmediate_operand" "%0")
7129             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7130           (match_dup 1)))
7131    (set (match_operand:DI 0 "register_operand" "=r")
7132         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7134   "add{l}\t{%2, %k0|%k0, %2}"
7135   [(set_attr "type" "alu")
7136    (set_attr "mode" "SI")])
7138 (define_insn "*add<mode>3_cconly_overflow_2"
7139   [(set (reg:CCC FLAGS_REG)
7140         (compare:CCC
7141           (plus:SWI
7142             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7143             (match_operand:SWI 2 "<general_operand>" "<g>"))
7144           (match_dup 2)))
7145    (clobber (match_scratch:SWI 0 "=<r>"))]
7146   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7148   [(set_attr "type" "alu")
7149    (set_attr "mode" "<MODE>")])
7151 (define_insn "*add<mode>3_cc_overflow_2"
7152   [(set (reg:CCC FLAGS_REG)
7153         (compare:CCC
7154             (plus:SWI
7155                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7156                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7157             (match_dup 2)))
7158    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7159         (plus:SWI (match_dup 1) (match_dup 2)))]
7160   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7161   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7162   [(set_attr "type" "alu")
7163    (set_attr "mode" "<MODE>")])
7165 (define_insn "*addsi3_zext_cc_overflow_2"
7166   [(set (reg:CCC FLAGS_REG)
7167         (compare:CCC
7168           (plus:SI
7169             (match_operand:SI 1 "nonimmediate_operand" "%0")
7170             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7171           (match_dup 2)))
7172    (set (match_operand:DI 0 "register_operand" "=r")
7173         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7174   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7175   "add{l}\t{%2, %k0|%k0, %2}"
7176   [(set_attr "type" "alu")
7177    (set_attr "mode" "SI")])
7179 ;; The patterns that match these are at the end of this file.
7181 (define_expand "<plusminus_insn>xf3"
7182   [(set (match_operand:XF 0 "register_operand")
7183         (plusminus:XF
7184           (match_operand:XF 1 "register_operand")
7185           (match_operand:XF 2 "register_operand")))]
7186   "TARGET_80387")
7188 (define_expand "<plusminus_insn><mode>3"
7189   [(set (match_operand:MODEF 0 "register_operand")
7190         (plusminus:MODEF
7191           (match_operand:MODEF 1 "register_operand")
7192           (match_operand:MODEF 2 "nonimmediate_operand")))]
7193   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7194     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7196 ;; Multiply instructions
7198 (define_expand "mul<mode>3"
7199   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7200                    (mult:SWIM248
7201                      (match_operand:SWIM248 1 "register_operand")
7202                      (match_operand:SWIM248 2 "<general_operand>")))
7203               (clobber (reg:CC FLAGS_REG))])])
7205 (define_expand "mulqi3"
7206   [(parallel [(set (match_operand:QI 0 "register_operand")
7207                    (mult:QI
7208                      (match_operand:QI 1 "register_operand")
7209                      (match_operand:QI 2 "nonimmediate_operand")))
7210               (clobber (reg:CC FLAGS_REG))])]
7211   "TARGET_QIMODE_MATH")
7213 ;; On AMDFAM10
7214 ;; IMUL reg32/64, reg32/64, imm8        Direct
7215 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7216 ;; IMUL reg32/64, reg32/64, imm32       Direct
7217 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7218 ;; IMUL reg32/64, reg32/64              Direct
7219 ;; IMUL reg32/64, mem32/64              Direct
7221 ;; On BDVER1, all above IMULs use DirectPath
7223 ;; On AMDFAM10
7224 ;; IMUL reg16, reg16, imm8      VectorPath
7225 ;; IMUL reg16, mem16, imm8      VectorPath
7226 ;; IMUL reg16, reg16, imm16     VectorPath
7227 ;; IMUL reg16, mem16, imm16     VectorPath
7228 ;; IMUL reg16, reg16            Direct
7229 ;; IMUL reg16, mem16            Direct
7231 ;; On BDVER1, all HI MULs use DoublePath
7233 (define_insn "*mul<mode>3_1"
7234   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7235         (mult:SWIM248
7236           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7237           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7238    (clobber (reg:CC FLAGS_REG))]
7239   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7240   "@
7241    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7242    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7243    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7244   [(set_attr "type" "imul")
7245    (set_attr "prefix_0f" "0,0,1")
7246    (set (attr "athlon_decode")
7247         (cond [(eq_attr "cpu" "athlon")
7248                   (const_string "vector")
7249                (eq_attr "alternative" "1")
7250                   (const_string "vector")
7251                (and (eq_attr "alternative" "2")
7252                     (ior (match_test "<MODE>mode == HImode")
7253                          (match_operand 1 "memory_operand")))
7254                   (const_string "vector")]
7255               (const_string "direct")))
7256    (set (attr "amdfam10_decode")
7257         (cond [(and (eq_attr "alternative" "0,1")
7258                     (ior (match_test "<MODE>mode == HImode")
7259                          (match_operand 1 "memory_operand")))
7260                   (const_string "vector")]
7261               (const_string "direct")))
7262    (set (attr "bdver1_decode")
7263         (if_then_else
7264           (match_test "<MODE>mode == HImode")
7265             (const_string "double")
7266             (const_string "direct")))
7267    (set_attr "mode" "<MODE>")])
7269 (define_insn "*mulsi3_1_zext"
7270   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7271         (zero_extend:DI
7272           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7273                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7274    (clobber (reg:CC FLAGS_REG))]
7275   "TARGET_64BIT
7276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7277   "@
7278    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7279    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7280    imul{l}\t{%2, %k0|%k0, %2}"
7281   [(set_attr "type" "imul")
7282    (set_attr "prefix_0f" "0,0,1")
7283    (set (attr "athlon_decode")
7284         (cond [(eq_attr "cpu" "athlon")
7285                   (const_string "vector")
7286                (eq_attr "alternative" "1")
7287                   (const_string "vector")
7288                (and (eq_attr "alternative" "2")
7289                     (match_operand 1 "memory_operand"))
7290                   (const_string "vector")]
7291               (const_string "direct")))
7292    (set (attr "amdfam10_decode")
7293         (cond [(and (eq_attr "alternative" "0,1")
7294                     (match_operand 1 "memory_operand"))
7295                   (const_string "vector")]
7296               (const_string "direct")))
7297    (set_attr "bdver1_decode" "direct")
7298    (set_attr "mode" "SI")])
7300 ;;On AMDFAM10 and BDVER1
7301 ;; MUL reg8     Direct
7302 ;; MUL mem8     Direct
7304 (define_insn "*mulqi3_1"
7305   [(set (match_operand:QI 0 "register_operand" "=a")
7306         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7307                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7308    (clobber (reg:CC FLAGS_REG))]
7309   "TARGET_QIMODE_MATH
7310    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7311   "mul{b}\t%2"
7312   [(set_attr "type" "imul")
7313    (set_attr "length_immediate" "0")
7314    (set (attr "athlon_decode")
7315      (if_then_else (eq_attr "cpu" "athlon")
7316         (const_string "vector")
7317         (const_string "direct")))
7318    (set_attr "amdfam10_decode" "direct")
7319    (set_attr "bdver1_decode" "direct")
7320    (set_attr "mode" "QI")])
7322 ;; Multiply with jump on overflow.
7323 (define_expand "mulv<mode>4"
7324   [(parallel [(set (reg:CCO FLAGS_REG)
7325                    (eq:CCO (mult:<DWI>
7326                               (sign_extend:<DWI>
7327                                  (match_operand:SWI248 1 "register_operand"))
7328                               (match_dup 4))
7329                            (sign_extend:<DWI>
7330                               (mult:SWI248 (match_dup 1)
7331                                            (match_operand:SWI248 2
7332                                               "<general_operand>")))))
7333               (set (match_operand:SWI248 0 "register_operand")
7334                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7335    (set (pc) (if_then_else
7336                (eq (reg:CCO FLAGS_REG) (const_int 0))
7337                (label_ref (match_operand 3))
7338                (pc)))]
7339   ""
7341   if (CONST_INT_P (operands[2]))
7342     operands[4] = operands[2];
7343   else
7344     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7347 (define_insn "*mulv<mode>4"
7348   [(set (reg:CCO FLAGS_REG)
7349         (eq:CCO (mult:<DWI>
7350                    (sign_extend:<DWI>
7351                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7352                    (sign_extend:<DWI>
7353                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7354                 (sign_extend:<DWI>
7355                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7356    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7357         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7358   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7359   "@
7360    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7361    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7362   [(set_attr "type" "imul")
7363    (set_attr "prefix_0f" "0,1")
7364    (set (attr "athlon_decode")
7365         (cond [(eq_attr "cpu" "athlon")
7366                   (const_string "vector")
7367                (eq_attr "alternative" "0")
7368                   (const_string "vector")
7369                (and (eq_attr "alternative" "1")
7370                     (match_operand 1 "memory_operand"))
7371                   (const_string "vector")]
7372               (const_string "direct")))
7373    (set (attr "amdfam10_decode")
7374         (cond [(and (eq_attr "alternative" "1")
7375                     (match_operand 1 "memory_operand"))
7376                   (const_string "vector")]
7377               (const_string "direct")))
7378    (set_attr "bdver1_decode" "direct")
7379    (set_attr "mode" "<MODE>")])
7381 (define_insn "*mulvhi4"
7382   [(set (reg:CCO FLAGS_REG)
7383         (eq:CCO (mult:SI
7384                    (sign_extend:SI
7385                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7386                    (sign_extend:SI
7387                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7388                 (sign_extend:SI
7389                    (mult:HI (match_dup 1) (match_dup 2)))))
7390    (set (match_operand:HI 0 "register_operand" "=r")
7391         (mult:HI (match_dup 1) (match_dup 2)))]
7392   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7393   "imul{w}\t{%2, %0|%0, %2}"
7394   [(set_attr "type" "imul")
7395    (set_attr "prefix_0f" "1")
7396    (set_attr "athlon_decode" "vector")
7397    (set_attr "amdfam10_decode" "direct")
7398    (set_attr "bdver1_decode" "double")
7399    (set_attr "mode" "HI")])
7401 (define_insn "*mulv<mode>4_1"
7402   [(set (reg:CCO FLAGS_REG)
7403         (eq:CCO (mult:<DWI>
7404                    (sign_extend:<DWI>
7405                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7406                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7407                 (sign_extend:<DWI>
7408                    (mult:SWI248 (match_dup 1)
7409                                 (match_operand:SWI248 2
7410                                    "<immediate_operand>" "K,<i>")))))
7411    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7412         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7413   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7414    && CONST_INT_P (operands[2])
7415    && INTVAL (operands[2]) == INTVAL (operands[3])"
7416   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7417   [(set_attr "type" "imul")
7418    (set (attr "prefix_0f")
7419         (if_then_else
7420           (match_test "<MODE>mode == HImode")
7421             (const_string "0")
7422             (const_string "*")))
7423    (set (attr "athlon_decode")
7424         (cond [(eq_attr "cpu" "athlon")
7425                   (const_string "vector")
7426                (eq_attr "alternative" "1")
7427                   (const_string "vector")]
7428               (const_string "direct")))
7429    (set (attr "amdfam10_decode")
7430         (cond [(ior (match_test "<MODE>mode == HImode")
7431                     (match_operand 1 "memory_operand"))
7432                   (const_string "vector")]
7433               (const_string "direct")))
7434    (set (attr "bdver1_decode")
7435         (if_then_else
7436           (match_test "<MODE>mode == HImode")
7437             (const_string "double")
7438             (const_string "direct")))
7439    (set_attr "mode" "<MODE>")
7440    (set (attr "length_immediate")
7441         (cond [(eq_attr "alternative" "0")
7442                   (const_string "1")
7443                (match_test "<MODE_SIZE> == 8")
7444                   (const_string "4")]
7445               (const_string "<MODE_SIZE>")))])
7447 (define_expand "umulv<mode>4"
7448   [(parallel [(set (reg:CCO FLAGS_REG)
7449                    (eq:CCO (mult:<DWI>
7450                               (zero_extend:<DWI>
7451                                  (match_operand:SWI248 1
7452                                                       "nonimmediate_operand"))
7453                               (zero_extend:<DWI>
7454                                  (match_operand:SWI248 2
7455                                                       "nonimmediate_operand")))
7456                            (zero_extend:<DWI>
7457                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7458               (set (match_operand:SWI248 0 "register_operand")
7459                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7460               (clobber (match_scratch:SWI248 4))])
7461    (set (pc) (if_then_else
7462                (eq (reg:CCO FLAGS_REG) (const_int 0))
7463                (label_ref (match_operand 3))
7464                (pc)))]
7465   ""
7467   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7468     operands[1] = force_reg (<MODE>mode, operands[1]);
7471 (define_insn "*umulv<mode>4"
7472   [(set (reg:CCO FLAGS_REG)
7473         (eq:CCO (mult:<DWI>
7474                    (zero_extend:<DWI>
7475                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7476                    (zero_extend:<DWI>
7477                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7478                 (zero_extend:<DWI>
7479                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7480    (set (match_operand:SWI248 0 "register_operand" "=a")
7481         (mult:SWI248 (match_dup 1) (match_dup 2)))
7482    (clobber (match_scratch:SWI248 3 "=d"))]
7483   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484   "mul{<imodesuffix>}\t%2"
7485   [(set_attr "type" "imul")
7486    (set_attr "length_immediate" "0")
7487    (set (attr "athlon_decode")
7488      (if_then_else (eq_attr "cpu" "athlon")
7489        (const_string "vector")
7490        (const_string "double")))
7491    (set_attr "amdfam10_decode" "double")
7492    (set_attr "bdver1_decode" "direct")
7493    (set_attr "mode" "<MODE>")])
7495 (define_expand "<u>mulvqi4"
7496   [(parallel [(set (reg:CCO FLAGS_REG)
7497                    (eq:CCO (mult:HI
7498                               (any_extend:HI
7499                                  (match_operand:QI 1 "nonimmediate_operand"))
7500                               (any_extend:HI
7501                                  (match_operand:QI 2 "nonimmediate_operand")))
7502                            (any_extend:HI
7503                               (mult:QI (match_dup 1) (match_dup 2)))))
7504               (set (match_operand:QI 0 "register_operand")
7505                    (mult:QI (match_dup 1) (match_dup 2)))])
7506    (set (pc) (if_then_else
7507                (eq (reg:CCO FLAGS_REG) (const_int 0))
7508                (label_ref (match_operand 3))
7509                (pc)))]
7510   "TARGET_QIMODE_MATH"
7512   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7513     operands[1] = force_reg (QImode, operands[1]);
7516 (define_insn "*<u>mulvqi4"
7517   [(set (reg:CCO FLAGS_REG)
7518         (eq:CCO (mult:HI
7519                    (any_extend:HI
7520                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7521                    (any_extend:HI
7522                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7523                 (any_extend:HI
7524                    (mult:QI (match_dup 1) (match_dup 2)))))
7525    (set (match_operand:QI 0 "register_operand" "=a")
7526         (mult:QI (match_dup 1) (match_dup 2)))]
7527   "TARGET_QIMODE_MATH
7528    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7529   "<sgnprefix>mul{b}\t%2"
7530   [(set_attr "type" "imul")
7531    (set_attr "length_immediate" "0")
7532    (set (attr "athlon_decode")
7533      (if_then_else (eq_attr "cpu" "athlon")
7534         (const_string "vector")
7535         (const_string "direct")))
7536    (set_attr "amdfam10_decode" "direct")
7537    (set_attr "bdver1_decode" "direct")
7538    (set_attr "mode" "QI")])
7540 (define_expand "<u>mul<mode><dwi>3"
7541   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7542                    (mult:<DWI>
7543                      (any_extend:<DWI>
7544                        (match_operand:DWIH 1 "nonimmediate_operand"))
7545                      (any_extend:<DWI>
7546                        (match_operand:DWIH 2 "register_operand"))))
7547               (clobber (reg:CC FLAGS_REG))])])
7549 (define_expand "<u>mulqihi3"
7550   [(parallel [(set (match_operand:HI 0 "register_operand")
7551                    (mult:HI
7552                      (any_extend:HI
7553                        (match_operand:QI 1 "nonimmediate_operand"))
7554                      (any_extend:HI
7555                        (match_operand:QI 2 "register_operand"))))
7556               (clobber (reg:CC FLAGS_REG))])]
7557   "TARGET_QIMODE_MATH")
7559 (define_insn "*bmi2_umul<mode><dwi>3_1"
7560   [(set (match_operand:DWIH 0 "register_operand" "=r")
7561         (mult:DWIH
7562           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7563           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7564    (set (match_operand:DWIH 1 "register_operand" "=r")
7565         (truncate:DWIH
7566           (lshiftrt:<DWI>
7567             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7568                         (zero_extend:<DWI> (match_dup 3)))
7569             (match_operand:QI 4 "const_int_operand" "n"))))]
7570   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7571    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7572   "mulx\t{%3, %0, %1|%1, %0, %3}"
7573   [(set_attr "type" "imulx")
7574    (set_attr "prefix" "vex")
7575    (set_attr "mode" "<MODE>")])
7577 (define_insn "*umul<mode><dwi>3_1"
7578   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7579         (mult:<DWI>
7580           (zero_extend:<DWI>
7581             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7582           (zero_extend:<DWI>
7583             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7586   "@
7587    #
7588    mul{<imodesuffix>}\t%2"
7589   [(set_attr "isa" "bmi2,*")
7590    (set_attr "type" "imulx,imul")
7591    (set_attr "length_immediate" "*,0")
7592    (set (attr "athlon_decode")
7593         (cond [(eq_attr "alternative" "1")
7594                  (if_then_else (eq_attr "cpu" "athlon")
7595                    (const_string "vector")
7596                    (const_string "double"))]
7597               (const_string "*")))
7598    (set_attr "amdfam10_decode" "*,double")
7599    (set_attr "bdver1_decode" "*,direct")
7600    (set_attr "prefix" "vex,orig")
7601    (set_attr "mode" "<MODE>")])
7603 ;; Convert mul to the mulx pattern to avoid flags dependency.
7604 (define_split
7605  [(set (match_operand:<DWI> 0 "register_operand")
7606        (mult:<DWI>
7607          (zero_extend:<DWI>
7608            (match_operand:DWIH 1 "register_operand"))
7609          (zero_extend:<DWI>
7610            (match_operand:DWIH 2 "nonimmediate_operand"))))
7611   (clobber (reg:CC FLAGS_REG))]
7612  "TARGET_BMI2 && reload_completed
7613   && REGNO (operands[1]) == DX_REG"
7614   [(parallel [(set (match_dup 3)
7615                    (mult:DWIH (match_dup 1) (match_dup 2)))
7616               (set (match_dup 4)
7617                    (truncate:DWIH
7618                      (lshiftrt:<DWI>
7619                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7620                                    (zero_extend:<DWI> (match_dup 2)))
7621                        (match_dup 5))))])]
7623   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7625   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7628 (define_insn "*mul<mode><dwi>3_1"
7629   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7630         (mult:<DWI>
7631           (sign_extend:<DWI>
7632             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7633           (sign_extend:<DWI>
7634             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7635    (clobber (reg:CC FLAGS_REG))]
7636   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7637   "imul{<imodesuffix>}\t%2"
7638   [(set_attr "type" "imul")
7639    (set_attr "length_immediate" "0")
7640    (set (attr "athlon_decode")
7641      (if_then_else (eq_attr "cpu" "athlon")
7642         (const_string "vector")
7643         (const_string "double")))
7644    (set_attr "amdfam10_decode" "double")
7645    (set_attr "bdver1_decode" "direct")
7646    (set_attr "mode" "<MODE>")])
7648 (define_insn "*<u>mulqihi3_1"
7649   [(set (match_operand:HI 0 "register_operand" "=a")
7650         (mult:HI
7651           (any_extend:HI
7652             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7653           (any_extend:HI
7654             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7655    (clobber (reg:CC FLAGS_REG))]
7656   "TARGET_QIMODE_MATH
7657    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7658   "<sgnprefix>mul{b}\t%2"
7659   [(set_attr "type" "imul")
7660    (set_attr "length_immediate" "0")
7661    (set (attr "athlon_decode")
7662      (if_then_else (eq_attr "cpu" "athlon")
7663         (const_string "vector")
7664         (const_string "direct")))
7665    (set_attr "amdfam10_decode" "direct")
7666    (set_attr "bdver1_decode" "direct")
7667    (set_attr "mode" "QI")])
7669 (define_expand "<s>mul<mode>3_highpart"
7670   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7671                    (truncate:SWI48
7672                      (lshiftrt:<DWI>
7673                        (mult:<DWI>
7674                          (any_extend:<DWI>
7675                            (match_operand:SWI48 1 "nonimmediate_operand"))
7676                          (any_extend:<DWI>
7677                            (match_operand:SWI48 2 "register_operand")))
7678                        (match_dup 3))))
7679               (clobber (match_scratch:SWI48 4))
7680               (clobber (reg:CC FLAGS_REG))])]
7681   ""
7682   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7684 (define_insn "*<s>muldi3_highpart_1"
7685   [(set (match_operand:DI 0 "register_operand" "=d")
7686         (truncate:DI
7687           (lshiftrt:TI
7688             (mult:TI
7689               (any_extend:TI
7690                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7691               (any_extend:TI
7692                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7693             (const_int 64))))
7694    (clobber (match_scratch:DI 3 "=1"))
7695    (clobber (reg:CC FLAGS_REG))]
7696   "TARGET_64BIT
7697    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698   "<sgnprefix>mul{q}\t%2"
7699   [(set_attr "type" "imul")
7700    (set_attr "length_immediate" "0")
7701    (set (attr "athlon_decode")
7702      (if_then_else (eq_attr "cpu" "athlon")
7703         (const_string "vector")
7704         (const_string "double")))
7705    (set_attr "amdfam10_decode" "double")
7706    (set_attr "bdver1_decode" "direct")
7707    (set_attr "mode" "DI")])
7709 (define_insn "*<s>mulsi3_highpart_zext"
7710   [(set (match_operand:DI 0 "register_operand" "=d")
7711         (zero_extend:DI (truncate:SI
7712           (lshiftrt:DI
7713             (mult:DI (any_extend:DI
7714                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7715                      (any_extend:DI
7716                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7717             (const_int 32)))))
7718    (clobber (match_scratch:SI 3 "=1"))
7719    (clobber (reg:CC FLAGS_REG))]
7720   "TARGET_64BIT
7721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722   "<sgnprefix>mul{l}\t%2"
7723   [(set_attr "type" "imul")
7724    (set_attr "length_immediate" "0")
7725    (set (attr "athlon_decode")
7726      (if_then_else (eq_attr "cpu" "athlon")
7727         (const_string "vector")
7728         (const_string "double")))
7729    (set_attr "amdfam10_decode" "double")
7730    (set_attr "bdver1_decode" "direct")
7731    (set_attr "mode" "SI")])
7733 (define_insn "*<s>mulsi3_highpart_1"
7734   [(set (match_operand:SI 0 "register_operand" "=d")
7735         (truncate:SI
7736           (lshiftrt:DI
7737             (mult:DI
7738               (any_extend:DI
7739                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7740               (any_extend:DI
7741                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7742             (const_int 32))))
7743    (clobber (match_scratch:SI 3 "=1"))
7744    (clobber (reg:CC FLAGS_REG))]
7745   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7746   "<sgnprefix>mul{l}\t%2"
7747   [(set_attr "type" "imul")
7748    (set_attr "length_immediate" "0")
7749    (set (attr "athlon_decode")
7750      (if_then_else (eq_attr "cpu" "athlon")
7751         (const_string "vector")
7752         (const_string "double")))
7753    (set_attr "amdfam10_decode" "double")
7754    (set_attr "bdver1_decode" "direct")
7755    (set_attr "mode" "SI")])
7757 ;; The patterns that match these are at the end of this file.
7759 (define_expand "mulxf3"
7760   [(set (match_operand:XF 0 "register_operand")
7761         (mult:XF (match_operand:XF 1 "register_operand")
7762                  (match_operand:XF 2 "register_operand")))]
7763   "TARGET_80387")
7765 (define_expand "mul<mode>3"
7766   [(set (match_operand:MODEF 0 "register_operand")
7767         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7768                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7769   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7770     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7772 ;; Divide instructions
7774 ;; The patterns that match these are at the end of this file.
7776 (define_expand "divxf3"
7777   [(set (match_operand:XF 0 "register_operand")
7778         (div:XF (match_operand:XF 1 "register_operand")
7779                 (match_operand:XF 2 "register_operand")))]
7780   "TARGET_80387")
7782 (define_expand "div<mode>3"
7783   [(set (match_operand:MODEF 0 "register_operand")
7784         (div:MODEF (match_operand:MODEF 1 "register_operand")
7785                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7786   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7787     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7789   if (<MODE>mode == SFmode
7790       && TARGET_SSE && TARGET_SSE_MATH
7791       && TARGET_RECIP_DIV
7792       && optimize_insn_for_speed_p ()
7793       && flag_finite_math_only && !flag_trapping_math
7794       && flag_unsafe_math_optimizations)
7795     {
7796       ix86_emit_swdivsf (operands[0], operands[1],
7797                          operands[2], SFmode);
7798       DONE;
7799     }
7802 ;; Divmod instructions.
7804 (define_expand "divmod<mode>4"
7805   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7806                    (div:SWIM248
7807                      (match_operand:SWIM248 1 "register_operand")
7808                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7809               (set (match_operand:SWIM248 3 "register_operand")
7810                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7811               (clobber (reg:CC FLAGS_REG))])])
7813 ;; Split with 8bit unsigned divide:
7814 ;;      if (dividend an divisor are in [0-255])
7815 ;;         use 8bit unsigned integer divide
7816 ;;       else
7817 ;;         use original integer divide
7818 (define_split
7819   [(set (match_operand:SWI48 0 "register_operand")
7820         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7821                     (match_operand:SWI48 3 "nonimmediate_operand")))
7822    (set (match_operand:SWI48 1 "register_operand")
7823         (mod:SWI48 (match_dup 2) (match_dup 3)))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "TARGET_USE_8BIT_IDIV
7826    && TARGET_QIMODE_MATH
7827    && can_create_pseudo_p ()
7828    && !optimize_insn_for_size_p ()"
7829   [(const_int 0)]
7830   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7832 (define_split
7833   [(set (match_operand:DI 0 "register_operand")
7834         (zero_extend:DI
7835           (div:SI (match_operand:SI 2 "register_operand")
7836                   (match_operand:SI 3 "nonimmediate_operand"))))
7837    (set (match_operand:SI 1 "register_operand")
7838         (mod:SI (match_dup 2) (match_dup 3)))
7839    (clobber (reg:CC FLAGS_REG))]
7840   "TARGET_USE_8BIT_IDIV
7841    && TARGET_QIMODE_MATH
7842    && can_create_pseudo_p ()
7843    && !optimize_insn_for_size_p ()"
7844   [(const_int 0)]
7845   "ix86_split_idivmod (SImode, operands, true); DONE;")
7847 (define_split
7848   [(set (match_operand:DI 1 "register_operand")
7849         (zero_extend:DI
7850           (mod:SI (match_operand:SI 2 "register_operand")
7851                   (match_operand:SI 3 "nonimmediate_operand"))))
7852    (set (match_operand:SI 0 "register_operand")
7853         (div:SI  (match_dup 2) (match_dup 3)))
7854    (clobber (reg:CC FLAGS_REG))]
7855   "TARGET_USE_8BIT_IDIV
7856    && TARGET_QIMODE_MATH
7857    && can_create_pseudo_p ()
7858    && !optimize_insn_for_size_p ()"
7859   [(const_int 0)]
7860   "ix86_split_idivmod (SImode, operands, true); DONE;")
7862 (define_insn_and_split "divmod<mode>4_1"
7863   [(set (match_operand:SWI48 0 "register_operand" "=a")
7864         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7865                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7866    (set (match_operand:SWI48 1 "register_operand" "=&d")
7867         (mod:SWI48 (match_dup 2) (match_dup 3)))
7868    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7869    (clobber (reg:CC FLAGS_REG))]
7870   ""
7871   "#"
7872   "reload_completed"
7873   [(parallel [(set (match_dup 1)
7874                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7875               (clobber (reg:CC FLAGS_REG))])
7876    (parallel [(set (match_dup 0)
7877                    (div:SWI48 (match_dup 2) (match_dup 3)))
7878               (set (match_dup 1)
7879                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7880               (use (match_dup 1))
7881               (clobber (reg:CC FLAGS_REG))])]
7883   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7885   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7886     operands[4] = operands[2];
7887   else
7888     {
7889       /* Avoid use of cltd in favor of a mov+shift.  */
7890       emit_move_insn (operands[1], operands[2]);
7891       operands[4] = operands[1];
7892     }
7894   [(set_attr "type" "multi")
7895    (set_attr "mode" "<MODE>")])
7897 (define_insn_and_split "divmodsi4_zext_1"
7898   [(set (match_operand:DI 0 "register_operand" "=a")
7899         (zero_extend:DI
7900           (div:SI (match_operand:SI 2 "register_operand" "0")
7901                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7902    (set (match_operand:SI 1 "register_operand" "=&d")
7903         (mod:SI (match_dup 2) (match_dup 3)))
7904    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7905    (clobber (reg:CC FLAGS_REG))]
7906   "TARGET_64BIT"
7907   "#"
7908   "reload_completed"
7909   [(parallel [(set (match_dup 1)
7910                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7911               (clobber (reg:CC FLAGS_REG))])
7912    (parallel [(set (match_dup 0)
7913                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7914               (set (match_dup 1)
7915                    (mod:SI (match_dup 2) (match_dup 3)))
7916               (use (match_dup 1))
7917               (clobber (reg:CC FLAGS_REG))])]
7919   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7921   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7922     operands[4] = operands[2];
7923   else
7924     {
7925       /* Avoid use of cltd in favor of a mov+shift.  */
7926       emit_move_insn (operands[1], operands[2]);
7927       operands[4] = operands[1];
7928     }
7930   [(set_attr "type" "multi")
7931    (set_attr "mode" "SI")])
7933 (define_insn_and_split "divmodsi4_zext_2"
7934   [(set (match_operand:DI 1 "register_operand" "=&d")
7935         (zero_extend:DI
7936           (mod:SI (match_operand:SI 2 "register_operand" "0")
7937                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7938    (set (match_operand:SI 0 "register_operand" "=a")
7939         (div:SI (match_dup 2) (match_dup 3)))
7940    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7941    (clobber (reg:CC FLAGS_REG))]
7942   "TARGET_64BIT"
7943   "#"
7944   "reload_completed"
7945   [(parallel [(set (match_dup 6)
7946                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7947               (clobber (reg:CC FLAGS_REG))])
7948    (parallel [(set (match_dup 1)
7949                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7950               (set (match_dup 0)
7951                    (div:SI (match_dup 2) (match_dup 3)))
7952               (use (match_dup 6))
7953               (clobber (reg:CC FLAGS_REG))])]
7955   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7956   operands[6] = gen_lowpart (SImode, operands[1]);
7958   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7959     operands[4] = operands[2];
7960   else
7961     {
7962       /* Avoid use of cltd in favor of a mov+shift.  */
7963       emit_move_insn (operands[6], operands[2]);
7964       operands[4] = operands[6];
7965     }
7967   [(set_attr "type" "multi")
7968    (set_attr "mode" "SI")])
7970 (define_insn_and_split "*divmod<mode>4"
7971   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7972         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7973                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7974    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7975         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7976    (clobber (reg:CC FLAGS_REG))]
7977   ""
7978   "#"
7979   "reload_completed"
7980   [(parallel [(set (match_dup 1)
7981                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7982               (clobber (reg:CC FLAGS_REG))])
7983    (parallel [(set (match_dup 0)
7984                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7985               (set (match_dup 1)
7986                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7987               (use (match_dup 1))
7988               (clobber (reg:CC FLAGS_REG))])]
7990   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7992   if (<MODE>mode != HImode
7993       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7994     operands[4] = operands[2];
7995   else
7996     {
7997       /* Avoid use of cltd in favor of a mov+shift.  */
7998       emit_move_insn (operands[1], operands[2]);
7999       operands[4] = operands[1];
8000     }
8002   [(set_attr "type" "multi")
8003    (set_attr "mode" "<MODE>")])
8005 (define_insn_and_split "*divmodsi4_zext_1"
8006   [(set (match_operand:DI 0 "register_operand" "=a")
8007         (zero_extend:DI
8008           (div:SI (match_operand:SI 2 "register_operand" "0")
8009                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8010    (set (match_operand:SI 1 "register_operand" "=&d")
8011         (mod:SI (match_dup 2) (match_dup 3)))
8012    (clobber (reg:CC FLAGS_REG))]
8013   "TARGET_64BIT"
8014   "#"
8015   "reload_completed"
8016   [(parallel [(set (match_dup 1)
8017                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8018               (clobber (reg:CC FLAGS_REG))])
8019    (parallel [(set (match_dup 0)
8020                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8021               (set (match_dup 1)
8022                    (mod:SI (match_dup 2) (match_dup 3)))
8023               (use (match_dup 1))
8024               (clobber (reg:CC FLAGS_REG))])]
8026   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8028   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8029     operands[4] = operands[2];
8030   else
8031     {
8032       /* Avoid use of cltd in favor of a mov+shift.  */
8033       emit_move_insn (operands[1], operands[2]);
8034       operands[4] = operands[1];
8035     }
8037   [(set_attr "type" "multi")
8038    (set_attr "mode" "SI")])
8040 (define_insn_and_split "*divmodsi4_zext_2"
8041   [(set (match_operand:DI 1 "register_operand" "=&d")
8042         (zero_extend:DI
8043           (mod:SI (match_operand:SI 2 "register_operand" "0")
8044                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8045    (set (match_operand:SI 0 "register_operand" "=a")
8046         (div:SI (match_dup 2) (match_dup 3)))
8047    (clobber (reg:CC FLAGS_REG))]
8048   "TARGET_64BIT"
8049   "#"
8050   "reload_completed"
8051   [(parallel [(set (match_dup 6)
8052                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8053               (clobber (reg:CC FLAGS_REG))])
8054    (parallel [(set (match_dup 1)
8055                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8056               (set (match_dup 0)
8057                    (div:SI (match_dup 2) (match_dup 3)))
8058               (use (match_dup 6))
8059               (clobber (reg:CC FLAGS_REG))])]
8061   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8062   operands[6] = gen_lowpart (SImode, operands[1]);
8064   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8065     operands[4] = operands[2];
8066   else
8067     {
8068       /* Avoid use of cltd in favor of a mov+shift.  */
8069       emit_move_insn (operands[6], operands[2]);
8070       operands[4] = operands[6];
8071     }
8073   [(set_attr "type" "multi")
8074    (set_attr "mode" "SI")])
8076 (define_insn "*divmod<mode>4_noext"
8077   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8078         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8079                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8080    (set (match_operand:SWIM248 1 "register_operand" "=d")
8081         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8082    (use (match_operand:SWIM248 4 "register_operand" "1"))
8083    (clobber (reg:CC FLAGS_REG))]
8084   ""
8085   "idiv{<imodesuffix>}\t%3"
8086   [(set_attr "type" "idiv")
8087    (set_attr "mode" "<MODE>")])
8089 (define_insn "*divmodsi4_noext_zext_1"
8090   [(set (match_operand:DI 0 "register_operand" "=a")
8091         (zero_extend:DI
8092           (div:SI (match_operand:SI 2 "register_operand" "0")
8093                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8094    (set (match_operand:SI 1 "register_operand" "=d")
8095         (mod:SI (match_dup 2) (match_dup 3)))
8096    (use (match_operand:SI 4 "register_operand" "1"))
8097    (clobber (reg:CC FLAGS_REG))]
8098   "TARGET_64BIT"
8099   "idiv{l}\t%3"
8100   [(set_attr "type" "idiv")
8101    (set_attr "mode" "SI")])
8103 (define_insn "*divmodsi4_noext_zext_2"
8104   [(set (match_operand:DI 1 "register_operand" "=d")
8105         (zero_extend:DI
8106           (mod:SI (match_operand:SI 2 "register_operand" "0")
8107                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8108    (set (match_operand:SI 0 "register_operand" "=a")
8109         (div:SI (match_dup 2) (match_dup 3)))
8110    (use (match_operand:SI 4 "register_operand" "1"))
8111    (clobber (reg:CC FLAGS_REG))]
8112   "TARGET_64BIT"
8113   "idiv{l}\t%3"
8114   [(set_attr "type" "idiv")
8115    (set_attr "mode" "SI")])
8117 (define_expand "divmodqi4"
8118   [(parallel [(set (match_operand:QI 0 "register_operand")
8119                    (div:QI
8120                      (match_operand:QI 1 "register_operand")
8121                      (match_operand:QI 2 "nonimmediate_operand")))
8122               (set (match_operand:QI 3 "register_operand")
8123                    (mod:QI (match_dup 1) (match_dup 2)))
8124               (clobber (reg:CC FLAGS_REG))])]
8125   "TARGET_QIMODE_MATH"
8127   rtx div, mod;
8128   rtx tmp0, tmp1;
8129   
8130   tmp0 = gen_reg_rtx (HImode);
8131   tmp1 = gen_reg_rtx (HImode);
8133   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8134   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8135   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8137   /* Extract remainder from AH.  */
8138   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8139   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8140   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8142   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8143   set_unique_reg_note (insn, REG_EQUAL, mod);
8145   /* Extract quotient from AL.  */
8146   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8148   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8149   set_unique_reg_note (insn, REG_EQUAL, div);
8151   DONE;
8154 ;; Divide AX by r/m8, with result stored in
8155 ;; AL <- Quotient
8156 ;; AH <- Remainder
8157 ;; Change div/mod to HImode and extend the second argument to HImode
8158 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8159 ;; combine may fail.
8160 (define_insn "divmodhiqi3"
8161   [(set (match_operand:HI 0 "register_operand" "=a")
8162         (ior:HI
8163           (ashift:HI
8164             (zero_extend:HI
8165               (truncate:QI
8166                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8167                         (sign_extend:HI
8168                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8169             (const_int 8))
8170           (zero_extend:HI
8171             (truncate:QI
8172               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8173    (clobber (reg:CC FLAGS_REG))]
8174   "TARGET_QIMODE_MATH"
8175   "idiv{b}\t%2"
8176   [(set_attr "type" "idiv")
8177    (set_attr "mode" "QI")])
8179 (define_expand "udivmod<mode>4"
8180   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8181                    (udiv:SWIM248
8182                      (match_operand:SWIM248 1 "register_operand")
8183                      (match_operand:SWIM248 2 "nonimmediate_operand")))
8184               (set (match_operand:SWIM248 3 "register_operand")
8185                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8186               (clobber (reg:CC FLAGS_REG))])])
8188 ;; Split with 8bit unsigned divide:
8189 ;;      if (dividend an divisor are in [0-255])
8190 ;;         use 8bit unsigned integer divide
8191 ;;       else
8192 ;;         use original integer divide
8193 (define_split
8194   [(set (match_operand:SWI48 0 "register_operand")
8195         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8196                     (match_operand:SWI48 3 "nonimmediate_operand")))
8197    (set (match_operand:SWI48 1 "register_operand")
8198         (umod:SWI48 (match_dup 2) (match_dup 3)))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "TARGET_USE_8BIT_IDIV
8201    && TARGET_QIMODE_MATH
8202    && can_create_pseudo_p ()
8203    && !optimize_insn_for_size_p ()"
8204   [(const_int 0)]
8205   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8207 (define_split
8208   [(set (match_operand:DI 0 "register_operand")
8209         (zero_extend:DI
8210           (udiv:SI (match_operand:SI 2 "register_operand")
8211                    (match_operand:SI 3 "nonimmediate_operand"))))
8212    (set (match_operand:SI 1 "register_operand")
8213         (umod:SI (match_dup 2) (match_dup 3)))
8214    (clobber (reg:CC FLAGS_REG))]
8215   "TARGET_64BIT
8216    && TARGET_USE_8BIT_IDIV
8217    && TARGET_QIMODE_MATH
8218    && can_create_pseudo_p ()
8219    && !optimize_insn_for_size_p ()"
8220   [(const_int 0)]
8221   "ix86_split_idivmod (SImode, operands, false); DONE;")
8223 (define_split
8224   [(set (match_operand:DI 1 "register_operand")
8225         (zero_extend:DI
8226           (umod:SI (match_operand:SI 2 "register_operand")
8227                    (match_operand:SI 3 "nonimmediate_operand"))))
8228    (set (match_operand:SI 0 "register_operand")
8229         (udiv:SI (match_dup 2) (match_dup 3)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "TARGET_64BIT
8232    && TARGET_USE_8BIT_IDIV
8233    && TARGET_QIMODE_MATH
8234    && can_create_pseudo_p ()
8235    && !optimize_insn_for_size_p ()"
8236   [(const_int 0)]
8237   "ix86_split_idivmod (SImode, operands, false); DONE;")
8239 (define_insn_and_split "udivmod<mode>4_1"
8240   [(set (match_operand:SWI48 0 "register_operand" "=a")
8241         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8242                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8243    (set (match_operand:SWI48 1 "register_operand" "=&d")
8244         (umod:SWI48 (match_dup 2) (match_dup 3)))
8245    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8246    (clobber (reg:CC FLAGS_REG))]
8247   ""
8248   "#"
8249   "reload_completed"
8250   [(set (match_dup 1) (const_int 0))
8251    (parallel [(set (match_dup 0)
8252                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
8253               (set (match_dup 1)
8254                    (umod:SWI48 (match_dup 2) (match_dup 3)))
8255               (use (match_dup 1))
8256               (clobber (reg:CC FLAGS_REG))])]
8257   ""
8258   [(set_attr "type" "multi")
8259    (set_attr "mode" "<MODE>")])
8261 (define_insn_and_split "udivmodsi4_zext_1"
8262   [(set (match_operand:DI 0 "register_operand" "=a")
8263         (zero_extend:DI
8264           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8265                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8266    (set (match_operand:SI 1 "register_operand" "=&d")
8267         (umod:SI (match_dup 2) (match_dup 3)))
8268    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8269    (clobber (reg:CC FLAGS_REG))]
8270   "TARGET_64BIT"
8271   "#"
8272   "reload_completed"
8273   [(set (match_dup 1) (const_int 0))
8274    (parallel [(set (match_dup 0)
8275                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8276               (set (match_dup 1)
8277                    (umod:SI (match_dup 2) (match_dup 3)))
8278               (use (match_dup 1))
8279               (clobber (reg:CC FLAGS_REG))])]
8280   ""
8281   [(set_attr "type" "multi")
8282    (set_attr "mode" "SI")])
8284 (define_insn_and_split "udivmodsi4_zext_2"
8285   [(set (match_operand:DI 1 "register_operand" "=&d")
8286         (zero_extend:DI
8287           (umod:SI (match_operand:SI 2 "register_operand" "0")
8288                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8289    (set (match_operand:SI 0 "register_operand" "=a")
8290         (udiv:SI (match_dup 2) (match_dup 3)))
8291    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8292    (clobber (reg:CC FLAGS_REG))]
8293   "TARGET_64BIT"
8294   "#"
8295   "reload_completed"
8296   [(set (match_dup 4) (const_int 0))
8297    (parallel [(set (match_dup 1)
8298                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8299               (set (match_dup 0)
8300                    (udiv:SI (match_dup 2) (match_dup 3)))
8301               (use (match_dup 4))
8302               (clobber (reg:CC FLAGS_REG))])]
8303   "operands[4] = gen_lowpart (SImode, operands[1]);"
8304   [(set_attr "type" "multi")
8305    (set_attr "mode" "SI")])
8307 (define_insn_and_split "*udivmod<mode>4"
8308   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8309         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8310                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8311    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8312         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8313    (clobber (reg:CC FLAGS_REG))]
8314   ""
8315   "#"
8316   "reload_completed"
8317   [(set (match_dup 1) (const_int 0))
8318    (parallel [(set (match_dup 0)
8319                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8320               (set (match_dup 1)
8321                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8322               (use (match_dup 1))
8323               (clobber (reg:CC FLAGS_REG))])]
8324   ""
8325   [(set_attr "type" "multi")
8326    (set_attr "mode" "<MODE>")])
8328 (define_insn_and_split "*udivmodsi4_zext_1"
8329   [(set (match_operand:DI 0 "register_operand" "=a")
8330         (zero_extend:DI
8331           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8332                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8333    (set (match_operand:SI 1 "register_operand" "=&d")
8334         (umod:SI (match_dup 2) (match_dup 3)))
8335    (clobber (reg:CC FLAGS_REG))]
8336   "TARGET_64BIT"
8337   "#"
8338   "reload_completed"
8339   [(set (match_dup 1) (const_int 0))
8340    (parallel [(set (match_dup 0)
8341                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8342               (set (match_dup 1)
8343                    (umod:SI (match_dup 2) (match_dup 3)))
8344               (use (match_dup 1))
8345               (clobber (reg:CC FLAGS_REG))])]
8346   ""
8347   [(set_attr "type" "multi")
8348    (set_attr "mode" "SI")])
8350 (define_insn_and_split "*udivmodsi4_zext_2"
8351   [(set (match_operand:DI 1 "register_operand" "=&d")
8352         (zero_extend:DI
8353           (umod:SI (match_operand:SI 2 "register_operand" "0")
8354                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8355    (set (match_operand:SI 0 "register_operand" "=a")
8356         (udiv:SI (match_dup 2) (match_dup 3)))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "TARGET_64BIT"
8359   "#"
8360   "reload_completed"
8361   [(set (match_dup 4) (const_int 0))
8362    (parallel [(set (match_dup 1)
8363                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8364               (set (match_dup 0)
8365                    (udiv:SI (match_dup 2) (match_dup 3)))
8366               (use (match_dup 4))
8367               (clobber (reg:CC FLAGS_REG))])]
8368   "operands[4] = gen_lowpart (SImode, operands[1]);"
8369   [(set_attr "type" "multi")
8370    (set_attr "mode" "SI")])
8372 ;; Optimize division or modulo by constant power of 2, if the constant
8373 ;; materializes only after expansion.
8374 (define_insn_and_split "*udivmod<mode>4_pow2"
8375   [(set (match_operand:SWI48 0 "register_operand" "=r")
8376         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8377                     (match_operand:SWI48 3 "const_int_operand" "n")))
8378    (set (match_operand:SWI48 1 "register_operand" "=r")
8379         (umod:SWI48 (match_dup 2) (match_dup 3)))
8380    (clobber (reg:CC FLAGS_REG))]
8381   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8382    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8383   "#"
8384   "&& 1"
8385   [(set (match_dup 1) (match_dup 2))
8386    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8387               (clobber (reg:CC FLAGS_REG))])
8388    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8389               (clobber (reg:CC FLAGS_REG))])]
8391   int v = exact_log2 (UINTVAL (operands[3]));
8392   operands[4] = GEN_INT (v);
8393   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8395   [(set_attr "type" "multi")
8396    (set_attr "mode" "<MODE>")])
8398 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8399   [(set (match_operand:DI 0 "register_operand" "=r")
8400         (zero_extend:DI
8401           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8402                    (match_operand:SI 3 "const_int_operand" "n"))))
8403    (set (match_operand:SI 1 "register_operand" "=r")
8404         (umod:SI (match_dup 2) (match_dup 3)))
8405    (clobber (reg:CC FLAGS_REG))]
8406   "TARGET_64BIT
8407    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8408    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8409   "#"
8410   "&& 1"
8411   [(set (match_dup 1) (match_dup 2))
8412    (parallel [(set (match_dup 0)
8413                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8414               (clobber (reg:CC FLAGS_REG))])
8415    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8416               (clobber (reg:CC FLAGS_REG))])]
8418   int v = exact_log2 (UINTVAL (operands[3]));
8419   operands[4] = GEN_INT (v);
8420   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8422   [(set_attr "type" "multi")
8423    (set_attr "mode" "SI")])
8425 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8426   [(set (match_operand:DI 1 "register_operand" "=r")
8427         (zero_extend:DI
8428           (umod:SI (match_operand:SI 2 "register_operand" "0")
8429                    (match_operand:SI 3 "const_int_operand" "n"))))
8430    (set (match_operand:SI 0 "register_operand" "=r")
8431         (umod:SI (match_dup 2) (match_dup 3)))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT
8434    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8435    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8436   "#"
8437   "&& 1"
8438   [(set (match_dup 1) (match_dup 2))
8439    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8440               (clobber (reg:CC FLAGS_REG))])
8441    (parallel [(set (match_dup 1)
8442                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8443               (clobber (reg:CC FLAGS_REG))])]
8445   int v = exact_log2 (UINTVAL (operands[3]));
8446   operands[4] = GEN_INT (v);
8447   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8449   [(set_attr "type" "multi")
8450    (set_attr "mode" "SI")])
8452 (define_insn "*udivmod<mode>4_noext"
8453   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8454         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8455                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8456    (set (match_operand:SWIM248 1 "register_operand" "=d")
8457         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8458    (use (match_operand:SWIM248 4 "register_operand" "1"))
8459    (clobber (reg:CC FLAGS_REG))]
8460   ""
8461   "div{<imodesuffix>}\t%3"
8462   [(set_attr "type" "idiv")
8463    (set_attr "mode" "<MODE>")])
8465 (define_insn "*udivmodsi4_noext_zext_1"
8466   [(set (match_operand:DI 0 "register_operand" "=a")
8467         (zero_extend:DI
8468           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8469                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8470    (set (match_operand:SI 1 "register_operand" "=d")
8471         (umod:SI (match_dup 2) (match_dup 3)))
8472    (use (match_operand:SI 4 "register_operand" "1"))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "TARGET_64BIT"
8475   "div{l}\t%3"
8476   [(set_attr "type" "idiv")
8477    (set_attr "mode" "SI")])
8479 (define_insn "*udivmodsi4_noext_zext_2"
8480   [(set (match_operand:DI 1 "register_operand" "=d")
8481         (zero_extend:DI
8482           (umod:SI (match_operand:SI 2 "register_operand" "0")
8483                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8484    (set (match_operand:SI 0 "register_operand" "=a")
8485         (udiv:SI (match_dup 2) (match_dup 3)))
8486    (use (match_operand:SI 4 "register_operand" "1"))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT"
8489   "div{l}\t%3"
8490   [(set_attr "type" "idiv")
8491    (set_attr "mode" "SI")])
8493 (define_expand "udivmodqi4"
8494   [(parallel [(set (match_operand:QI 0 "register_operand")
8495                    (udiv:QI
8496                      (match_operand:QI 1 "register_operand")
8497                      (match_operand:QI 2 "nonimmediate_operand")))
8498               (set (match_operand:QI 3 "register_operand")
8499                    (umod:QI (match_dup 1) (match_dup 2)))
8500               (clobber (reg:CC FLAGS_REG))])]
8501   "TARGET_QIMODE_MATH"
8503   rtx div, mod;
8504   rtx tmp0, tmp1;
8505   
8506   tmp0 = gen_reg_rtx (HImode);
8507   tmp1 = gen_reg_rtx (HImode);
8509   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8510   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8511   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8513   /* Extract remainder from AH.  */
8514   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8515   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8516   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8518   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8519   set_unique_reg_note (insn, REG_EQUAL, mod);
8521   /* Extract quotient from AL.  */
8522   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8524   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8525   set_unique_reg_note (insn, REG_EQUAL, div);
8527   DONE;
8530 (define_insn "udivmodhiqi3"
8531   [(set (match_operand:HI 0 "register_operand" "=a")
8532         (ior:HI
8533           (ashift:HI
8534             (zero_extend:HI
8535               (truncate:QI
8536                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8537                         (zero_extend:HI
8538                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8539             (const_int 8))
8540           (zero_extend:HI
8541             (truncate:QI
8542               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8543    (clobber (reg:CC FLAGS_REG))]
8544   "TARGET_QIMODE_MATH"
8545   "div{b}\t%2"
8546   [(set_attr "type" "idiv")
8547    (set_attr "mode" "QI")])
8549 ;; We cannot use div/idiv for double division, because it causes
8550 ;; "division by zero" on the overflow and that's not what we expect
8551 ;; from truncate.  Because true (non truncating) double division is
8552 ;; never generated, we can't create this insn anyway.
8554 ;(define_insn ""
8555 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8556 ;       (truncate:SI
8557 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8558 ;                  (zero_extend:DI
8559 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8560 ;   (set (match_operand:SI 3 "register_operand" "=d")
8561 ;       (truncate:SI
8562 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8563 ;   (clobber (reg:CC FLAGS_REG))]
8564 ;  ""
8565 ;  "div{l}\t{%2, %0|%0, %2}"
8566 ;  [(set_attr "type" "idiv")])
8568 ;;- Logical AND instructions
8570 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8571 ;; Note that this excludes ah.
8573 (define_expand "testsi_ccno_1"
8574   [(set (reg:CCNO FLAGS_REG)
8575         (compare:CCNO
8576           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8577                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8578           (const_int 0)))])
8580 (define_expand "testqi_ccz_1"
8581   [(set (reg:CCZ FLAGS_REG)
8582         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8583                              (match_operand:QI 1 "nonmemory_operand"))
8584                  (const_int 0)))])
8586 (define_expand "testdi_ccno_1"
8587   [(set (reg:CCNO FLAGS_REG)
8588         (compare:CCNO
8589           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8590                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8591           (const_int 0)))]
8592   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8594 (define_insn "*testdi_1"
8595   [(set (reg FLAGS_REG)
8596         (compare
8597          (and:DI
8598           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8599           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8600          (const_int 0)))]
8601   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8602    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8603   "@
8604    test{l}\t{%k1, %k0|%k0, %k1}
8605    test{l}\t{%k1, %k0|%k0, %k1}
8606    test{q}\t{%1, %0|%0, %1}
8607    test{q}\t{%1, %0|%0, %1}
8608    test{q}\t{%1, %0|%0, %1}"
8609   [(set_attr "type" "test")
8610    (set_attr "modrm" "0,1,0,1,1")
8611    (set_attr "mode" "SI,SI,DI,DI,DI")])
8613 (define_insn "*testqi_1_maybe_si"
8614   [(set (reg FLAGS_REG)
8615         (compare
8616           (and:QI
8617             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8618             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8619           (const_int 0)))]
8620    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8621     && ix86_match_ccmode (insn,
8622                          CONST_INT_P (operands[1])
8623                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8625   if (which_alternative == 3)
8626     {
8627       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8628         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8629       return "test{l}\t{%1, %k0|%k0, %1}";
8630     }
8631   return "test{b}\t{%1, %0|%0, %1}";
8633   [(set_attr "type" "test")
8634    (set_attr "modrm" "0,1,1,1")
8635    (set_attr "mode" "QI,QI,QI,SI")
8636    (set_attr "pent_pair" "uv,np,uv,np")])
8638 (define_insn "*test<mode>_1"
8639   [(set (reg FLAGS_REG)
8640         (compare
8641          (and:SWI124
8642           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8643           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8644          (const_int 0)))]
8645   "ix86_match_ccmode (insn, CCNOmode)
8646    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8647   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8648   [(set_attr "type" "test")
8649    (set_attr "modrm" "0,1,1")
8650    (set_attr "mode" "<MODE>")
8651    (set_attr "pent_pair" "uv,np,uv")])
8653 (define_expand "testqi_ext_1_ccno"
8654   [(set (reg:CCNO FLAGS_REG)
8655         (compare:CCNO
8656           (and:QI
8657             (subreg:QI
8658               (zero_extract:SI (match_operand 0 "ext_register_operand")
8659                                (const_int 8)
8660                                (const_int 8)) 0)
8661               (match_operand 1 "const_int_operand"))
8662           (const_int 0)))])
8664 (define_insn "*testqi_ext_1"
8665   [(set (reg FLAGS_REG)
8666         (compare
8667           (and:QI
8668             (subreg:QI
8669               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8670                                (const_int 8)
8671                                (const_int 8)) 0)
8672             (match_operand:QI 1 "general_operand" "QnBc,m"))
8673           (const_int 0)))]
8674   "ix86_match_ccmode (insn, CCNOmode)"
8675   "test{b}\t{%1, %h0|%h0, %1}"
8676   [(set_attr "isa" "*,nox64")
8677    (set_attr "type" "test")
8678    (set_attr "mode" "QI")])
8680 (define_insn "*testqi_ext_2"
8681   [(set (reg FLAGS_REG)
8682         (compare
8683           (and:QI
8684             (subreg:QI
8685               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8686                                (const_int 8)
8687                                (const_int 8)) 0)
8688             (subreg:QI
8689               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8690                                (const_int 8)
8691                                (const_int 8)) 0))
8692           (const_int 0)))]
8693   "ix86_match_ccmode (insn, CCNOmode)"
8694   "test{b}\t{%h1, %h0|%h0, %h1}"
8695   [(set_attr "type" "test")
8696    (set_attr "mode" "QI")])
8698 ;; Combine likes to form bit extractions for some tests.  Humor it.
8699 (define_insn_and_split "*testqi_ext_3"
8700   [(set (match_operand 0 "flags_reg_operand")
8701         (match_operator 1 "compare_operator"
8702           [(zero_extract:SWI248
8703              (match_operand 2 "nonimmediate_operand" "rm")
8704              (match_operand 3 "const_int_operand" "n")
8705              (match_operand 4 "const_int_operand" "n"))
8706            (const_int 0)]))]
8707   "ix86_match_ccmode (insn, CCNOmode)
8708    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8709        || GET_MODE (operands[2]) == SImode
8710        || GET_MODE (operands[2]) == HImode
8711        || GET_MODE (operands[2]) == QImode)
8712    /* Ensure that resulting mask is zero or sign extended operand.  */
8713    && INTVAL (operands[4]) >= 0
8714    && ((INTVAL (operands[3]) > 0
8715         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8716        || (<MODE>mode == DImode
8717            && INTVAL (operands[3]) > 32
8718            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8719   "#"
8720   "&& 1"
8721   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8723   rtx val = operands[2];
8724   HOST_WIDE_INT len = INTVAL (operands[3]);
8725   HOST_WIDE_INT pos = INTVAL (operands[4]);
8726   machine_mode mode = GET_MODE (val);
8728   if (SUBREG_P (val))
8729     {
8730       machine_mode submode = GET_MODE (SUBREG_REG (val));
8732       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8733       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8734           && GET_MODE_CLASS (submode) == MODE_INT)
8735         {
8736           val = SUBREG_REG (val);
8737           mode = submode;
8738         }
8739     }
8741   /* Small HImode tests can be converted to QImode.  */
8742   if (register_operand (val, HImode) && pos + len <= 8)
8743     {
8744       val = gen_lowpart (QImode, val);
8745       mode = QImode;
8746     }
8748   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8750   wide_int mask
8751     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8753   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8756 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8757 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8758 ;; this is relatively important trick.
8759 ;; Do the conversion only post-reload to avoid limiting of the register class
8760 ;; to QI regs.
8761 (define_split
8762   [(set (match_operand 0 "flags_reg_operand")
8763         (match_operator 1 "compare_operator"
8764           [(and (match_operand 2 "QIreg_operand")
8765                 (match_operand 3 "const_int_operand"))
8766            (const_int 0)]))]
8767    "reload_completed
8768     && GET_MODE (operands[2]) != QImode
8769     && ((ix86_match_ccmode (insn, CCZmode)
8770          && !(INTVAL (operands[3]) & ~(255 << 8)))
8771         || (ix86_match_ccmode (insn, CCNOmode)
8772             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8773   [(set (match_dup 0)
8774         (match_op_dup 1
8775           [(and:QI
8776              (subreg:QI
8777                (zero_extract:SI (match_dup 2)
8778                                 (const_int 8)
8779                                 (const_int 8)) 0)
8780              (match_dup 3))
8781            (const_int 0)]))]
8783   operands[2] = gen_lowpart (SImode, operands[2]);
8784   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8787 (define_split
8788   [(set (match_operand 0 "flags_reg_operand")
8789         (match_operator 1 "compare_operator"
8790           [(and (match_operand 2 "nonimmediate_operand")
8791                 (match_operand 3 "const_int_operand"))
8792            (const_int 0)]))]
8793    "reload_completed
8794     && GET_MODE (operands[2]) != QImode
8795     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8796     && ((ix86_match_ccmode (insn, CCZmode)
8797          && !(INTVAL (operands[3]) & ~255))
8798         || (ix86_match_ccmode (insn, CCNOmode)
8799             && !(INTVAL (operands[3]) & ~127)))"
8800   [(set (match_dup 0)
8801         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8802                          (const_int 0)]))]
8804   operands[2] = gen_lowpart (QImode, operands[2]);
8805   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8808 ;; %%% This used to optimize known byte-wide and operations to memory,
8809 ;; and sometimes to QImode registers.  If this is considered useful,
8810 ;; it should be done with splitters.
8812 (define_expand "and<mode>3"
8813   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8814         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8815                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8816   ""
8818   machine_mode mode = <MODE>mode;
8819   rtx (*insn) (rtx, rtx);
8821   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8822     {
8823       HOST_WIDE_INT ival = INTVAL (operands[2]);
8825       if (ival == (HOST_WIDE_INT) 0xffffffff)
8826         mode = SImode;
8827       else if (ival == 0xffff)
8828         mode = HImode;
8829       else if (ival == 0xff)
8830         mode = QImode;
8831       }
8833   if (mode == <MODE>mode)
8834     {
8835       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8836       DONE;
8837     }
8839   if (<MODE>mode == DImode)
8840     insn = (mode == SImode)
8841            ? gen_zero_extendsidi2
8842            : (mode == HImode)
8843            ? gen_zero_extendhidi2
8844            : gen_zero_extendqidi2;
8845   else if (<MODE>mode == SImode)
8846     insn = (mode == HImode)
8847            ? gen_zero_extendhisi2
8848            : gen_zero_extendqisi2;
8849   else if (<MODE>mode == HImode)
8850     insn = gen_zero_extendqihi2;
8851   else
8852     gcc_unreachable ();
8854   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8855   DONE;
8858 (define_insn_and_split "*anddi3_doubleword"
8859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8860         (and:DI
8861          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8862          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8863    (clobber (reg:CC FLAGS_REG))]
8864   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8865    && ix86_binary_operator_ok (AND, DImode, operands)"
8866   "#"
8867   "&& reload_completed"
8868   [(const_int 0)]
8870   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8871   if (operands[2] == const0_rtx)
8872     {
8873       operands[1] = const0_rtx;
8874       ix86_expand_move (SImode, &operands[0]);
8875     }
8876   else if (operands[2] != constm1_rtx)
8877     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8878   else if (operands[5] == constm1_rtx)
8879     emit_note (NOTE_INSN_DELETED);
8880   if (operands[5] == const0_rtx)
8881     {
8882       operands[4] = const0_rtx;
8883       ix86_expand_move (SImode, &operands[3]);
8884     }
8885   else if (operands[5] != constm1_rtx)
8886     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8887   DONE;
8890 (define_insn "*anddi_1"
8891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8892         (and:DI
8893          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895    (clobber (reg:CC FLAGS_REG))]
8896   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8897   "@
8898    and{l}\t{%k2, %k0|%k0, %k2}
8899    and{q}\t{%2, %0|%0, %2}
8900    and{q}\t{%2, %0|%0, %2}
8901    #"
8902   [(set_attr "type" "alu,alu,alu,imovx")
8903    (set_attr "length_immediate" "*,*,*,0")
8904    (set (attr "prefix_rex")
8905      (if_then_else
8906        (and (eq_attr "type" "imovx")
8907             (and (match_test "INTVAL (operands[2]) == 0xff")
8908                  (match_operand 1 "ext_QIreg_operand")))
8909        (const_string "1")
8910        (const_string "*")))
8911    (set_attr "mode" "SI,DI,DI,SI")])
8913 (define_insn_and_split "*anddi_1_btr"
8914   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8915         (and:DI
8916          (match_operand:DI 1 "nonimmediate_operand" "%0")
8917          (match_operand:DI 2 "const_int_operand" "n")))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && TARGET_USE_BT
8920    && ix86_binary_operator_ok (AND, DImode, operands)
8921    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8922   "#"
8923   "&& reload_completed"
8924   [(parallel [(set (zero_extract:DI (match_dup 0)
8925                                     (const_int 1)
8926                                     (match_dup 3))
8927                    (const_int 0))
8928               (clobber (reg:CC FLAGS_REG))])]
8929   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8930   [(set_attr "type" "alu1")
8931    (set_attr "prefix_0f" "1")
8932    (set_attr "znver1_decode" "double")
8933    (set_attr "mode" "DI")])
8935 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8936 (define_split
8937   [(set (match_operand:DI 0 "register_operand")
8938         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8939                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "TARGET_64BIT"
8942   [(parallel [(set (match_dup 0)
8943                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8944               (clobber (reg:CC FLAGS_REG))])]
8945   "operands[2] = gen_lowpart (SImode, operands[2]);")
8947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8948 (define_insn "*andsi_1_zext"
8949   [(set (match_operand:DI 0 "register_operand" "=r")
8950         (zero_extend:DI
8951           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8952                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8953    (clobber (reg:CC FLAGS_REG))]
8954   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8955   "and{l}\t{%2, %k0|%k0, %2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "mode" "SI")])
8959 (define_insn "*and<mode>_1"
8960   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8961         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8962                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8965   "@
8966    and{<imodesuffix>}\t{%2, %0|%0, %2}
8967    and{<imodesuffix>}\t{%2, %0|%0, %2}
8968    #"
8969   [(set_attr "type" "alu,alu,imovx")
8970    (set_attr "length_immediate" "*,*,0")
8971    (set (attr "prefix_rex")
8972      (if_then_else
8973        (and (eq_attr "type" "imovx")
8974             (and (match_test "INTVAL (operands[2]) == 0xff")
8975                  (match_operand 1 "ext_QIreg_operand")))
8976        (const_string "1")
8977        (const_string "*")))
8978    (set_attr "mode" "<MODE>,<MODE>,SI")])
8980 (define_insn "*andqi_1"
8981   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8982         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8983                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8984    (clobber (reg:CC FLAGS_REG))]
8985   "ix86_binary_operator_ok (AND, QImode, operands)"
8986   "@
8987    and{b}\t{%2, %0|%0, %2}
8988    and{b}\t{%2, %0|%0, %2}
8989    and{l}\t{%k2, %k0|%k0, %k2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "mode" "QI,QI,SI")
8992    ;; Potential partial reg stall on alternative 2.
8993    (set (attr "preferred_for_speed")
8994      (cond [(eq_attr "alternative" "2")
8995               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8996            (symbol_ref "true")))])
8998 (define_insn "*andqi_1_slp"
8999   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9000         (and:QI (match_dup 0)
9001                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9002    (clobber (reg:CC FLAGS_REG))]
9003   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9004    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9005   "and{b}\t{%1, %0|%0, %1}"
9006   [(set_attr "type" "alu1")
9007    (set_attr "mode" "QI")])
9009 (define_split
9010   [(set (match_operand:SWI248 0 "register_operand")
9011         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9012                     (match_operand:SWI248 2 "const_int_operand")))
9013    (clobber (reg:CC FLAGS_REG))]
9014   "reload_completed
9015    && (!REG_P (operands[1])
9016        || REGNO (operands[0]) != REGNO (operands[1]))"
9017   [(const_int 0)]
9019   HOST_WIDE_INT ival = INTVAL (operands[2]);
9020   machine_mode mode;
9021   rtx (*insn) (rtx, rtx);
9023   if (ival == (HOST_WIDE_INT) 0xffffffff)
9024     mode = SImode;
9025   else if (ival == 0xffff)
9026     mode = HImode;
9027   else
9028     {
9029       gcc_assert (ival == 0xff);
9030       mode = QImode;
9031     }
9033   if (<MODE>mode == DImode)
9034     insn = (mode == SImode)
9035            ? gen_zero_extendsidi2
9036            : (mode == HImode)
9037            ? gen_zero_extendhidi2
9038            : gen_zero_extendqidi2;
9039   else
9040     {
9041       if (<MODE>mode != SImode)
9042         /* Zero extend to SImode to avoid partial register stalls.  */
9043         operands[0] = gen_lowpart (SImode, operands[0]);
9045       insn = (mode == HImode)
9046              ? gen_zero_extendhisi2
9047              : gen_zero_extendqisi2;
9048     }
9049   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9050   DONE;
9053 (define_split
9054   [(set (match_operand:SWI48 0 "register_operand")
9055         (and:SWI48 (match_dup 0)
9056                    (const_int -65536)))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9059     || optimize_function_for_size_p (cfun)"
9060   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9061   "operands[1] = gen_lowpart (HImode, operands[0]);")
9063 (define_split
9064   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9065         (and:SWI248 (match_dup 0)
9066                     (const_int -256)))
9067    (clobber (reg:CC FLAGS_REG))]
9068   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9069    && reload_completed"
9070   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9071   "operands[1] = gen_lowpart (QImode, operands[0]);")
9073 (define_split
9074   [(set (match_operand:SWI248 0 "QIreg_operand")
9075         (and:SWI248 (match_dup 0)
9076                     (const_int -65281)))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9079    && reload_completed"
9080   [(parallel
9081      [(set (zero_extract:SI (match_dup 0)
9082                             (const_int 8)
9083                             (const_int 8))
9084            (subreg:SI
9085              (xor:QI
9086                (subreg:QI
9087                  (zero_extract:SI (match_dup 0)
9088                                   (const_int 8)
9089                                   (const_int 8)) 0)
9090                (subreg:QI
9091                  (zero_extract:SI (match_dup 0)
9092                                   (const_int 8)
9093                                   (const_int 8)) 0)) 0))
9094       (clobber (reg:CC FLAGS_REG))])]
9095   "operands[0] = gen_lowpart (SImode, operands[0]);")
9097 (define_insn "*anddi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare
9100          (and:DI
9101           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9102           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9103          (const_int 0)))
9104    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9105         (and:DI (match_dup 1) (match_dup 2)))]
9106   "TARGET_64BIT
9107    && ix86_match_ccmode
9108         (insn,
9109          /* If we are going to emit andl instead of andq, and the operands[2]
9110             constant might have the SImode sign bit set, make sure the sign
9111             flag isn't tested, because the instruction will set the sign flag
9112             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9113             conservatively assume it might have bit 31 set.  */
9114          (satisfies_constraint_Z (operands[2])
9115           && (!CONST_INT_P (operands[2])
9116               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9117          ? CCZmode : CCNOmode)
9118    && ix86_binary_operator_ok (AND, DImode, operands)"
9119   "@
9120    and{l}\t{%k2, %k0|%k0, %k2}
9121    and{q}\t{%2, %0|%0, %2}
9122    and{q}\t{%2, %0|%0, %2}"
9123   [(set_attr "type" "alu")
9124    (set_attr "mode" "SI,DI,DI")])
9126 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9127 (define_insn "*andsi_2_zext"
9128   [(set (reg FLAGS_REG)
9129         (compare (and:SI
9130                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9131                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
9132                  (const_int 0)))
9133    (set (match_operand:DI 0 "register_operand" "=r")
9134         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9135   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9136    && ix86_binary_operator_ok (AND, SImode, operands)"
9137   "and{l}\t{%2, %k0|%k0, %2}"
9138   [(set_attr "type" "alu")
9139    (set_attr "mode" "SI")])
9141 (define_insn "*andqi_2_maybe_si"
9142   [(set (reg FLAGS_REG)
9143         (compare (and:QI
9144                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9146                  (const_int 0)))
9147    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9148         (and:QI (match_dup 1) (match_dup 2)))]
9149   "ix86_binary_operator_ok (AND, QImode, operands)
9150    && ix86_match_ccmode (insn,
9151                          CONST_INT_P (operands[2])
9152                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9154   if (which_alternative == 2)
9155     {
9156       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9157         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9158       return "and{l}\t{%2, %k0|%k0, %2}";
9159     }
9160   return "and{b}\t{%2, %0|%0, %2}";
9162   [(set_attr "type" "alu")
9163    (set_attr "mode" "QI,QI,SI")])
9165 (define_insn "*and<mode>_2"
9166   [(set (reg FLAGS_REG)
9167         (compare (and:SWI124
9168                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9169                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9170                  (const_int 0)))
9171    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9172         (and:SWI124 (match_dup 1) (match_dup 2)))]
9173   "ix86_match_ccmode (insn, CCNOmode)
9174    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9175   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9176   [(set_attr "type" "alu")
9177    (set_attr "mode" "<MODE>")])
9179 (define_insn "*andqi_2_slp"
9180   [(set (reg FLAGS_REG)
9181         (compare (and:QI
9182                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9183                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9184                  (const_int 0)))
9185    (set (strict_low_part (match_dup 0))
9186         (and:QI (match_dup 0) (match_dup 1)))]
9187   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9188    && ix86_match_ccmode (insn, CCNOmode)
9189    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9190   "and{b}\t{%1, %0|%0, %1}"
9191   [(set_attr "type" "alu1")
9192    (set_attr "mode" "QI")])
9194 (define_insn "andqi_ext_1"
9195   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9196                          (const_int 8)
9197                          (const_int 8))
9198         (subreg:SI
9199           (and:QI
9200             (subreg:QI
9201               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9202                                (const_int 8)
9203                                (const_int 8)) 0)
9204             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9207    rtx_equal_p (operands[0], operands[1])"
9208   "and{b}\t{%2, %h0|%h0, %2}"
9209   [(set_attr "isa" "*,nox64")
9210    (set_attr "type" "alu")
9211    (set_attr "mode" "QI")])
9213 ;; Generated by peephole translating test to and.  This shows up
9214 ;; often in fp comparisons.
9215 (define_insn "*andqi_ext_1_cc"
9216   [(set (reg FLAGS_REG)
9217         (compare
9218           (and:QI
9219             (subreg:QI
9220               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9221                                (const_int 8)
9222                                (const_int 8)) 0)
9223             (match_operand:QI 2 "general_operand" "QnBc,m"))
9224           (const_int 0)))
9225    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9226                          (const_int 8)
9227                          (const_int 8))
9228         (subreg:SI
9229           (and:QI
9230             (subreg:QI
9231               (zero_extract:SI (match_dup 1)
9232                                (const_int 8)
9233                                (const_int 8)) 0)
9234             (match_dup 2)) 0))]
9235   "ix86_match_ccmode (insn, CCNOmode)
9236    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9237    && rtx_equal_p (operands[0], operands[1])"
9238   "and{b}\t{%2, %h0|%h0, %2}"
9239   [(set_attr "isa" "*,nox64")
9240    (set_attr "type" "alu")
9241    (set_attr "mode" "QI")])
9243 (define_insn "*andqi_ext_2"
9244   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9245                          (const_int 8)
9246                          (const_int 8))
9247         (subreg:SI
9248           (and:QI
9249             (subreg:QI
9250               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9251                                (const_int 8)
9252                                (const_int 8)) 0)
9253             (subreg:QI
9254               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9255                                (const_int 8)
9256                                (const_int 8)) 0)) 0))
9257    (clobber (reg:CC FLAGS_REG))]
9258   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9259    rtx_equal_p (operands[0], operands[1])
9260    || rtx_equal_p (operands[0], operands[2])"
9261   "and{b}\t{%h2, %h0|%h0, %h2}"
9262   [(set_attr "type" "alu")
9263    (set_attr "mode" "QI")])
9265 ;; Convert wide AND instructions with immediate operand to shorter QImode
9266 ;; equivalents when possible.
9267 ;; Don't do the splitting with memory operands, since it introduces risk
9268 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9269 ;; for size, but that can (should?) be handled by generic code instead.
9270 (define_split
9271   [(set (match_operand:SWI248 0 "QIreg_operand")
9272         (and:SWI248 (match_operand:SWI248 1 "register_operand")
9273                     (match_operand:SWI248 2 "const_int_operand")))
9274    (clobber (reg:CC FLAGS_REG))]
9275    "reload_completed
9276     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9277     && !(~INTVAL (operands[2]) & ~(255 << 8))"
9278   [(parallel
9279      [(set (zero_extract:SI (match_dup 0)
9280                             (const_int 8)
9281                             (const_int 8))
9282            (subreg:SI
9283              (and:QI
9284                (subreg:QI
9285                  (zero_extract:SI (match_dup 1)
9286                                   (const_int 8)
9287                                   (const_int 8)) 0)
9288                (match_dup 2)) 0))
9289       (clobber (reg:CC FLAGS_REG))])]
9291   operands[0] = gen_lowpart (SImode, operands[0]);
9292   operands[1] = gen_lowpart (SImode, operands[1]);
9293   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9296 ;; Since AND can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is not set.
9298 (define_split
9299   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9300         (and:SWI248 (match_operand:SWI248 1 "general_operand")
9301                     (match_operand:SWI248 2 "const_int_operand")))
9302    (clobber (reg:CC FLAGS_REG))]
9303    "reload_completed
9304     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9305     && !(~INTVAL (operands[2]) & ~255)
9306     && !(INTVAL (operands[2]) & 128)"
9307   [(parallel [(set (strict_low_part (match_dup 0))
9308                    (and:QI (match_dup 1)
9309                            (match_dup 2)))
9310               (clobber (reg:CC FLAGS_REG))])]
9312   operands[0] = gen_lowpart (QImode, operands[0]);
9313   operands[1] = gen_lowpart (QImode, operands[1]);
9314   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9317 (define_insn "*andndi3_doubleword"
9318   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9319         (and:DI
9320           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9321           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9322    (clobber (reg:CC FLAGS_REG))]
9323   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9324   "#"
9325   [(set_attr "isa" "bmi,bmi,bmi,*")])
9327 (define_split
9328   [(set (match_operand:DI 0 "register_operand")
9329         (and:DI
9330           (not:DI (match_operand:DI 1 "register_operand"))
9331           (match_operand:DI 2 "nonimmediate_operand")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9334    && reload_completed"
9335   [(parallel [(set (match_dup 0)
9336                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9337               (clobber (reg:CC FLAGS_REG))])
9338    (parallel [(set (match_dup 3)
9339                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9340               (clobber (reg:CC FLAGS_REG))])]
9341   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9343 (define_split
9344   [(set (match_operand:DI 0 "register_operand")
9345         (and:DI
9346           (not:DI (match_dup 0))
9347           (match_operand:DI 1 "nonimmediate_operand")))
9348    (clobber (reg:CC FLAGS_REG))]
9349   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9350    && reload_completed"
9351   [(set (match_dup 0) (not:SI (match_dup 0)))
9352    (parallel [(set (match_dup 0)
9353                    (and:SI (match_dup 0) (match_dup 1)))
9354               (clobber (reg:CC FLAGS_REG))])
9355    (set (match_dup 2) (not:SI (match_dup 2)))
9356    (parallel [(set (match_dup 2)
9357                    (and:SI (match_dup 2) (match_dup 3)))
9358               (clobber (reg:CC FLAGS_REG))])]
9359   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9361 (define_insn "*andn<mode>_1"
9362   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9363         (and:SWI48
9364           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9365           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9366    (clobber (reg:CC FLAGS_REG))]
9367   "TARGET_BMI"
9368   "andn\t{%2, %1, %0|%0, %1, %2}"
9369   [(set_attr "type" "bitmanip")
9370    (set_attr "btver2_decode" "direct, double")
9371    (set_attr "mode" "<MODE>")])
9373 (define_insn "*andn<mode>_1"
9374   [(set (match_operand:SWI12 0 "register_operand" "=r")
9375         (and:SWI12
9376           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9377           (match_operand:SWI12 2 "register_operand" "r")))
9378    (clobber (reg:CC FLAGS_REG))]
9379   "TARGET_BMI"
9380   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9381   [(set_attr "type" "bitmanip")
9382    (set_attr "btver2_decode" "direct")
9383    (set_attr "mode" "SI")])
9385 (define_insn "*andn_<mode>_ccno"
9386   [(set (reg FLAGS_REG)
9387         (compare
9388           (and:SWI48
9389             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9390             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9391           (const_int 0)))
9392    (clobber (match_scratch:SWI48 0 "=r,r"))]
9393   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9394   "andn\t{%2, %1, %0|%0, %1, %2}"
9395   [(set_attr "type" "bitmanip")
9396    (set_attr "btver2_decode" "direct, double")
9397    (set_attr "mode" "<MODE>")])
9399 ;; Logical inclusive and exclusive OR instructions
9401 ;; %%% This used to optimize known byte-wide and operations to memory.
9402 ;; If this is considered useful, it should be done with splitters.
9404 (define_expand "<code><mode>3"
9405   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9406         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9407                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9408   ""
9409   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9411 (define_insn_and_split "*<code>di3_doubleword"
9412   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9413         (any_or:DI
9414          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9415          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9416    (clobber (reg:CC FLAGS_REG))]
9417   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9418    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9419   "#"
9420   "&& reload_completed"
9421   [(const_int 0)]
9423   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9424   if (operands[2] == constm1_rtx)
9425     {
9426       if (<CODE> == IOR)
9427         {
9428           operands[1] = constm1_rtx;
9429           ix86_expand_move (SImode, &operands[0]);
9430         }
9431       else
9432         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9433     }
9434   else if (operands[2] != const0_rtx)
9435     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9436   else if (operands[5] == const0_rtx)
9437     emit_note (NOTE_INSN_DELETED);
9438   if (operands[5] == constm1_rtx)
9439     {
9440       if (<CODE> == IOR)
9441         {
9442           operands[4] = constm1_rtx;
9443           ix86_expand_move (SImode, &operands[3]);
9444         }
9445       else
9446         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9447     }
9448   else if (operands[5] != const0_rtx)
9449     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9450   DONE;
9453 (define_insn "*<code><mode>_1"
9454   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9455         (any_or:SWI248
9456          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9457          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9458    (clobber (reg:CC FLAGS_REG))]
9459   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9460   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9461   [(set_attr "type" "alu")
9462    (set_attr "mode" "<MODE>")])
9464 (define_insn_and_split "*iordi_1_bts"
9465   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9466         (ior:DI
9467          (match_operand:DI 1 "nonimmediate_operand" "%0")
9468          (match_operand:DI 2 "const_int_operand" "n")))
9469    (clobber (reg:CC FLAGS_REG))]
9470   "TARGET_64BIT && TARGET_USE_BT
9471    && ix86_binary_operator_ok (IOR, DImode, operands)
9472    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9473   "#"
9474   "&& reload_completed"
9475   [(parallel [(set (zero_extract:DI (match_dup 0)
9476                                     (const_int 1)
9477                                     (match_dup 3))
9478                    (const_int 1))
9479               (clobber (reg:CC FLAGS_REG))])]
9480   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9481   [(set_attr "type" "alu1")
9482    (set_attr "prefix_0f" "1")
9483    (set_attr "znver1_decode" "double")
9484    (set_attr "mode" "DI")])
9486 (define_insn_and_split "*xordi_1_btc"
9487   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9488         (xor:DI
9489          (match_operand:DI 1 "nonimmediate_operand" "%0")
9490          (match_operand:DI 2 "const_int_operand" "n")))
9491    (clobber (reg:CC FLAGS_REG))]
9492   "TARGET_64BIT && TARGET_USE_BT
9493    && ix86_binary_operator_ok (XOR, DImode, operands)
9494    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9495   "#"
9496   "&& reload_completed"
9497   [(parallel [(set (zero_extract:DI (match_dup 0)
9498                                     (const_int 1)
9499                                     (match_dup 3))
9500                    (not:DI (zero_extract:DI (match_dup 0)
9501                                             (const_int 1)
9502                                             (match_dup 3))))
9503               (clobber (reg:CC FLAGS_REG))])]
9504   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9505   [(set_attr "type" "alu1")
9506    (set_attr "prefix_0f" "1")
9507    (set_attr "znver1_decode" "double")
9508    (set_attr "mode" "DI")])
9510 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9511 (define_insn "*<code>si_1_zext"
9512   [(set (match_operand:DI 0 "register_operand" "=r")
9513         (zero_extend:DI
9514          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9515                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9518   "<logic>{l}\t{%2, %k0|%k0, %2}"
9519   [(set_attr "type" "alu")
9520    (set_attr "mode" "SI")])
9522 (define_insn "*<code>si_1_zext_imm"
9523   [(set (match_operand:DI 0 "register_operand" "=r")
9524         (any_or:DI
9525          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9526          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9527    (clobber (reg:CC FLAGS_REG))]
9528   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9529   "<logic>{l}\t{%2, %k0|%k0, %2}"
9530   [(set_attr "type" "alu")
9531    (set_attr "mode" "SI")])
9533 (define_insn "*<code>qi_1"
9534   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9535         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9536                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9537    (clobber (reg:CC FLAGS_REG))]
9538   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9539   "@
9540    <logic>{b}\t{%2, %0|%0, %2}
9541    <logic>{b}\t{%2, %0|%0, %2}
9542    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9543   [(set_attr "type" "alu")
9544    (set_attr "mode" "QI,QI,SI")
9545    ;; Potential partial reg stall on alternative 2.
9546    (set (attr "preferred_for_speed")
9547      (cond [(eq_attr "alternative" "2")
9548               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9549            (symbol_ref "true")))])
9551 (define_insn "*<code>qi_1_slp"
9552   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9553         (any_or:QI (match_dup 0)
9554                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9555    (clobber (reg:CC FLAGS_REG))]
9556   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9557    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9558   "<logic>{b}\t{%1, %0|%0, %1}"
9559   [(set_attr "type" "alu1")
9560    (set_attr "mode" "QI")])
9562 (define_insn "*<code><mode>_2"
9563   [(set (reg FLAGS_REG)
9564         (compare (any_or:SWI
9565                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9566                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9567                  (const_int 0)))
9568    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9569         (any_or:SWI (match_dup 1) (match_dup 2)))]
9570   "ix86_match_ccmode (insn, CCNOmode)
9571    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9572   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9573   [(set_attr "type" "alu")
9574    (set_attr "mode" "<MODE>")])
9576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9577 ;; ??? Special case for immediate operand is missing - it is tricky.
9578 (define_insn "*<code>si_2_zext"
9579   [(set (reg FLAGS_REG)
9580         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9581                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9582                  (const_int 0)))
9583    (set (match_operand:DI 0 "register_operand" "=r")
9584         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9585   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9586    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9587   "<logic>{l}\t{%2, %k0|%k0, %2}"
9588   [(set_attr "type" "alu")
9589    (set_attr "mode" "SI")])
9591 (define_insn "*<code>si_2_zext_imm"
9592   [(set (reg FLAGS_REG)
9593         (compare (any_or:SI
9594                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9595                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9596                  (const_int 0)))
9597    (set (match_operand:DI 0 "register_operand" "=r")
9598         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9599   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9600    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9601   "<logic>{l}\t{%2, %k0|%k0, %2}"
9602   [(set_attr "type" "alu")
9603    (set_attr "mode" "SI")])
9605 (define_insn "*<code>qi_2_slp"
9606   [(set (reg FLAGS_REG)
9607         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9608                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9609                  (const_int 0)))
9610    (set (strict_low_part (match_dup 0))
9611         (any_or:QI (match_dup 0) (match_dup 1)))]
9612   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9613    && ix86_match_ccmode (insn, CCNOmode)
9614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9615   "<logic>{b}\t{%1, %0|%0, %1}"
9616   [(set_attr "type" "alu1")
9617    (set_attr "mode" "QI")])
9619 (define_insn "*<code><mode>_3"
9620   [(set (reg FLAGS_REG)
9621         (compare (any_or:SWI
9622                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9623                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9624                  (const_int 0)))
9625    (clobber (match_scratch:SWI 0 "=<r>"))]
9626   "ix86_match_ccmode (insn, CCNOmode)
9627    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9628   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9629   [(set_attr "type" "alu")
9630    (set_attr "mode" "<MODE>")])
9632 (define_insn "*<code>qi_ext_1"
9633   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9634                          (const_int 8)
9635                          (const_int 8))
9636         (subreg:SI
9637           (any_or:QI
9638             (subreg:QI
9639               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9640                                (const_int 8)
9641                                (const_int 8)) 0)
9642             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9645    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9646    && rtx_equal_p (operands[0], operands[1])"
9647   "<logic>{b}\t{%2, %h0|%h0, %2}"
9648   [(set_attr "isa" "*,nox64")
9649    (set_attr "type" "alu")
9650    (set_attr "mode" "QI")])
9652 (define_insn "*<code>qi_ext_2"
9653   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9654                          (const_int 8)
9655                          (const_int 8))
9656         (subreg:SI
9657           (any_or:QI
9658             (subreg:QI
9659               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9660                                (const_int 8)
9661                                (const_int 8)) 0)
9662             (subreg:QI
9663               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9664                                (const_int 8)
9665                                (const_int 8)) 0)) 0))
9666    (clobber (reg:CC FLAGS_REG))]
9667   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9668    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9669    && (rtx_equal_p (operands[0], operands[1])
9670        || rtx_equal_p (operands[0], operands[2]))"
9671   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9672   [(set_attr "type" "alu")
9673    (set_attr "mode" "QI")])
9675 ;; Convert wide OR instructions with immediate operand to shorter QImode
9676 ;; equivalents when possible.
9677 ;; Don't do the splitting with memory operands, since it introduces risk
9678 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9679 ;; for size, but that can (should?) be handled by generic code instead.
9680 (define_split
9681   [(set (match_operand:SWI248 0 "QIreg_operand")
9682         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9683                        (match_operand:SWI248 2 "const_int_operand")))
9684    (clobber (reg:CC FLAGS_REG))]
9685    "reload_completed
9686     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9687     && !(INTVAL (operands[2]) & ~(255 << 8))"
9688   [(parallel
9689      [(set (zero_extract:SI (match_dup 0)
9690                             (const_int 8)
9691                             (const_int 8))
9692            (subreg:SI
9693              (any_or:QI
9694                (subreg:QI
9695                  (zero_extract:SI (match_dup 1)
9696                                   (const_int 8)
9697                                   (const_int 8)) 0)
9698                (match_dup 2)) 0))
9699       (clobber (reg:CC FLAGS_REG))])]
9701   operands[0] = gen_lowpart (SImode, operands[0]);
9702   operands[1] = gen_lowpart (SImode, operands[1]);
9703   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9706 ;; Since OR can be encoded with sign extended immediate, this is only
9707 ;; profitable when 7th bit is set.
9708 (define_split
9709   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9710         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9711                        (match_operand:SWI248 2 "const_int_operand")))
9712    (clobber (reg:CC FLAGS_REG))]
9713    "reload_completed
9714     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9715     && !(INTVAL (operands[2]) & ~255)
9716     && (INTVAL (operands[2]) & 128)"
9717   [(parallel [(set (strict_low_part (match_dup 0))
9718                    (any_or:QI (match_dup 1)
9719                               (match_dup 2)))
9720               (clobber (reg:CC FLAGS_REG))])]
9722   operands[0] = gen_lowpart (QImode, operands[0]);
9723   operands[1] = gen_lowpart (QImode, operands[1]);
9724   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9727 (define_expand "xorqi_ext_1_cc"
9728   [(parallel [
9729      (set (reg:CCNO FLAGS_REG)
9730           (compare:CCNO
9731             (xor:QI
9732               (subreg:QI
9733                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9734                                  (const_int 8)
9735                                  (const_int 8)) 0)
9736               (match_operand 2 "const_int_operand"))
9737             (const_int 0)))
9738      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9739                            (const_int 8)
9740                            (const_int 8))
9741           (subreg:SI
9742             (xor:QI
9743               (subreg:QI
9744                 (zero_extract:SI (match_dup 1)
9745                                  (const_int 8)
9746                                  (const_int 8)) 0)
9747             (match_dup 2)) 0))])])
9749 (define_insn "*xorqi_ext_1_cc"
9750   [(set (reg FLAGS_REG)
9751         (compare
9752           (xor:QI
9753             (subreg:QI
9754               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9755                                (const_int 8)
9756                                (const_int 8)) 0)
9757             (match_operand:QI 2 "general_operand" "QnBc,m"))
9758           (const_int 0)))
9759    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9760                          (const_int 8)
9761                          (const_int 8))
9762         (subreg:SI
9763           (xor:QI
9764             (subreg:QI
9765               (zero_extract:SI (match_dup 1)
9766                                (const_int 8)
9767                                (const_int 8)) 0)
9768           (match_dup 2)) 0))]
9769   "ix86_match_ccmode (insn, CCNOmode)
9770    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9771    && rtx_equal_p (operands[0], operands[1])"
9772   "xor{b}\t{%2, %h0|%h0, %2}"
9773   [(set_attr "isa" "*,nox64")
9774    (set_attr "type" "alu")
9775    (set_attr "mode" "QI")])
9777 ;; Negation instructions
9779 (define_expand "neg<mode>2"
9780   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9781         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9782   ""
9783   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9785 (define_insn_and_split "*neg<dwi>2_doubleword"
9786   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9787         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9788    (clobber (reg:CC FLAGS_REG))]
9789   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9790   "#"
9791   "reload_completed"
9792   [(parallel
9793     [(set (reg:CCZ FLAGS_REG)
9794           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9795      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9796    (parallel
9797     [(set (match_dup 2)
9798           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9799                                 (match_dup 3))
9800                      (const_int 0)))
9801      (clobber (reg:CC FLAGS_REG))])
9802    (parallel
9803     [(set (match_dup 2)
9804           (neg:DWIH (match_dup 2)))
9805      (clobber (reg:CC FLAGS_REG))])]
9806   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9808 (define_insn "*neg<mode>2_1"
9809   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9810         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9811    (clobber (reg:CC FLAGS_REG))]
9812   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9813   "neg{<imodesuffix>}\t%0"
9814   [(set_attr "type" "negnot")
9815    (set_attr "mode" "<MODE>")])
9817 ;; Combine is quite creative about this pattern.
9818 (define_insn "*negsi2_1_zext"
9819   [(set (match_operand:DI 0 "register_operand" "=r")
9820         (lshiftrt:DI
9821           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9822                              (const_int 32)))
9823         (const_int 32)))
9824    (clobber (reg:CC FLAGS_REG))]
9825   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9826   "neg{l}\t%k0"
9827   [(set_attr "type" "negnot")
9828    (set_attr "mode" "SI")])
9830 ;; The problem with neg is that it does not perform (compare x 0),
9831 ;; it really performs (compare 0 x), which leaves us with the zero
9832 ;; flag being the only useful item.
9834 (define_insn "*neg<mode>2_cmpz"
9835   [(set (reg:CCZ FLAGS_REG)
9836         (compare:CCZ
9837           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9838                    (const_int 0)))
9839    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9840         (neg:SWI (match_dup 1)))]
9841   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9842   "neg{<imodesuffix>}\t%0"
9843   [(set_attr "type" "negnot")
9844    (set_attr "mode" "<MODE>")])
9846 (define_insn "*negsi2_cmpz_zext"
9847   [(set (reg:CCZ FLAGS_REG)
9848         (compare:CCZ
9849           (lshiftrt:DI
9850             (neg:DI (ashift:DI
9851                       (match_operand:DI 1 "register_operand" "0")
9852                       (const_int 32)))
9853             (const_int 32))
9854           (const_int 0)))
9855    (set (match_operand:DI 0 "register_operand" "=r")
9856         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9857                                         (const_int 32)))
9858                      (const_int 32)))]
9859   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9860   "neg{l}\t%k0"
9861   [(set_attr "type" "negnot")
9862    (set_attr "mode" "SI")])
9864 ;; Negate with jump on overflow.
9865 (define_expand "negv<mode>3"
9866   [(parallel [(set (reg:CCO FLAGS_REG)
9867                    (ne:CCO (match_operand:SWI 1 "register_operand")
9868                            (match_dup 3)))
9869               (set (match_operand:SWI 0 "register_operand")
9870                    (neg:SWI (match_dup 1)))])
9871    (set (pc) (if_then_else
9872                (eq (reg:CCO FLAGS_REG) (const_int 0))
9873                (label_ref (match_operand 2))
9874                (pc)))]
9875   ""
9877   operands[3]
9878     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9879                     <MODE>mode);
9882 (define_insn "*negv<mode>3"
9883   [(set (reg:CCO FLAGS_REG)
9884         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9885                 (match_operand:SWI 2 "const_int_operand")))
9886    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9887         (neg:SWI (match_dup 1)))]
9888   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9889    && mode_signbit_p (<MODE>mode, operands[2])"
9890   "neg{<imodesuffix>}\t%0"
9891   [(set_attr "type" "negnot")
9892    (set_attr "mode" "<MODE>")])
9894 ;; Changing of sign for FP values is doable using integer unit too.
9896 (define_expand "<code><mode>2"
9897   [(set (match_operand:X87MODEF 0 "register_operand")
9898         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9899   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9900   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9902 (define_insn "*absneg<mode>2"
9903   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9904         (match_operator:MODEF 3 "absneg_operator"
9905           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9906    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9907    (clobber (reg:CC FLAGS_REG))]
9908   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9909   "#"
9910   [(set (attr "enabled")
9911      (if_then_else
9912        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9913        (if_then_else
9914          (eq_attr "alternative" "2")
9915          (symbol_ref "TARGET_MIX_SSE_I387")
9916          (symbol_ref "true"))
9917        (if_then_else
9918          (eq_attr "alternative" "2,3")
9919          (symbol_ref "true")
9920          (symbol_ref "false"))))])
9922 (define_insn "*absnegxf2_i387"
9923   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9924         (match_operator:XF 3 "absneg_operator"
9925           [(match_operand:XF 1 "register_operand" "0,0")]))
9926    (use (match_operand 2))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "TARGET_80387"
9929   "#")
9931 (define_expand "<code>tf2"
9932   [(set (match_operand:TF 0 "register_operand")
9933         (absneg:TF (match_operand:TF 1 "register_operand")))]
9934   "TARGET_SSE"
9935   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9937 (define_insn "*absnegtf2_sse"
9938   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9939         (match_operator:TF 3 "absneg_operator"
9940           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9941    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9942    (clobber (reg:CC FLAGS_REG))]
9943   "TARGET_SSE"
9944   "#")
9946 ;; Splitters for fp abs and neg.
9948 (define_split
9949   [(set (match_operand 0 "fp_register_operand")
9950         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9951    (use (match_operand 2))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "reload_completed"
9954   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9956 (define_split
9957   [(set (match_operand 0 "sse_reg_operand")
9958         (match_operator 3 "absneg_operator"
9959           [(match_operand 1 "register_operand")]))
9960    (use (match_operand 2 "nonimmediate_operand"))
9961    (clobber (reg:CC FLAGS_REG))]
9962   "reload_completed"
9963   [(set (match_dup 0) (match_dup 3))]
9965   machine_mode mode = GET_MODE (operands[0]);
9966   machine_mode vmode = GET_MODE (operands[2]);
9967   rtx tmp;
9969   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9970   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9971   if (operands_match_p (operands[0], operands[2]))
9972     std::swap (operands[1], operands[2]);
9973   if (GET_CODE (operands[3]) == ABS)
9974     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9975   else
9976     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9977   operands[3] = tmp;
9980 (define_split
9981   [(set (match_operand:SF 0 "general_reg_operand")
9982         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9983    (use (match_operand:V4SF 2))
9984    (clobber (reg:CC FLAGS_REG))]
9985   "reload_completed"
9986   [(parallel [(set (match_dup 0) (match_dup 1))
9987               (clobber (reg:CC FLAGS_REG))])]
9989   rtx tmp;
9990   operands[0] = gen_lowpart (SImode, operands[0]);
9991   if (GET_CODE (operands[1]) == ABS)
9992     {
9993       tmp = gen_int_mode (0x7fffffff, SImode);
9994       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9995     }
9996   else
9997     {
9998       tmp = gen_int_mode (0x80000000, SImode);
9999       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10000     }
10001   operands[1] = tmp;
10004 (define_split
10005   [(set (match_operand:DF 0 "general_reg_operand")
10006         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10007    (use (match_operand 2))
10008    (clobber (reg:CC FLAGS_REG))]
10009   "reload_completed"
10010   [(parallel [(set (match_dup 0) (match_dup 1))
10011               (clobber (reg:CC FLAGS_REG))])]
10013   rtx tmp;
10014   if (TARGET_64BIT)
10015     {
10016       tmp = gen_lowpart (DImode, operands[0]);
10017       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10018       operands[0] = tmp;
10020       if (GET_CODE (operands[1]) == ABS)
10021         tmp = const0_rtx;
10022       else
10023         tmp = gen_rtx_NOT (DImode, tmp);
10024     }
10025   else
10026     {
10027       operands[0] = gen_highpart (SImode, operands[0]);
10028       if (GET_CODE (operands[1]) == ABS)
10029         {
10030           tmp = gen_int_mode (0x7fffffff, SImode);
10031           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10032         }
10033       else
10034         {
10035           tmp = gen_int_mode (0x80000000, SImode);
10036           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10037         }
10038     }
10039   operands[1] = tmp;
10042 (define_split
10043   [(set (match_operand:XF 0 "general_reg_operand")
10044         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10045    (use (match_operand 2))
10046    (clobber (reg:CC FLAGS_REG))]
10047   "reload_completed"
10048   [(parallel [(set (match_dup 0) (match_dup 1))
10049               (clobber (reg:CC FLAGS_REG))])]
10051   rtx tmp;
10052   operands[0] = gen_rtx_REG (SImode,
10053                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10054   if (GET_CODE (operands[1]) == ABS)
10055     {
10056       tmp = GEN_INT (0x7fff);
10057       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10058     }
10059   else
10060     {
10061       tmp = GEN_INT (0x8000);
10062       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10063     }
10064   operands[1] = tmp;
10067 ;; Conditionalize these after reload. If they match before reload, we
10068 ;; lose the clobber and ability to use integer instructions.
10070 (define_insn "*<code><mode>2_1"
10071   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10072         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10073   "TARGET_80387
10074    && (reload_completed
10075        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10076   "f<absneg_mnemonic>"
10077   [(set_attr "type" "fsgn")
10078    (set_attr "mode" "<MODE>")])
10080 (define_insn "*<code>extendsfdf2"
10081   [(set (match_operand:DF 0 "register_operand" "=f")
10082         (absneg:DF (float_extend:DF
10083                      (match_operand:SF 1 "register_operand" "0"))))]
10084   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10085   "f<absneg_mnemonic>"
10086   [(set_attr "type" "fsgn")
10087    (set_attr "mode" "DF")])
10089 (define_insn "*<code>extendsfxf2"
10090   [(set (match_operand:XF 0 "register_operand" "=f")
10091         (absneg:XF (float_extend:XF
10092                      (match_operand:SF 1 "register_operand" "0"))))]
10093   "TARGET_80387"
10094   "f<absneg_mnemonic>"
10095   [(set_attr "type" "fsgn")
10096    (set_attr "mode" "XF")])
10098 (define_insn "*<code>extenddfxf2"
10099   [(set (match_operand:XF 0 "register_operand" "=f")
10100         (absneg:XF (float_extend:XF
10101                      (match_operand:DF 1 "register_operand" "0"))))]
10102   "TARGET_80387"
10103   "f<absneg_mnemonic>"
10104   [(set_attr "type" "fsgn")
10105    (set_attr "mode" "XF")])
10107 ;; Copysign instructions
10109 (define_mode_iterator CSGNMODE [SF DF TF])
10110 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10112 (define_expand "copysign<mode>3"
10113   [(match_operand:CSGNMODE 0 "register_operand")
10114    (match_operand:CSGNMODE 1 "nonmemory_operand")
10115    (match_operand:CSGNMODE 2 "register_operand")]
10116   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10117    || (TARGET_SSE && (<MODE>mode == TFmode))"
10118   "ix86_expand_copysign (operands); DONE;")
10120 (define_insn_and_split "copysign<mode>3_const"
10121   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10122         (unspec:CSGNMODE
10123           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10124            (match_operand:CSGNMODE 2 "register_operand" "0")
10125            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10126           UNSPEC_COPYSIGN))]
10127   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10128    || (TARGET_SSE && (<MODE>mode == TFmode))"
10129   "#"
10130   "&& reload_completed"
10131   [(const_int 0)]
10132   "ix86_split_copysign_const (operands); DONE;")
10134 (define_insn "copysign<mode>3_var"
10135   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10136         (unspec:CSGNMODE
10137           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10138            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10139            (match_operand:<CSGNVMODE> 4
10140              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10141            (match_operand:<CSGNVMODE> 5
10142              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10143           UNSPEC_COPYSIGN))
10144    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10145   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10146    || (TARGET_SSE && (<MODE>mode == TFmode))"
10147   "#")
10149 (define_split
10150   [(set (match_operand:CSGNMODE 0 "register_operand")
10151         (unspec:CSGNMODE
10152           [(match_operand:CSGNMODE 2 "register_operand")
10153            (match_operand:CSGNMODE 3 "register_operand")
10154            (match_operand:<CSGNVMODE> 4)
10155            (match_operand:<CSGNVMODE> 5)]
10156           UNSPEC_COPYSIGN))
10157    (clobber (match_scratch:<CSGNVMODE> 1))]
10158   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10159     || (TARGET_SSE && (<MODE>mode == TFmode)))
10160    && reload_completed"
10161   [(const_int 0)]
10162   "ix86_split_copysign_var (operands); DONE;")
10164 ;; One complement instructions
10166 (define_expand "one_cmpl<mode>2"
10167   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10168         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10169   ""
10170   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10172 (define_insn_and_split "*one_cmpldi2_doubleword"
10173   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10174         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10175   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10176    && ix86_unary_operator_ok (NOT, DImode, operands)"
10177   "#"
10178   "&& reload_completed"
10179   [(set (match_dup 0)
10180         (not:SI (match_dup 1)))
10181    (set (match_dup 2)
10182         (not:SI (match_dup 3)))]
10183   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10185 (define_insn "*one_cmpl<mode>2_1"
10186   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10187         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10188   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10189   "not{<imodesuffix>}\t%0"
10190   [(set_attr "type" "negnot")
10191    (set_attr "mode" "<MODE>")])
10193 ;; ??? Currently never generated - xor is used instead.
10194 (define_insn "*one_cmplsi2_1_zext"
10195   [(set (match_operand:DI 0 "register_operand" "=r")
10196         (zero_extend:DI
10197           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10198   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10199   "not{l}\t%k0"
10200   [(set_attr "type" "negnot")
10201    (set_attr "mode" "SI")])
10203 (define_insn "*one_cmplqi2_1"
10204   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10205         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10206   "ix86_unary_operator_ok (NOT, QImode, operands)"
10207   "@
10208    not{b}\t%0
10209    not{l}\t%k0"
10210   [(set_attr "type" "negnot")
10211    (set_attr "mode" "QI,SI")
10212    ;; Potential partial reg stall on alternative 1.
10213    (set (attr "preferred_for_speed")
10214      (cond [(eq_attr "alternative" "1")
10215               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10216            (symbol_ref "true")))])
10218 (define_insn "*one_cmpl<mode>2_2"
10219   [(set (reg FLAGS_REG)
10220         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10221                  (const_int 0)))
10222    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10223         (not:SWI (match_dup 1)))]
10224   "ix86_match_ccmode (insn, CCNOmode)
10225    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10226   "#"
10227   [(set_attr "type" "alu1")
10228    (set_attr "mode" "<MODE>")])
10230 (define_split
10231   [(set (match_operand 0 "flags_reg_operand")
10232         (match_operator 2 "compare_operator"
10233           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10234            (const_int 0)]))
10235    (set (match_operand:SWI 1 "nonimmediate_operand")
10236         (not:SWI (match_dup 3)))]
10237   "ix86_match_ccmode (insn, CCNOmode)"
10238   [(parallel [(set (match_dup 0)
10239                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10240                                     (const_int 0)]))
10241               (set (match_dup 1)
10242                    (xor:SWI (match_dup 3) (const_int -1)))])])
10244 ;; ??? Currently never generated - xor is used instead.
10245 (define_insn "*one_cmplsi2_2_zext"
10246   [(set (reg FLAGS_REG)
10247         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10248                  (const_int 0)))
10249    (set (match_operand:DI 0 "register_operand" "=r")
10250         (zero_extend:DI (not:SI (match_dup 1))))]
10251   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10252    && ix86_unary_operator_ok (NOT, SImode, operands)"
10253   "#"
10254   [(set_attr "type" "alu1")
10255    (set_attr "mode" "SI")])
10257 (define_split
10258   [(set (match_operand 0 "flags_reg_operand")
10259         (match_operator 2 "compare_operator"
10260           [(not:SI (match_operand:SI 3 "register_operand"))
10261            (const_int 0)]))
10262    (set (match_operand:DI 1 "register_operand")
10263         (zero_extend:DI (not:SI (match_dup 3))))]
10264   "ix86_match_ccmode (insn, CCNOmode)"
10265   [(parallel [(set (match_dup 0)
10266                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10267                                     (const_int 0)]))
10268               (set (match_dup 1)
10269                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10271 ;; Shift instructions
10273 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10274 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10275 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10276 ;; from the assembler input.
10278 ;; This instruction shifts the target reg/mem as usual, but instead of
10279 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10280 ;; is a left shift double, bits are taken from the high order bits of
10281 ;; reg, else if the insn is a shift right double, bits are taken from the
10282 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10283 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10285 ;; Since sh[lr]d does not change the `reg' operand, that is done
10286 ;; separately, making all shifts emit pairs of shift double and normal
10287 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10288 ;; support a 63 bit shift, each shift where the count is in a reg expands
10289 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10291 ;; If the shift count is a constant, we need never emit more than one
10292 ;; shift pair, instead using moves and sign extension for counts greater
10293 ;; than 31.
10295 (define_expand "ashl<mode>3"
10296   [(set (match_operand:SDWIM 0 "<shift_operand>")
10297         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10298                       (match_operand:QI 2 "nonmemory_operand")))]
10299   ""
10300   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10302 (define_insn "*ashl<mode>3_doubleword"
10303   [(set (match_operand:DWI 0 "register_operand" "=&r")
10304         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10305                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10306    (clobber (reg:CC FLAGS_REG))]
10307   ""
10308   "#"
10309   [(set_attr "type" "multi")])
10311 (define_split
10312   [(set (match_operand:DWI 0 "register_operand")
10313         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10314                     (match_operand:QI 2 "nonmemory_operand")))
10315    (clobber (reg:CC FLAGS_REG))]
10316   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10317   [(const_int 0)]
10318   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10320 ;; By default we don't ask for a scratch register, because when DWImode
10321 ;; values are manipulated, registers are already at a premium.  But if
10322 ;; we have one handy, we won't turn it away.
10324 (define_peephole2
10325   [(match_scratch:DWIH 3 "r")
10326    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10327                    (ashift:<DWI>
10328                      (match_operand:<DWI> 1 "nonmemory_operand")
10329                      (match_operand:QI 2 "nonmemory_operand")))
10330               (clobber (reg:CC FLAGS_REG))])
10331    (match_dup 3)]
10332   "TARGET_CMOVE"
10333   [(const_int 0)]
10334   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10336 (define_insn "x86_64_shld"
10337   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10338         (ior:DI (ashift:DI (match_dup 0)
10339                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10340                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10341                   (minus:QI (const_int 64) (match_dup 2)))))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT"
10344   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10345   [(set_attr "type" "ishift")
10346    (set_attr "prefix_0f" "1")
10347    (set_attr "mode" "DI")
10348    (set_attr "athlon_decode" "vector")
10349    (set_attr "amdfam10_decode" "vector")
10350    (set_attr "bdver1_decode" "vector")])
10352 (define_insn "x86_shld"
10353   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10354         (ior:SI (ashift:SI (match_dup 0)
10355                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10356                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10357                   (minus:QI (const_int 32) (match_dup 2)))))
10358    (clobber (reg:CC FLAGS_REG))]
10359   ""
10360   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10361   [(set_attr "type" "ishift")
10362    (set_attr "prefix_0f" "1")
10363    (set_attr "mode" "SI")
10364    (set_attr "pent_pair" "np")
10365    (set_attr "athlon_decode" "vector")
10366    (set_attr "amdfam10_decode" "vector")
10367    (set_attr "bdver1_decode" "vector")])
10369 (define_expand "x86_shift<mode>_adj_1"
10370   [(set (reg:CCZ FLAGS_REG)
10371         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10372                              (match_dup 4))
10373                      (const_int 0)))
10374    (set (match_operand:SWI48 0 "register_operand")
10375         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10376                             (match_operand:SWI48 1 "register_operand")
10377                             (match_dup 0)))
10378    (set (match_dup 1)
10379         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10380                             (match_operand:SWI48 3 "register_operand")
10381                             (match_dup 1)))]
10382   "TARGET_CMOVE"
10383   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10385 (define_expand "x86_shift<mode>_adj_2"
10386   [(use (match_operand:SWI48 0 "register_operand"))
10387    (use (match_operand:SWI48 1 "register_operand"))
10388    (use (match_operand:QI 2 "register_operand"))]
10389   ""
10391   rtx_code_label *label = gen_label_rtx ();
10392   rtx tmp;
10394   emit_insn (gen_testqi_ccz_1 (operands[2],
10395                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10397   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10398   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10399   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10400                               gen_rtx_LABEL_REF (VOIDmode, label),
10401                               pc_rtx);
10402   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10403   JUMP_LABEL (tmp) = label;
10405   emit_move_insn (operands[0], operands[1]);
10406   ix86_expand_clear (operands[1]);
10408   emit_label (label);
10409   LABEL_NUSES (label) = 1;
10411   DONE;
10414 ;; Avoid useless masking of count operand.
10415 (define_insn_and_split "*ashl<mode>3_mask"
10416   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10417         (ashift:SWI48
10418           (match_operand:SWI48 1 "nonimmediate_operand")
10419           (subreg:QI
10420             (and:SI
10421               (match_operand:SI 2 "register_operand" "c,r")
10422               (match_operand:SI 3 "const_int_operand")) 0)))
10423    (clobber (reg:CC FLAGS_REG))]
10424   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10425    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10426       == GET_MODE_BITSIZE (<MODE>mode)-1
10427    && can_create_pseudo_p ()"
10428   "#"
10429   "&& 1"
10430   [(parallel
10431      [(set (match_dup 0)
10432            (ashift:SWI48 (match_dup 1)
10433                          (match_dup 2)))
10434       (clobber (reg:CC FLAGS_REG))])]
10435   "operands[2] = gen_lowpart (QImode, operands[2]);"
10436   [(set_attr "isa" "*,bmi2")])
10438 (define_insn_and_split "*ashl<mode>3_mask_1"
10439   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10440         (ashift:SWI48
10441           (match_operand:SWI48 1 "nonimmediate_operand")
10442           (and:QI
10443             (match_operand:QI 2 "register_operand" "c,r")
10444             (match_operand:QI 3 "const_int_operand"))))
10445    (clobber (reg:CC FLAGS_REG))]
10446   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10447    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10448       == GET_MODE_BITSIZE (<MODE>mode)-1
10449    && can_create_pseudo_p ()"
10450   "#"
10451   "&& 1"
10452   [(parallel
10453      [(set (match_dup 0)
10454            (ashift:SWI48 (match_dup 1)
10455                          (match_dup 2)))
10456       (clobber (reg:CC FLAGS_REG))])]
10457   ""
10458   [(set_attr "isa" "*,bmi2")])
10460 (define_insn "*bmi2_ashl<mode>3_1"
10461   [(set (match_operand:SWI48 0 "register_operand" "=r")
10462         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10463                       (match_operand:SWI48 2 "register_operand" "r")))]
10464   "TARGET_BMI2"
10465   "shlx\t{%2, %1, %0|%0, %1, %2}"
10466   [(set_attr "type" "ishiftx")
10467    (set_attr "mode" "<MODE>")])
10469 (define_insn "*ashl<mode>3_1"
10470   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10471         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10472                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10476   switch (get_attr_type (insn))
10477     {
10478     case TYPE_LEA:
10479     case TYPE_ISHIFTX:
10480       return "#";
10482     case TYPE_ALU:
10483       gcc_assert (operands[2] == const1_rtx);
10484       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10485       return "add{<imodesuffix>}\t%0, %0";
10487     default:
10488       if (operands[2] == const1_rtx
10489           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10490         return "sal{<imodesuffix>}\t%0";
10491       else
10492         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10493     }
10495   [(set_attr "isa" "*,*,bmi2")
10496    (set (attr "type")
10497      (cond [(eq_attr "alternative" "1")
10498               (const_string "lea")
10499             (eq_attr "alternative" "2")
10500               (const_string "ishiftx")
10501             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10502                       (match_operand 0 "register_operand"))
10503                  (match_operand 2 "const1_operand"))
10504               (const_string "alu")
10505            ]
10506            (const_string "ishift")))
10507    (set (attr "length_immediate")
10508      (if_then_else
10509        (ior (eq_attr "type" "alu")
10510             (and (eq_attr "type" "ishift")
10511                  (and (match_operand 2 "const1_operand")
10512                       (ior (match_test "TARGET_SHIFT1")
10513                            (match_test "optimize_function_for_size_p (cfun)")))))
10514        (const_string "0")
10515        (const_string "*")))
10516    (set_attr "mode" "<MODE>")])
10518 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10519 (define_split
10520   [(set (match_operand:SWI48 0 "register_operand")
10521         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10522                       (match_operand:QI 2 "register_operand")))
10523    (clobber (reg:CC FLAGS_REG))]
10524   "TARGET_BMI2 && reload_completed"
10525   [(set (match_dup 0)
10526         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10527   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10529 (define_insn "*bmi2_ashlsi3_1_zext"
10530   [(set (match_operand:DI 0 "register_operand" "=r")
10531         (zero_extend:DI
10532           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10533                      (match_operand:SI 2 "register_operand" "r"))))]
10534   "TARGET_64BIT && TARGET_BMI2"
10535   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10536   [(set_attr "type" "ishiftx")
10537    (set_attr "mode" "SI")])
10539 (define_insn "*ashlsi3_1_zext"
10540   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10541         (zero_extend:DI
10542           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10543                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10544    (clobber (reg:CC FLAGS_REG))]
10545   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10547   switch (get_attr_type (insn))
10548     {
10549     case TYPE_LEA:
10550     case TYPE_ISHIFTX:
10551       return "#";
10553     case TYPE_ALU:
10554       gcc_assert (operands[2] == const1_rtx);
10555       return "add{l}\t%k0, %k0";
10557     default:
10558       if (operands[2] == const1_rtx
10559           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10560         return "sal{l}\t%k0";
10561       else
10562         return "sal{l}\t{%2, %k0|%k0, %2}";
10563     }
10565   [(set_attr "isa" "*,*,bmi2")
10566    (set (attr "type")
10567      (cond [(eq_attr "alternative" "1")
10568               (const_string "lea")
10569             (eq_attr "alternative" "2")
10570               (const_string "ishiftx")
10571             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10572                  (match_operand 2 "const1_operand"))
10573               (const_string "alu")
10574            ]
10575            (const_string "ishift")))
10576    (set (attr "length_immediate")
10577      (if_then_else
10578        (ior (eq_attr "type" "alu")
10579             (and (eq_attr "type" "ishift")
10580                  (and (match_operand 2 "const1_operand")
10581                       (ior (match_test "TARGET_SHIFT1")
10582                            (match_test "optimize_function_for_size_p (cfun)")))))
10583        (const_string "0")
10584        (const_string "*")))
10585    (set_attr "mode" "SI")])
10587 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10588 (define_split
10589   [(set (match_operand:DI 0 "register_operand")
10590         (zero_extend:DI
10591           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10592                      (match_operand:QI 2 "register_operand"))))
10593    (clobber (reg:CC FLAGS_REG))]
10594   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10595   [(set (match_dup 0)
10596         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10597   "operands[2] = gen_lowpart (SImode, operands[2]);")
10599 (define_insn "*ashlhi3_1"
10600   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10601         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10602                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10603    (clobber (reg:CC FLAGS_REG))]
10604   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10606   switch (get_attr_type (insn))
10607     {
10608     case TYPE_LEA:
10609       return "#";
10611     case TYPE_ALU:
10612       gcc_assert (operands[2] == const1_rtx);
10613       return "add{w}\t%0, %0";
10615     default:
10616       if (operands[2] == const1_rtx
10617           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618         return "sal{w}\t%0";
10619       else
10620         return "sal{w}\t{%2, %0|%0, %2}";
10621     }
10623   [(set (attr "type")
10624      (cond [(eq_attr "alternative" "1")
10625               (const_string "lea")
10626             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10627                       (match_operand 0 "register_operand"))
10628                  (match_operand 2 "const1_operand"))
10629               (const_string "alu")
10630            ]
10631            (const_string "ishift")))
10632    (set (attr "length_immediate")
10633      (if_then_else
10634        (ior (eq_attr "type" "alu")
10635             (and (eq_attr "type" "ishift")
10636                  (and (match_operand 2 "const1_operand")
10637                       (ior (match_test "TARGET_SHIFT1")
10638                            (match_test "optimize_function_for_size_p (cfun)")))))
10639        (const_string "0")
10640        (const_string "*")))
10641    (set_attr "mode" "HI,SI")])
10643 (define_insn "*ashlqi3_1"
10644   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10645         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10646                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10647    (clobber (reg:CC FLAGS_REG))]
10648   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10650   switch (get_attr_type (insn))
10651     {
10652     case TYPE_LEA:
10653       return "#";
10655     case TYPE_ALU:
10656       gcc_assert (operands[2] == const1_rtx);
10657       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10658         return "add{l}\t%k0, %k0";
10659       else
10660         return "add{b}\t%0, %0";
10662     default:
10663       if (operands[2] == const1_rtx
10664           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10665         {
10666           if (get_attr_mode (insn) == MODE_SI)
10667             return "sal{l}\t%k0";
10668           else
10669             return "sal{b}\t%0";
10670         }
10671       else
10672         {
10673           if (get_attr_mode (insn) == MODE_SI)
10674             return "sal{l}\t{%2, %k0|%k0, %2}";
10675           else
10676             return "sal{b}\t{%2, %0|%0, %2}";
10677         }
10678     }
10680   [(set (attr "type")
10681      (cond [(eq_attr "alternative" "2")
10682               (const_string "lea")
10683             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10684                       (match_operand 0 "register_operand"))
10685                  (match_operand 2 "const1_operand"))
10686               (const_string "alu")
10687            ]
10688            (const_string "ishift")))
10689    (set (attr "length_immediate")
10690      (if_then_else
10691        (ior (eq_attr "type" "alu")
10692             (and (eq_attr "type" "ishift")
10693                  (and (match_operand 2 "const1_operand")
10694                       (ior (match_test "TARGET_SHIFT1")
10695                            (match_test "optimize_function_for_size_p (cfun)")))))
10696        (const_string "0")
10697        (const_string "*")))
10698    (set_attr "mode" "QI,SI,SI")
10699    ;; Potential partial reg stall on alternative 1.
10700    (set (attr "preferred_for_speed")
10701      (cond [(eq_attr "alternative" "1")
10702               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10703            (symbol_ref "true")))])
10705 (define_insn "*ashlqi3_1_slp"
10706   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10707         (ashift:QI (match_dup 0)
10708                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10709    (clobber (reg:CC FLAGS_REG))]
10710   "(optimize_function_for_size_p (cfun)
10711     || !TARGET_PARTIAL_FLAG_REG_STALL
10712     || (operands[1] == const1_rtx
10713         && (TARGET_SHIFT1
10714             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10716   switch (get_attr_type (insn))
10717     {
10718     case TYPE_ALU1:
10719       gcc_assert (operands[1] == const1_rtx);
10720       return "add{b}\t%0, %0";
10722     default:
10723       if (operands[1] == const1_rtx
10724           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10725         return "sal{b}\t%0";
10726       else
10727         return "sal{b}\t{%1, %0|%0, %1}";
10728     }
10730   [(set (attr "type")
10731      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10732                       (match_operand 0 "register_operand"))
10733                  (match_operand 1 "const1_operand"))
10734               (const_string "alu1")
10735            ]
10736            (const_string "ishift1")))
10737    (set (attr "length_immediate")
10738      (if_then_else
10739        (ior (eq_attr "type" "alu1")
10740             (and (eq_attr "type" "ishift1")
10741                  (and (match_operand 1 "const1_operand")
10742                       (ior (match_test "TARGET_SHIFT1")
10743                            (match_test "optimize_function_for_size_p (cfun)")))))
10744        (const_string "0")
10745        (const_string "*")))
10746    (set_attr "mode" "QI")])
10748 ;; Convert ashift to the lea pattern to avoid flags dependency.
10749 (define_split
10750   [(set (match_operand:SWI 0 "register_operand")
10751         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10752                     (match_operand 2 "const_0_to_3_operand")))
10753    (clobber (reg:CC FLAGS_REG))]
10754   "reload_completed
10755    && REGNO (operands[0]) != REGNO (operands[1])"
10756   [(set (match_dup 0)
10757         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10759   if (<MODE>mode != <LEAMODE>mode)
10760     {
10761       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10762       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10763     }
10764   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10767 ;; Convert ashift to the lea pattern to avoid flags dependency.
10768 (define_split
10769   [(set (match_operand:DI 0 "register_operand")
10770         (zero_extend:DI
10771           (ashift:SI (match_operand:SI 1 "index_register_operand")
10772                      (match_operand 2 "const_0_to_3_operand"))))
10773    (clobber (reg:CC FLAGS_REG))]
10774   "TARGET_64BIT && reload_completed
10775    && REGNO (operands[0]) != REGNO (operands[1])"
10776   [(set (match_dup 0)
10777         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10779   operands[1] = gen_lowpart (SImode, operands[1]);
10780   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags.  We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashl<mode>3_cmp"
10787   [(set (reg FLAGS_REG)
10788         (compare
10789           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10790                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10791           (const_int 0)))
10792    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10793         (ashift:SWI (match_dup 1) (match_dup 2)))]
10794   "(optimize_function_for_size_p (cfun)
10795     || !TARGET_PARTIAL_FLAG_REG_STALL
10796     || (operands[2] == const1_rtx
10797         && (TARGET_SHIFT1
10798             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10799    && ix86_match_ccmode (insn, CCGOCmode)
10800    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10802   switch (get_attr_type (insn))
10803     {
10804     case TYPE_ALU:
10805       gcc_assert (operands[2] == const1_rtx);
10806       return "add{<imodesuffix>}\t%0, %0";
10808     default:
10809       if (operands[2] == const1_rtx
10810           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10811         return "sal{<imodesuffix>}\t%0";
10812       else
10813         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10814     }
10816   [(set (attr "type")
10817      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10818                       (match_operand 0 "register_operand"))
10819                  (match_operand 2 "const1_operand"))
10820               (const_string "alu")
10821            ]
10822            (const_string "ishift")))
10823    (set (attr "length_immediate")
10824      (if_then_else
10825        (ior (eq_attr "type" "alu")
10826             (and (eq_attr "type" "ishift")
10827                  (and (match_operand 2 "const1_operand")
10828                       (ior (match_test "TARGET_SHIFT1")
10829                            (match_test "optimize_function_for_size_p (cfun)")))))
10830        (const_string "0")
10831        (const_string "*")))
10832    (set_attr "mode" "<MODE>")])
10834 (define_insn "*ashlsi3_cmp_zext"
10835   [(set (reg FLAGS_REG)
10836         (compare
10837           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10838                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10839           (const_int 0)))
10840    (set (match_operand:DI 0 "register_operand" "=r")
10841         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10842   "TARGET_64BIT
10843    && (optimize_function_for_size_p (cfun)
10844        || !TARGET_PARTIAL_FLAG_REG_STALL
10845        || (operands[2] == const1_rtx
10846            && (TARGET_SHIFT1
10847                || TARGET_DOUBLE_WITH_ADD)))
10848    && ix86_match_ccmode (insn, CCGOCmode)
10849    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10851   switch (get_attr_type (insn))
10852     {
10853     case TYPE_ALU:
10854       gcc_assert (operands[2] == const1_rtx);
10855       return "add{l}\t%k0, %k0";
10857     default:
10858       if (operands[2] == const1_rtx
10859           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10860         return "sal{l}\t%k0";
10861       else
10862         return "sal{l}\t{%2, %k0|%k0, %2}";
10863     }
10865   [(set (attr "type")
10866      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10867                  (match_operand 2 "const1_operand"))
10868               (const_string "alu")
10869            ]
10870            (const_string "ishift")))
10871    (set (attr "length_immediate")
10872      (if_then_else
10873        (ior (eq_attr "type" "alu")
10874             (and (eq_attr "type" "ishift")
10875                  (and (match_operand 2 "const1_operand")
10876                       (ior (match_test "TARGET_SHIFT1")
10877                            (match_test "optimize_function_for_size_p (cfun)")))))
10878        (const_string "0")
10879        (const_string "*")))
10880    (set_attr "mode" "SI")])
10882 (define_insn "*ashl<mode>3_cconly"
10883   [(set (reg FLAGS_REG)
10884         (compare
10885           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10886                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10887           (const_int 0)))
10888    (clobber (match_scratch:SWI 0 "=<r>"))]
10889   "(optimize_function_for_size_p (cfun)
10890     || !TARGET_PARTIAL_FLAG_REG_STALL
10891     || (operands[2] == const1_rtx
10892         && (TARGET_SHIFT1
10893             || TARGET_DOUBLE_WITH_ADD)))
10894    && ix86_match_ccmode (insn, CCGOCmode)"
10896   switch (get_attr_type (insn))
10897     {
10898     case TYPE_ALU:
10899       gcc_assert (operands[2] == const1_rtx);
10900       return "add{<imodesuffix>}\t%0, %0";
10902     default:
10903       if (operands[2] == const1_rtx
10904           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10905         return "sal{<imodesuffix>}\t%0";
10906       else
10907         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10908     }
10910   [(set (attr "type")
10911      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10912                       (match_operand 0 "register_operand"))
10913                  (match_operand 2 "const1_operand"))
10914               (const_string "alu")
10915            ]
10916            (const_string "ishift")))
10917    (set (attr "length_immediate")
10918      (if_then_else
10919        (ior (eq_attr "type" "alu")
10920             (and (eq_attr "type" "ishift")
10921                  (and (match_operand 2 "const1_operand")
10922                       (ior (match_test "TARGET_SHIFT1")
10923                            (match_test "optimize_function_for_size_p (cfun)")))))
10924        (const_string "0")
10925        (const_string "*")))
10926    (set_attr "mode" "<MODE>")])
10928 ;; See comment above `ashl<mode>3' about how this works.
10930 (define_expand "<shift_insn><mode>3"
10931   [(set (match_operand:SDWIM 0 "<shift_operand>")
10932         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10933                            (match_operand:QI 2 "nonmemory_operand")))]
10934   ""
10935   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10937 ;; Avoid useless masking of count operand.
10938 (define_insn_and_split "*<shift_insn><mode>3_mask"
10939   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10940         (any_shiftrt:SWI48
10941           (match_operand:SWI48 1 "nonimmediate_operand")
10942           (subreg:QI
10943             (and:SI
10944               (match_operand:SI 2 "register_operand" "c,r")
10945               (match_operand:SI 3 "const_int_operand")) 0)))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10948    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10949       == GET_MODE_BITSIZE (<MODE>mode)-1
10950    && can_create_pseudo_p ()"
10951   "#"
10952   "&& 1"
10953   [(parallel
10954      [(set (match_dup 0)
10955            (any_shiftrt:SWI48 (match_dup 1)
10956                               (match_dup 2)))
10957       (clobber (reg:CC FLAGS_REG))])]
10958   "operands[2] = gen_lowpart (QImode, operands[2]);"
10959   [(set_attr "isa" "*,bmi2")])
10961 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10962   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10963         (any_shiftrt:SWI48
10964           (match_operand:SWI48 1 "nonimmediate_operand")
10965           (and:QI
10966             (match_operand:QI 2 "register_operand" "c,r")
10967             (match_operand:QI 3 "const_int_operand"))))
10968    (clobber (reg:CC FLAGS_REG))]
10969   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10970    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10971       == GET_MODE_BITSIZE (<MODE>mode)-1
10972    && can_create_pseudo_p ()"
10973   "#"
10974   "&& 1"
10975   [(parallel
10976      [(set (match_dup 0)
10977            (any_shiftrt:SWI48 (match_dup 1)
10978                               (match_dup 2)))
10979       (clobber (reg:CC FLAGS_REG))])]
10980   ""
10981   [(set_attr "isa" "*,bmi2")])
10983 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10984   [(set (match_operand:DWI 0 "register_operand" "=&r")
10985         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10986                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10987    (clobber (reg:CC FLAGS_REG))]
10988   ""
10989   "#"
10990   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10991   [(const_int 0)]
10992   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10993   [(set_attr "type" "multi")])
10995 ;; By default we don't ask for a scratch register, because when DWImode
10996 ;; values are manipulated, registers are already at a premium.  But if
10997 ;; we have one handy, we won't turn it away.
10999 (define_peephole2
11000   [(match_scratch:DWIH 3 "r")
11001    (parallel [(set (match_operand:<DWI> 0 "register_operand")
11002                    (any_shiftrt:<DWI>
11003                      (match_operand:<DWI> 1 "register_operand")
11004                      (match_operand:QI 2 "nonmemory_operand")))
11005               (clobber (reg:CC FLAGS_REG))])
11006    (match_dup 3)]
11007   "TARGET_CMOVE"
11008   [(const_int 0)]
11009   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11011 (define_insn "x86_64_shrd"
11012   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11013         (ior:DI (lshiftrt:DI (match_dup 0)
11014                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11015                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11016                   (minus:QI (const_int 64) (match_dup 2)))))
11017    (clobber (reg:CC FLAGS_REG))]
11018   "TARGET_64BIT"
11019   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11020   [(set_attr "type" "ishift")
11021    (set_attr "prefix_0f" "1")
11022    (set_attr "mode" "DI")
11023    (set_attr "athlon_decode" "vector")
11024    (set_attr "amdfam10_decode" "vector")
11025    (set_attr "bdver1_decode" "vector")])
11027 (define_insn "x86_shrd"
11028   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11029         (ior:SI (lshiftrt:SI (match_dup 0)
11030                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11031                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11032                   (minus:QI (const_int 32) (match_dup 2)))))
11033    (clobber (reg:CC FLAGS_REG))]
11034   ""
11035   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11036   [(set_attr "type" "ishift")
11037    (set_attr "prefix_0f" "1")
11038    (set_attr "mode" "SI")
11039    (set_attr "pent_pair" "np")
11040    (set_attr "athlon_decode" "vector")
11041    (set_attr "amdfam10_decode" "vector")
11042    (set_attr "bdver1_decode" "vector")])
11044 (define_insn "ashrdi3_cvt"
11045   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11046         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11047                      (match_operand:QI 2 "const_int_operand")))
11048    (clobber (reg:CC FLAGS_REG))]
11049   "TARGET_64BIT && INTVAL (operands[2]) == 63
11050    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11051    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11052   "@
11053    {cqto|cqo}
11054    sar{q}\t{%2, %0|%0, %2}"
11055   [(set_attr "type" "imovx,ishift")
11056    (set_attr "prefix_0f" "0,*")
11057    (set_attr "length_immediate" "0,*")
11058    (set_attr "modrm" "0,1")
11059    (set_attr "mode" "DI")])
11061 (define_insn "*ashrsi3_cvt_zext"
11062   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11063         (zero_extend:DI
11064           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11065                        (match_operand:QI 2 "const_int_operand"))))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_64BIT && INTVAL (operands[2]) == 31
11068    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11069    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11070   "@
11071    {cltd|cdq}
11072    sar{l}\t{%2, %k0|%k0, %2}"
11073   [(set_attr "type" "imovx,ishift")
11074    (set_attr "prefix_0f" "0,*")
11075    (set_attr "length_immediate" "0,*")
11076    (set_attr "modrm" "0,1")
11077    (set_attr "mode" "SI")])
11079 (define_insn "ashrsi3_cvt"
11080   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11081         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11082                      (match_operand:QI 2 "const_int_operand")))
11083    (clobber (reg:CC FLAGS_REG))]
11084   "INTVAL (operands[2]) == 31
11085    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11086    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11087   "@
11088    {cltd|cdq}
11089    sar{l}\t{%2, %0|%0, %2}"
11090   [(set_attr "type" "imovx,ishift")
11091    (set_attr "prefix_0f" "0,*")
11092    (set_attr "length_immediate" "0,*")
11093    (set_attr "modrm" "0,1")
11094    (set_attr "mode" "SI")])
11096 (define_expand "x86_shift<mode>_adj_3"
11097   [(use (match_operand:SWI48 0 "register_operand"))
11098    (use (match_operand:SWI48 1 "register_operand"))
11099    (use (match_operand:QI 2 "register_operand"))]
11100   ""
11102   rtx_code_label *label = gen_label_rtx ();
11103   rtx tmp;
11105   emit_insn (gen_testqi_ccz_1 (operands[2],
11106                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11108   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11109   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11110   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11111                               gen_rtx_LABEL_REF (VOIDmode, label),
11112                               pc_rtx);
11113   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11114   JUMP_LABEL (tmp) = label;
11116   emit_move_insn (operands[0], operands[1]);
11117   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11118                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11119   emit_label (label);
11120   LABEL_NUSES (label) = 1;
11122   DONE;
11125 (define_insn "*bmi2_<shift_insn><mode>3_1"
11126   [(set (match_operand:SWI48 0 "register_operand" "=r")
11127         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11128                            (match_operand:SWI48 2 "register_operand" "r")))]
11129   "TARGET_BMI2"
11130   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11131   [(set_attr "type" "ishiftx")
11132    (set_attr "mode" "<MODE>")])
11134 (define_insn "*<shift_insn><mode>3_1"
11135   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11136         (any_shiftrt:SWI48
11137           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11138           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11142   switch (get_attr_type (insn))
11143     {
11144     case TYPE_ISHIFTX:
11145       return "#";
11147     default:
11148       if (operands[2] == const1_rtx
11149           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11150         return "<shift>{<imodesuffix>}\t%0";
11151       else
11152         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11153     }
11155   [(set_attr "isa" "*,bmi2")
11156    (set_attr "type" "ishift,ishiftx")
11157    (set (attr "length_immediate")
11158      (if_then_else
11159        (and (match_operand 2 "const1_operand")
11160             (ior (match_test "TARGET_SHIFT1")
11161                  (match_test "optimize_function_for_size_p (cfun)")))
11162        (const_string "0")
11163        (const_string "*")))
11164    (set_attr "mode" "<MODE>")])
11166 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11167 (define_split
11168   [(set (match_operand:SWI48 0 "register_operand")
11169         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11170                            (match_operand:QI 2 "register_operand")))
11171    (clobber (reg:CC FLAGS_REG))]
11172   "TARGET_BMI2 && reload_completed"
11173   [(set (match_dup 0)
11174         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11175   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11177 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11178   [(set (match_operand:DI 0 "register_operand" "=r")
11179         (zero_extend:DI
11180           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11181                           (match_operand:SI 2 "register_operand" "r"))))]
11182   "TARGET_64BIT && TARGET_BMI2"
11183   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11184   [(set_attr "type" "ishiftx")
11185    (set_attr "mode" "SI")])
11187 (define_insn "*<shift_insn>si3_1_zext"
11188   [(set (match_operand:DI 0 "register_operand" "=r,r")
11189         (zero_extend:DI
11190           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11191                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11192    (clobber (reg:CC FLAGS_REG))]
11193   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11195   switch (get_attr_type (insn))
11196     {
11197     case TYPE_ISHIFTX:
11198       return "#";
11200     default:
11201       if (operands[2] == const1_rtx
11202           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11203         return "<shift>{l}\t%k0";
11204       else
11205         return "<shift>{l}\t{%2, %k0|%k0, %2}";
11206     }
11208   [(set_attr "isa" "*,bmi2")
11209    (set_attr "type" "ishift,ishiftx")
11210    (set (attr "length_immediate")
11211      (if_then_else
11212        (and (match_operand 2 "const1_operand")
11213             (ior (match_test "TARGET_SHIFT1")
11214                  (match_test "optimize_function_for_size_p (cfun)")))
11215        (const_string "0")
11216        (const_string "*")))
11217    (set_attr "mode" "SI")])
11219 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11220 (define_split
11221   [(set (match_operand:DI 0 "register_operand")
11222         (zero_extend:DI
11223           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11224                           (match_operand:QI 2 "register_operand"))))
11225    (clobber (reg:CC FLAGS_REG))]
11226   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11227   [(set (match_dup 0)
11228         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11229   "operands[2] = gen_lowpart (SImode, operands[2]);")
11231 (define_insn "*<shift_insn><mode>3_1"
11232   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11233         (any_shiftrt:SWI12
11234           (match_operand:SWI12 1 "nonimmediate_operand" "0")
11235           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11236    (clobber (reg:CC FLAGS_REG))]
11237   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11239   if (operands[2] == const1_rtx
11240       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11241     return "<shift>{<imodesuffix>}\t%0";
11242   else
11243     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11245   [(set_attr "type" "ishift")
11246    (set (attr "length_immediate")
11247      (if_then_else
11248        (and (match_operand 2 "const1_operand")
11249             (ior (match_test "TARGET_SHIFT1")
11250                  (match_test "optimize_function_for_size_p (cfun)")))
11251        (const_string "0")
11252        (const_string "*")))
11253    (set_attr "mode" "<MODE>")])
11255 (define_insn "*<shift_insn>qi3_1_slp"
11256   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11257         (any_shiftrt:QI (match_dup 0)
11258                         (match_operand:QI 1 "nonmemory_operand" "cI")))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "(optimize_function_for_size_p (cfun)
11261     || !TARGET_PARTIAL_REG_STALL
11262     || (operands[1] == const1_rtx
11263         && TARGET_SHIFT1))"
11265   if (operands[1] == const1_rtx
11266       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11267     return "<shift>{b}\t%0";
11268   else
11269     return "<shift>{b}\t{%1, %0|%0, %1}";
11271   [(set_attr "type" "ishift1")
11272    (set (attr "length_immediate")
11273      (if_then_else
11274        (and (match_operand 1 "const1_operand")
11275             (ior (match_test "TARGET_SHIFT1")
11276                  (match_test "optimize_function_for_size_p (cfun)")))
11277        (const_string "0")
11278        (const_string "*")))
11279    (set_attr "mode" "QI")])
11281 ;; This pattern can't accept a variable shift count, since shifts by
11282 ;; zero don't affect the flags.  We assume that shifts by constant
11283 ;; zero are optimized away.
11284 (define_insn "*<shift_insn><mode>3_cmp"
11285   [(set (reg FLAGS_REG)
11286         (compare
11287           (any_shiftrt:SWI
11288             (match_operand:SWI 1 "nonimmediate_operand" "0")
11289             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11290           (const_int 0)))
11291    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11292         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11293   "(optimize_function_for_size_p (cfun)
11294     || !TARGET_PARTIAL_FLAG_REG_STALL
11295     || (operands[2] == const1_rtx
11296         && TARGET_SHIFT1))
11297    && ix86_match_ccmode (insn, CCGOCmode)
11298    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11300   if (operands[2] == const1_rtx
11301       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11302     return "<shift>{<imodesuffix>}\t%0";
11303   else
11304     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11306   [(set_attr "type" "ishift")
11307    (set (attr "length_immediate")
11308      (if_then_else
11309        (and (match_operand 2 "const1_operand")
11310             (ior (match_test "TARGET_SHIFT1")
11311                  (match_test "optimize_function_for_size_p (cfun)")))
11312        (const_string "0")
11313        (const_string "*")))
11314    (set_attr "mode" "<MODE>")])
11316 (define_insn "*<shift_insn>si3_cmp_zext"
11317   [(set (reg FLAGS_REG)
11318         (compare
11319           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11320                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11321           (const_int 0)))
11322    (set (match_operand:DI 0 "register_operand" "=r")
11323         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11324   "TARGET_64BIT
11325    && (optimize_function_for_size_p (cfun)
11326        || !TARGET_PARTIAL_FLAG_REG_STALL
11327        || (operands[2] == const1_rtx
11328            && TARGET_SHIFT1))
11329    && ix86_match_ccmode (insn, CCGOCmode)
11330    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11332   if (operands[2] == const1_rtx
11333       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11334     return "<shift>{l}\t%k0";
11335   else
11336     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11338   [(set_attr "type" "ishift")
11339    (set (attr "length_immediate")
11340      (if_then_else
11341        (and (match_operand 2 "const1_operand")
11342             (ior (match_test "TARGET_SHIFT1")
11343                  (match_test "optimize_function_for_size_p (cfun)")))
11344        (const_string "0")
11345        (const_string "*")))
11346    (set_attr "mode" "SI")])
11348 (define_insn "*<shift_insn><mode>3_cconly"
11349   [(set (reg FLAGS_REG)
11350         (compare
11351           (any_shiftrt:SWI
11352             (match_operand:SWI 1 "register_operand" "0")
11353             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11354           (const_int 0)))
11355    (clobber (match_scratch:SWI 0 "=<r>"))]
11356   "(optimize_function_for_size_p (cfun)
11357     || !TARGET_PARTIAL_FLAG_REG_STALL
11358     || (operands[2] == const1_rtx
11359         && TARGET_SHIFT1))
11360    && ix86_match_ccmode (insn, CCGOCmode)"
11362   if (operands[2] == const1_rtx
11363       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11364     return "<shift>{<imodesuffix>}\t%0";
11365   else
11366     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11368   [(set_attr "type" "ishift")
11369    (set (attr "length_immediate")
11370      (if_then_else
11371        (and (match_operand 2 "const1_operand")
11372             (ior (match_test "TARGET_SHIFT1")
11373                  (match_test "optimize_function_for_size_p (cfun)")))
11374        (const_string "0")
11375        (const_string "*")))
11376    (set_attr "mode" "<MODE>")])
11378 ;; Rotate instructions
11380 (define_expand "<rotate_insn>ti3"
11381   [(set (match_operand:TI 0 "register_operand")
11382         (any_rotate:TI (match_operand:TI 1 "register_operand")
11383                        (match_operand:QI 2 "nonmemory_operand")))]
11384   "TARGET_64BIT"
11386   if (const_1_to_63_operand (operands[2], VOIDmode))
11387     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11388                 (operands[0], operands[1], operands[2]));
11389   else
11390     FAIL;
11392   DONE;
11395 (define_expand "<rotate_insn>di3"
11396   [(set (match_operand:DI 0 "shiftdi_operand")
11397         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11398                        (match_operand:QI 2 "nonmemory_operand")))]
11399  ""
11401   if (TARGET_64BIT)
11402     ix86_expand_binary_operator (<CODE>, DImode, operands);
11403   else if (const_1_to_31_operand (operands[2], VOIDmode))
11404     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11405                 (operands[0], operands[1], operands[2]));
11406   else
11407     FAIL;
11409   DONE;
11412 (define_expand "<rotate_insn><mode>3"
11413   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11414         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11415                             (match_operand:QI 2 "nonmemory_operand")))]
11416   ""
11417   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11419 ;; Avoid useless masking of count operand.
11420 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11421   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11422         (any_rotate:SWI48
11423           (match_operand:SWI48 1 "nonimmediate_operand")
11424           (subreg:QI
11425             (and:SI
11426               (match_operand:SI 2 "register_operand" "c")
11427               (match_operand:SI 3 "const_int_operand")) 0)))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11430    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11431       == GET_MODE_BITSIZE (<MODE>mode)-1
11432    && can_create_pseudo_p ()"
11433   "#"
11434   "&& 1"
11435   [(parallel
11436      [(set (match_dup 0)
11437            (any_rotate:SWI48 (match_dup 1)
11438                              (match_dup 2)))
11439       (clobber (reg:CC FLAGS_REG))])]
11440   "operands[2] = gen_lowpart (QImode, operands[2]);")
11442 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11443   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11444         (any_rotate:SWI48
11445           (match_operand:SWI48 1 "nonimmediate_operand")
11446           (and:QI
11447             (match_operand:QI 2 "register_operand" "c")
11448             (match_operand:QI 3 "const_int_operand"))))
11449    (clobber (reg:CC FLAGS_REG))]
11450   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11451    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11452       == GET_MODE_BITSIZE (<MODE>mode)-1
11453    && can_create_pseudo_p ()"
11454   "#"
11455   "&& 1"
11456   [(parallel
11457      [(set (match_dup 0)
11458            (any_rotate:SWI48 (match_dup 1)
11459                              (match_dup 2)))
11460       (clobber (reg:CC FLAGS_REG))])])
11462 ;; Implement rotation using two double-precision
11463 ;; shift instructions and a scratch register.
11465 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11466  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11467        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11468                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11469   (clobber (reg:CC FLAGS_REG))
11470   (clobber (match_scratch:DWIH 3 "=&r"))]
11471  ""
11472  "#"
11473  "reload_completed"
11474  [(set (match_dup 3) (match_dup 4))
11475   (parallel
11476    [(set (match_dup 4)
11477          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11478                    (lshiftrt:DWIH (match_dup 5)
11479                                   (minus:QI (match_dup 6) (match_dup 2)))))
11480     (clobber (reg:CC FLAGS_REG))])
11481   (parallel
11482    [(set (match_dup 5)
11483          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11484                    (lshiftrt:DWIH (match_dup 3)
11485                                   (minus:QI (match_dup 6) (match_dup 2)))))
11486     (clobber (reg:CC FLAGS_REG))])]
11488   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11490   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11493 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11494  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11495        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11496                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11497   (clobber (reg:CC FLAGS_REG))
11498   (clobber (match_scratch:DWIH 3 "=&r"))]
11499  ""
11500  "#"
11501  "reload_completed"
11502  [(set (match_dup 3) (match_dup 4))
11503   (parallel
11504    [(set (match_dup 4)
11505          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11506                    (ashift:DWIH (match_dup 5)
11507                                 (minus:QI (match_dup 6) (match_dup 2)))))
11508     (clobber (reg:CC FLAGS_REG))])
11509   (parallel
11510    [(set (match_dup 5)
11511          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11512                    (ashift:DWIH (match_dup 3)
11513                                 (minus:QI (match_dup 6) (match_dup 2)))))
11514     (clobber (reg:CC FLAGS_REG))])]
11516   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11518   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11521 (define_mode_attr rorx_immediate_operand
11522         [(SI "const_0_to_31_operand")
11523          (DI "const_0_to_63_operand")])
11525 (define_insn "*bmi2_rorx<mode>3_1"
11526   [(set (match_operand:SWI48 0 "register_operand" "=r")
11527         (rotatert:SWI48
11528           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11529           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11530   "TARGET_BMI2"
11531   "rorx\t{%2, %1, %0|%0, %1, %2}"
11532   [(set_attr "type" "rotatex")
11533    (set_attr "mode" "<MODE>")])
11535 (define_insn "*<rotate_insn><mode>3_1"
11536   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11537         (any_rotate:SWI48
11538           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11539           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11540    (clobber (reg:CC FLAGS_REG))]
11541   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11543   switch (get_attr_type (insn))
11544     {
11545     case TYPE_ROTATEX:
11546       return "#";
11548     default:
11549       if (operands[2] == const1_rtx
11550           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11551         return "<rotate>{<imodesuffix>}\t%0";
11552       else
11553         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11554     }
11556   [(set_attr "isa" "*,bmi2")
11557    (set_attr "type" "rotate,rotatex")
11558    (set (attr "length_immediate")
11559      (if_then_else
11560        (and (eq_attr "type" "rotate")
11561             (and (match_operand 2 "const1_operand")
11562                  (ior (match_test "TARGET_SHIFT1")
11563                       (match_test "optimize_function_for_size_p (cfun)"))))
11564        (const_string "0")
11565        (const_string "*")))
11566    (set_attr "mode" "<MODE>")])
11568 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11569 (define_split
11570   [(set (match_operand:SWI48 0 "register_operand")
11571         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11572                       (match_operand:QI 2 "const_int_operand")))
11573    (clobber (reg:CC FLAGS_REG))]
11574   "TARGET_BMI2 && reload_completed"
11575   [(set (match_dup 0)
11576         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11578   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11580   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11583 (define_split
11584   [(set (match_operand:SWI48 0 "register_operand")
11585         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11586                         (match_operand:QI 2 "const_int_operand")))
11587    (clobber (reg:CC FLAGS_REG))]
11588   "TARGET_BMI2 && reload_completed"
11589   [(set (match_dup 0)
11590         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11592 (define_insn "*bmi2_rorxsi3_1_zext"
11593   [(set (match_operand:DI 0 "register_operand" "=r")
11594         (zero_extend:DI
11595           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11596                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11597   "TARGET_64BIT && TARGET_BMI2"
11598   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11599   [(set_attr "type" "rotatex")
11600    (set_attr "mode" "SI")])
11602 (define_insn "*<rotate_insn>si3_1_zext"
11603   [(set (match_operand:DI 0 "register_operand" "=r,r")
11604         (zero_extend:DI
11605           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11606                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11607    (clobber (reg:CC FLAGS_REG))]
11608   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11610   switch (get_attr_type (insn))
11611     {
11612     case TYPE_ROTATEX:
11613       return "#";
11615     default:
11616       if (operands[2] == const1_rtx
11617           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11618         return "<rotate>{l}\t%k0";
11619       else
11620         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11621     }
11623   [(set_attr "isa" "*,bmi2")
11624    (set_attr "type" "rotate,rotatex")
11625    (set (attr "length_immediate")
11626      (if_then_else
11627        (and (eq_attr "type" "rotate")
11628             (and (match_operand 2 "const1_operand")
11629                  (ior (match_test "TARGET_SHIFT1")
11630                       (match_test "optimize_function_for_size_p (cfun)"))))
11631        (const_string "0")
11632        (const_string "*")))
11633    (set_attr "mode" "SI")])
11635 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11636 (define_split
11637   [(set (match_operand:DI 0 "register_operand")
11638         (zero_extend:DI
11639           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11640                      (match_operand:QI 2 "const_int_operand"))))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11643   [(set (match_dup 0)
11644         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11646   int bitsize = GET_MODE_BITSIZE (SImode);
11648   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11651 (define_split
11652   [(set (match_operand:DI 0 "register_operand")
11653         (zero_extend:DI
11654           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11655                        (match_operand:QI 2 "const_int_operand"))))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11658   [(set (match_dup 0)
11659         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11661 (define_insn "*<rotate_insn><mode>3_1"
11662   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11663         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11664                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11665    (clobber (reg:CC FLAGS_REG))]
11666   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11668   if (operands[2] == const1_rtx
11669       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11670     return "<rotate>{<imodesuffix>}\t%0";
11671   else
11672     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11674   [(set_attr "type" "rotate")
11675    (set (attr "length_immediate")
11676      (if_then_else
11677        (and (match_operand 2 "const1_operand")
11678             (ior (match_test "TARGET_SHIFT1")
11679                  (match_test "optimize_function_for_size_p (cfun)")))
11680        (const_string "0")
11681        (const_string "*")))
11682    (set_attr "mode" "<MODE>")])
11684 (define_insn "*<rotate_insn>qi3_1_slp"
11685   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11686         (any_rotate:QI (match_dup 0)
11687                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "(optimize_function_for_size_p (cfun)
11690     || !TARGET_PARTIAL_REG_STALL
11691     || (operands[1] == const1_rtx
11692         && TARGET_SHIFT1))"
11694   if (operands[1] == const1_rtx
11695       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11696     return "<rotate>{b}\t%0";
11697   else
11698     return "<rotate>{b}\t{%1, %0|%0, %1}";
11700   [(set_attr "type" "rotate1")
11701    (set (attr "length_immediate")
11702      (if_then_else
11703        (and (match_operand 1 "const1_operand")
11704             (ior (match_test "TARGET_SHIFT1")
11705                  (match_test "optimize_function_for_size_p (cfun)")))
11706        (const_string "0")
11707        (const_string "*")))
11708    (set_attr "mode" "QI")])
11710 (define_split
11711  [(set (match_operand:HI 0 "QIreg_operand")
11712        (any_rotate:HI (match_dup 0) (const_int 8)))
11713   (clobber (reg:CC FLAGS_REG))]
11714  "reload_completed
11715   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11716  [(parallel [(set (strict_low_part (match_dup 0))
11717                   (bswap:HI (match_dup 0)))
11718              (clobber (reg:CC FLAGS_REG))])])
11720 ;; Bit set / bit test instructions
11722 ;; %%% bts, btr, btc
11724 ;; These instructions are *slow* when applied to memory.
11726 (define_code_attr btsc [(ior "bts") (xor "btc")])
11728 (define_insn "*<btsc><mode>"
11729   [(set (match_operand:SWI48 0 "register_operand" "=r")
11730         (any_or:SWI48
11731           (ashift:SWI48 (const_int 1)
11732                         (match_operand:QI 2 "register_operand" "r"))
11733           (match_operand:SWI48 1 "register_operand" "0")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_USE_BT"
11736   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11737   [(set_attr "type" "alu1")
11738    (set_attr "prefix_0f" "1")
11739    (set_attr "znver1_decode" "double")
11740    (set_attr "mode" "<MODE>")])
11742 ;; Avoid useless masking of count operand.
11743 (define_insn_and_split "*<btsc><mode>_mask"
11744   [(set (match_operand:SWI48 0 "register_operand")
11745         (any_or:SWI48
11746           (ashift:SWI48
11747             (const_int 1)
11748             (subreg:QI
11749               (and:SI
11750                 (match_operand:SI 1 "register_operand")
11751                 (match_operand:SI 2 "const_int_operand")) 0))
11752           (match_operand:SWI48 3 "register_operand")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   "TARGET_USE_BT
11755    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11756       == GET_MODE_BITSIZE (<MODE>mode)-1
11757    && can_create_pseudo_p ()"
11758   "#"
11759   "&& 1"
11760   [(parallel
11761      [(set (match_dup 0)
11762            (any_or:SWI48
11763              (ashift:SWI48 (const_int 1)
11764                            (match_dup 1))
11765              (match_dup 3)))
11766       (clobber (reg:CC FLAGS_REG))])]
11767   "operands[1] = gen_lowpart (QImode, operands[1]);")
11769 (define_insn_and_split "*<btsc><mode>_mask_1"
11770   [(set (match_operand:SWI48 0 "register_operand")
11771         (any_or:SWI48
11772           (ashift:SWI48
11773             (const_int 1)
11774             (and:QI
11775               (match_operand:QI 1 "register_operand")
11776               (match_operand:QI 2 "const_int_operand")))
11777           (match_operand:SWI48 3 "register_operand")))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "TARGET_USE_BT
11780    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11781       == GET_MODE_BITSIZE (<MODE>mode)-1
11782    && can_create_pseudo_p ()"
11783   "#"
11784   "&& 1"
11785   [(parallel
11786      [(set (match_dup 0)
11787            (any_or:SWI48
11788              (ashift:SWI48 (const_int 1)
11789                            (match_dup 1))
11790              (match_dup 3)))
11791       (clobber (reg:CC FLAGS_REG))])])
11793 (define_insn "*btr<mode>"
11794   [(set (match_operand:SWI48 0 "register_operand" "=r")
11795         (and:SWI48
11796           (rotate:SWI48 (const_int -2)
11797                         (match_operand:QI 2 "register_operand" "r"))
11798         (match_operand:SWI48 1 "register_operand" "0")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "TARGET_USE_BT"
11801   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11802   [(set_attr "type" "alu1")
11803    (set_attr "prefix_0f" "1")
11804    (set_attr "znver1_decode" "double")
11805    (set_attr "mode" "<MODE>")])
11807 ;; Avoid useless masking of count operand.
11808 (define_insn_and_split "*btr<mode>_mask"
11809   [(set (match_operand:SWI48 0 "register_operand")
11810         (and:SWI48
11811           (rotate:SWI48
11812             (const_int -2)
11813             (subreg:QI
11814               (and:SI
11815                 (match_operand:SI 1 "register_operand")
11816                 (match_operand:SI 2 "const_int_operand")) 0))
11817           (match_operand:SWI48 3 "register_operand")))
11818    (clobber (reg:CC FLAGS_REG))]
11819   "TARGET_USE_BT
11820    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11821       == GET_MODE_BITSIZE (<MODE>mode)-1
11822    && can_create_pseudo_p ()"
11823   "#"
11824   "&& 1"
11825   [(parallel
11826      [(set (match_dup 0)
11827            (and:SWI48
11828              (rotate:SWI48 (const_int -2)
11829                            (match_dup 1))
11830              (match_dup 3)))
11831       (clobber (reg:CC FLAGS_REG))])]
11832   "operands[1] = gen_lowpart (QImode, operands[1]);")
11834 (define_insn_and_split "*btr<mode>_mask_1"
11835   [(set (match_operand:SWI48 0 "register_operand")
11836         (and:SWI48
11837           (rotate:SWI48
11838             (const_int -2)
11839             (and:QI
11840               (match_operand:QI 1 "register_operand")
11841               (match_operand:QI 2 "const_int_operand")))
11842           (match_operand:SWI48 3 "register_operand")))
11843    (clobber (reg:CC FLAGS_REG))]
11844   "TARGET_USE_BT
11845    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11846       == GET_MODE_BITSIZE (<MODE>mode)-1
11847    && can_create_pseudo_p ()"
11848   "#"
11849   "&& 1"
11850   [(parallel
11851      [(set (match_dup 0)
11852            (and:SWI48
11853              (rotate:SWI48 (const_int -2)
11854                            (match_dup 1))
11855              (match_dup 3)))
11856       (clobber (reg:CC FLAGS_REG))])])
11858 ;; These instructions are never faster than the corresponding
11859 ;; and/ior/xor operations when using immediate operand, so with
11860 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11861 ;; relevant immediates within the instruction itself, so operating
11862 ;; on bits in the high 32-bits of a register becomes easier.
11864 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11865 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11866 ;; negdf respectively, so they can never be disabled entirely.
11868 (define_insn "*btsq_imm"
11869   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11870                          (const_int 1)
11871                          (match_operand 1 "const_0_to_63_operand" "J"))
11872         (const_int 1))
11873    (clobber (reg:CC FLAGS_REG))]
11874   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11875   "bts{q}\t{%1, %0|%0, %1}"
11876   [(set_attr "type" "alu1")
11877    (set_attr "prefix_0f" "1")
11878    (set_attr "znver1_decode" "double")
11879    (set_attr "mode" "DI")])
11881 (define_insn "*btrq_imm"
11882   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11883                          (const_int 1)
11884                          (match_operand 1 "const_0_to_63_operand" "J"))
11885         (const_int 0))
11886    (clobber (reg:CC FLAGS_REG))]
11887   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11888   "btr{q}\t{%1, %0|%0, %1}"
11889   [(set_attr "type" "alu1")
11890    (set_attr "prefix_0f" "1")
11891    (set_attr "znver1_decode" "double")
11892    (set_attr "mode" "DI")])
11894 (define_insn "*btcq_imm"
11895   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11896                          (const_int 1)
11897                          (match_operand 1 "const_0_to_63_operand" "J"))
11898         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11901   "btc{q}\t{%1, %0|%0, %1}"
11902   [(set_attr "type" "alu1")
11903    (set_attr "prefix_0f" "1")
11904    (set_attr "znver1_decode" "double")
11905    (set_attr "mode" "DI")])
11907 ;; Allow Nocona to avoid these instructions if a register is available.
11909 (define_peephole2
11910   [(match_scratch:DI 2 "r")
11911    (parallel [(set (zero_extract:DI
11912                      (match_operand:DI 0 "nonimmediate_operand")
11913                      (const_int 1)
11914                      (match_operand 1 "const_0_to_63_operand"))
11915                    (const_int 1))
11916               (clobber (reg:CC FLAGS_REG))])]
11917   "TARGET_64BIT && !TARGET_USE_BT"
11918   [(parallel [(set (match_dup 0)
11919                    (ior:DI (match_dup 0) (match_dup 3)))
11920               (clobber (reg:CC FLAGS_REG))])]
11922   int i = INTVAL (operands[1]);
11924   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11926   if (!x86_64_immediate_operand (operands[3], DImode))
11927     {
11928       emit_move_insn (operands[2], operands[3]);
11929       operands[3] = operands[2];
11930     }
11933 (define_peephole2
11934   [(match_scratch:DI 2 "r")
11935    (parallel [(set (zero_extract:DI
11936                      (match_operand:DI 0 "nonimmediate_operand")
11937                      (const_int 1)
11938                      (match_operand 1 "const_0_to_63_operand"))
11939                    (const_int 0))
11940               (clobber (reg:CC FLAGS_REG))])]
11941   "TARGET_64BIT && !TARGET_USE_BT"
11942   [(parallel [(set (match_dup 0)
11943                    (and:DI (match_dup 0) (match_dup 3)))
11944               (clobber (reg:CC FLAGS_REG))])]
11946   int i = INTVAL (operands[1]);
11948   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11950   if (!x86_64_immediate_operand (operands[3], DImode))
11951     {
11952       emit_move_insn (operands[2], operands[3]);
11953       operands[3] = operands[2];
11954     }
11957 (define_peephole2
11958   [(match_scratch:DI 2 "r")
11959    (parallel [(set (zero_extract:DI
11960                      (match_operand:DI 0 "nonimmediate_operand")
11961                      (const_int 1)
11962                      (match_operand 1 "const_0_to_63_operand"))
11963               (not:DI (zero_extract:DI
11964                         (match_dup 0) (const_int 1) (match_dup 1))))
11965               (clobber (reg:CC FLAGS_REG))])]
11966   "TARGET_64BIT && !TARGET_USE_BT"
11967   [(parallel [(set (match_dup 0)
11968                    (xor:DI (match_dup 0) (match_dup 3)))
11969               (clobber (reg:CC FLAGS_REG))])]
11971   int i = INTVAL (operands[1]);
11973   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11975   if (!x86_64_immediate_operand (operands[3], DImode))
11976     {
11977       emit_move_insn (operands[2], operands[3]);
11978       operands[3] = operands[2];
11979     }
11982 ;; %%% bt
11984 (define_insn "*bt<mode>"
11985   [(set (reg:CCC FLAGS_REG)
11986         (compare:CCC
11987           (zero_extract:SWI48
11988             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11989             (const_int 1)
11990             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11991           (const_int 0)))]
11992   ""
11994   switch (get_attr_mode (insn))
11995     {
11996     case MODE_SI:
11997       return "bt{l}\t{%1, %k0|%k0, %1}";
11999     case MODE_DI:
12000       return "bt{q}\t{%q1, %0|%0, %q1}";
12002     default:
12003       gcc_unreachable ();
12004     }
12006   [(set_attr "type" "alu1")
12007    (set_attr "prefix_0f" "1")
12008    (set (attr "mode")
12009         (if_then_else
12010           (and (match_test "CONST_INT_P (operands[1])")
12011                (match_test "INTVAL (operands[1]) < 32"))
12012           (const_string "SI")
12013           (const_string "<MODE>")))])
12015 (define_insn_and_split "*jcc_bt<mode>"
12016   [(set (pc)
12017         (if_then_else (match_operator 0 "bt_comparison_operator"
12018                         [(zero_extract:SWI48
12019                            (match_operand:SWI48 1 "nonimmediate_operand")
12020                            (const_int 1)
12021                            (match_operand:SI 2 "nonmemory_operand"))
12022                          (const_int 0)])
12023                       (label_ref (match_operand 3))
12024                       (pc)))
12025    (clobber (reg:CC FLAGS_REG))]
12026   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12027    && (CONST_INT_P (operands[2])
12028        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12029           && INTVAL (operands[2])
12030                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12031        : !memory_operand (operands[1], <MODE>mode))
12032    && can_create_pseudo_p ()"
12033   "#"
12034   "&& 1"
12035   [(set (reg:CCC FLAGS_REG)
12036         (compare:CCC
12037           (zero_extract:SWI48
12038             (match_dup 1)
12039             (const_int 1)
12040             (match_dup 2))
12041           (const_int 0)))
12042    (set (pc)
12043         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12044                       (label_ref (match_dup 3))
12045                       (pc)))]
12047   operands[0] = shallow_copy_rtx (operands[0]);
12048   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12051 (define_insn_and_split "*jcc_bt<mode>_1"
12052   [(set (pc)
12053         (if_then_else (match_operator 0 "bt_comparison_operator"
12054                         [(zero_extract:SWI48
12055                            (match_operand:SWI48 1 "register_operand")
12056                            (const_int 1)
12057                            (zero_extend:SI
12058                              (match_operand:QI 2 "register_operand")))
12059                          (const_int 0)])
12060                       (label_ref (match_operand 3))
12061                       (pc)))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12064    && can_create_pseudo_p ()"
12065   "#"
12066   "&& 1"
12067   [(set (reg:CCC FLAGS_REG)
12068         (compare:CCC
12069           (zero_extract:SWI48
12070             (match_dup 1)
12071             (const_int 1)
12072             (match_dup 2))
12073           (const_int 0)))
12074    (set (pc)
12075         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12076                       (label_ref (match_dup 3))
12077                       (pc)))]
12079   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12080   operands[0] = shallow_copy_rtx (operands[0]);
12081   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12084 ;; Avoid useless masking of bit offset operand.
12085 (define_insn_and_split "*jcc_bt<mode>_mask"
12086   [(set (pc)
12087         (if_then_else (match_operator 0 "bt_comparison_operator"
12088                         [(zero_extract:SWI48
12089                            (match_operand:SWI48 1 "register_operand")
12090                            (const_int 1)
12091                            (and:SI
12092                              (match_operand:SI 2 "register_operand")
12093                              (match_operand 3 "const_int_operand")))])
12094                       (label_ref (match_operand 4))
12095                       (pc)))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12098    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12099       == GET_MODE_BITSIZE (<MODE>mode)-1
12100    && can_create_pseudo_p ()"
12101   "#"
12102   "&& 1"
12103   [(set (reg:CCC FLAGS_REG)
12104         (compare:CCC
12105           (zero_extract:SWI48
12106             (match_dup 1)
12107             (const_int 1)
12108             (match_dup 2))
12109           (const_int 0)))
12110    (set (pc)
12111         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12112                       (label_ref (match_dup 4))
12113                       (pc)))]
12115   operands[0] = shallow_copy_rtx (operands[0]);
12116   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12119 ;; Store-flag instructions.
12121 ;; For all sCOND expanders, also expand the compare or test insn that
12122 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12124 (define_insn_and_split "*setcc_di_1"
12125   [(set (match_operand:DI 0 "register_operand" "=q")
12126         (match_operator:DI 1 "ix86_comparison_operator"
12127           [(reg FLAGS_REG) (const_int 0)]))]
12128   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12129   "#"
12130   "&& reload_completed"
12131   [(set (match_dup 2) (match_dup 1))
12132    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12134   operands[1] = shallow_copy_rtx (operands[1]);
12135   PUT_MODE (operands[1], QImode);
12136   operands[2] = gen_lowpart (QImode, operands[0]);
12139 (define_insn_and_split "*setcc_si_1_and"
12140   [(set (match_operand:SI 0 "register_operand" "=q")
12141         (match_operator:SI 1 "ix86_comparison_operator"
12142           [(reg FLAGS_REG) (const_int 0)]))
12143    (clobber (reg:CC FLAGS_REG))]
12144   "!TARGET_PARTIAL_REG_STALL
12145    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12146   "#"
12147   "&& reload_completed"
12148   [(set (match_dup 2) (match_dup 1))
12149    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12150               (clobber (reg:CC FLAGS_REG))])]
12152   operands[1] = shallow_copy_rtx (operands[1]);
12153   PUT_MODE (operands[1], QImode);
12154   operands[2] = gen_lowpart (QImode, operands[0]);
12157 (define_insn_and_split "*setcc_si_1_movzbl"
12158   [(set (match_operand:SI 0 "register_operand" "=q")
12159         (match_operator:SI 1 "ix86_comparison_operator"
12160           [(reg FLAGS_REG) (const_int 0)]))]
12161   "!TARGET_PARTIAL_REG_STALL
12162    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12163   "#"
12164   "&& reload_completed"
12165   [(set (match_dup 2) (match_dup 1))
12166    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12168   operands[1] = shallow_copy_rtx (operands[1]);
12169   PUT_MODE (operands[1], QImode);
12170   operands[2] = gen_lowpart (QImode, operands[0]);
12173 (define_insn "*setcc_qi"
12174   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12175         (match_operator:QI 1 "ix86_comparison_operator"
12176           [(reg FLAGS_REG) (const_int 0)]))]
12177   ""
12178   "set%C1\t%0"
12179   [(set_attr "type" "setcc")
12180    (set_attr "mode" "QI")])
12182 (define_insn "*setcc_qi_slp"
12183   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12184         (match_operator:QI 1 "ix86_comparison_operator"
12185           [(reg FLAGS_REG) (const_int 0)]))]
12186   ""
12187   "set%C1\t%0"
12188   [(set_attr "type" "setcc")
12189    (set_attr "mode" "QI")])
12191 ;; In general it is not safe to assume too much about CCmode registers,
12192 ;; so simplify-rtx stops when it sees a second one.  Under certain
12193 ;; conditions this is safe on x86, so help combine not create
12195 ;;      seta    %al
12196 ;;      testb   %al, %al
12197 ;;      sete    %al
12199 (define_split
12200   [(set (match_operand:QI 0 "nonimmediate_operand")
12201         (ne:QI (match_operator 1 "ix86_comparison_operator"
12202                  [(reg FLAGS_REG) (const_int 0)])
12203             (const_int 0)))]
12204   ""
12205   [(set (match_dup 0) (match_dup 1))]
12207   operands[1] = shallow_copy_rtx (operands[1]);
12208   PUT_MODE (operands[1], QImode);
12211 (define_split
12212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12213         (ne:QI (match_operator 1 "ix86_comparison_operator"
12214                  [(reg FLAGS_REG) (const_int 0)])
12215             (const_int 0)))]
12216   ""
12217   [(set (match_dup 0) (match_dup 1))]
12219   operands[1] = shallow_copy_rtx (operands[1]);
12220   PUT_MODE (operands[1], QImode);
12223 (define_split
12224   [(set (match_operand:QI 0 "nonimmediate_operand")
12225         (eq:QI (match_operator 1 "ix86_comparison_operator"
12226                  [(reg FLAGS_REG) (const_int 0)])
12227             (const_int 0)))]
12228   ""
12229   [(set (match_dup 0) (match_dup 1))]
12231   operands[1] = shallow_copy_rtx (operands[1]);
12232   PUT_MODE (operands[1], QImode);
12233   PUT_CODE (operands[1],
12234             ix86_reverse_condition (GET_CODE (operands[1]),
12235                                     GET_MODE (XEXP (operands[1], 0))));
12237   /* Make sure that (a) the CCmode we have for the flags is strong
12238      enough for the reversed compare or (b) we have a valid FP compare.  */
12239   if (! ix86_comparison_operator (operands[1], VOIDmode))
12240     FAIL;
12243 (define_split
12244   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12245         (eq:QI (match_operator 1 "ix86_comparison_operator"
12246                  [(reg FLAGS_REG) (const_int 0)])
12247             (const_int 0)))]
12248   ""
12249   [(set (match_dup 0) (match_dup 1))]
12251   operands[1] = shallow_copy_rtx (operands[1]);
12252   PUT_MODE (operands[1], QImode);
12253   PUT_CODE (operands[1],
12254             ix86_reverse_condition (GET_CODE (operands[1]),
12255                                     GET_MODE (XEXP (operands[1], 0))));
12257   /* Make sure that (a) the CCmode we have for the flags is strong
12258      enough for the reversed compare or (b) we have a valid FP compare.  */
12259   if (! ix86_comparison_operator (operands[1], VOIDmode))
12260     FAIL;
12263 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12264 ;; subsequent logical operations are used to imitate conditional moves.
12265 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12266 ;; it directly.
12268 (define_insn "setcc_<mode>_sse"
12269   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12270         (match_operator:MODEF 3 "sse_comparison_operator"
12271           [(match_operand:MODEF 1 "register_operand" "0,x")
12272            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12273   "SSE_FLOAT_MODE_P (<MODE>mode)"
12274   "@
12275    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12276    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12277   [(set_attr "isa" "noavx,avx")
12278    (set_attr "type" "ssecmp")
12279    (set_attr "length_immediate" "1")
12280    (set_attr "prefix" "orig,vex")
12281    (set_attr "mode" "<MODE>")])
12283 ;; Basic conditional jump instructions.
12284 ;; We ignore the overflow flag for signed branch instructions.
12286 (define_insn "*jcc"
12287   [(set (pc)
12288         (if_then_else (match_operator 1 "ix86_comparison_operator"
12289                                       [(reg FLAGS_REG) (const_int 0)])
12290                       (label_ref (match_operand 0))
12291                       (pc)))]
12292   ""
12293   "%!%+j%C1\t%l0"
12294   [(set_attr "type" "ibr")
12295    (set_attr "modrm" "0")
12296    (set (attr "length")
12297         (if_then_else
12298           (and (ge (minus (match_dup 0) (pc))
12299                    (const_int -126))
12300                (lt (minus (match_dup 0) (pc))
12301                    (const_int 128)))
12302           (const_int 2)
12303           (const_int 6)))
12304    (set_attr "maybe_prefix_bnd" "1")])
12306 ;; In general it is not safe to assume too much about CCmode registers,
12307 ;; so simplify-rtx stops when it sees a second one.  Under certain
12308 ;; conditions this is safe on x86, so help combine not create
12310 ;;      seta    %al
12311 ;;      testb   %al, %al
12312 ;;      je      Lfoo
12314 (define_split
12315   [(set (pc)
12316         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12317                                       [(reg FLAGS_REG) (const_int 0)])
12318                           (const_int 0))
12319                       (label_ref (match_operand 1))
12320                       (pc)))]
12321   ""
12322   [(set (pc)
12323         (if_then_else (match_dup 0)
12324                       (label_ref (match_dup 1))
12325                       (pc)))]
12327   operands[0] = shallow_copy_rtx (operands[0]);
12328   PUT_MODE (operands[0], VOIDmode);
12331 (define_split
12332   [(set (pc)
12333         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12334                                       [(reg FLAGS_REG) (const_int 0)])
12335                           (const_int 0))
12336                       (label_ref (match_operand 1))
12337                       (pc)))]
12338   ""
12339   [(set (pc)
12340         (if_then_else (match_dup 0)
12341                       (label_ref (match_dup 1))
12342                       (pc)))]
12344   operands[0] = shallow_copy_rtx (operands[0]);
12345   PUT_MODE (operands[0], VOIDmode);
12346   PUT_CODE (operands[0],
12347             ix86_reverse_condition (GET_CODE (operands[0]),
12348                                     GET_MODE (XEXP (operands[0], 0))));
12350   /* Make sure that (a) the CCmode we have for the flags is strong
12351      enough for the reversed compare or (b) we have a valid FP compare.  */
12352   if (! ix86_comparison_operator (operands[0], VOIDmode))
12353     FAIL;
12356 ;; Unconditional and other jump instructions
12358 (define_insn "jump"
12359   [(set (pc)
12360         (label_ref (match_operand 0)))]
12361   ""
12362   "%!jmp\t%l0"
12363   [(set_attr "type" "ibr")
12364    (set_attr "modrm" "0")
12365    (set (attr "length")
12366         (if_then_else
12367           (and (ge (minus (match_dup 0) (pc))
12368                    (const_int -126))
12369                (lt (minus (match_dup 0) (pc))
12370                    (const_int 128)))
12371           (const_int 2)
12372           (const_int 5)))
12373    (set_attr "maybe_prefix_bnd" "1")])
12375 (define_expand "indirect_jump"
12376   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12377   ""
12379   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12380     operands[0] = convert_memory_address (word_mode, operands[0]);
12381   cfun->machine->has_local_indirect_jump = true;
12384 (define_insn "*indirect_jump"
12385   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12386   ""
12387   "* return ix86_output_indirect_jmp (operands[0]);"
12388   [(set (attr "type")
12389      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12390                                  != indirect_branch_keep)")
12391         (const_string "multi")
12392         (const_string "ibr")))
12393    (set_attr "length_immediate" "0")
12394    (set_attr "maybe_prefix_bnd" "1")])
12396 (define_expand "tablejump"
12397   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12398               (use (label_ref (match_operand 1)))])]
12399   ""
12401   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12402      relative.  Convert the relative address to an absolute address.  */
12403   if (flag_pic)
12404     {
12405       rtx op0, op1;
12406       enum rtx_code code;
12408       /* We can't use @GOTOFF for text labels on VxWorks;
12409          see gotoff_operand.  */
12410       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12411         {
12412           code = PLUS;
12413           op0 = operands[0];
12414           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12415         }
12416       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12417         {
12418           code = PLUS;
12419           op0 = operands[0];
12420           op1 = pic_offset_table_rtx;
12421         }
12422       else
12423         {
12424           code = MINUS;
12425           op0 = pic_offset_table_rtx;
12426           op1 = operands[0];
12427         }
12429       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12430                                          OPTAB_DIRECT);
12431     }
12433   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12434     operands[0] = convert_memory_address (word_mode, operands[0]);
12435   cfun->machine->has_local_indirect_jump = true;
12438 (define_insn "*tablejump_1"
12439   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12440    (use (label_ref (match_operand 1)))]
12441   ""
12442   "* return ix86_output_indirect_jmp (operands[0]);"
12443   [(set (attr "type")
12444      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12445                                  != indirect_branch_keep)")
12446         (const_string "multi")
12447         (const_string "ibr")))
12448    (set_attr "length_immediate" "0")
12449    (set_attr "maybe_prefix_bnd" "1")])
12451 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12453 (define_peephole2
12454   [(set (reg FLAGS_REG) (match_operand 0))
12455    (set (match_operand:QI 1 "register_operand")
12456         (match_operator:QI 2 "ix86_comparison_operator"
12457           [(reg FLAGS_REG) (const_int 0)]))
12458    (set (match_operand 3 "any_QIreg_operand")
12459         (zero_extend (match_dup 1)))]
12460   "(peep2_reg_dead_p (3, operands[1])
12461     || operands_match_p (operands[1], operands[3]))
12462    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12463    && peep2_regno_dead_p (0, FLAGS_REG)"
12464   [(set (match_dup 4) (match_dup 0))
12465    (set (strict_low_part (match_dup 5))
12466         (match_dup 2))]
12468   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12469   operands[5] = gen_lowpart (QImode, operands[3]);
12470   ix86_expand_clear (operands[3]);
12473 (define_peephole2
12474   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12475               (match_operand 4)])
12476    (set (match_operand:QI 1 "register_operand")
12477         (match_operator:QI 2 "ix86_comparison_operator"
12478           [(reg FLAGS_REG) (const_int 0)]))
12479    (set (match_operand 3 "any_QIreg_operand")
12480         (zero_extend (match_dup 1)))]
12481   "(peep2_reg_dead_p (3, operands[1])
12482     || operands_match_p (operands[1], operands[3]))
12483    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12484    && ! reg_set_p (operands[3], operands[4])
12485    && peep2_regno_dead_p (0, FLAGS_REG)"
12486   [(parallel [(set (match_dup 5) (match_dup 0))
12487               (match_dup 4)])
12488    (set (strict_low_part (match_dup 6))
12489         (match_dup 2))]
12491   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12492   operands[6] = gen_lowpart (QImode, operands[3]);
12493   ix86_expand_clear (operands[3]);
12496 (define_peephole2
12497   [(set (reg FLAGS_REG) (match_operand 0))
12498    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12499               (match_operand 5)])
12500    (set (match_operand:QI 2 "register_operand")
12501         (match_operator:QI 3 "ix86_comparison_operator"
12502           [(reg FLAGS_REG) (const_int 0)]))
12503    (set (match_operand 4 "any_QIreg_operand")
12504         (zero_extend (match_dup 2)))]
12505   "(peep2_reg_dead_p (4, operands[2])
12506     || operands_match_p (operands[2], operands[4]))
12507    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12508    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12509    && ! reg_set_p (operands[4], operands[5])
12510    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12511    && peep2_regno_dead_p (0, FLAGS_REG)"
12512   [(set (match_dup 6) (match_dup 0))
12513    (parallel [(set (match_dup 7) (match_dup 1))
12514               (match_dup 5)])
12515    (set (strict_low_part (match_dup 8))
12516         (match_dup 3))]
12518   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12519   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12520   operands[8] = gen_lowpart (QImode, operands[4]);
12521   ix86_expand_clear (operands[4]);
12524 ;; Similar, but match zero extend with andsi3.
12526 (define_peephole2
12527   [(set (reg FLAGS_REG) (match_operand 0))
12528    (set (match_operand:QI 1 "register_operand")
12529         (match_operator:QI 2 "ix86_comparison_operator"
12530           [(reg FLAGS_REG) (const_int 0)]))
12531    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12532                    (and:SI (match_dup 3) (const_int 255)))
12533               (clobber (reg:CC FLAGS_REG))])]
12534   "REGNO (operands[1]) == REGNO (operands[3])
12535    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12536    && peep2_regno_dead_p (0, FLAGS_REG)"
12537   [(set (match_dup 4) (match_dup 0))
12538    (set (strict_low_part (match_dup 5))
12539         (match_dup 2))]
12541   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12542   operands[5] = gen_lowpart (QImode, operands[3]);
12543   ix86_expand_clear (operands[3]);
12546 (define_peephole2
12547   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12548               (match_operand 4)])
12549    (set (match_operand:QI 1 "register_operand")
12550         (match_operator:QI 2 "ix86_comparison_operator"
12551           [(reg FLAGS_REG) (const_int 0)]))
12552    (parallel [(set (match_operand 3 "any_QIreg_operand")
12553                    (zero_extend (match_dup 1)))
12554               (clobber (reg:CC FLAGS_REG))])]
12555   "(peep2_reg_dead_p (3, operands[1])
12556     || operands_match_p (operands[1], operands[3]))
12557    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12558    && ! reg_set_p (operands[3], operands[4])
12559    && peep2_regno_dead_p (0, FLAGS_REG)"
12560   [(parallel [(set (match_dup 5) (match_dup 0))
12561               (match_dup 4)])
12562    (set (strict_low_part (match_dup 6))
12563         (match_dup 2))]
12565   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12566   operands[6] = gen_lowpart (QImode, operands[3]);
12567   ix86_expand_clear (operands[3]);
12570 (define_peephole2
12571   [(set (reg FLAGS_REG) (match_operand 0))
12572    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12573               (match_operand 5)])
12574    (set (match_operand:QI 2 "register_operand")
12575         (match_operator:QI 3 "ix86_comparison_operator"
12576           [(reg FLAGS_REG) (const_int 0)]))
12577    (parallel [(set (match_operand 4 "any_QIreg_operand")
12578                    (zero_extend (match_dup 2)))
12579               (clobber (reg:CC FLAGS_REG))])]
12580   "(peep2_reg_dead_p (4, operands[2])
12581     || operands_match_p (operands[2], operands[4]))
12582    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12583    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12584    && ! reg_set_p (operands[4], operands[5])
12585    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12586    && peep2_regno_dead_p (0, FLAGS_REG)"
12587   [(set (match_dup 6) (match_dup 0))
12588    (parallel [(set (match_dup 7) (match_dup 1))
12589               (match_dup 5)])
12590    (set (strict_low_part (match_dup 8))
12591         (match_dup 3))]
12593   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12594   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12595   operands[8] = gen_lowpart (QImode, operands[4]);
12596   ix86_expand_clear (operands[4]);
12599 ;; Call instructions.
12601 ;; The predicates normally associated with named expanders are not properly
12602 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12603 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12605 ;; P6 processors will jump to the address after the decrement when %esp
12606 ;; is used as a call operand, so they will execute return address as a code.
12607 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12609 ;; Register constraint for call instruction.
12610 (define_mode_attr c [(SI "l") (DI "r")])
12612 ;; Call subroutine returning no value.
12614 (define_expand "call"
12615   [(call (match_operand:QI 0)
12616          (match_operand 1))
12617    (use (match_operand 2))]
12618   ""
12620   ix86_expand_call (NULL, operands[0], operands[1],
12621                     operands[2], NULL, false);
12622   DONE;
12625 (define_expand "sibcall"
12626   [(call (match_operand:QI 0)
12627          (match_operand 1))
12628    (use (match_operand 2))]
12629   ""
12631   ix86_expand_call (NULL, operands[0], operands[1],
12632                     operands[2], NULL, true);
12633   DONE;
12636 (define_insn "*call"
12637   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12638          (match_operand 1))]
12639   "!SIBLING_CALL_P (insn)"
12640   "* return ix86_output_call_insn (insn, operands[0]);"
12641   [(set_attr "type" "call")])
12643 ;; This covers both call and sibcall since only GOT slot is allowed.
12644 (define_insn "*call_got_x32"
12645   [(call (mem:QI (zero_extend:DI
12646                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12647          (match_operand 1))]
12648   "TARGET_X32"
12650   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12651   return ix86_output_call_insn (insn, fnaddr);
12653   [(set_attr "type" "call")])
12655 ;; Since sibcall never returns, we can only use call-clobbered register
12656 ;; as GOT base.
12657 (define_insn "*sibcall_GOT_32"
12658   [(call (mem:QI
12659            (mem:SI (plus:SI
12660                      (match_operand:SI 0 "register_no_elim_operand" "U")
12661                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12662          (match_operand 2))]
12663   "!TARGET_MACHO
12664   && !TARGET_64BIT
12665   && !TARGET_INDIRECT_BRANCH_REGISTER
12666   && SIBLING_CALL_P (insn)"
12668   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12669   fnaddr = gen_const_mem (SImode, fnaddr);
12670   return ix86_output_call_insn (insn, fnaddr);
12672   [(set_attr "type" "call")])
12674 (define_insn "*sibcall"
12675   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12676          (match_operand 1))]
12677   "SIBLING_CALL_P (insn)"
12678   "* return ix86_output_call_insn (insn, operands[0]);"
12679   [(set_attr "type" "call")])
12681 (define_insn "*sibcall_memory"
12682   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12683          (match_operand 1))
12684    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12685   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12686   "* return ix86_output_call_insn (insn, operands[0]);"
12687   [(set_attr "type" "call")])
12689 (define_peephole2
12690   [(set (match_operand:W 0 "register_operand")
12691         (match_operand:W 1 "memory_operand"))
12692    (call (mem:QI (match_dup 0))
12693          (match_operand 3))]
12694   "!TARGET_X32
12695    && !TARGET_INDIRECT_BRANCH_REGISTER
12696    && SIBLING_CALL_P (peep2_next_insn (1))
12697    && !reg_mentioned_p (operands[0],
12698                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12699   [(parallel [(call (mem:QI (match_dup 1))
12700                     (match_dup 3))
12701               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12703 (define_peephole2
12704   [(set (match_operand:W 0 "register_operand")
12705         (match_operand:W 1 "memory_operand"))
12706    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12707    (call (mem:QI (match_dup 0))
12708          (match_operand 3))]
12709   "!TARGET_X32
12710    && !TARGET_INDIRECT_BRANCH_REGISTER
12711    && SIBLING_CALL_P (peep2_next_insn (2))
12712    && !reg_mentioned_p (operands[0],
12713                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12714   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12715    (parallel [(call (mem:QI (match_dup 1))
12716                     (match_dup 3))
12717               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12719 (define_expand "call_pop"
12720   [(parallel [(call (match_operand:QI 0)
12721                     (match_operand:SI 1))
12722               (set (reg:SI SP_REG)
12723                    (plus:SI (reg:SI SP_REG)
12724                             (match_operand:SI 3)))])]
12725   "!TARGET_64BIT"
12727   ix86_expand_call (NULL, operands[0], operands[1],
12728                     operands[2], operands[3], false);
12729   DONE;
12732 (define_insn "*call_pop"
12733   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12734          (match_operand 1))
12735    (set (reg:SI SP_REG)
12736         (plus:SI (reg:SI SP_REG)
12737                  (match_operand:SI 2 "immediate_operand" "i")))]
12738   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12739   "* return ix86_output_call_insn (insn, operands[0]);"
12740   [(set_attr "type" "call")])
12742 (define_insn "*sibcall_pop"
12743   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12744          (match_operand 1))
12745    (set (reg:SI SP_REG)
12746         (plus:SI (reg:SI SP_REG)
12747                  (match_operand:SI 2 "immediate_operand" "i")))]
12748   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12749   "* return ix86_output_call_insn (insn, operands[0]);"
12750   [(set_attr "type" "call")])
12752 (define_insn "*sibcall_pop_memory"
12753   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12754          (match_operand 1))
12755    (set (reg:SI SP_REG)
12756         (plus:SI (reg:SI SP_REG)
12757                  (match_operand:SI 2 "immediate_operand" "i")))
12758    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12759   "!TARGET_64BIT"
12760   "* return ix86_output_call_insn (insn, operands[0]);"
12761   [(set_attr "type" "call")])
12763 (define_peephole2
12764   [(set (match_operand:SI 0 "register_operand")
12765         (match_operand:SI 1 "memory_operand"))
12766    (parallel [(call (mem:QI (match_dup 0))
12767                     (match_operand 3))
12768               (set (reg:SI SP_REG)
12769                    (plus:SI (reg:SI SP_REG)
12770                             (match_operand:SI 4 "immediate_operand")))])]
12771   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12772    && !reg_mentioned_p (operands[0],
12773                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12774   [(parallel [(call (mem:QI (match_dup 1))
12775                     (match_dup 3))
12776               (set (reg:SI SP_REG)
12777                    (plus:SI (reg:SI SP_REG)
12778                             (match_dup 4)))
12779               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12781 (define_peephole2
12782   [(set (match_operand:SI 0 "register_operand")
12783         (match_operand:SI 1 "memory_operand"))
12784    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12785    (parallel [(call (mem:QI (match_dup 0))
12786                     (match_operand 3))
12787               (set (reg:SI SP_REG)
12788                    (plus:SI (reg:SI SP_REG)
12789                             (match_operand:SI 4 "immediate_operand")))])]
12790   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12791    && !reg_mentioned_p (operands[0],
12792                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12793   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12794    (parallel [(call (mem:QI (match_dup 1))
12795                     (match_dup 3))
12796               (set (reg:SI SP_REG)
12797                    (plus:SI (reg:SI SP_REG)
12798                             (match_dup 4)))
12799               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12801 ;; Combining simple memory jump instruction
12803 (define_peephole2
12804   [(set (match_operand:W 0 "register_operand")
12805         (match_operand:W 1 "memory_operand"))
12806    (set (pc) (match_dup 0))]
12807   "!TARGET_X32
12808    && !TARGET_INDIRECT_BRANCH_REGISTER
12809    && peep2_reg_dead_p (2, operands[0])"
12810   [(set (pc) (match_dup 1))])
12812 ;; Call subroutine, returning value in operand 0
12814 (define_expand "call_value"
12815   [(set (match_operand 0)
12816         (call (match_operand:QI 1)
12817               (match_operand 2)))
12818    (use (match_operand 3))]
12819   ""
12821   ix86_expand_call (operands[0], operands[1], operands[2],
12822                     operands[3], NULL, false);
12823   DONE;
12826 (define_expand "sibcall_value"
12827   [(set (match_operand 0)
12828         (call (match_operand:QI 1)
12829               (match_operand 2)))
12830    (use (match_operand 3))]
12831   ""
12833   ix86_expand_call (operands[0], operands[1], operands[2],
12834                     operands[3], NULL, true);
12835   DONE;
12838 (define_insn "*call_value"
12839   [(set (match_operand 0)
12840         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12841               (match_operand 2)))]
12842   "!SIBLING_CALL_P (insn)"
12843   "* return ix86_output_call_insn (insn, operands[1]);"
12844   [(set_attr "type" "callv")])
12846 ;; This covers both call and sibcall since only GOT slot is allowed.
12847 (define_insn "*call_value_got_x32"
12848   [(set (match_operand 0)
12849         (call (mem:QI
12850                 (zero_extend:DI
12851                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12852               (match_operand 2)))]
12853   "TARGET_X32"
12855   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12856   return ix86_output_call_insn (insn, fnaddr);
12858   [(set_attr "type" "callv")])
12860 ;; Since sibcall never returns, we can only use call-clobbered register
12861 ;; as GOT base.
12862 (define_insn "*sibcall_value_GOT_32"
12863   [(set (match_operand 0)
12864         (call (mem:QI
12865                 (mem:SI (plus:SI
12866                           (match_operand:SI 1 "register_no_elim_operand" "U")
12867                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12868          (match_operand 3)))]
12869   "!TARGET_MACHO
12870    && !TARGET_64BIT
12871    && !TARGET_INDIRECT_BRANCH_REGISTER
12872    && SIBLING_CALL_P (insn)"
12874   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12875   fnaddr = gen_const_mem (SImode, fnaddr);
12876   return ix86_output_call_insn (insn, fnaddr);
12878   [(set_attr "type" "callv")])
12880 (define_insn "*sibcall_value"
12881   [(set (match_operand 0)
12882         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12883               (match_operand 2)))]
12884   "SIBLING_CALL_P (insn)"
12885   "* return ix86_output_call_insn (insn, operands[1]);"
12886   [(set_attr "type" "callv")])
12888 (define_insn "*sibcall_value_memory"
12889   [(set (match_operand 0)
12890         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12891               (match_operand 2)))
12892    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12893   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12894   "* return ix86_output_call_insn (insn, operands[1]);"
12895   [(set_attr "type" "callv")])
12897 (define_peephole2
12898   [(set (match_operand:W 0 "register_operand")
12899         (match_operand:W 1 "memory_operand"))
12900    (set (match_operand 2)
12901    (call (mem:QI (match_dup 0))
12902                  (match_operand 3)))]
12903   "!TARGET_X32
12904    && !TARGET_INDIRECT_BRANCH_REGISTER
12905    && SIBLING_CALL_P (peep2_next_insn (1))
12906    && !reg_mentioned_p (operands[0],
12907                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12908   [(parallel [(set (match_dup 2)
12909                    (call (mem:QI (match_dup 1))
12910                          (match_dup 3)))
12911               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12913 (define_peephole2
12914   [(set (match_operand:W 0 "register_operand")
12915         (match_operand:W 1 "memory_operand"))
12916    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12917    (set (match_operand 2)
12918         (call (mem:QI (match_dup 0))
12919               (match_operand 3)))]
12920   "!TARGET_X32
12921    && !TARGET_INDIRECT_BRANCH_REGISTER
12922    && SIBLING_CALL_P (peep2_next_insn (2))
12923    && !reg_mentioned_p (operands[0],
12924                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12925   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12926    (parallel [(set (match_dup 2)
12927                    (call (mem:QI (match_dup 1))
12928                          (match_dup 3)))
12929               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12931 (define_expand "call_value_pop"
12932   [(parallel [(set (match_operand 0)
12933                    (call (match_operand:QI 1)
12934                          (match_operand:SI 2)))
12935               (set (reg:SI SP_REG)
12936                    (plus:SI (reg:SI SP_REG)
12937                             (match_operand:SI 4)))])]
12938   "!TARGET_64BIT"
12940   ix86_expand_call (operands[0], operands[1], operands[2],
12941                     operands[3], operands[4], false);
12942   DONE;
12945 (define_insn "*call_value_pop"
12946   [(set (match_operand 0)
12947         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12948               (match_operand 2)))
12949    (set (reg:SI SP_REG)
12950         (plus:SI (reg:SI SP_REG)
12951                  (match_operand:SI 3 "immediate_operand" "i")))]
12952   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12953   "* return ix86_output_call_insn (insn, operands[1]);"
12954   [(set_attr "type" "callv")])
12956 (define_insn "*sibcall_value_pop"
12957   [(set (match_operand 0)
12958         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12959               (match_operand 2)))
12960    (set (reg:SI SP_REG)
12961         (plus:SI (reg:SI SP_REG)
12962                  (match_operand:SI 3 "immediate_operand" "i")))]
12963   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12964   "* return ix86_output_call_insn (insn, operands[1]);"
12965   [(set_attr "type" "callv")])
12967 (define_insn "*sibcall_value_pop_memory"
12968   [(set (match_operand 0)
12969         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12970               (match_operand 2)))
12971    (set (reg:SI SP_REG)
12972         (plus:SI (reg:SI SP_REG)
12973                  (match_operand:SI 3 "immediate_operand" "i")))
12974    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12975   "!TARGET_64BIT"
12976   "* return ix86_output_call_insn (insn, operands[1]);"
12977   [(set_attr "type" "callv")])
12979 (define_peephole2
12980   [(set (match_operand:SI 0 "register_operand")
12981         (match_operand:SI 1 "memory_operand"))
12982    (parallel [(set (match_operand 2)
12983                    (call (mem:QI (match_dup 0))
12984                          (match_operand 3)))
12985               (set (reg:SI SP_REG)
12986                    (plus:SI (reg:SI SP_REG)
12987                             (match_operand:SI 4 "immediate_operand")))])]
12988   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12989    && !reg_mentioned_p (operands[0],
12990                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12991   [(parallel [(set (match_dup 2)
12992                    (call (mem:QI (match_dup 1))
12993                          (match_dup 3)))
12994               (set (reg:SI SP_REG)
12995                    (plus:SI (reg:SI SP_REG)
12996                             (match_dup 4)))
12997               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12999 (define_peephole2
13000   [(set (match_operand:SI 0 "register_operand")
13001         (match_operand:SI 1 "memory_operand"))
13002    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13003    (parallel [(set (match_operand 2)
13004                    (call (mem:QI (match_dup 0))
13005                          (match_operand 3)))
13006               (set (reg:SI SP_REG)
13007                    (plus:SI (reg:SI SP_REG)
13008                             (match_operand:SI 4 "immediate_operand")))])]
13009   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13010    && !reg_mentioned_p (operands[0],
13011                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13012   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13013    (parallel [(set (match_dup 2)
13014                    (call (mem:QI (match_dup 1))
13015                          (match_dup 3)))
13016               (set (reg:SI SP_REG)
13017                    (plus:SI (reg:SI SP_REG)
13018                             (match_dup 4)))
13019               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13021 ;; Call subroutine returning any type.
13023 (define_expand "untyped_call"
13024   [(parallel [(call (match_operand 0)
13025                     (const_int 0))
13026               (match_operand 1)
13027               (match_operand 2)])]
13028   ""
13030   int i;
13032   /* In order to give reg-stack an easier job in validating two
13033      coprocessor registers as containing a possible return value,
13034      simply pretend the untyped call returns a complex long double
13035      value. 
13037      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13038      and should have the default ABI.  */
13040   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13041                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13042                     operands[0], const0_rtx,
13043                     GEN_INT ((TARGET_64BIT
13044                               ? (ix86_abi == SYSV_ABI
13045                                  ? X86_64_SSE_REGPARM_MAX
13046                                  : X86_64_MS_SSE_REGPARM_MAX)
13047                               : X86_32_SSE_REGPARM_MAX)
13048                              - 1),
13049                     NULL, false);
13051   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13052     {
13053       rtx set = XVECEXP (operands[2], 0, i);
13054       emit_move_insn (SET_DEST (set), SET_SRC (set));
13055     }
13057   /* The optimizer does not know that the call sets the function value
13058      registers we stored in the result block.  We avoid problems by
13059      claiming that all hard registers are used and clobbered at this
13060      point.  */
13061   emit_insn (gen_blockage ());
13063   DONE;
13066 ;; Prologue and epilogue instructions
13068 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13069 ;; all of memory.  This blocks insns from being moved across this point.
13071 (define_insn "blockage"
13072   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13073   ""
13074   ""
13075   [(set_attr "length" "0")])
13077 ;; Do not schedule instructions accessing memory across this point.
13079 (define_expand "memory_blockage"
13080   [(set (match_dup 0)
13081         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13082   ""
13084   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13085   MEM_VOLATILE_P (operands[0]) = 1;
13088 (define_insn "*memory_blockage"
13089   [(set (match_operand:BLK 0)
13090         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13091   ""
13092   ""
13093   [(set_attr "length" "0")])
13095 ;; As USE insns aren't meaningful after reload, this is used instead
13096 ;; to prevent deleting instructions setting registers for PIC code
13097 (define_insn "prologue_use"
13098   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13099   ""
13100   ""
13101   [(set_attr "length" "0")])
13103 ;; Insn emitted into the body of a function to return from a function.
13104 ;; This is only done if the function's epilogue is known to be simple.
13105 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13107 (define_expand "return"
13108   [(simple_return)]
13109   "ix86_can_use_return_insn_p ()"
13111   if (crtl->args.pops_args)
13112     {
13113       rtx popc = GEN_INT (crtl->args.pops_args);
13114       emit_jump_insn (gen_simple_return_pop_internal (popc));
13115       DONE;
13116     }
13119 ;; We need to disable this for TARGET_SEH, as otherwise
13120 ;; shrink-wrapped prologue gets enabled too.  This might exceed
13121 ;; the maximum size of prologue in unwind information.
13122 ;; Also disallow shrink-wrapping if using stack slot to pass the
13123 ;; static chain pointer - the first instruction has to be pushl %esi
13124 ;; and it can't be moved around, as we use alternate entry points
13125 ;; in that case.
13127 (define_expand "simple_return"
13128   [(simple_return)]
13129   "!TARGET_SEH && !ix86_static_chain_on_stack"
13131   if (crtl->args.pops_args)
13132     {
13133       rtx popc = GEN_INT (crtl->args.pops_args);
13134       emit_jump_insn (gen_simple_return_pop_internal (popc));
13135       DONE;
13136     }
13139 (define_insn "simple_return_internal"
13140   [(simple_return)]
13141   "reload_completed"
13142   "* return ix86_output_function_return (false);"
13143   [(set_attr "length" "1")
13144    (set_attr "atom_unit" "jeu")
13145    (set_attr "length_immediate" "0")
13146    (set_attr "modrm" "0")
13147    (set_attr "maybe_prefix_bnd" "1")])
13149 (define_insn "interrupt_return"
13150   [(simple_return)
13151    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13152   "reload_completed"
13154   return TARGET_64BIT ? "iretq" : "iret";
13157 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13158 ;; instruction Athlon and K8 have.
13160 (define_insn "simple_return_internal_long"
13161   [(simple_return)
13162    (unspec [(const_int 0)] UNSPEC_REP)]
13163   "reload_completed"
13164   "* return ix86_output_function_return (true);"
13165   [(set_attr "length" "2")
13166    (set_attr "atom_unit" "jeu")
13167    (set_attr "length_immediate" "0")
13168    (set_attr "prefix_rep" "1")
13169    (set_attr "modrm" "0")])
13171 (define_insn_and_split "simple_return_pop_internal"
13172   [(simple_return)
13173    (use (match_operand:SI 0 "const_int_operand"))]
13174   "reload_completed"
13175   "%!ret\t%0"
13176   "&& cfun->machine->function_return_type != indirect_branch_keep"
13177   [(const_int 0)]
13178   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13179   [(set_attr "length" "3")
13180    (set_attr "atom_unit" "jeu")
13181    (set_attr "length_immediate" "2")
13182    (set_attr "modrm" "0")
13183    (set_attr "maybe_prefix_bnd" "1")])
13185 (define_insn "simple_return_indirect_internal"
13186   [(simple_return)
13187    (use (match_operand 0 "register_operand" "r"))]
13188   "reload_completed"
13189   "* return ix86_output_indirect_function_return (operands[0]);"
13190   [(set (attr "type")
13191      (if_then_else (match_test "(cfun->machine->indirect_branch_type
13192                                  != indirect_branch_keep)")
13193         (const_string "multi")
13194         (const_string "ibr")))
13195    (set_attr "length_immediate" "0")
13196    (set_attr "maybe_prefix_bnd" "1")])
13198 (define_insn "nop"
13199   [(const_int 0)]
13200   ""
13201   "nop"
13202   [(set_attr "length" "1")
13203    (set_attr "length_immediate" "0")
13204    (set_attr "modrm" "0")])
13206 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
13207 (define_insn "nops"
13208   [(unspec_volatile [(match_operand 0 "const_int_operand")]
13209                     UNSPECV_NOPS)]
13210   "reload_completed"
13212   int num = INTVAL (operands[0]);
13214   gcc_assert (IN_RANGE (num, 1, 8));
13216   while (num--)
13217     fputs ("\tnop\n", asm_out_file);
13219   return "";
13221   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13222    (set_attr "length_immediate" "0")
13223    (set_attr "modrm" "0")])
13225 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13226 ;; branch prediction penalty for the third jump in a 16-byte
13227 ;; block on K8.
13229 (define_insn "pad"
13230   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13231   ""
13233 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13234   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13235 #else
13236   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13237      The align insn is used to avoid 3 jump instructions in the row to improve
13238      branch prediction and the benefits hardly outweigh the cost of extra 8
13239      nops on the average inserted by full alignment pseudo operation.  */
13240 #endif
13241   return "";
13243   [(set_attr "length" "16")])
13245 (define_expand "prologue"
13246   [(const_int 0)]
13247   ""
13248   "ix86_expand_prologue (); DONE;")
13250 (define_expand "set_got"
13251   [(parallel
13252      [(set (match_operand:SI 0 "register_operand")
13253            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13254       (clobber (reg:CC FLAGS_REG))])]
13255   "!TARGET_64BIT"
13257   if (flag_pic && !TARGET_VXWORKS_RTP)
13258     ix86_pc_thunk_call_expanded = true;
13261 (define_insn "*set_got"
13262   [(set (match_operand:SI 0 "register_operand" "=r")
13263         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13264    (clobber (reg:CC FLAGS_REG))]
13265   "!TARGET_64BIT"
13266   "* return output_set_got (operands[0], NULL_RTX);"
13267   [(set_attr "type" "multi")
13268    (set_attr "length" "12")])
13270 (define_expand "set_got_labelled"
13271   [(parallel
13272      [(set (match_operand:SI 0 "register_operand")
13273            (unspec:SI [(label_ref (match_operand 1))]
13274                       UNSPEC_SET_GOT))
13275       (clobber (reg:CC FLAGS_REG))])]
13276   "!TARGET_64BIT"
13278   if (flag_pic && !TARGET_VXWORKS_RTP)
13279     ix86_pc_thunk_call_expanded = true;
13282 (define_insn "*set_got_labelled"
13283   [(set (match_operand:SI 0 "register_operand" "=r")
13284         (unspec:SI [(label_ref (match_operand 1))]
13285          UNSPEC_SET_GOT))
13286    (clobber (reg:CC FLAGS_REG))]
13287   "!TARGET_64BIT"
13288   "* return output_set_got (operands[0], operands[1]);"
13289   [(set_attr "type" "multi")
13290    (set_attr "length" "12")])
13292 (define_insn "set_got_rex64"
13293   [(set (match_operand:DI 0 "register_operand" "=r")
13294         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13295   "TARGET_64BIT"
13296   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13297   [(set_attr "type" "lea")
13298    (set_attr "length_address" "4")
13299    (set_attr "modrm_class" "unknown")
13300    (set_attr "mode" "DI")])
13302 (define_insn "set_rip_rex64"
13303   [(set (match_operand:DI 0 "register_operand" "=r")
13304         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13305   "TARGET_64BIT"
13306   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13307   [(set_attr "type" "lea")
13308    (set_attr "length_address" "4")
13309    (set_attr "mode" "DI")])
13311 (define_insn "set_got_offset_rex64"
13312   [(set (match_operand:DI 0 "register_operand" "=r")
13313         (unspec:DI
13314           [(label_ref (match_operand 1))]
13315           UNSPEC_SET_GOT_OFFSET))]
13316   "TARGET_LP64"
13317   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13318   [(set_attr "type" "imov")
13319    (set_attr "length_immediate" "0")
13320    (set_attr "length_address" "8")
13321    (set_attr "mode" "DI")])
13323 (define_expand "epilogue"
13324   [(const_int 0)]
13325   ""
13326   "ix86_expand_epilogue (1); DONE;")
13328 (define_expand "sibcall_epilogue"
13329   [(const_int 0)]
13330   ""
13331   "ix86_expand_epilogue (0); DONE;")
13333 (define_expand "eh_return"
13334   [(use (match_operand 0 "register_operand"))]
13335   ""
13337   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13339   /* Tricky bit: we write the address of the handler to which we will
13340      be returning into someone else's stack frame, one word below the
13341      stack address we wish to restore.  */
13342   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13343   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13344   tmp = gen_rtx_MEM (Pmode, tmp);
13345   emit_move_insn (tmp, ra);
13347   emit_jump_insn (gen_eh_return_internal ());
13348   emit_barrier ();
13349   DONE;
13352 (define_insn_and_split "eh_return_internal"
13353   [(eh_return)]
13354   ""
13355   "#"
13356   "epilogue_completed"
13357   [(const_int 0)]
13358   "ix86_expand_epilogue (2); DONE;")
13360 (define_insn "leave"
13361   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13362    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13363    (clobber (mem:BLK (scratch)))]
13364   "!TARGET_64BIT"
13365   "leave"
13366   [(set_attr "type" "leave")])
13368 (define_insn "leave_rex64"
13369   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13370    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13371    (clobber (mem:BLK (scratch)))]
13372   "TARGET_64BIT"
13373   "leave"
13374   [(set_attr "type" "leave")])
13376 ;; Handle -fsplit-stack.
13378 (define_expand "split_stack_prologue"
13379   [(const_int 0)]
13380   ""
13382   ix86_expand_split_stack_prologue ();
13383   DONE;
13386 ;; In order to support the call/return predictor, we use a return
13387 ;; instruction which the middle-end doesn't see.
13388 (define_insn "split_stack_return"
13389   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13390                      UNSPECV_SPLIT_STACK_RETURN)]
13391   ""
13393   if (operands[0] == const0_rtx)
13394     return "ret";
13395   else
13396     return "ret\t%0";
13398   [(set_attr "atom_unit" "jeu")
13399    (set_attr "modrm" "0")
13400    (set (attr "length")
13401         (if_then_else (match_operand:SI 0 "const0_operand")
13402                       (const_int 1)
13403                       (const_int 3)))
13404    (set (attr "length_immediate")
13405         (if_then_else (match_operand:SI 0 "const0_operand")
13406                       (const_int 0)
13407                       (const_int 2)))])
13409 ;; If there are operand 0 bytes available on the stack, jump to
13410 ;; operand 1.
13412 (define_expand "split_stack_space_check"
13413   [(set (pc) (if_then_else
13414               (ltu (minus (reg SP_REG)
13415                           (match_operand 0 "register_operand"))
13416                    (match_dup 2))
13417               (label_ref (match_operand 1))
13418               (pc)))]
13419   ""
13421   rtx reg = gen_reg_rtx (Pmode);
13423   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13425   operands[2] = ix86_split_stack_guard ();
13426   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13428   DONE;
13431 ;; Bit manipulation instructions.
13433 (define_expand "ffs<mode>2"
13434   [(set (match_dup 2) (const_int -1))
13435    (parallel [(set (match_dup 3) (match_dup 4))
13436               (set (match_operand:SWI48 0 "register_operand")
13437                    (ctz:SWI48
13438                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13439    (set (match_dup 0) (if_then_else:SWI48
13440                         (eq (match_dup 3) (const_int 0))
13441                         (match_dup 2)
13442                         (match_dup 0)))
13443    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13444               (clobber (reg:CC FLAGS_REG))])]
13445   ""
13447   machine_mode flags_mode;
13449   if (<MODE>mode == SImode && !TARGET_CMOVE)
13450     {
13451       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13452       DONE;
13453     }
13455   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13457   operands[2] = gen_reg_rtx (<MODE>mode);
13458   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13459   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13462 (define_insn_and_split "ffssi2_no_cmove"
13463   [(set (match_operand:SI 0 "register_operand" "=r")
13464         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13465    (clobber (match_scratch:SI 2 "=&q"))
13466    (clobber (reg:CC FLAGS_REG))]
13467   "!TARGET_CMOVE"
13468   "#"
13469   "&& reload_completed"
13470   [(parallel [(set (match_dup 4) (match_dup 5))
13471               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13472    (set (strict_low_part (match_dup 3))
13473         (eq:QI (match_dup 4) (const_int 0)))
13474    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13475               (clobber (reg:CC FLAGS_REG))])
13476    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13477               (clobber (reg:CC FLAGS_REG))])
13478    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13479               (clobber (reg:CC FLAGS_REG))])]
13481   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13483   operands[3] = gen_lowpart (QImode, operands[2]);
13484   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13485   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13487   ix86_expand_clear (operands[2]);
13490 (define_insn_and_split "*tzcnt<mode>_1"
13491   [(set (reg:CCC FLAGS_REG)
13492         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13493                      (const_int 0)))
13494    (set (match_operand:SWI48 0 "register_operand" "=r")
13495         (ctz:SWI48 (match_dup 1)))]
13496   "TARGET_BMI"
13497   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13498   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13499    && optimize_function_for_speed_p (cfun)
13500    && !reg_mentioned_p (operands[0], operands[1])"
13501   [(parallel
13502     [(set (reg:CCC FLAGS_REG)
13503           (compare:CCC (match_dup 1) (const_int 0)))
13504      (set (match_dup 0)
13505           (ctz:SWI48 (match_dup 1)))
13506      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13507   "ix86_expand_clear (operands[0]);"
13508   [(set_attr "type" "alu1")
13509    (set_attr "prefix_0f" "1")
13510    (set_attr "prefix_rep" "1")
13511    (set_attr "btver2_decode" "double")
13512    (set_attr "mode" "<MODE>")])
13514 ; False dependency happens when destination is only updated by tzcnt,
13515 ; lzcnt or popcnt.  There is no false dependency when destination is
13516 ; also used in source.
13517 (define_insn "*tzcnt<mode>_1_falsedep"
13518   [(set (reg:CCC FLAGS_REG)
13519         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13520                      (const_int 0)))
13521    (set (match_operand:SWI48 0 "register_operand" "=r")
13522         (ctz:SWI48 (match_dup 1)))
13523    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13524            UNSPEC_INSN_FALSE_DEP)]
13525   "TARGET_BMI"
13526   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13527   [(set_attr "type" "alu1")
13528    (set_attr "prefix_0f" "1")
13529    (set_attr "prefix_rep" "1")
13530    (set_attr "btver2_decode" "double")
13531    (set_attr "mode" "<MODE>")])
13533 (define_insn "*bsf<mode>_1"
13534   [(set (reg:CCZ FLAGS_REG)
13535         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13536                      (const_int 0)))
13537    (set (match_operand:SWI48 0 "register_operand" "=r")
13538         (ctz:SWI48 (match_dup 1)))]
13539   ""
13540   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13541   [(set_attr "type" "alu1")
13542    (set_attr "prefix_0f" "1")
13543    (set_attr "btver2_decode" "double")
13544    (set_attr "znver1_decode" "vector")
13545    (set_attr "mode" "<MODE>")])
13547 (define_insn_and_split "ctz<mode>2"
13548   [(set (match_operand:SWI48 0 "register_operand" "=r")
13549         (ctz:SWI48
13550           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13551    (clobber (reg:CC FLAGS_REG))]
13552   ""
13554   if (TARGET_BMI)
13555     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13556   else if (optimize_function_for_size_p (cfun))
13557     ;
13558   else if (TARGET_GENERIC)
13559     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13560     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13562   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13564   "(TARGET_BMI || TARGET_GENERIC)
13565    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13566    && optimize_function_for_speed_p (cfun)
13567    && !reg_mentioned_p (operands[0], operands[1])"
13568   [(parallel
13569     [(set (match_dup 0)
13570           (ctz:SWI48 (match_dup 1)))
13571      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13572      (clobber (reg:CC FLAGS_REG))])]
13573   "ix86_expand_clear (operands[0]);"
13574   [(set_attr "type" "alu1")
13575    (set_attr "prefix_0f" "1")
13576    (set (attr "prefix_rep")
13577      (if_then_else
13578        (ior (match_test "TARGET_BMI")
13579             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13580                  (match_test "TARGET_GENERIC")))
13581        (const_string "1")
13582        (const_string "0")))
13583    (set_attr "mode" "<MODE>")])
13585 ; False dependency happens when destination is only updated by tzcnt,
13586 ; lzcnt or popcnt.  There is no false dependency when destination is
13587 ; also used in source.
13588 (define_insn "*ctz<mode>2_falsedep"
13589   [(set (match_operand:SWI48 0 "register_operand" "=r")
13590         (ctz:SWI48
13591           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13592    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13593            UNSPEC_INSN_FALSE_DEP)
13594    (clobber (reg:CC FLAGS_REG))]
13595   ""
13597   if (TARGET_BMI)
13598     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13599   else if (TARGET_GENERIC)
13600     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13601     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13602   else
13603     gcc_unreachable ();
13605   [(set_attr "type" "alu1")
13606    (set_attr "prefix_0f" "1")
13607    (set_attr "prefix_rep" "1")
13608    (set_attr "mode" "<MODE>")])
13610 (define_insn "bsr_rex64"
13611   [(set (match_operand:DI 0 "register_operand" "=r")
13612         (minus:DI (const_int 63)
13613                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13614    (clobber (reg:CC FLAGS_REG))]
13615   "TARGET_64BIT"
13616   "bsr{q}\t{%1, %0|%0, %1}"
13617   [(set_attr "type" "alu1")
13618    (set_attr "prefix_0f" "1")
13619    (set_attr "znver1_decode" "vector")
13620    (set_attr "mode" "DI")])
13622 (define_insn "bsr"
13623   [(set (match_operand:SI 0 "register_operand" "=r")
13624         (minus:SI (const_int 31)
13625                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13626    (clobber (reg:CC FLAGS_REG))]
13627   ""
13628   "bsr{l}\t{%1, %0|%0, %1}"
13629   [(set_attr "type" "alu1")
13630    (set_attr "prefix_0f" "1")
13631    (set_attr "znver1_decode" "vector")
13632    (set_attr "mode" "SI")])
13634 (define_insn "*bsrhi"
13635   [(set (match_operand:HI 0 "register_operand" "=r")
13636         (minus:HI (const_int 15)
13637                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13638    (clobber (reg:CC FLAGS_REG))]
13639   ""
13640   "bsr{w}\t{%1, %0|%0, %1}"
13641   [(set_attr "type" "alu1")
13642    (set_attr "prefix_0f" "1")
13643    (set_attr "znver1_decode" "vector")
13644    (set_attr "mode" "HI")])
13646 (define_expand "clz<mode>2"
13647   [(parallel
13648      [(set (match_operand:SWI48 0 "register_operand")
13649            (minus:SWI48
13650              (match_dup 2)
13651              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13652       (clobber (reg:CC FLAGS_REG))])
13653    (parallel
13654      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13655       (clobber (reg:CC FLAGS_REG))])]
13656   ""
13658   if (TARGET_LZCNT)
13659     {
13660       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13661       DONE;
13662     }
13663   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13666 (define_insn_and_split "clz<mode>2_lzcnt"
13667   [(set (match_operand:SWI48 0 "register_operand" "=r")
13668         (clz:SWI48
13669           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13670    (clobber (reg:CC FLAGS_REG))]
13671   "TARGET_LZCNT"
13672   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13673   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13674    && optimize_function_for_speed_p (cfun)
13675    && !reg_mentioned_p (operands[0], operands[1])"
13676   [(parallel
13677     [(set (match_dup 0)
13678           (clz:SWI48 (match_dup 1)))
13679      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13680      (clobber (reg:CC FLAGS_REG))])]
13681   "ix86_expand_clear (operands[0]);"
13682   [(set_attr "prefix_rep" "1")
13683    (set_attr "type" "bitmanip")
13684    (set_attr "mode" "<MODE>")])
13686 ; False dependency happens when destination is only updated by tzcnt,
13687 ; lzcnt or popcnt.  There is no false dependency when destination is
13688 ; also used in source.
13689 (define_insn "*clz<mode>2_lzcnt_falsedep"
13690   [(set (match_operand:SWI48 0 "register_operand" "=r")
13691         (clz:SWI48
13692           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13693    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13694            UNSPEC_INSN_FALSE_DEP)
13695    (clobber (reg:CC FLAGS_REG))]
13696   "TARGET_LZCNT"
13697   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13698   [(set_attr "prefix_rep" "1")
13699    (set_attr "type" "bitmanip")
13700    (set_attr "mode" "<MODE>")])
13702 (define_int_iterator LT_ZCNT
13703         [(UNSPEC_TZCNT "TARGET_BMI")
13704          (UNSPEC_LZCNT "TARGET_LZCNT")])
13706 (define_int_attr lt_zcnt
13707         [(UNSPEC_TZCNT "tzcnt")
13708          (UNSPEC_LZCNT "lzcnt")])
13710 (define_int_attr lt_zcnt_type
13711         [(UNSPEC_TZCNT "alu1")
13712          (UNSPEC_LZCNT "bitmanip")])
13714 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13715 ;; provides operand size as output when source operand is zero. 
13717 (define_insn_and_split "<lt_zcnt>_<mode>"
13718   [(set (match_operand:SWI48 0 "register_operand" "=r")
13719         (unspec:SWI48
13720           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13721    (clobber (reg:CC FLAGS_REG))]
13722   ""
13723   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13724   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13725    && optimize_function_for_speed_p (cfun)
13726    && !reg_mentioned_p (operands[0], operands[1])"
13727   [(parallel
13728     [(set (match_dup 0)
13729           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13730      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13731      (clobber (reg:CC FLAGS_REG))])]
13732   "ix86_expand_clear (operands[0]);"
13733   [(set_attr "type" "<lt_zcnt_type>")
13734    (set_attr "prefix_0f" "1")
13735    (set_attr "prefix_rep" "1")
13736    (set_attr "mode" "<MODE>")])
13738 ; False dependency happens when destination is only updated by tzcnt,
13739 ; lzcnt or popcnt.  There is no false dependency when destination is
13740 ; also used in source.
13741 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13742   [(set (match_operand:SWI48 0 "register_operand" "=r")
13743         (unspec:SWI48
13744           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13745    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13746            UNSPEC_INSN_FALSE_DEP)
13747    (clobber (reg:CC FLAGS_REG))]
13748   ""
13749   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13750   [(set_attr "type" "<lt_zcnt_type>")
13751    (set_attr "prefix_0f" "1")
13752    (set_attr "prefix_rep" "1")
13753    (set_attr "mode" "<MODE>")])
13755 (define_insn "<lt_zcnt>_hi"
13756   [(set (match_operand:HI 0 "register_operand" "=r")
13757         (unspec:HI
13758           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13759    (clobber (reg:CC FLAGS_REG))]
13760   ""
13761   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13762   [(set_attr "type" "<lt_zcnt_type>")
13763    (set_attr "prefix_0f" "1")
13764    (set_attr "prefix_rep" "1")
13765    (set_attr "mode" "HI")])
13767 ;; BMI instructions.
13769 (define_insn "bmi_bextr_<mode>"
13770   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13771         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13772                        (match_operand:SWI48 2 "register_operand" "r,r")]
13773                       UNSPEC_BEXTR))
13774    (clobber (reg:CC FLAGS_REG))]
13775   "TARGET_BMI"
13776   "bextr\t{%2, %1, %0|%0, %1, %2}"
13777   [(set_attr "type" "bitmanip")
13778    (set_attr "btver2_decode" "direct, double")
13779    (set_attr "mode" "<MODE>")])
13781 (define_insn "*bmi_bextr_<mode>_ccz"
13782   [(set (reg:CCZ FLAGS_REG)
13783         (compare:CCZ
13784           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13785                          (match_operand:SWI48 2 "register_operand" "r,r")]
13786                         UNSPEC_BEXTR)
13787           (const_int 0)))
13788    (clobber (match_scratch:SWI48 0 "=r,r"))]
13789   "TARGET_BMI"
13790   "bextr\t{%2, %1, %0|%0, %1, %2}"
13791   [(set_attr "type" "bitmanip")
13792    (set_attr "btver2_decode" "direct, double")
13793    (set_attr "mode" "<MODE>")])
13795 (define_insn "*bmi_blsi_<mode>"
13796   [(set (match_operand:SWI48 0 "register_operand" "=r")
13797         (and:SWI48
13798           (neg:SWI48
13799             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13800           (match_dup 1)))
13801    (clobber (reg:CC FLAGS_REG))]
13802   "TARGET_BMI"
13803   "blsi\t{%1, %0|%0, %1}"
13804   [(set_attr "type" "bitmanip")
13805    (set_attr "btver2_decode" "double")
13806    (set_attr "mode" "<MODE>")])
13808 (define_insn "*bmi_blsmsk_<mode>"
13809   [(set (match_operand:SWI48 0 "register_operand" "=r")
13810         (xor:SWI48
13811           (plus:SWI48
13812             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13813             (const_int -1))
13814           (match_dup 1)))
13815    (clobber (reg:CC FLAGS_REG))]
13816   "TARGET_BMI"
13817   "blsmsk\t{%1, %0|%0, %1}"
13818   [(set_attr "type" "bitmanip")
13819    (set_attr "btver2_decode" "double")
13820    (set_attr "mode" "<MODE>")])
13822 (define_insn "*bmi_blsr_<mode>"
13823   [(set (match_operand:SWI48 0 "register_operand" "=r")
13824         (and:SWI48
13825           (plus:SWI48
13826             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13827             (const_int -1))
13828           (match_dup 1)))
13829    (clobber (reg:CC FLAGS_REG))]
13830    "TARGET_BMI"
13831    "blsr\t{%1, %0|%0, %1}"
13832   [(set_attr "type" "bitmanip")
13833    (set_attr "btver2_decode" "double")
13834    (set_attr "mode" "<MODE>")])
13836 (define_insn "*bmi_blsr_<mode>_cmp"
13837   [(set (reg:CCZ FLAGS_REG)
13838         (compare:CCZ
13839           (and:SWI48
13840             (plus:SWI48
13841               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13842               (const_int -1))
13843             (match_dup 1))
13844           (const_int 0)))
13845    (set (match_operand:SWI48 0 "register_operand" "=r")
13846         (and:SWI48
13847           (plus:SWI48
13848             (match_dup 1)
13849             (const_int -1))
13850           (match_dup 1)))]
13851    "TARGET_BMI"
13852    "blsr\t{%1, %0|%0, %1}"
13853   [(set_attr "type" "bitmanip")
13854    (set_attr "btver2_decode" "double")
13855    (set_attr "mode" "<MODE>")])
13857 (define_insn "*bmi_blsr_<mode>_ccz"
13858   [(set (reg:CCZ FLAGS_REG)
13859         (compare:CCZ
13860           (and:SWI48
13861             (plus:SWI48
13862               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13863               (const_int -1))
13864             (match_dup 1))
13865           (const_int 0)))
13866    (clobber (match_scratch:SWI48 0 "=r"))]
13867    "TARGET_BMI"
13868    "blsr\t{%1, %0|%0, %1}"
13869   [(set_attr "type" "bitmanip")
13870    (set_attr "btver2_decode" "double")
13871    (set_attr "mode" "<MODE>")])
13873 ;; BMI2 instructions.
13874 (define_expand "bmi2_bzhi_<mode>3"
13875   [(parallel
13876     [(set (match_operand:SWI48 0 "register_operand")
13877           (zero_extract:SWI48
13878             (match_operand:SWI48 1 "nonimmediate_operand")
13879             (umin:SWI48
13880               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13881                          (const_int 255))
13882               (match_dup 3))
13883             (const_int 0)))
13884      (clobber (reg:CC FLAGS_REG))])]
13885   "TARGET_BMI2"
13886   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13888 (define_insn "*bmi2_bzhi_<mode>3"
13889   [(set (match_operand:SWI48 0 "register_operand" "=r")
13890         (zero_extract:SWI48
13891           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13892           (umin:SWI48
13893             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13894                        (const_int 255))
13895             (match_operand:SWI48 3 "const_int_operand" "n"))
13896           (const_int 0)))
13897    (clobber (reg:CC FLAGS_REG))]
13898   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13899   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13900   [(set_attr "type" "bitmanip")
13901    (set_attr "prefix" "vex")
13902    (set_attr "mode" "<MODE>")])
13904 (define_insn "*bmi2_bzhi_<mode>3_1"
13905   [(set (match_operand:SWI48 0 "register_operand" "=r")
13906         (zero_extract:SWI48
13907           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13908           (umin:SWI48
13909             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13910             (match_operand:SWI48 3 "const_int_operand" "n"))
13911           (const_int 0)))
13912    (clobber (reg:CC FLAGS_REG))]
13913   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13914   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13915   [(set_attr "type" "bitmanip")
13916    (set_attr "prefix" "vex")
13917    (set_attr "mode" "<MODE>")])
13919 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13920   [(set (reg:CCZ FLAGS_REG)
13921         (compare:CCZ
13922           (zero_extract:SWI48
13923             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13924             (umin:SWI48
13925               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13926               (match_operand:SWI48 3 "const_int_operand" "n"))
13927             (const_int 0))
13928         (const_int 0)))
13929    (clobber (match_scratch:SWI48 0 "=r"))]
13930   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13931   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13932   [(set_attr "type" "bitmanip")
13933    (set_attr "prefix" "vex")
13934    (set_attr "mode" "<MODE>")])
13936 (define_insn "bmi2_pdep_<mode>3"
13937   [(set (match_operand:SWI48 0 "register_operand" "=r")
13938         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13939                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13940                        UNSPEC_PDEP))]
13941   "TARGET_BMI2"
13942   "pdep\t{%2, %1, %0|%0, %1, %2}"
13943   [(set_attr "type" "bitmanip")
13944    (set_attr "prefix" "vex")
13945    (set_attr "mode" "<MODE>")])
13947 (define_insn "bmi2_pext_<mode>3"
13948   [(set (match_operand:SWI48 0 "register_operand" "=r")
13949         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13950                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13951                        UNSPEC_PEXT))]
13952   "TARGET_BMI2"
13953   "pext\t{%2, %1, %0|%0, %1, %2}"
13954   [(set_attr "type" "bitmanip")
13955    (set_attr "prefix" "vex")
13956    (set_attr "mode" "<MODE>")])
13958 ;; TBM instructions.
13959 (define_insn "tbm_bextri_<mode>"
13960   [(set (match_operand:SWI48 0 "register_operand" "=r")
13961         (zero_extract:SWI48
13962           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13963           (match_operand 2 "const_0_to_255_operand" "N")
13964           (match_operand 3 "const_0_to_255_operand" "N")))
13965    (clobber (reg:CC FLAGS_REG))]
13966    "TARGET_TBM"
13968   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13969   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13971   [(set_attr "type" "bitmanip")
13972    (set_attr "mode" "<MODE>")])
13974 (define_insn "*tbm_blcfill_<mode>"
13975   [(set (match_operand:SWI48 0 "register_operand" "=r")
13976         (and:SWI48
13977           (plus:SWI48
13978             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13979             (const_int 1))
13980           (match_dup 1)))
13981    (clobber (reg:CC FLAGS_REG))]
13982    "TARGET_TBM"
13983    "blcfill\t{%1, %0|%0, %1}"
13984   [(set_attr "type" "bitmanip")
13985    (set_attr "mode" "<MODE>")])
13987 (define_insn "*tbm_blci_<mode>"
13988   [(set (match_operand:SWI48 0 "register_operand" "=r")
13989         (ior:SWI48
13990           (not:SWI48
13991             (plus:SWI48
13992               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13993               (const_int 1)))
13994           (match_dup 1)))
13995    (clobber (reg:CC FLAGS_REG))]
13996    "TARGET_TBM"
13997    "blci\t{%1, %0|%0, %1}"
13998   [(set_attr "type" "bitmanip")
13999    (set_attr "mode" "<MODE>")])
14001 (define_insn "*tbm_blcic_<mode>"
14002   [(set (match_operand:SWI48 0 "register_operand" "=r")
14003         (and:SWI48
14004           (plus:SWI48
14005             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14006             (const_int 1))
14007           (not:SWI48
14008             (match_dup 1))))
14009    (clobber (reg:CC FLAGS_REG))]
14010    "TARGET_TBM"
14011    "blcic\t{%1, %0|%0, %1}"
14012   [(set_attr "type" "bitmanip")
14013    (set_attr "mode" "<MODE>")])
14015 (define_insn "*tbm_blcmsk_<mode>"
14016   [(set (match_operand:SWI48 0 "register_operand" "=r")
14017         (xor:SWI48
14018           (plus:SWI48
14019             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14020             (const_int 1))
14021           (match_dup 1)))
14022    (clobber (reg:CC FLAGS_REG))]
14023    "TARGET_TBM"
14024    "blcmsk\t{%1, %0|%0, %1}"
14025   [(set_attr "type" "bitmanip")
14026    (set_attr "mode" "<MODE>")])
14028 (define_insn "*tbm_blcs_<mode>"
14029   [(set (match_operand:SWI48 0 "register_operand" "=r")
14030         (ior:SWI48
14031           (plus:SWI48
14032             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14033             (const_int 1))
14034           (match_dup 1)))
14035    (clobber (reg:CC FLAGS_REG))]
14036    "TARGET_TBM"
14037    "blcs\t{%1, %0|%0, %1}"
14038   [(set_attr "type" "bitmanip")
14039    (set_attr "mode" "<MODE>")])
14041 (define_insn "*tbm_blsfill_<mode>"
14042   [(set (match_operand:SWI48 0 "register_operand" "=r")
14043         (ior:SWI48
14044           (plus:SWI48
14045             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14046             (const_int -1))
14047           (match_dup 1)))
14048    (clobber (reg:CC FLAGS_REG))]
14049    "TARGET_TBM"
14050    "blsfill\t{%1, %0|%0, %1}"
14051   [(set_attr "type" "bitmanip")
14052    (set_attr "mode" "<MODE>")])
14054 (define_insn "*tbm_blsic_<mode>"
14055   [(set (match_operand:SWI48 0 "register_operand" "=r")
14056         (ior:SWI48
14057           (plus:SWI48
14058             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14059             (const_int -1))
14060           (not:SWI48
14061             (match_dup 1))))
14062    (clobber (reg:CC FLAGS_REG))]
14063    "TARGET_TBM"
14064    "blsic\t{%1, %0|%0, %1}"
14065   [(set_attr "type" "bitmanip")
14066    (set_attr "mode" "<MODE>")])
14068 (define_insn "*tbm_t1mskc_<mode>"
14069   [(set (match_operand:SWI48 0 "register_operand" "=r")
14070         (ior:SWI48
14071           (plus:SWI48
14072             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14073             (const_int 1))
14074           (not:SWI48
14075             (match_dup 1))))
14076    (clobber (reg:CC FLAGS_REG))]
14077    "TARGET_TBM"
14078    "t1mskc\t{%1, %0|%0, %1}"
14079   [(set_attr "type" "bitmanip")
14080    (set_attr "mode" "<MODE>")])
14082 (define_insn "*tbm_tzmsk_<mode>"
14083   [(set (match_operand:SWI48 0 "register_operand" "=r")
14084         (and:SWI48
14085           (plus:SWI48
14086             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14087             (const_int -1))
14088           (not:SWI48
14089             (match_dup 1))))
14090    (clobber (reg:CC FLAGS_REG))]
14091    "TARGET_TBM"
14092    "tzmsk\t{%1, %0|%0, %1}"
14093   [(set_attr "type" "bitmanip")
14094    (set_attr "mode" "<MODE>")])
14096 (define_insn_and_split "popcount<mode>2"
14097   [(set (match_operand:SWI48 0 "register_operand" "=r")
14098         (popcount:SWI48
14099           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14100    (clobber (reg:CC FLAGS_REG))]
14101   "TARGET_POPCNT"
14103 #if TARGET_MACHO
14104   return "popcnt\t{%1, %0|%0, %1}";
14105 #else
14106   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14107 #endif
14109   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14110    && optimize_function_for_speed_p (cfun)
14111    && !reg_mentioned_p (operands[0], operands[1])"
14112   [(parallel
14113     [(set (match_dup 0)
14114           (popcount:SWI48 (match_dup 1)))
14115      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14116      (clobber (reg:CC FLAGS_REG))])]
14117   "ix86_expand_clear (operands[0]);"
14118   [(set_attr "prefix_rep" "1")
14119    (set_attr "type" "bitmanip")
14120    (set_attr "mode" "<MODE>")])
14122 ; False dependency happens when destination is only updated by tzcnt,
14123 ; lzcnt or popcnt.  There is no false dependency when destination is
14124 ; also used in source.
14125 (define_insn "*popcount<mode>2_falsedep"
14126   [(set (match_operand:SWI48 0 "register_operand" "=r")
14127         (popcount:SWI48
14128           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14129    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14130            UNSPEC_INSN_FALSE_DEP)
14131    (clobber (reg:CC FLAGS_REG))]
14132   "TARGET_POPCNT"
14134 #if TARGET_MACHO
14135   return "popcnt\t{%1, %0|%0, %1}";
14136 #else
14137   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14138 #endif
14140   [(set_attr "prefix_rep" "1")
14141    (set_attr "type" "bitmanip")
14142    (set_attr "mode" "<MODE>")])
14144 (define_insn_and_split "*popcounthi2_1"
14145   [(set (match_operand:SI 0 "register_operand")
14146         (popcount:SI
14147           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14148    (clobber (reg:CC FLAGS_REG))]
14149   "TARGET_POPCNT
14150    && can_create_pseudo_p ()"
14151   "#"
14152   "&& 1"
14153   [(const_int 0)]
14155   rtx tmp = gen_reg_rtx (HImode);
14157   emit_insn (gen_popcounthi2 (tmp, operands[1]));
14158   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14159   DONE;
14162 (define_insn "popcounthi2"
14163   [(set (match_operand:HI 0 "register_operand" "=r")
14164         (popcount:HI
14165           (match_operand:HI 1 "nonimmediate_operand" "rm")))
14166    (clobber (reg:CC FLAGS_REG))]
14167   "TARGET_POPCNT"
14169 #if TARGET_MACHO
14170   return "popcnt\t{%1, %0|%0, %1}";
14171 #else
14172   return "popcnt{w}\t{%1, %0|%0, %1}";
14173 #endif
14175   [(set_attr "prefix_rep" "1")
14176    (set_attr "type" "bitmanip")
14177    (set_attr "mode" "HI")])
14179 (define_expand "bswapdi2"
14180   [(set (match_operand:DI 0 "register_operand")
14181         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14182   "TARGET_64BIT"
14184   if (!TARGET_MOVBE)
14185     operands[1] = force_reg (DImode, operands[1]);
14188 (define_expand "bswapsi2"
14189   [(set (match_operand:SI 0 "register_operand")
14190         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14191   ""
14193   if (TARGET_MOVBE)
14194     ;
14195   else if (TARGET_BSWAP)
14196     operands[1] = force_reg (SImode, operands[1]);
14197   else
14198     {
14199       rtx x = operands[0];
14201       emit_move_insn (x, operands[1]);
14202       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14203       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14204       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14205       DONE;
14206     }
14209 (define_insn "*bswap<mode>2_movbe"
14210   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14211         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14212   "TARGET_MOVBE
14213    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14214   "@
14215     bswap\t%0
14216     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14217     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14218   [(set_attr "type" "bitmanip,imov,imov")
14219    (set_attr "modrm" "0,1,1")
14220    (set_attr "prefix_0f" "*,1,1")
14221    (set_attr "prefix_extra" "*,1,1")
14222    (set_attr "mode" "<MODE>")])
14224 (define_insn "*bswap<mode>2"
14225   [(set (match_operand:SWI48 0 "register_operand" "=r")
14226         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14227   "TARGET_BSWAP"
14228   "bswap\t%0"
14229   [(set_attr "type" "bitmanip")
14230    (set_attr "modrm" "0")
14231    (set_attr "mode" "<MODE>")])
14233 (define_expand "bswaphi2"
14234   [(set (match_operand:HI 0 "register_operand")
14235         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14236   "TARGET_MOVBE")
14238 (define_insn "*bswaphi2_movbe"
14239   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14240         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14241   "TARGET_MOVBE
14242    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14243   "@
14244     xchg{b}\t{%h0, %b0|%b0, %h0}
14245     movbe{w}\t{%1, %0|%0, %1}
14246     movbe{w}\t{%1, %0|%0, %1}"
14247   [(set_attr "type" "imov")
14248    (set_attr "modrm" "*,1,1")
14249    (set_attr "prefix_0f" "*,1,1")
14250    (set_attr "prefix_extra" "*,1,1")
14251    (set_attr "pent_pair" "np,*,*")
14252    (set_attr "athlon_decode" "vector,*,*")
14253    (set_attr "amdfam10_decode" "double,*,*")
14254    (set_attr "bdver1_decode" "double,*,*")
14255    (set_attr "mode" "QI,HI,HI")])
14257 (define_peephole2
14258   [(set (match_operand:HI 0 "general_reg_operand")
14259         (bswap:HI (match_dup 0)))]
14260   "TARGET_MOVBE
14261    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14262    && peep2_regno_dead_p (0, FLAGS_REG)"
14263   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14264               (clobber (reg:CC FLAGS_REG))])])
14266 (define_insn "bswaphi_lowpart"
14267   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14268         (bswap:HI (match_dup 0)))
14269    (clobber (reg:CC FLAGS_REG))]
14270   ""
14271   "@
14272     xchg{b}\t{%h0, %b0|%b0, %h0}
14273     rol{w}\t{$8, %0|%0, 8}"
14274   [(set (attr "preferred_for_size")
14275      (cond [(eq_attr "alternative" "0")
14276               (symbol_ref "true")]
14277            (symbol_ref "false")))
14278    (set (attr "preferred_for_speed")
14279      (cond [(eq_attr "alternative" "0")
14280               (symbol_ref "TARGET_USE_XCHGB")]
14281            (symbol_ref "!TARGET_USE_XCHGB")))
14282    (set_attr "length" "2,4")
14283    (set_attr "mode" "QI,HI")])
14285 (define_expand "paritydi2"
14286   [(set (match_operand:DI 0 "register_operand")
14287         (parity:DI (match_operand:DI 1 "register_operand")))]
14288   "! TARGET_POPCNT"
14290   rtx scratch = gen_reg_rtx (QImode);
14292   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14293                                 NULL_RTX, operands[1]));
14295   ix86_expand_setcc (scratch, ORDERED,
14296                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14298   if (TARGET_64BIT)
14299     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14300   else
14301     {
14302       rtx tmp = gen_reg_rtx (SImode);
14304       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14305       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14306     }
14307   DONE;
14310 (define_expand "paritysi2"
14311   [(set (match_operand:SI 0 "register_operand")
14312         (parity:SI (match_operand:SI 1 "register_operand")))]
14313   "! TARGET_POPCNT"
14315   rtx scratch = gen_reg_rtx (QImode);
14317   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14319   ix86_expand_setcc (scratch, ORDERED,
14320                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14322   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14323   DONE;
14326 (define_insn_and_split "paritydi2_cmp"
14327   [(set (reg:CC FLAGS_REG)
14328         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14329                    UNSPEC_PARITY))
14330    (clobber (match_scratch:DI 0 "=r"))
14331    (clobber (match_scratch:SI 1 "=&r"))
14332    (clobber (match_scratch:HI 2 "=Q"))]
14333   "! TARGET_POPCNT"
14334   "#"
14335   "&& reload_completed"
14336   [(parallel
14337      [(set (match_dup 1)
14338            (xor:SI (match_dup 1) (match_dup 4)))
14339       (clobber (reg:CC FLAGS_REG))])
14340    (parallel
14341      [(set (reg:CC FLAGS_REG)
14342            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14343       (clobber (match_dup 1))
14344       (clobber (match_dup 2))])]
14346   operands[4] = gen_lowpart (SImode, operands[3]);
14348   if (TARGET_64BIT)
14349     {
14350       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14351       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14352     }
14353   else
14354     operands[1] = gen_highpart (SImode, operands[3]);
14357 (define_insn_and_split "paritysi2_cmp"
14358   [(set (reg:CC FLAGS_REG)
14359         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14360                    UNSPEC_PARITY))
14361    (clobber (match_scratch:SI 0 "=r"))
14362    (clobber (match_scratch:HI 1 "=&Q"))]
14363   "! TARGET_POPCNT"
14364   "#"
14365   "&& reload_completed"
14366   [(parallel
14367      [(set (match_dup 1)
14368            (xor:HI (match_dup 1) (match_dup 3)))
14369       (clobber (reg:CC FLAGS_REG))])
14370    (parallel
14371      [(set (reg:CC FLAGS_REG)
14372            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14373       (clobber (match_dup 1))])]
14375   operands[3] = gen_lowpart (HImode, operands[2]);
14377   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14378   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14381 (define_insn "*parityhi2_cmp"
14382   [(set (reg:CC FLAGS_REG)
14383         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14384                    UNSPEC_PARITY))
14385    (clobber (match_scratch:HI 0 "=Q"))]
14386   "! TARGET_POPCNT"
14387   "xor{b}\t{%h0, %b0|%b0, %h0}"
14388   [(set_attr "length" "2")
14389    (set_attr "mode" "HI")])
14392 ;; Thread-local storage patterns for ELF.
14394 ;; Note that these code sequences must appear exactly as shown
14395 ;; in order to allow linker relaxation.
14397 (define_insn "*tls_global_dynamic_32_gnu"
14398   [(set (match_operand:SI 0 "register_operand" "=a")
14399         (unspec:SI
14400          [(match_operand:SI 1 "register_operand" "Yb")
14401           (match_operand 2 "tls_symbolic_operand")
14402           (match_operand 3 "constant_call_address_operand" "Bz")
14403           (reg:SI SP_REG)]
14404          UNSPEC_TLS_GD))
14405    (clobber (match_scratch:SI 4 "=d"))
14406    (clobber (match_scratch:SI 5 "=c"))
14407    (clobber (reg:CC FLAGS_REG))]
14408   "!TARGET_64BIT && TARGET_GNU_TLS"
14410   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14411     output_asm_insn
14412       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14413   else
14414     output_asm_insn
14415       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14416   if (TARGET_SUN_TLS)
14417 #ifdef HAVE_AS_IX86_TLSGDPLT
14418     return "call\t%a2@tlsgdplt";
14419 #else
14420     return "call\t%p3@plt";
14421 #endif
14422   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14423     return "call\t%P3";
14424   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14426   [(set_attr "type" "multi")
14427    (set_attr "length" "12")])
14429 (define_expand "tls_global_dynamic_32"
14430   [(parallel
14431     [(set (match_operand:SI 0 "register_operand")
14432           (unspec:SI [(match_operand:SI 2 "register_operand")
14433                       (match_operand 1 "tls_symbolic_operand")
14434                       (match_operand 3 "constant_call_address_operand")
14435                       (reg:SI SP_REG)]
14436                      UNSPEC_TLS_GD))
14437      (clobber (match_scratch:SI 4))
14438      (clobber (match_scratch:SI 5))
14439      (clobber (reg:CC FLAGS_REG))])]
14440   ""
14441   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14443 (define_insn "*tls_global_dynamic_64_<mode>"
14444   [(set (match_operand:P 0 "register_operand" "=a")
14445         (call:P
14446          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14447          (match_operand 3)))
14448    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14449               (reg:P SP_REG)]
14450              UNSPEC_TLS_GD)]
14451   "TARGET_64BIT"
14453   if (!TARGET_X32)
14454     fputs (ASM_BYTE "0x66\n", asm_out_file);
14455   output_asm_insn
14456     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14457   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14458     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14459   else
14460     fputs (ASM_BYTE "0x66\n", asm_out_file);
14461   fputs ("\trex64\n", asm_out_file);
14462   if (TARGET_SUN_TLS)
14463     return "call\t%p2@plt";
14464   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14465     return "call\t%P2";
14466   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14468   [(set_attr "type" "multi")
14469    (set (attr "length")
14470         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14472 (define_insn "*tls_global_dynamic_64_largepic"
14473   [(set (match_operand:DI 0 "register_operand" "=a")
14474         (call:DI
14475          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14476                           (match_operand:DI 3 "immediate_operand" "i")))
14477          (match_operand 4)))
14478    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14479                (reg:DI SP_REG)]
14480               UNSPEC_TLS_GD)]
14481   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14482    && GET_CODE (operands[3]) == CONST
14483    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14484    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14486   output_asm_insn
14487     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14488   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14489   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14490   return "call\t{*%%rax|rax}";
14492   [(set_attr "type" "multi")
14493    (set_attr "length" "22")])
14495 (define_expand "tls_global_dynamic_64_<mode>"
14496   [(parallel
14497     [(set (match_operand:P 0 "register_operand")
14498           (call:P
14499            (mem:QI (match_operand 2))
14500            (const_int 0)))
14501      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14502                 (reg:P SP_REG)]
14503                UNSPEC_TLS_GD)])]
14504   "TARGET_64BIT"
14505   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14507 (define_insn "*tls_local_dynamic_base_32_gnu"
14508   [(set (match_operand:SI 0 "register_operand" "=a")
14509         (unspec:SI
14510          [(match_operand:SI 1 "register_operand" "Yb")
14511           (match_operand 2 "constant_call_address_operand" "Bz")
14512           (reg:SI SP_REG)]
14513          UNSPEC_TLS_LD_BASE))
14514    (clobber (match_scratch:SI 3 "=d"))
14515    (clobber (match_scratch:SI 4 "=c"))
14516    (clobber (reg:CC FLAGS_REG))]
14517   "!TARGET_64BIT && TARGET_GNU_TLS"
14519   output_asm_insn
14520     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14521   if (TARGET_SUN_TLS)
14522     {
14523       if (HAVE_AS_IX86_TLSLDMPLT)
14524         return "call\t%&@tlsldmplt";
14525       else
14526         return "call\t%p2@plt";
14527     }
14528   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14529     return "call\t%P2";
14530   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14532   [(set_attr "type" "multi")
14533    (set_attr "length" "11")])
14535 (define_expand "tls_local_dynamic_base_32"
14536   [(parallel
14537      [(set (match_operand:SI 0 "register_operand")
14538            (unspec:SI
14539             [(match_operand:SI 1 "register_operand")
14540              (match_operand 2 "constant_call_address_operand")
14541              (reg:SI SP_REG)]
14542             UNSPEC_TLS_LD_BASE))
14543       (clobber (match_scratch:SI 3))
14544       (clobber (match_scratch:SI 4))
14545       (clobber (reg:CC FLAGS_REG))])]
14546   ""
14547   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14549 (define_insn "*tls_local_dynamic_base_64_<mode>"
14550   [(set (match_operand:P 0 "register_operand" "=a")
14551         (call:P
14552          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14553          (match_operand 2)))
14554    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14555   "TARGET_64BIT"
14557   output_asm_insn
14558     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14559   if (TARGET_SUN_TLS)
14560     return "call\t%p1@plt";
14561   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14562     return "call\t%P1";
14563   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14565   [(set_attr "type" "multi")
14566    (set_attr "length" "12")])
14568 (define_insn "*tls_local_dynamic_base_64_largepic"
14569   [(set (match_operand:DI 0 "register_operand" "=a")
14570         (call:DI
14571          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14572                           (match_operand:DI 2 "immediate_operand" "i")))
14573          (match_operand 3)))
14574    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14575   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14576    && GET_CODE (operands[2]) == CONST
14577    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14578    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14580   output_asm_insn
14581     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14582   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14583   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14584   return "call\t{*%%rax|rax}";
14586   [(set_attr "type" "multi")
14587    (set_attr "length" "22")])
14589 (define_expand "tls_local_dynamic_base_64_<mode>"
14590   [(parallel
14591      [(set (match_operand:P 0 "register_operand")
14592            (call:P
14593             (mem:QI (match_operand 1))
14594             (const_int 0)))
14595       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14596   "TARGET_64BIT"
14597   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14599 ;; Local dynamic of a single variable is a lose.  Show combine how
14600 ;; to convert that back to global dynamic.
14602 (define_insn_and_split "*tls_local_dynamic_32_once"
14603   [(set (match_operand:SI 0 "register_operand" "=a")
14604         (plus:SI
14605          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14606                      (match_operand 2 "constant_call_address_operand" "Bz")
14607                      (reg:SI SP_REG)]
14608                     UNSPEC_TLS_LD_BASE)
14609          (const:SI (unspec:SI
14610                     [(match_operand 3 "tls_symbolic_operand")]
14611                     UNSPEC_DTPOFF))))
14612    (clobber (match_scratch:SI 4 "=d"))
14613    (clobber (match_scratch:SI 5 "=c"))
14614    (clobber (reg:CC FLAGS_REG))]
14615   ""
14616   "#"
14617   ""
14618   [(parallel
14619      [(set (match_dup 0)
14620            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14621                        (reg:SI SP_REG)]
14622                       UNSPEC_TLS_GD))
14623       (clobber (match_dup 4))
14624       (clobber (match_dup 5))
14625       (clobber (reg:CC FLAGS_REG))])])
14627 ;; Load and add the thread base pointer from %<tp_seg>:0.
14628 (define_insn_and_split "*load_tp_<mode>"
14629   [(set (match_operand:PTR 0 "register_operand" "=r")
14630         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14631   ""
14632   "#"
14633   ""
14634   [(set (match_dup 0)
14635         (match_dup 1))]
14637   addr_space_t as = DEFAULT_TLS_SEG_REG;
14639   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14640   set_mem_addr_space (operands[1], as);
14643 (define_insn_and_split "*load_tp_x32_zext"
14644   [(set (match_operand:DI 0 "register_operand" "=r")
14645         (zero_extend:DI
14646           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14647   "TARGET_X32"
14648   "#"
14649   ""
14650   [(set (match_dup 0)
14651         (zero_extend:DI (match_dup 1)))]
14653   addr_space_t as = DEFAULT_TLS_SEG_REG;
14655   operands[1] = gen_const_mem (SImode, const0_rtx);
14656   set_mem_addr_space (operands[1], as);
14659 (define_insn_and_split "*add_tp_<mode>"
14660   [(set (match_operand:PTR 0 "register_operand" "=r")
14661         (plus:PTR
14662           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14663           (match_operand:PTR 1 "register_operand" "0")))
14664    (clobber (reg:CC FLAGS_REG))]
14665   ""
14666   "#"
14667   ""
14668   [(parallel
14669      [(set (match_dup 0)
14670            (plus:PTR (match_dup 1) (match_dup 2)))
14671       (clobber (reg:CC FLAGS_REG))])]
14673   addr_space_t as = DEFAULT_TLS_SEG_REG;
14675   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14676   set_mem_addr_space (operands[2], as);
14679 (define_insn_and_split "*add_tp_x32_zext"
14680   [(set (match_operand:DI 0 "register_operand" "=r")
14681         (zero_extend:DI
14682           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14683                    (match_operand:SI 1 "register_operand" "0"))))
14684    (clobber (reg:CC FLAGS_REG))]
14685   "TARGET_X32"
14686   "#"
14687   ""
14688   [(parallel
14689      [(set (match_dup 0)
14690            (zero_extend:DI
14691              (plus:SI (match_dup 1) (match_dup 2))))
14692       (clobber (reg:CC FLAGS_REG))])]
14694   addr_space_t as = DEFAULT_TLS_SEG_REG;
14696   operands[2] = gen_const_mem (SImode, const0_rtx);
14697   set_mem_addr_space (operands[2], as);
14700 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14701 ;; %rax as destination of the initial executable code sequence.
14702 (define_insn "tls_initial_exec_64_sun"
14703   [(set (match_operand:DI 0 "register_operand" "=a")
14704         (unspec:DI
14705          [(match_operand 1 "tls_symbolic_operand")]
14706          UNSPEC_TLS_IE_SUN))
14707    (clobber (reg:CC FLAGS_REG))]
14708   "TARGET_64BIT && TARGET_SUN_TLS"
14710   output_asm_insn
14711     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14712   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14714   [(set_attr "type" "multi")])
14716 ;; GNU2 TLS patterns can be split.
14718 (define_expand "tls_dynamic_gnu2_32"
14719   [(set (match_dup 3)
14720         (plus:SI (match_operand:SI 2 "register_operand")
14721                  (const:SI
14722                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14723                              UNSPEC_TLSDESC))))
14724    (parallel
14725     [(set (match_operand:SI 0 "register_operand")
14726           (unspec:SI [(match_dup 1) (match_dup 3)
14727                       (match_dup 2) (reg:SI SP_REG)]
14728                       UNSPEC_TLSDESC))
14729      (clobber (reg:CC FLAGS_REG))])]
14730   "!TARGET_64BIT && TARGET_GNU2_TLS"
14732   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14733   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14736 (define_insn "*tls_dynamic_gnu2_lea_32"
14737   [(set (match_operand:SI 0 "register_operand" "=r")
14738         (plus:SI (match_operand:SI 1 "register_operand" "b")
14739                  (const:SI
14740                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14741                               UNSPEC_TLSDESC))))]
14742   "!TARGET_64BIT && TARGET_GNU2_TLS"
14743   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14744   [(set_attr "type" "lea")
14745    (set_attr "mode" "SI")
14746    (set_attr "length" "6")
14747    (set_attr "length_address" "4")])
14749 (define_insn "*tls_dynamic_gnu2_call_32"
14750   [(set (match_operand:SI 0 "register_operand" "=a")
14751         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14752                     (match_operand:SI 2 "register_operand" "0")
14753                     ;; we have to make sure %ebx still points to the GOT
14754                     (match_operand:SI 3 "register_operand" "b")
14755                     (reg:SI SP_REG)]
14756                    UNSPEC_TLSDESC))
14757    (clobber (reg:CC FLAGS_REG))]
14758   "!TARGET_64BIT && TARGET_GNU2_TLS"
14759   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14760   [(set_attr "type" "call")
14761    (set_attr "length" "2")
14762    (set_attr "length_address" "0")])
14764 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14765   [(set (match_operand:SI 0 "register_operand" "=&a")
14766         (plus:SI
14767          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14768                      (match_operand:SI 4)
14769                      (match_operand:SI 2 "register_operand" "b")
14770                      (reg:SI SP_REG)]
14771                     UNSPEC_TLSDESC)
14772          (const:SI (unspec:SI
14773                     [(match_operand 1 "tls_symbolic_operand")]
14774                     UNSPEC_DTPOFF))))
14775    (clobber (reg:CC FLAGS_REG))]
14776   "!TARGET_64BIT && TARGET_GNU2_TLS"
14777   "#"
14778   ""
14779   [(set (match_dup 0) (match_dup 5))]
14781   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14782   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14785 (define_expand "tls_dynamic_gnu2_64"
14786   [(set (match_dup 2)
14787         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14788                    UNSPEC_TLSDESC))
14789    (parallel
14790     [(set (match_operand:DI 0 "register_operand")
14791           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14792                      UNSPEC_TLSDESC))
14793      (clobber (reg:CC FLAGS_REG))])]
14794   "TARGET_64BIT && TARGET_GNU2_TLS"
14796   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14797   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14800 (define_insn "*tls_dynamic_gnu2_lea_64"
14801   [(set (match_operand:DI 0 "register_operand" "=r")
14802         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14803                    UNSPEC_TLSDESC))]
14804   "TARGET_64BIT && TARGET_GNU2_TLS"
14805   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14806   [(set_attr "type" "lea")
14807    (set_attr "mode" "DI")
14808    (set_attr "length" "7")
14809    (set_attr "length_address" "4")])
14811 (define_insn "*tls_dynamic_gnu2_call_64"
14812   [(set (match_operand:DI 0 "register_operand" "=a")
14813         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14814                     (match_operand:DI 2 "register_operand" "0")
14815                     (reg:DI SP_REG)]
14816                    UNSPEC_TLSDESC))
14817    (clobber (reg:CC FLAGS_REG))]
14818   "TARGET_64BIT && TARGET_GNU2_TLS"
14819   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14820   [(set_attr "type" "call")
14821    (set_attr "length" "2")
14822    (set_attr "length_address" "0")])
14824 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14825   [(set (match_operand:DI 0 "register_operand" "=&a")
14826         (plus:DI
14827          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14828                      (match_operand:DI 3)
14829                      (reg:DI SP_REG)]
14830                     UNSPEC_TLSDESC)
14831          (const:DI (unspec:DI
14832                     [(match_operand 1 "tls_symbolic_operand")]
14833                     UNSPEC_DTPOFF))))
14834    (clobber (reg:CC FLAGS_REG))]
14835   "TARGET_64BIT && TARGET_GNU2_TLS"
14836   "#"
14837   ""
14838   [(set (match_dup 0) (match_dup 4))]
14840   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14841   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14844 (define_split
14845   [(match_operand 0 "tls_address_pattern")]
14846   "TARGET_TLS_DIRECT_SEG_REFS"
14847   [(match_dup 0)]
14848   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14851 ;; These patterns match the binary 387 instructions for addM3, subM3,
14852 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14853 ;; SFmode.  The first is the normal insn, the second the same insn but
14854 ;; with one operand a conversion, and the third the same insn but with
14855 ;; the other operand a conversion.  The conversion may be SFmode or
14856 ;; SImode if the target mode DFmode, but only SImode if the target mode
14857 ;; is SFmode.
14859 ;; Gcc is slightly more smart about handling normal two address instructions
14860 ;; so use special patterns for add and mull.
14862 (define_insn "*fop_<mode>_comm"
14863   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14864         (match_operator:MODEF 3 "binary_fp_operator"
14865           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14866            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14867   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14868     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14869    && COMMUTATIVE_ARITH_P (operands[3])
14870    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14871   "* return output_387_binary_op (insn, operands);"
14872   [(set (attr "type")
14873         (if_then_else (eq_attr "alternative" "1,2")
14874            (if_then_else (match_operand:MODEF 3 "mult_operator")
14875               (const_string "ssemul")
14876               (const_string "sseadd"))
14877            (if_then_else (match_operand:MODEF 3 "mult_operator")
14878               (const_string "fmul")
14879               (const_string "fop"))))
14880    (set_attr "isa" "*,noavx,avx")
14881    (set_attr "prefix" "orig,orig,vex")
14882    (set_attr "mode" "<MODE>")
14883    (set (attr "enabled")
14884      (if_then_else
14885        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14886        (if_then_else
14887          (eq_attr "alternative" "0")
14888          (symbol_ref "TARGET_MIX_SSE_I387
14889                       && X87_ENABLE_ARITH (<MODE>mode)")
14890          (const_string "*"))
14891        (if_then_else
14892          (eq_attr "alternative" "0")
14893          (symbol_ref "true")
14894          (symbol_ref "false"))))])
14896 (define_insn "*rcpsf2_sse"
14897   [(set (match_operand:SF 0 "register_operand" "=x")
14898         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14899                    UNSPEC_RCP))]
14900   "TARGET_SSE && TARGET_SSE_MATH"
14901   "%vrcpss\t{%1, %d0|%d0, %1}"
14902   [(set_attr "type" "sse")
14903    (set_attr "atom_sse_attr" "rcp")
14904    (set_attr "btver2_sse_attr" "rcp")
14905    (set_attr "prefix" "maybe_vex")
14906    (set_attr "mode" "SF")])
14908 (define_insn "*fop_<mode>_1"
14909   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14910         (match_operator:MODEF 3 "binary_fp_operator"
14911           [(match_operand:MODEF 1
14912              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14913            (match_operand:MODEF 2
14914              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14915   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14917    && !COMMUTATIVE_ARITH_P (operands[3])
14918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14919   "* return output_387_binary_op (insn, operands);"
14920   [(set (attr "type")
14921         (if_then_else (eq_attr "alternative" "2,3")
14922            (if_then_else (match_operand:MODEF 3 "div_operator")
14923               (const_string "ssediv")
14924               (const_string "sseadd"))
14925            (if_then_else (match_operand:MODEF 3 "div_operator")
14926               (const_string "fdiv")
14927               (const_string "fop"))))
14928    (set_attr "isa" "*,*,noavx,avx")
14929    (set_attr "prefix" "orig,orig,orig,vex")
14930    (set_attr "mode" "<MODE>")
14931    (set (attr "enabled")
14932      (if_then_else
14933        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14934        (if_then_else
14935          (eq_attr "alternative" "0,1")
14936          (symbol_ref "TARGET_MIX_SSE_I387
14937                       && X87_ENABLE_ARITH (<MODE>mode)")
14938          (const_string "*"))
14939        (if_then_else
14940          (eq_attr "alternative" "0,1")
14941          (symbol_ref "true")
14942          (symbol_ref "false"))))])
14944 ;; ??? Add SSE splitters for these!
14945 (define_insn "*fop_<MODEF:mode>_2_i387"
14946   [(set (match_operand:MODEF 0 "register_operand" "=f")
14947         (match_operator:MODEF 3 "binary_fp_operator"
14948           [(float:MODEF
14949              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14950            (match_operand:MODEF 2 "register_operand" "0")]))]
14951   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14952    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14953    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14954        || optimize_function_for_size_p (cfun))"
14955   "* return output_387_binary_op (insn, operands);"
14956   [(set (attr "type")
14957         (cond [(match_operand:MODEF 3 "mult_operator")
14958                  (const_string "fmul")
14959                (match_operand:MODEF 3 "div_operator")
14960                  (const_string "fdiv")
14961               ]
14962               (const_string "fop")))
14963    (set_attr "fp_int_src" "true")
14964    (set_attr "mode" "<SWI24:MODE>")])
14966 (define_insn "*fop_<MODEF:mode>_3_i387"
14967   [(set (match_operand:MODEF 0 "register_operand" "=f")
14968         (match_operator:MODEF 3 "binary_fp_operator"
14969           [(match_operand:MODEF 1 "register_operand" "0")
14970            (float:MODEF
14971              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14972   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14973    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14974    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14975        || optimize_function_for_size_p (cfun))"
14976   "* return output_387_binary_op (insn, operands);"
14977   [(set (attr "type")
14978         (cond [(match_operand:MODEF 3 "mult_operator")
14979                  (const_string "fmul")
14980                (match_operand:MODEF 3 "div_operator")
14981                  (const_string "fdiv")
14982               ]
14983               (const_string "fop")))
14984    (set_attr "fp_int_src" "true")
14985    (set_attr "mode" "<MODE>")])
14987 (define_insn "*fop_df_4_i387"
14988   [(set (match_operand:DF 0 "register_operand" "=f,f")
14989         (match_operator:DF 3 "binary_fp_operator"
14990            [(float_extend:DF
14991              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14992             (match_operand:DF 2 "register_operand" "0,f")]))]
14993   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14994    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14995   "* return output_387_binary_op (insn, operands);"
14996   [(set (attr "type")
14997         (cond [(match_operand:DF 3 "mult_operator")
14998                  (const_string "fmul")
14999                (match_operand:DF 3 "div_operator")
15000                  (const_string "fdiv")
15001               ]
15002               (const_string "fop")))
15003    (set_attr "mode" "SF")])
15005 (define_insn "*fop_df_5_i387"
15006   [(set (match_operand:DF 0 "register_operand" "=f,f")
15007         (match_operator:DF 3 "binary_fp_operator"
15008           [(match_operand:DF 1 "register_operand" "0,f")
15009            (float_extend:DF
15010             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15011   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15012    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15013   "* return output_387_binary_op (insn, operands);"
15014   [(set (attr "type")
15015         (cond [(match_operand:DF 3 "mult_operator")
15016                  (const_string "fmul")
15017                (match_operand:DF 3 "div_operator")
15018                  (const_string "fdiv")
15019               ]
15020               (const_string "fop")))
15021    (set_attr "mode" "SF")])
15023 (define_insn "*fop_df_6_i387"
15024   [(set (match_operand:DF 0 "register_operand" "=f,f")
15025         (match_operator:DF 3 "binary_fp_operator"
15026           [(float_extend:DF
15027             (match_operand:SF 1 "register_operand" "0,f"))
15028            (float_extend:DF
15029             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15030   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15031    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15032   "* return output_387_binary_op (insn, operands);"
15033   [(set (attr "type")
15034         (cond [(match_operand:DF 3 "mult_operator")
15035                  (const_string "fmul")
15036                (match_operand:DF 3 "div_operator")
15037                  (const_string "fdiv")
15038               ]
15039               (const_string "fop")))
15040    (set_attr "mode" "SF")])
15042 (define_insn "*fop_xf_comm_i387"
15043   [(set (match_operand:XF 0 "register_operand" "=f")
15044         (match_operator:XF 3 "binary_fp_operator"
15045                         [(match_operand:XF 1 "register_operand" "%0")
15046                          (match_operand:XF 2 "register_operand" "f")]))]
15047   "TARGET_80387
15048    && COMMUTATIVE_ARITH_P (operands[3])"
15049   "* return output_387_binary_op (insn, operands);"
15050   [(set (attr "type")
15051         (if_then_else (match_operand:XF 3 "mult_operator")
15052            (const_string "fmul")
15053            (const_string "fop")))
15054    (set_attr "mode" "XF")])
15056 (define_insn "*fop_xf_1_i387"
15057   [(set (match_operand:XF 0 "register_operand" "=f,f")
15058         (match_operator:XF 3 "binary_fp_operator"
15059                         [(match_operand:XF 1 "register_operand" "0,f")
15060                          (match_operand:XF 2 "register_operand" "f,0")]))]
15061   "TARGET_80387
15062    && !COMMUTATIVE_ARITH_P (operands[3])"
15063   "* return output_387_binary_op (insn, operands);"
15064   [(set (attr "type")
15065         (if_then_else (match_operand:XF 3 "div_operator")
15066            (const_string "fdiv")
15067            (const_string "fop")))
15068    (set_attr "mode" "XF")])
15070 (define_insn "*fop_xf_2_i387"
15071   [(set (match_operand:XF 0 "register_operand" "=f")
15072         (match_operator:XF 3 "binary_fp_operator"
15073           [(float:XF
15074              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15075            (match_operand:XF 2 "register_operand" "0")]))]
15076   "TARGET_80387
15077    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15078   "* return output_387_binary_op (insn, operands);"
15079   [(set (attr "type")
15080         (cond [(match_operand:XF 3 "mult_operator")
15081                  (const_string "fmul")
15082                (match_operand:XF 3 "div_operator")
15083                  (const_string "fdiv")
15084               ]
15085               (const_string "fop")))
15086    (set_attr "fp_int_src" "true")
15087    (set_attr "mode" "<MODE>")])
15089 (define_insn "*fop_xf_3_i387"
15090   [(set (match_operand:XF 0 "register_operand" "=f")
15091         (match_operator:XF 3 "binary_fp_operator"
15092           [(match_operand:XF 1 "register_operand" "0")
15093            (float:XF
15094              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15095   "TARGET_80387
15096    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15097   "* return output_387_binary_op (insn, operands);"
15098   [(set (attr "type")
15099         (cond [(match_operand:XF 3 "mult_operator")
15100                  (const_string "fmul")
15101                (match_operand:XF 3 "div_operator")
15102                  (const_string "fdiv")
15103               ]
15104               (const_string "fop")))
15105    (set_attr "fp_int_src" "true")
15106    (set_attr "mode" "<MODE>")])
15108 (define_insn "*fop_xf_4_i387"
15109   [(set (match_operand:XF 0 "register_operand" "=f,f")
15110         (match_operator:XF 3 "binary_fp_operator"
15111            [(float_extend:XF
15112               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15113             (match_operand:XF 2 "register_operand" "0,f")]))]
15114   "TARGET_80387"
15115   "* return output_387_binary_op (insn, operands);"
15116   [(set (attr "type")
15117         (cond [(match_operand:XF 3 "mult_operator")
15118                  (const_string "fmul")
15119                (match_operand:XF 3 "div_operator")
15120                  (const_string "fdiv")
15121               ]
15122               (const_string "fop")))
15123    (set_attr "mode" "<MODE>")])
15125 (define_insn "*fop_xf_5_i387"
15126   [(set (match_operand:XF 0 "register_operand" "=f,f")
15127         (match_operator:XF 3 "binary_fp_operator"
15128           [(match_operand:XF 1 "register_operand" "0,f")
15129            (float_extend:XF
15130              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15131   "TARGET_80387"
15132   "* return output_387_binary_op (insn, operands);"
15133   [(set (attr "type")
15134         (cond [(match_operand:XF 3 "mult_operator")
15135                  (const_string "fmul")
15136                (match_operand:XF 3 "div_operator")
15137                  (const_string "fdiv")
15138               ]
15139               (const_string "fop")))
15140    (set_attr "mode" "<MODE>")])
15142 (define_insn "*fop_xf_6_i387"
15143   [(set (match_operand:XF 0 "register_operand" "=f,f")
15144         (match_operator:XF 3 "binary_fp_operator"
15145           [(float_extend:XF
15146              (match_operand:MODEF 1 "register_operand" "0,f"))
15147            (float_extend:XF
15148              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15149   "TARGET_80387"
15150   "* return output_387_binary_op (insn, operands);"
15151   [(set (attr "type")
15152         (cond [(match_operand:XF 3 "mult_operator")
15153                  (const_string "fmul")
15154                (match_operand:XF 3 "div_operator")
15155                  (const_string "fdiv")
15156               ]
15157               (const_string "fop")))
15158    (set_attr "mode" "<MODE>")])
15160 ;; FPU special functions.
15162 ;; This pattern implements a no-op XFmode truncation for
15163 ;; all fancy i386 XFmode math functions.
15165 (define_insn "truncxf<mode>2_i387_noop_unspec"
15166   [(set (match_operand:MODEF 0 "register_operand" "=f")
15167         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15168         UNSPEC_TRUNC_NOOP))]
15169   "TARGET_USE_FANCY_MATH_387"
15170   "* return output_387_reg_move (insn, operands);"
15171   [(set_attr "type" "fmov")
15172    (set_attr "mode" "<MODE>")])
15174 (define_insn "sqrtxf2"
15175   [(set (match_operand:XF 0 "register_operand" "=f")
15176         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15177   "TARGET_USE_FANCY_MATH_387"
15178   "fsqrt"
15179   [(set_attr "type" "fpspc")
15180    (set_attr "mode" "XF")
15181    (set_attr "athlon_decode" "direct")
15182    (set_attr "amdfam10_decode" "direct")
15183    (set_attr "bdver1_decode" "direct")])
15185 (define_insn "sqrt_extend<mode>xf2_i387"
15186   [(set (match_operand:XF 0 "register_operand" "=f")
15187         (sqrt:XF
15188           (float_extend:XF
15189             (match_operand:MODEF 1 "register_operand" "0"))))]
15190   "TARGET_USE_FANCY_MATH_387"
15191   "fsqrt"
15192   [(set_attr "type" "fpspc")
15193    (set_attr "mode" "XF")
15194    (set_attr "athlon_decode" "direct")
15195    (set_attr "amdfam10_decode" "direct")
15196    (set_attr "bdver1_decode" "direct")])
15198 (define_insn "*rsqrtsf2_sse"
15199   [(set (match_operand:SF 0 "register_operand" "=x")
15200         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15201                    UNSPEC_RSQRT))]
15202   "TARGET_SSE && TARGET_SSE_MATH"
15203   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15204   [(set_attr "type" "sse")
15205    (set_attr "atom_sse_attr" "rcp")
15206    (set_attr "btver2_sse_attr" "rcp")
15207    (set_attr "prefix" "maybe_vex")
15208    (set_attr "mode" "SF")])
15210 (define_expand "rsqrtsf2"
15211   [(set (match_operand:SF 0 "register_operand")
15212         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15213                    UNSPEC_RSQRT))]
15214   "TARGET_SSE && TARGET_SSE_MATH"
15216   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15217   DONE;
15220 (define_insn "*sqrt<mode>2_sse"
15221   [(set (match_operand:MODEF 0 "register_operand" "=v")
15222         (sqrt:MODEF
15223           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15224   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15225   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15226   [(set_attr "type" "sse")
15227    (set_attr "atom_sse_attr" "sqrt")
15228    (set_attr "btver2_sse_attr" "sqrt")
15229    (set_attr "prefix" "maybe_vex")
15230    (set_attr "mode" "<MODE>")
15231    (set_attr "athlon_decode" "*")
15232    (set_attr "amdfam10_decode" "*")
15233    (set_attr "bdver1_decode" "*")])
15235 (define_expand "sqrt<mode>2"
15236   [(set (match_operand:MODEF 0 "register_operand")
15237         (sqrt:MODEF
15238           (match_operand:MODEF 1 "nonimmediate_operand")))]
15239   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15240    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15242   if (<MODE>mode == SFmode
15243       && TARGET_SSE && TARGET_SSE_MATH
15244       && TARGET_RECIP_SQRT
15245       && !optimize_function_for_size_p (cfun)
15246       && flag_finite_math_only && !flag_trapping_math
15247       && flag_unsafe_math_optimizations)
15248     {
15249       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15250       DONE;
15251     }
15253   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15254     {
15255       rtx op0 = gen_reg_rtx (XFmode);
15256       rtx op1 = force_reg (<MODE>mode, operands[1]);
15258       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15259       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15260       DONE;
15261    }
15264 (define_insn "fpremxf4_i387"
15265   [(set (match_operand:XF 0 "register_operand" "=f")
15266         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15267                     (match_operand:XF 3 "register_operand" "1")]
15268                    UNSPEC_FPREM_F))
15269    (set (match_operand:XF 1 "register_operand" "=u")
15270         (unspec:XF [(match_dup 2) (match_dup 3)]
15271                    UNSPEC_FPREM_U))
15272    (set (reg:CCFP FPSR_REG)
15273         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15274                      UNSPEC_C2_FLAG))]
15275   "TARGET_USE_FANCY_MATH_387
15276    && flag_finite_math_only"
15277   "fprem"
15278   [(set_attr "type" "fpspc")
15279    (set_attr "znver1_decode" "vector")
15280    (set_attr "mode" "XF")])
15282 (define_expand "fmodxf3"
15283   [(use (match_operand:XF 0 "register_operand"))
15284    (use (match_operand:XF 1 "general_operand"))
15285    (use (match_operand:XF 2 "general_operand"))]
15286   "TARGET_USE_FANCY_MATH_387
15287    && flag_finite_math_only"
15289   rtx_code_label *label = gen_label_rtx ();
15291   rtx op1 = gen_reg_rtx (XFmode);
15292   rtx op2 = gen_reg_rtx (XFmode);
15294   emit_move_insn (op2, operands[2]);
15295   emit_move_insn (op1, operands[1]);
15297   emit_label (label);
15298   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15299   ix86_emit_fp_unordered_jump (label);
15300   LABEL_NUSES (label) = 1;
15302   emit_move_insn (operands[0], op1);
15303   DONE;
15306 (define_expand "fmod<mode>3"
15307   [(use (match_operand:MODEF 0 "register_operand"))
15308    (use (match_operand:MODEF 1 "general_operand"))
15309    (use (match_operand:MODEF 2 "general_operand"))]
15310   "TARGET_USE_FANCY_MATH_387
15311    && flag_finite_math_only"
15313   rtx (*gen_truncxf) (rtx, rtx);
15315   rtx_code_label *label = gen_label_rtx ();
15317   rtx op1 = gen_reg_rtx (XFmode);
15318   rtx op2 = gen_reg_rtx (XFmode);
15320   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15321   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15323   emit_label (label);
15324   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15325   ix86_emit_fp_unordered_jump (label);
15326   LABEL_NUSES (label) = 1;
15328   /* Truncate the result properly for strict SSE math.  */
15329   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15330       && !TARGET_MIX_SSE_I387)
15331     gen_truncxf = gen_truncxf<mode>2;
15332   else
15333     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15335   emit_insn (gen_truncxf (operands[0], op1));
15336   DONE;
15339 (define_insn "fprem1xf4_i387"
15340   [(set (match_operand:XF 0 "register_operand" "=f")
15341         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15342                     (match_operand:XF 3 "register_operand" "1")]
15343                    UNSPEC_FPREM1_F))
15344    (set (match_operand:XF 1 "register_operand" "=u")
15345         (unspec:XF [(match_dup 2) (match_dup 3)]
15346                    UNSPEC_FPREM1_U))
15347    (set (reg:CCFP FPSR_REG)
15348         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15349                      UNSPEC_C2_FLAG))]
15350   "TARGET_USE_FANCY_MATH_387
15351    && flag_finite_math_only"
15352   "fprem1"
15353   [(set_attr "type" "fpspc")
15354    (set_attr "znver1_decode" "vector")
15355    (set_attr "mode" "XF")])
15357 (define_expand "remainderxf3"
15358   [(use (match_operand:XF 0 "register_operand"))
15359    (use (match_operand:XF 1 "general_operand"))
15360    (use (match_operand:XF 2 "general_operand"))]
15361   "TARGET_USE_FANCY_MATH_387
15362    && flag_finite_math_only"
15364   rtx_code_label *label = gen_label_rtx ();
15366   rtx op1 = gen_reg_rtx (XFmode);
15367   rtx op2 = gen_reg_rtx (XFmode);
15369   emit_move_insn (op2, operands[2]);
15370   emit_move_insn (op1, operands[1]);
15372   emit_label (label);
15373   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15374   ix86_emit_fp_unordered_jump (label);
15375   LABEL_NUSES (label) = 1;
15377   emit_move_insn (operands[0], op1);
15378   DONE;
15381 (define_expand "remainder<mode>3"
15382   [(use (match_operand:MODEF 0 "register_operand"))
15383    (use (match_operand:MODEF 1 "general_operand"))
15384    (use (match_operand:MODEF 2 "general_operand"))]
15385   "TARGET_USE_FANCY_MATH_387
15386    && flag_finite_math_only"
15388   rtx (*gen_truncxf) (rtx, rtx);
15390   rtx_code_label *label = gen_label_rtx ();
15392   rtx op1 = gen_reg_rtx (XFmode);
15393   rtx op2 = gen_reg_rtx (XFmode);
15395   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15396   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15398   emit_label (label);
15400   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15401   ix86_emit_fp_unordered_jump (label);
15402   LABEL_NUSES (label) = 1;
15404   /* Truncate the result properly for strict SSE math.  */
15405   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406       && !TARGET_MIX_SSE_I387)
15407     gen_truncxf = gen_truncxf<mode>2;
15408   else
15409     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15411   emit_insn (gen_truncxf (operands[0], op1));
15412   DONE;
15415 (define_int_iterator SINCOS
15416         [UNSPEC_SIN
15417          UNSPEC_COS])
15419 (define_int_attr sincos
15420         [(UNSPEC_SIN "sin")
15421          (UNSPEC_COS "cos")])
15423 (define_insn "*<sincos>xf2_i387"
15424   [(set (match_operand:XF 0 "register_operand" "=f")
15425         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15426                    SINCOS))]
15427   "TARGET_USE_FANCY_MATH_387
15428    && flag_unsafe_math_optimizations"
15429   "f<sincos>"
15430   [(set_attr "type" "fpspc")
15431    (set_attr "znver1_decode" "vector")
15432    (set_attr "mode" "XF")])
15434 (define_insn "*<sincos>_extend<mode>xf2_i387"
15435   [(set (match_operand:XF 0 "register_operand" "=f")
15436         (unspec:XF [(float_extend:XF
15437                       (match_operand:MODEF 1 "register_operand" "0"))]
15438                    SINCOS))]
15439   "TARGET_USE_FANCY_MATH_387
15440    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15441        || TARGET_MIX_SSE_I387)
15442    && flag_unsafe_math_optimizations"
15443   "f<sincos>"
15444   [(set_attr "type" "fpspc")
15445    (set_attr "znver1_decode" "vector")
15446    (set_attr "mode" "XF")])
15448 ;; When sincos pattern is defined, sin and cos builtin functions will be
15449 ;; expanded to sincos pattern with one of its outputs left unused.
15450 ;; CSE pass will figure out if two sincos patterns can be combined,
15451 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15452 ;; depending on the unused output.
15454 (define_insn "sincosxf3"
15455   [(set (match_operand:XF 0 "register_operand" "=f")
15456         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15457                    UNSPEC_SINCOS_COS))
15458    (set (match_operand:XF 1 "register_operand" "=u")
15459         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15460   "TARGET_USE_FANCY_MATH_387
15461    && flag_unsafe_math_optimizations"
15462   "fsincos"
15463   [(set_attr "type" "fpspc")
15464    (set_attr "znver1_decode" "vector")
15465    (set_attr "mode" "XF")])
15467 (define_split
15468   [(set (match_operand:XF 0 "register_operand")
15469         (unspec:XF [(match_operand:XF 2 "register_operand")]
15470                    UNSPEC_SINCOS_COS))
15471    (set (match_operand:XF 1 "register_operand")
15472         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15473   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15474    && can_create_pseudo_p ()"
15475   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15477 (define_split
15478   [(set (match_operand:XF 0 "register_operand")
15479         (unspec:XF [(match_operand:XF 2 "register_operand")]
15480                    UNSPEC_SINCOS_COS))
15481    (set (match_operand:XF 1 "register_operand")
15482         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15483   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15484    && can_create_pseudo_p ()"
15485   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15487 (define_insn "sincos_extend<mode>xf3_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (unspec:XF [(float_extend:XF
15490                       (match_operand:MODEF 2 "register_operand" "0"))]
15491                    UNSPEC_SINCOS_COS))
15492    (set (match_operand:XF 1 "register_operand" "=u")
15493         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15496        || TARGET_MIX_SSE_I387)
15497    && flag_unsafe_math_optimizations"
15498   "fsincos"
15499   [(set_attr "type" "fpspc")
15500    (set_attr "znver1_decode" "vector")
15501    (set_attr "mode" "XF")])
15503 (define_split
15504   [(set (match_operand:XF 0 "register_operand")
15505         (unspec:XF [(float_extend:XF
15506                       (match_operand:MODEF 2 "register_operand"))]
15507                    UNSPEC_SINCOS_COS))
15508    (set (match_operand:XF 1 "register_operand")
15509         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15510   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15511    && can_create_pseudo_p ()"
15512   [(set (match_dup 1)
15513         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15515 (define_split
15516   [(set (match_operand:XF 0 "register_operand")
15517         (unspec:XF [(float_extend:XF
15518                       (match_operand:MODEF 2 "register_operand"))]
15519                    UNSPEC_SINCOS_COS))
15520    (set (match_operand:XF 1 "register_operand")
15521         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15522   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15523    && can_create_pseudo_p ()"
15524   [(set (match_dup 0)
15525         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15527 (define_expand "sincos<mode>3"
15528   [(use (match_operand:MODEF 0 "register_operand"))
15529    (use (match_operand:MODEF 1 "register_operand"))
15530    (use (match_operand:MODEF 2 "register_operand"))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15533        || TARGET_MIX_SSE_I387)
15534    && flag_unsafe_math_optimizations"
15536   rtx op0 = gen_reg_rtx (XFmode);
15537   rtx op1 = gen_reg_rtx (XFmode);
15539   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15540   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15541   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15542   DONE;
15545 (define_insn "fptanxf4_i387"
15546   [(set (match_operand:XF 0 "register_operand" "=f")
15547         (match_operand:XF 3 "const_double_operand" "F"))
15548    (set (match_operand:XF 1 "register_operand" "=u")
15549         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15550                    UNSPEC_TAN))]
15551   "TARGET_USE_FANCY_MATH_387
15552    && flag_unsafe_math_optimizations
15553    && standard_80387_constant_p (operands[3]) == 2"
15554   "fptan"
15555   [(set_attr "type" "fpspc")
15556    (set_attr "znver1_decode" "vector")
15557    (set_attr "mode" "XF")])
15559 (define_insn "fptan_extend<mode>xf4_i387"
15560   [(set (match_operand:MODEF 0 "register_operand" "=f")
15561         (match_operand:MODEF 3 "const_double_operand" "F"))
15562    (set (match_operand:XF 1 "register_operand" "=u")
15563         (unspec:XF [(float_extend:XF
15564                       (match_operand:MODEF 2 "register_operand" "0"))]
15565                    UNSPEC_TAN))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15568        || TARGET_MIX_SSE_I387)
15569    && flag_unsafe_math_optimizations
15570    && standard_80387_constant_p (operands[3]) == 2"
15571   "fptan"
15572   [(set_attr "type" "fpspc")
15573    (set_attr "znver1_decode" "vector")
15574    (set_attr "mode" "XF")])
15576 (define_expand "tanxf2"
15577   [(use (match_operand:XF 0 "register_operand"))
15578    (use (match_operand:XF 1 "register_operand"))]
15579   "TARGET_USE_FANCY_MATH_387
15580    && flag_unsafe_math_optimizations"
15582   rtx one = gen_reg_rtx (XFmode);
15583   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15585   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15586   DONE;
15589 (define_expand "tan<mode>2"
15590   [(use (match_operand:MODEF 0 "register_operand"))
15591    (use (match_operand:MODEF 1 "register_operand"))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15594        || TARGET_MIX_SSE_I387)
15595    && flag_unsafe_math_optimizations"
15597   rtx op0 = gen_reg_rtx (XFmode);
15599   rtx one = gen_reg_rtx (<MODE>mode);
15600   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15602   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15603                                              operands[1], op2));
15604   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15605   DONE;
15608 (define_insn "*fpatanxf3_i387"
15609   [(set (match_operand:XF 0 "register_operand" "=f")
15610         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15611                     (match_operand:XF 2 "register_operand" "u")]
15612                    UNSPEC_FPATAN))
15613    (clobber (match_scratch:XF 3 "=2"))]
15614   "TARGET_USE_FANCY_MATH_387
15615    && flag_unsafe_math_optimizations"
15616   "fpatan"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "znver1_decode" "vector")
15619    (set_attr "mode" "XF")])
15621 (define_insn "fpatan_extend<mode>xf3_i387"
15622   [(set (match_operand:XF 0 "register_operand" "=f")
15623         (unspec:XF [(float_extend:XF
15624                       (match_operand:MODEF 1 "register_operand" "0"))
15625                     (float_extend:XF
15626                       (match_operand:MODEF 2 "register_operand" "u"))]
15627                    UNSPEC_FPATAN))
15628    (clobber (match_scratch:XF 3 "=2"))]
15629   "TARGET_USE_FANCY_MATH_387
15630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15631        || TARGET_MIX_SSE_I387)
15632    && flag_unsafe_math_optimizations"
15633   "fpatan"
15634   [(set_attr "type" "fpspc")
15635    (set_attr "znver1_decode" "vector")
15636    (set_attr "mode" "XF")])
15638 (define_expand "atan2xf3"
15639   [(parallel [(set (match_operand:XF 0 "register_operand")
15640                    (unspec:XF [(match_operand:XF 2 "register_operand")
15641                                (match_operand:XF 1 "register_operand")]
15642                               UNSPEC_FPATAN))
15643               (clobber (match_scratch:XF 3))])]
15644   "TARGET_USE_FANCY_MATH_387
15645    && flag_unsafe_math_optimizations")
15647 (define_expand "atan2<mode>3"
15648   [(use (match_operand:MODEF 0 "register_operand"))
15649    (use (match_operand:MODEF 1 "register_operand"))
15650    (use (match_operand:MODEF 2 "register_operand"))]
15651   "TARGET_USE_FANCY_MATH_387
15652    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15653        || TARGET_MIX_SSE_I387)
15654    && flag_unsafe_math_optimizations"
15656   rtx op0 = gen_reg_rtx (XFmode);
15658   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15659   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15660   DONE;
15663 (define_expand "atanxf2"
15664   [(parallel [(set (match_operand:XF 0 "register_operand")
15665                    (unspec:XF [(match_dup 2)
15666                                (match_operand:XF 1 "register_operand")]
15667                               UNSPEC_FPATAN))
15668               (clobber (match_scratch:XF 3))])]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15672   operands[2] = gen_reg_rtx (XFmode);
15673   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15676 (define_expand "atan<mode>2"
15677   [(use (match_operand:MODEF 0 "register_operand"))
15678    (use (match_operand:MODEF 1 "register_operand"))]
15679   "TARGET_USE_FANCY_MATH_387
15680    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15681        || TARGET_MIX_SSE_I387)
15682    && flag_unsafe_math_optimizations"
15684   rtx op0 = gen_reg_rtx (XFmode);
15686   rtx op2 = gen_reg_rtx (<MODE>mode);
15687   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15689   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15690   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15691   DONE;
15694 (define_expand "asinxf2"
15695   [(set (match_dup 2)
15696         (mult:XF (match_operand:XF 1 "register_operand")
15697                  (match_dup 1)))
15698    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15699    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15700    (parallel [(set (match_operand:XF 0 "register_operand")
15701                    (unspec:XF [(match_dup 5) (match_dup 1)]
15702                               UNSPEC_FPATAN))
15703               (clobber (match_scratch:XF 6))])]
15704   "TARGET_USE_FANCY_MATH_387
15705    && flag_unsafe_math_optimizations"
15707   int i;
15709   for (i = 2; i < 6; i++)
15710     operands[i] = gen_reg_rtx (XFmode);
15712   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15715 (define_expand "asin<mode>2"
15716   [(use (match_operand:MODEF 0 "register_operand"))
15717    (use (match_operand:MODEF 1 "general_operand"))]
15718   "TARGET_USE_FANCY_MATH_387
15719    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15720        || TARGET_MIX_SSE_I387)
15721    && flag_unsafe_math_optimizations"
15723   rtx op0 = gen_reg_rtx (XFmode);
15724   rtx op1 = gen_reg_rtx (XFmode);
15726   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15727   emit_insn (gen_asinxf2 (op0, op1));
15728   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15729   DONE;
15732 (define_expand "acosxf2"
15733   [(set (match_dup 2)
15734         (mult:XF (match_operand:XF 1 "register_operand")
15735                  (match_dup 1)))
15736    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15737    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15738    (parallel [(set (match_operand:XF 0 "register_operand")
15739                    (unspec:XF [(match_dup 1) (match_dup 5)]
15740                               UNSPEC_FPATAN))
15741               (clobber (match_scratch:XF 6))])]
15742   "TARGET_USE_FANCY_MATH_387
15743    && flag_unsafe_math_optimizations"
15745   int i;
15747   for (i = 2; i < 6; i++)
15748     operands[i] = gen_reg_rtx (XFmode);
15750   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15753 (define_expand "acos<mode>2"
15754   [(use (match_operand:MODEF 0 "register_operand"))
15755    (use (match_operand:MODEF 1 "general_operand"))]
15756   "TARGET_USE_FANCY_MATH_387
15757    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15758        || TARGET_MIX_SSE_I387)
15759    && flag_unsafe_math_optimizations"
15761   rtx op0 = gen_reg_rtx (XFmode);
15762   rtx op1 = gen_reg_rtx (XFmode);
15764   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15765   emit_insn (gen_acosxf2 (op0, op1));
15766   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15767   DONE;
15770 (define_insn "fyl2xxf3_i387"
15771   [(set (match_operand:XF 0 "register_operand" "=f")
15772         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15773                     (match_operand:XF 2 "register_operand" "u")]
15774                    UNSPEC_FYL2X))
15775    (clobber (match_scratch:XF 3 "=2"))]
15776   "TARGET_USE_FANCY_MATH_387
15777    && flag_unsafe_math_optimizations"
15778   "fyl2x"
15779   [(set_attr "type" "fpspc")
15780    (set_attr "znver1_decode" "vector")
15781    (set_attr "mode" "XF")])
15783 (define_insn "fyl2x_extend<mode>xf3_i387"
15784   [(set (match_operand:XF 0 "register_operand" "=f")
15785         (unspec:XF [(float_extend:XF
15786                       (match_operand:MODEF 1 "register_operand" "0"))
15787                     (match_operand:XF 2 "register_operand" "u")]
15788                    UNSPEC_FYL2X))
15789    (clobber (match_scratch:XF 3 "=2"))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15792        || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15794   "fyl2x"
15795   [(set_attr "type" "fpspc")
15796    (set_attr "znver1_decode" "vector")
15797    (set_attr "mode" "XF")])
15799 (define_expand "logxf2"
15800   [(parallel [(set (match_operand:XF 0 "register_operand")
15801                    (unspec:XF [(match_operand:XF 1 "register_operand")
15802                                (match_dup 2)] UNSPEC_FYL2X))
15803               (clobber (match_scratch:XF 3))])]
15804   "TARGET_USE_FANCY_MATH_387
15805    && flag_unsafe_math_optimizations"
15807   operands[2] = gen_reg_rtx (XFmode);
15808   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15811 (define_expand "log<mode>2"
15812   [(use (match_operand:MODEF 0 "register_operand"))
15813    (use (match_operand:MODEF 1 "register_operand"))]
15814   "TARGET_USE_FANCY_MATH_387
15815    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15816        || TARGET_MIX_SSE_I387)
15817    && flag_unsafe_math_optimizations"
15819   rtx op0 = gen_reg_rtx (XFmode);
15821   rtx op2 = gen_reg_rtx (XFmode);
15822   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15824   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15825   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15826   DONE;
15829 (define_expand "log10xf2"
15830   [(parallel [(set (match_operand:XF 0 "register_operand")
15831                    (unspec:XF [(match_operand:XF 1 "register_operand")
15832                                (match_dup 2)] UNSPEC_FYL2X))
15833               (clobber (match_scratch:XF 3))])]
15834   "TARGET_USE_FANCY_MATH_387
15835    && flag_unsafe_math_optimizations"
15837   operands[2] = gen_reg_rtx (XFmode);
15838   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15841 (define_expand "log10<mode>2"
15842   [(use (match_operand:MODEF 0 "register_operand"))
15843    (use (match_operand:MODEF 1 "register_operand"))]
15844   "TARGET_USE_FANCY_MATH_387
15845    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15846        || TARGET_MIX_SSE_I387)
15847    && flag_unsafe_math_optimizations"
15849   rtx op0 = gen_reg_rtx (XFmode);
15851   rtx op2 = gen_reg_rtx (XFmode);
15852   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15854   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15855   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15856   DONE;
15859 (define_expand "log2xf2"
15860   [(parallel [(set (match_operand:XF 0 "register_operand")
15861                    (unspec:XF [(match_operand:XF 1 "register_operand")
15862                                (match_dup 2)] UNSPEC_FYL2X))
15863               (clobber (match_scratch:XF 3))])]
15864   "TARGET_USE_FANCY_MATH_387
15865    && flag_unsafe_math_optimizations"
15867   operands[2] = gen_reg_rtx (XFmode);
15868   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15871 (define_expand "log2<mode>2"
15872   [(use (match_operand:MODEF 0 "register_operand"))
15873    (use (match_operand:MODEF 1 "register_operand"))]
15874   "TARGET_USE_FANCY_MATH_387
15875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15876        || TARGET_MIX_SSE_I387)
15877    && flag_unsafe_math_optimizations"
15879   rtx op0 = gen_reg_rtx (XFmode);
15881   rtx op2 = gen_reg_rtx (XFmode);
15882   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15884   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15885   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15886   DONE;
15889 (define_insn "fyl2xp1xf3_i387"
15890   [(set (match_operand:XF 0 "register_operand" "=f")
15891         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15892                     (match_operand:XF 2 "register_operand" "u")]
15893                    UNSPEC_FYL2XP1))
15894    (clobber (match_scratch:XF 3 "=2"))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && flag_unsafe_math_optimizations"
15897   "fyl2xp1"
15898   [(set_attr "type" "fpspc")
15899    (set_attr "znver1_decode" "vector")
15900    (set_attr "mode" "XF")])
15902 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15903   [(set (match_operand:XF 0 "register_operand" "=f")
15904         (unspec:XF [(float_extend:XF
15905                       (match_operand:MODEF 1 "register_operand" "0"))
15906                     (match_operand:XF 2 "register_operand" "u")]
15907                    UNSPEC_FYL2XP1))
15908    (clobber (match_scratch:XF 3 "=2"))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15911        || TARGET_MIX_SSE_I387)
15912    && flag_unsafe_math_optimizations"
15913   "fyl2xp1"
15914   [(set_attr "type" "fpspc")
15915    (set_attr "znver1_decode" "vector")
15916    (set_attr "mode" "XF")])
15918 (define_expand "log1pxf2"
15919   [(use (match_operand:XF 0 "register_operand"))
15920    (use (match_operand:XF 1 "register_operand"))]
15921   "TARGET_USE_FANCY_MATH_387
15922    && flag_unsafe_math_optimizations"
15924   ix86_emit_i387_log1p (operands[0], operands[1]);
15925   DONE;
15928 (define_expand "log1p<mode>2"
15929   [(use (match_operand:MODEF 0 "register_operand"))
15930    (use (match_operand:MODEF 1 "register_operand"))]
15931   "TARGET_USE_FANCY_MATH_387
15932    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15933        || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15936   rtx op0;
15938   op0 = gen_reg_rtx (XFmode);
15940   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15942   ix86_emit_i387_log1p (op0, operands[1]);
15943   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15944   DONE;
15947 (define_insn "fxtractxf3_i387"
15948   [(set (match_operand:XF 0 "register_operand" "=f")
15949         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15950                    UNSPEC_XTRACT_FRACT))
15951    (set (match_operand:XF 1 "register_operand" "=u")
15952         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15953   "TARGET_USE_FANCY_MATH_387
15954    && flag_unsafe_math_optimizations"
15955   "fxtract"
15956   [(set_attr "type" "fpspc")
15957    (set_attr "znver1_decode" "vector")
15958    (set_attr "mode" "XF")])
15960 (define_insn "fxtract_extend<mode>xf3_i387"
15961   [(set (match_operand:XF 0 "register_operand" "=f")
15962         (unspec:XF [(float_extend:XF
15963                       (match_operand:MODEF 2 "register_operand" "0"))]
15964                    UNSPEC_XTRACT_FRACT))
15965    (set (match_operand:XF 1 "register_operand" "=u")
15966         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15967   "TARGET_USE_FANCY_MATH_387
15968    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15969        || TARGET_MIX_SSE_I387)
15970    && flag_unsafe_math_optimizations"
15971   "fxtract"
15972   [(set_attr "type" "fpspc")
15973    (set_attr "znver1_decode" "vector")
15974    (set_attr "mode" "XF")])
15976 (define_expand "logbxf2"
15977   [(parallel [(set (match_dup 2)
15978                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15979                               UNSPEC_XTRACT_FRACT))
15980               (set (match_operand:XF 0 "register_operand")
15981                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15982   "TARGET_USE_FANCY_MATH_387
15983    && flag_unsafe_math_optimizations"
15984   "operands[2] = gen_reg_rtx (XFmode);")
15986 (define_expand "logb<mode>2"
15987   [(use (match_operand:MODEF 0 "register_operand"))
15988    (use (match_operand:MODEF 1 "register_operand"))]
15989   "TARGET_USE_FANCY_MATH_387
15990    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15991        || TARGET_MIX_SSE_I387)
15992    && flag_unsafe_math_optimizations"
15994   rtx op0 = gen_reg_rtx (XFmode);
15995   rtx op1 = gen_reg_rtx (XFmode);
15997   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15998   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15999   DONE;
16002 (define_expand "ilogbxf2"
16003   [(use (match_operand:SI 0 "register_operand"))
16004    (use (match_operand:XF 1 "register_operand"))]
16005   "TARGET_USE_FANCY_MATH_387
16006    && flag_unsafe_math_optimizations"
16008   rtx op0, op1;
16010   if (optimize_insn_for_size_p ())
16011     FAIL;
16013   op0 = gen_reg_rtx (XFmode);
16014   op1 = gen_reg_rtx (XFmode);
16016   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16017   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16018   DONE;
16021 (define_expand "ilogb<mode>2"
16022   [(use (match_operand:SI 0 "register_operand"))
16023    (use (match_operand:MODEF 1 "register_operand"))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16026        || TARGET_MIX_SSE_I387)
16027    && flag_unsafe_math_optimizations"
16029   rtx op0, op1;
16031   if (optimize_insn_for_size_p ())
16032     FAIL;
16034   op0 = gen_reg_rtx (XFmode);
16035   op1 = gen_reg_rtx (XFmode);
16037   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16038   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16039   DONE;
16042 (define_insn "*f2xm1xf2_i387"
16043   [(set (match_operand:XF 0 "register_operand" "=f")
16044         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16045                    UNSPEC_F2XM1))]
16046   "TARGET_USE_FANCY_MATH_387
16047    && flag_unsafe_math_optimizations"
16048   "f2xm1"
16049   [(set_attr "type" "fpspc")
16050    (set_attr "znver1_decode" "vector")
16051    (set_attr "mode" "XF")])
16053 (define_insn "fscalexf4_i387"
16054   [(set (match_operand:XF 0 "register_operand" "=f")
16055         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16056                     (match_operand:XF 3 "register_operand" "1")]
16057                    UNSPEC_FSCALE_FRACT))
16058    (set (match_operand:XF 1 "register_operand" "=u")
16059         (unspec:XF [(match_dup 2) (match_dup 3)]
16060                    UNSPEC_FSCALE_EXP))]
16061   "TARGET_USE_FANCY_MATH_387
16062    && flag_unsafe_math_optimizations"
16063   "fscale"
16064   [(set_attr "type" "fpspc")
16065    (set_attr "znver1_decode" "vector")
16066    (set_attr "mode" "XF")])
16068 (define_expand "expNcorexf3"
16069   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16070                                (match_operand:XF 2 "register_operand")))
16071    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16072    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16073    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16074    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16075    (parallel [(set (match_operand:XF 0 "register_operand")
16076                    (unspec:XF [(match_dup 8) (match_dup 4)]
16077                               UNSPEC_FSCALE_FRACT))
16078               (set (match_dup 9)
16079                    (unspec:XF [(match_dup 8) (match_dup 4)]
16080                               UNSPEC_FSCALE_EXP))])]
16081   "TARGET_USE_FANCY_MATH_387
16082    && flag_unsafe_math_optimizations"
16084   int i;
16086   for (i = 3; i < 10; i++)
16087     operands[i] = gen_reg_rtx (XFmode);
16089   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16092 (define_expand "expxf2"
16093   [(use (match_operand:XF 0 "register_operand"))
16094    (use (match_operand:XF 1 "register_operand"))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16098   rtx op2;
16100   op2 = gen_reg_rtx (XFmode);
16101   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16103   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16104   DONE;
16107 (define_expand "exp<mode>2"
16108   [(use (match_operand:MODEF 0 "register_operand"))
16109    (use (match_operand:MODEF 1 "general_operand"))]
16110   "TARGET_USE_FANCY_MATH_387
16111    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16112        || TARGET_MIX_SSE_I387)
16113    && flag_unsafe_math_optimizations"
16115   rtx op0, op1;
16117   op0 = gen_reg_rtx (XFmode);
16118   op1 = gen_reg_rtx (XFmode);
16120   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16121   emit_insn (gen_expxf2 (op0, op1));
16122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16123   DONE;
16126 (define_expand "exp10xf2"
16127   [(use (match_operand:XF 0 "register_operand"))
16128    (use (match_operand:XF 1 "register_operand"))]
16129   "TARGET_USE_FANCY_MATH_387
16130    && flag_unsafe_math_optimizations"
16132   rtx op2;
16134   op2 = gen_reg_rtx (XFmode);
16135   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16137   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16138   DONE;
16141 (define_expand "exp10<mode>2"
16142   [(use (match_operand:MODEF 0 "register_operand"))
16143    (use (match_operand:MODEF 1 "general_operand"))]
16144   "TARGET_USE_FANCY_MATH_387
16145    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16146        || TARGET_MIX_SSE_I387)
16147    && flag_unsafe_math_optimizations"
16149   rtx op0, op1;
16151   op0 = gen_reg_rtx (XFmode);
16152   op1 = gen_reg_rtx (XFmode);
16154   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16155   emit_insn (gen_exp10xf2 (op0, op1));
16156   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16157   DONE;
16160 (define_expand "exp2xf2"
16161   [(use (match_operand:XF 0 "register_operand"))
16162    (use (match_operand:XF 1 "register_operand"))]
16163   "TARGET_USE_FANCY_MATH_387
16164    && flag_unsafe_math_optimizations"
16166   rtx op2;
16168   op2 = gen_reg_rtx (XFmode);
16169   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16171   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16172   DONE;
16175 (define_expand "exp2<mode>2"
16176   [(use (match_operand:MODEF 0 "register_operand"))
16177    (use (match_operand:MODEF 1 "general_operand"))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16180        || TARGET_MIX_SSE_I387)
16181    && flag_unsafe_math_optimizations"
16183   rtx op0, op1;
16185   op0 = gen_reg_rtx (XFmode);
16186   op1 = gen_reg_rtx (XFmode);
16188   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16189   emit_insn (gen_exp2xf2 (op0, op1));
16190   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16191   DONE;
16194 (define_expand "expm1xf2"
16195   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16196                                (match_dup 2)))
16197    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16198    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16199    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16200    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16201    (parallel [(set (match_dup 7)
16202                    (unspec:XF [(match_dup 6) (match_dup 4)]
16203                               UNSPEC_FSCALE_FRACT))
16204               (set (match_dup 8)
16205                    (unspec:XF [(match_dup 6) (match_dup 4)]
16206                               UNSPEC_FSCALE_EXP))])
16207    (parallel [(set (match_dup 10)
16208                    (unspec:XF [(match_dup 9) (match_dup 8)]
16209                               UNSPEC_FSCALE_FRACT))
16210               (set (match_dup 11)
16211                    (unspec:XF [(match_dup 9) (match_dup 8)]
16212                               UNSPEC_FSCALE_EXP))])
16213    (set (match_dup 12) (minus:XF (match_dup 10)
16214                                  (float_extend:XF (match_dup 13))))
16215    (set (match_operand:XF 0 "register_operand")
16216         (plus:XF (match_dup 12) (match_dup 7)))]
16217   "TARGET_USE_FANCY_MATH_387
16218    && flag_unsafe_math_optimizations"
16220   int i;
16222   for (i = 2; i < 13; i++)
16223     operands[i] = gen_reg_rtx (XFmode);
16225   operands[13]
16226     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16228   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16231 (define_expand "expm1<mode>2"
16232   [(use (match_operand:MODEF 0 "register_operand"))
16233    (use (match_operand:MODEF 1 "general_operand"))]
16234   "TARGET_USE_FANCY_MATH_387
16235    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16236        || TARGET_MIX_SSE_I387)
16237    && flag_unsafe_math_optimizations"
16239   rtx op0, op1;
16241   op0 = gen_reg_rtx (XFmode);
16242   op1 = gen_reg_rtx (XFmode);
16244   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16245   emit_insn (gen_expm1xf2 (op0, op1));
16246   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16247   DONE;
16250 (define_expand "ldexpxf3"
16251   [(match_operand:XF 0 "register_operand")
16252    (match_operand:XF 1 "register_operand")
16253    (match_operand:SI 2 "register_operand")]
16254   "TARGET_USE_FANCY_MATH_387
16255    && flag_unsafe_math_optimizations"
16257   rtx tmp1, tmp2;
16259   tmp1 = gen_reg_rtx (XFmode);
16260   tmp2 = gen_reg_rtx (XFmode);
16262   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16263   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16264                                  operands[1], tmp1));
16265   DONE;
16268 (define_expand "ldexp<mode>3"
16269   [(use (match_operand:MODEF 0 "register_operand"))
16270    (use (match_operand:MODEF 1 "general_operand"))
16271    (use (match_operand:SI 2 "register_operand"))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16274        || TARGET_MIX_SSE_I387)
16275    && flag_unsafe_math_optimizations"
16277   rtx op0, op1;
16279   op0 = gen_reg_rtx (XFmode);
16280   op1 = gen_reg_rtx (XFmode);
16282   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16283   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16284   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16285   DONE;
16288 (define_expand "scalbxf3"
16289   [(parallel [(set (match_operand:XF 0 " register_operand")
16290                    (unspec:XF [(match_operand:XF 1 "register_operand")
16291                                (match_operand:XF 2 "register_operand")]
16292                               UNSPEC_FSCALE_FRACT))
16293               (set (match_dup 3)
16294                    (unspec:XF [(match_dup 1) (match_dup 2)]
16295                               UNSPEC_FSCALE_EXP))])]
16296   "TARGET_USE_FANCY_MATH_387
16297    && flag_unsafe_math_optimizations"
16299   operands[3] = gen_reg_rtx (XFmode);
16302 (define_expand "scalb<mode>3"
16303   [(use (match_operand:MODEF 0 "register_operand"))
16304    (use (match_operand:MODEF 1 "general_operand"))
16305    (use (match_operand:MODEF 2 "general_operand"))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16308        || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16311   rtx op0, op1, op2;
16313   op0 = gen_reg_rtx (XFmode);
16314   op1 = gen_reg_rtx (XFmode);
16315   op2 = gen_reg_rtx (XFmode);
16317   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16318   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16319   emit_insn (gen_scalbxf3 (op0, op1, op2));
16320   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16321   DONE;
16324 (define_expand "significandxf2"
16325   [(parallel [(set (match_operand:XF 0 "register_operand")
16326                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16327                               UNSPEC_XTRACT_FRACT))
16328               (set (match_dup 2)
16329                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16330   "TARGET_USE_FANCY_MATH_387
16331    && flag_unsafe_math_optimizations"
16332   "operands[2] = gen_reg_rtx (XFmode);")
16334 (define_expand "significand<mode>2"
16335   [(use (match_operand:MODEF 0 "register_operand"))
16336    (use (match_operand:MODEF 1 "register_operand"))]
16337   "TARGET_USE_FANCY_MATH_387
16338    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16339        || TARGET_MIX_SSE_I387)
16340    && flag_unsafe_math_optimizations"
16342   rtx op0 = gen_reg_rtx (XFmode);
16343   rtx op1 = gen_reg_rtx (XFmode);
16345   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16346   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16347   DONE;
16351 (define_insn "sse4_1_round<mode>2"
16352   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16353         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16354                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16355                       UNSPEC_ROUND))]
16356   "TARGET_SSE4_1"
16357   "@
16358    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16359    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16360   [(set_attr "type" "ssecvt")
16361    (set_attr "prefix_extra" "1,*")
16362    (set_attr "length_immediate" "*,1")
16363    (set_attr "prefix" "maybe_vex,evex")
16364    (set_attr "isa" "noavx512f,avx512f")
16365    (set_attr "mode" "<MODE>")])
16367 (define_insn "rintxf2"
16368   [(set (match_operand:XF 0 "register_operand" "=f")
16369         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16370                    UNSPEC_FRNDINT))]
16371   "TARGET_USE_FANCY_MATH_387"
16372   "frndint"
16373   [(set_attr "type" "fpspc")
16374    (set_attr "znver1_decode" "vector")
16375    (set_attr "mode" "XF")])
16377 (define_insn "rint<mode>2_frndint"
16378   [(set (match_operand:MODEF 0 "register_operand" "=f")
16379         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16380                       UNSPEC_FRNDINT))]
16381   "TARGET_USE_FANCY_MATH_387"
16382   "frndint"
16383   [(set_attr "type" "fpspc")
16384    (set_attr "znver1_decode" "vector")
16385    (set_attr "mode" "<MODE>")])
16387 (define_expand "rint<mode>2"
16388   [(use (match_operand:MODEF 0 "register_operand"))
16389    (use (match_operand:MODEF 1 "register_operand"))]
16390   "(TARGET_USE_FANCY_MATH_387
16391     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16392         || TARGET_MIX_SSE_I387))
16393    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16395   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396     {
16397       if (TARGET_SSE4_1)
16398         emit_insn (gen_sse4_1_round<mode>2
16399                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16400       else
16401         ix86_expand_rint (operands[0], operands[1]);
16402     }
16403   else
16404     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16405   DONE;
16408 (define_expand "round<mode>2"
16409   [(match_operand:X87MODEF 0 "register_operand")
16410    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16411   "(TARGET_USE_FANCY_MATH_387
16412     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16413         || TARGET_MIX_SSE_I387)
16414     && flag_unsafe_math_optimizations
16415     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16416    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16417        && !flag_trapping_math && !flag_rounding_math)"
16419   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16420       && !flag_trapping_math && !flag_rounding_math)
16421     {
16422       if (TARGET_SSE4_1)
16423         {
16424           operands[1] = force_reg (<MODE>mode, operands[1]);
16425           ix86_expand_round_sse4 (operands[0], operands[1]);
16426         }
16427       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16428         ix86_expand_round (operands[0], operands[1]);
16429       else
16430         ix86_expand_rounddf_32 (operands[0], operands[1]);
16431     }
16432   else
16433     {
16434       operands[1] = force_reg (<MODE>mode, operands[1]);
16435       ix86_emit_i387_round (operands[0], operands[1]);
16436     }
16437   DONE;
16440 (define_insn_and_split "*fistdi2_1"
16441   [(set (match_operand:DI 0 "nonimmediate_operand")
16442         (unspec:DI [(match_operand:XF 1 "register_operand")]
16443                    UNSPEC_FIST))]
16444   "TARGET_USE_FANCY_MATH_387
16445    && can_create_pseudo_p ()"
16446   "#"
16447   "&& 1"
16448   [(const_int 0)]
16450   if (memory_operand (operands[0], VOIDmode))
16451     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16452   else
16453     {
16454       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16455       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16456                                          operands[2]));
16457     }
16458   DONE;
16460   [(set_attr "type" "fpspc")
16461    (set_attr "mode" "DI")])
16463 (define_insn "fistdi2"
16464   [(set (match_operand:DI 0 "memory_operand" "=m")
16465         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16466                    UNSPEC_FIST))
16467    (clobber (match_scratch:XF 2 "=&1f"))]
16468   "TARGET_USE_FANCY_MATH_387"
16469   "* return output_fix_trunc (insn, operands, false);"
16470   [(set_attr "type" "fpspc")
16471    (set_attr "mode" "DI")])
16473 (define_insn "fistdi2_with_temp"
16474   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16475         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16476                    UNSPEC_FIST))
16477    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16478    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16479   "TARGET_USE_FANCY_MATH_387"
16480   "#"
16481   [(set_attr "type" "fpspc")
16482    (set_attr "mode" "DI")])
16484 (define_split
16485   [(set (match_operand:DI 0 "register_operand")
16486         (unspec:DI [(match_operand:XF 1 "register_operand")]
16487                    UNSPEC_FIST))
16488    (clobber (match_operand:DI 2 "memory_operand"))
16489    (clobber (match_scratch 3))]
16490   "reload_completed"
16491   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16492               (clobber (match_dup 3))])
16493    (set (match_dup 0) (match_dup 2))])
16495 (define_split
16496   [(set (match_operand:DI 0 "memory_operand")
16497         (unspec:DI [(match_operand:XF 1 "register_operand")]
16498                    UNSPEC_FIST))
16499    (clobber (match_operand:DI 2 "memory_operand"))
16500    (clobber (match_scratch 3))]
16501   "reload_completed"
16502   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16503               (clobber (match_dup 3))])])
16505 (define_insn_and_split "*fist<mode>2_1"
16506   [(set (match_operand:SWI24 0 "register_operand")
16507         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16508                       UNSPEC_FIST))]
16509   "TARGET_USE_FANCY_MATH_387
16510    && can_create_pseudo_p ()"
16511   "#"
16512   "&& 1"
16513   [(const_int 0)]
16515   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16516   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16517                                         operands[2]));
16518   DONE;
16520   [(set_attr "type" "fpspc")
16521    (set_attr "mode" "<MODE>")])
16523 (define_insn "fist<mode>2"
16524   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16525         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16526                       UNSPEC_FIST))]
16527   "TARGET_USE_FANCY_MATH_387"
16528   "* return output_fix_trunc (insn, operands, false);"
16529   [(set_attr "type" "fpspc")
16530    (set_attr "mode" "<MODE>")])
16532 (define_insn "fist<mode>2_with_temp"
16533   [(set (match_operand:SWI24 0 "register_operand" "=r")
16534         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16535                       UNSPEC_FIST))
16536    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16537   "TARGET_USE_FANCY_MATH_387"
16538   "#"
16539   [(set_attr "type" "fpspc")
16540    (set_attr "mode" "<MODE>")])
16542 (define_split
16543   [(set (match_operand:SWI24 0 "register_operand")
16544         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16545                       UNSPEC_FIST))
16546    (clobber (match_operand:SWI24 2 "memory_operand"))]
16547   "reload_completed"
16548   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16549    (set (match_dup 0) (match_dup 2))])
16551 (define_split
16552   [(set (match_operand:SWI24 0 "memory_operand")
16553         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16554                       UNSPEC_FIST))
16555    (clobber (match_operand:SWI24 2 "memory_operand"))]
16556   "reload_completed"
16557   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16559 (define_expand "lrintxf<mode>2"
16560   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16561      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16562                      UNSPEC_FIST))]
16563   "TARGET_USE_FANCY_MATH_387")
16565 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16566   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16567      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16568                    UNSPEC_FIX_NOTRUNC))]
16569   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16571 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16572   [(match_operand:SWI248x 0 "nonimmediate_operand")
16573    (match_operand:X87MODEF 1 "register_operand")]
16574   "(TARGET_USE_FANCY_MATH_387
16575     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16576         || TARGET_MIX_SSE_I387)
16577     && flag_unsafe_math_optimizations)
16578    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16579        && <SWI248x:MODE>mode != HImode 
16580        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16581        && !flag_trapping_math && !flag_rounding_math)"
16583   if (optimize_insn_for_size_p ())
16584     FAIL;
16586   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16587       && <SWI248x:MODE>mode != HImode
16588       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16589       && !flag_trapping_math && !flag_rounding_math)
16590     ix86_expand_lround (operands[0], operands[1]);
16591   else
16592     ix86_emit_i387_round (operands[0], operands[1]);
16593   DONE;
16596 (define_int_iterator FRNDINT_ROUNDING
16597         [UNSPEC_FRNDINT_FLOOR
16598          UNSPEC_FRNDINT_CEIL
16599          UNSPEC_FRNDINT_TRUNC])
16601 (define_int_iterator FIST_ROUNDING
16602         [UNSPEC_FIST_FLOOR
16603          UNSPEC_FIST_CEIL])
16605 ;; Base name for define_insn
16606 (define_int_attr rounding_insn
16607         [(UNSPEC_FRNDINT_FLOOR "floor")
16608          (UNSPEC_FRNDINT_CEIL "ceil")
16609          (UNSPEC_FRNDINT_TRUNC "btrunc")
16610          (UNSPEC_FIST_FLOOR "floor")
16611          (UNSPEC_FIST_CEIL "ceil")])
16613 (define_int_attr rounding
16614         [(UNSPEC_FRNDINT_FLOOR "floor")
16615          (UNSPEC_FRNDINT_CEIL "ceil")
16616          (UNSPEC_FRNDINT_TRUNC "trunc")
16617          (UNSPEC_FIST_FLOOR "floor")
16618          (UNSPEC_FIST_CEIL "ceil")])
16620 (define_int_attr ROUNDING
16621         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16622          (UNSPEC_FRNDINT_CEIL "CEIL")
16623          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16624          (UNSPEC_FIST_FLOOR "FLOOR")
16625          (UNSPEC_FIST_CEIL "CEIL")])
16627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16628 (define_insn_and_split "frndint<mode>2_<rounding>"
16629   [(set (match_operand:X87MODEF 0 "register_operand")
16630         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16631                    FRNDINT_ROUNDING))
16632    (clobber (reg:CC FLAGS_REG))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16635    && can_create_pseudo_p ()"
16636   "#"
16637   "&& 1"
16638   [(const_int 0)]
16640   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16642   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16643   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16645   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16646                                                  operands[2], operands[3]));
16647   DONE;
16649   [(set_attr "type" "frndint")
16650    (set_attr "i387_cw" "<rounding>")
16651    (set_attr "mode" "<MODE>")])
16653 (define_insn "frndint<mode>2_<rounding>_i387"
16654   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16655         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16656                          FRNDINT_ROUNDING))
16657    (use (match_operand:HI 2 "memory_operand" "m"))
16658    (use (match_operand:HI 3 "memory_operand" "m"))]
16659   "TARGET_USE_FANCY_MATH_387
16660    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16661   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16662   [(set_attr "type" "frndint")
16663    (set_attr "i387_cw" "<rounding>")
16664    (set_attr "mode" "<MODE>")])
16666 (define_expand "<rounding_insn>xf2"
16667   [(parallel [(set (match_operand:XF 0 "register_operand")
16668                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16669                               FRNDINT_ROUNDING))
16670               (clobber (reg:CC FLAGS_REG))])]
16671   "TARGET_USE_FANCY_MATH_387
16672    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16674 (define_expand "<rounding_insn><mode>2"
16675   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16676                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16677                                  FRNDINT_ROUNDING))
16678               (clobber (reg:CC FLAGS_REG))])]
16679   "(TARGET_USE_FANCY_MATH_387
16680     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681         || TARGET_MIX_SSE_I387)
16682     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16683    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16684        && (TARGET_SSE4_1 || !flag_trapping_math
16685            || flag_fp_int_builtin_inexact))"
16687   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16688       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16689     {
16690       if (TARGET_SSE4_1)
16691         emit_insn (gen_sse4_1_round<mode>2
16692                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16693                                                        | ROUND_NO_EXC)));
16694       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16695         {
16696           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16697             ix86_expand_floorceil (operands[0], operands[1], true);
16698           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16699             ix86_expand_floorceil (operands[0], operands[1], false);
16700           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16701             ix86_expand_trunc (operands[0], operands[1]);
16702           else
16703             gcc_unreachable ();
16704         }
16705       else
16706         {
16707           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16708             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16709           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16710             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16711           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16712             ix86_expand_truncdf_32 (operands[0], operands[1]);
16713           else
16714             gcc_unreachable ();
16715         }
16716     }
16717   else
16718     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16719   DONE;
16722 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16723 (define_insn_and_split "frndintxf2_mask_pm"
16724   [(set (match_operand:XF 0 "register_operand")
16725         (unspec:XF [(match_operand:XF 1 "register_operand")]
16726                    UNSPEC_FRNDINT_MASK_PM))
16727    (clobber (reg:CC FLAGS_REG))]
16728   "TARGET_USE_FANCY_MATH_387
16729    && flag_unsafe_math_optimizations
16730    && can_create_pseudo_p ()"
16731   "#"
16732   "&& 1"
16733   [(const_int 0)]
16735   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16737   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16738   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16740   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16741                                           operands[2], operands[3]));
16742   DONE;
16744   [(set_attr "type" "frndint")
16745    (set_attr "i387_cw" "mask_pm")
16746    (set_attr "mode" "XF")])
16748 (define_insn "frndintxf2_mask_pm_i387"
16749   [(set (match_operand:XF 0 "register_operand" "=f")
16750         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16751                    UNSPEC_FRNDINT_MASK_PM))
16752    (use (match_operand:HI 2 "memory_operand" "m"))
16753    (use (match_operand:HI 3 "memory_operand" "m"))]
16754   "TARGET_USE_FANCY_MATH_387
16755    && flag_unsafe_math_optimizations"
16756   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16757   [(set_attr "type" "frndint")
16758    (set_attr "i387_cw" "mask_pm")
16759    (set_attr "mode" "XF")])
16761 (define_expand "nearbyintxf2"
16762   [(parallel [(set (match_operand:XF 0 "register_operand")
16763                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16764                               UNSPEC_FRNDINT_MASK_PM))
16765               (clobber (reg:CC FLAGS_REG))])]
16766   "TARGET_USE_FANCY_MATH_387
16767    && flag_unsafe_math_optimizations")
16769 (define_expand "nearbyint<mode>2"
16770   [(use (match_operand:MODEF 0 "register_operand"))
16771    (use (match_operand:MODEF 1 "register_operand"))]
16772   "TARGET_USE_FANCY_MATH_387
16773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16774        || TARGET_MIX_SSE_I387)
16775    && flag_unsafe_math_optimizations"
16777   rtx op0 = gen_reg_rtx (XFmode);
16778   rtx op1 = gen_reg_rtx (XFmode);
16780   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16781   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16783   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16784   DONE;
16787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16788 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16789   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16790         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16791                         FIST_ROUNDING))
16792    (clobber (reg:CC FLAGS_REG))]
16793   "TARGET_USE_FANCY_MATH_387
16794    && flag_unsafe_math_optimizations
16795    && can_create_pseudo_p ()"
16796   "#"
16797   "&& 1"
16798   [(const_int 0)]
16800   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16802   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16803   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16804   if (memory_operand (operands[0], VOIDmode))
16805     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16806                                            operands[2], operands[3]));
16807   else
16808     {
16809       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16810       emit_insn (gen_fist<mode>2_<rounding>_with_temp
16811                   (operands[0], operands[1], operands[2],
16812                    operands[3], operands[4]));
16813     }
16814   DONE;
16816   [(set_attr "type" "fistp")
16817    (set_attr "i387_cw" "<rounding>")
16818    (set_attr "mode" "<MODE>")])
16820 (define_insn "fistdi2_<rounding>"
16821   [(set (match_operand:DI 0 "memory_operand" "=m")
16822         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16823                    FIST_ROUNDING))
16824    (use (match_operand:HI 2 "memory_operand" "m"))
16825    (use (match_operand:HI 3 "memory_operand" "m"))
16826    (clobber (match_scratch:XF 4 "=&1f"))]
16827   "TARGET_USE_FANCY_MATH_387
16828    && flag_unsafe_math_optimizations"
16829   "* return output_fix_trunc (insn, operands, false);"
16830   [(set_attr "type" "fistp")
16831    (set_attr "i387_cw" "<rounding>")
16832    (set_attr "mode" "DI")])
16834 (define_insn "fistdi2_<rounding>_with_temp"
16835   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16836         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16837                    FIST_ROUNDING))
16838    (use (match_operand:HI 2 "memory_operand" "m,m"))
16839    (use (match_operand:HI 3 "memory_operand" "m,m"))
16840    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16841    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16842   "TARGET_USE_FANCY_MATH_387
16843    && flag_unsafe_math_optimizations"
16844   "#"
16845   [(set_attr "type" "fistp")
16846    (set_attr "i387_cw" "<rounding>")
16847    (set_attr "mode" "DI")])
16849 (define_split
16850   [(set (match_operand:DI 0 "register_operand")
16851         (unspec:DI [(match_operand:XF 1 "register_operand")]
16852                    FIST_ROUNDING))
16853    (use (match_operand:HI 2 "memory_operand"))
16854    (use (match_operand:HI 3 "memory_operand"))
16855    (clobber (match_operand:DI 4 "memory_operand"))
16856    (clobber (match_scratch 5))]
16857   "reload_completed"
16858   [(parallel [(set (match_dup 4)
16859                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16860               (use (match_dup 2))
16861               (use (match_dup 3))
16862               (clobber (match_dup 5))])
16863    (set (match_dup 0) (match_dup 4))])
16865 (define_split
16866   [(set (match_operand:DI 0 "memory_operand")
16867         (unspec:DI [(match_operand:XF 1 "register_operand")]
16868                    FIST_ROUNDING))
16869    (use (match_operand:HI 2 "memory_operand"))
16870    (use (match_operand:HI 3 "memory_operand"))
16871    (clobber (match_operand:DI 4 "memory_operand"))
16872    (clobber (match_scratch 5))]
16873   "reload_completed"
16874   [(parallel [(set (match_dup 0)
16875                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16876               (use (match_dup 2))
16877               (use (match_dup 3))
16878               (clobber (match_dup 5))])])
16880 (define_insn "fist<mode>2_<rounding>"
16881   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16882         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16883                       FIST_ROUNDING))
16884    (use (match_operand:HI 2 "memory_operand" "m"))
16885    (use (match_operand:HI 3 "memory_operand" "m"))]
16886   "TARGET_USE_FANCY_MATH_387
16887    && flag_unsafe_math_optimizations"
16888   "* return output_fix_trunc (insn, operands, false);"
16889   [(set_attr "type" "fistp")
16890    (set_attr "i387_cw" "<rounding>")
16891    (set_attr "mode" "<MODE>")])
16893 (define_insn "fist<mode>2_<rounding>_with_temp"
16894   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16895         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16896                       FIST_ROUNDING))
16897    (use (match_operand:HI 2 "memory_operand" "m,m"))
16898    (use (match_operand:HI 3 "memory_operand" "m,m"))
16899    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16900   "TARGET_USE_FANCY_MATH_387
16901    && flag_unsafe_math_optimizations"
16902   "#"
16903   [(set_attr "type" "fistp")
16904    (set_attr "i387_cw" "<rounding>")
16905    (set_attr "mode" "<MODE>")])
16907 (define_split
16908   [(set (match_operand:SWI24 0 "register_operand")
16909         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16910                       FIST_ROUNDING))
16911    (use (match_operand:HI 2 "memory_operand"))
16912    (use (match_operand:HI 3 "memory_operand"))
16913    (clobber (match_operand:SWI24 4 "memory_operand"))]
16914   "reload_completed"
16915   [(parallel [(set (match_dup 4)
16916                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16917               (use (match_dup 2))
16918               (use (match_dup 3))])
16919    (set (match_dup 0) (match_dup 4))])
16921 (define_split
16922   [(set (match_operand:SWI24 0 "memory_operand")
16923         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16924                       FIST_ROUNDING))
16925    (use (match_operand:HI 2 "memory_operand"))
16926    (use (match_operand:HI 3 "memory_operand"))
16927    (clobber (match_operand:SWI24 4 "memory_operand"))]
16928   "reload_completed"
16929   [(parallel [(set (match_dup 0)
16930                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16931               (use (match_dup 2))
16932               (use (match_dup 3))])])
16934 (define_expand "l<rounding_insn>xf<mode>2"
16935   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16936                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16937                                    FIST_ROUNDING))
16938               (clobber (reg:CC FLAGS_REG))])]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16941    && flag_unsafe_math_optimizations")
16943 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16944   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16945                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16946                                  FIST_ROUNDING))
16947               (clobber (reg:CC FLAGS_REG))])]
16948   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16949    && !flag_trapping_math"
16951   if (TARGET_64BIT && optimize_insn_for_size_p ())
16952     FAIL;
16954   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16955     ix86_expand_lfloorceil (operands[0], operands[1], true);
16956   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16957     ix86_expand_lfloorceil (operands[0], operands[1], false);
16958   else
16959     gcc_unreachable ();
16961   DONE;
16964 (define_insn "fxam<mode>2_i387"
16965   [(set (match_operand:HI 0 "register_operand" "=a")
16966         (unspec:HI
16967           [(match_operand:X87MODEF 1 "register_operand" "f")]
16968           UNSPEC_FXAM))]
16969   "TARGET_USE_FANCY_MATH_387"
16970   "fxam\n\tfnstsw\t%0"
16971   [(set_attr "type" "multi")
16972    (set_attr "length" "4")
16973    (set_attr "unit" "i387")
16974    (set_attr "mode" "<MODE>")])
16976 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16977   [(set (match_operand:HI 0 "register_operand")
16978         (unspec:HI
16979           [(match_operand:MODEF 1 "memory_operand")]
16980           UNSPEC_FXAM_MEM))]
16981   "TARGET_USE_FANCY_MATH_387
16982    && can_create_pseudo_p ()"
16983   "#"
16984   "&& 1"
16985   [(set (match_dup 2)(match_dup 1))
16986    (set (match_dup 0)
16987         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16989   operands[2] = gen_reg_rtx (<MODE>mode);
16991   MEM_VOLATILE_P (operands[1]) = 1;
16993   [(set_attr "type" "multi")
16994    (set_attr "unit" "i387")
16995    (set_attr "mode" "<MODE>")])
16997 (define_expand "isinfxf2"
16998   [(use (match_operand:SI 0 "register_operand"))
16999    (use (match_operand:XF 1 "register_operand"))]
17000   "TARGET_USE_FANCY_MATH_387
17001    && ix86_libc_has_function (function_c99_misc)"
17003   rtx mask = GEN_INT (0x45);
17004   rtx val = GEN_INT (0x05);
17006   rtx scratch = gen_reg_rtx (HImode);
17007   rtx res = gen_reg_rtx (QImode);
17009   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17011   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17012   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17013   ix86_expand_setcc (res, EQ,
17014                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17015   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17016   DONE;
17019 (define_expand "isinf<mode>2"
17020   [(use (match_operand:SI 0 "register_operand"))
17021    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17022   "TARGET_USE_FANCY_MATH_387
17023    && ix86_libc_has_function (function_c99_misc)
17024    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17026   rtx mask = GEN_INT (0x45);
17027   rtx val = GEN_INT (0x05);
17029   rtx scratch = gen_reg_rtx (HImode);
17030   rtx res = gen_reg_rtx (QImode);
17032   /* Remove excess precision by forcing value through memory. */
17033   if (memory_operand (operands[1], VOIDmode))
17034     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17035   else
17036     {
17037       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17039       emit_move_insn (temp, operands[1]);
17040       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17041     }
17043   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17044   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17045   ix86_expand_setcc (res, EQ,
17046                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17047   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17048   DONE;
17051 (define_expand "signbittf2"
17052   [(use (match_operand:SI 0 "register_operand"))
17053    (use (match_operand:TF 1 "register_operand"))]
17054   "TARGET_SSE"
17056   if (TARGET_SSE4_1)
17057     {
17058       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17059       rtx scratch = gen_reg_rtx (QImode);
17061       emit_insn (gen_ptesttf2 (operands[1], mask));
17062         ix86_expand_setcc (scratch, NE,
17063                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17065       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17066     }
17067   else
17068     {
17069       emit_insn (gen_sse_movmskps (operands[0],
17070                                    gen_lowpart (V4SFmode, operands[1])));
17071       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17072     }
17073   DONE;
17076 (define_expand "signbitxf2"
17077   [(use (match_operand:SI 0 "register_operand"))
17078    (use (match_operand:XF 1 "register_operand"))]
17079   "TARGET_USE_FANCY_MATH_387"
17081   rtx scratch = gen_reg_rtx (HImode);
17083   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17084   emit_insn (gen_andsi3 (operands[0],
17085              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17086   DONE;
17089 (define_insn "movmsk_df"
17090   [(set (match_operand:SI 0 "register_operand" "=r")
17091         (unspec:SI
17092           [(match_operand:DF 1 "register_operand" "x")]
17093           UNSPEC_MOVMSK))]
17094   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17095   "%vmovmskpd\t{%1, %0|%0, %1}"
17096   [(set_attr "type" "ssemov")
17097    (set_attr "prefix" "maybe_vex")
17098    (set_attr "mode" "DF")])
17100 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17101 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17102 (define_expand "signbitdf2"
17103   [(use (match_operand:SI 0 "register_operand"))
17104    (use (match_operand:DF 1 "register_operand"))]
17105   "TARGET_USE_FANCY_MATH_387
17106    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17108   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17109     {
17110       emit_insn (gen_movmsk_df (operands[0], operands[1]));
17111       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17112     }
17113   else
17114     {
17115       rtx scratch = gen_reg_rtx (HImode);
17117       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17118       emit_insn (gen_andsi3 (operands[0],
17119                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17120     }
17121   DONE;
17124 (define_expand "signbitsf2"
17125   [(use (match_operand:SI 0 "register_operand"))
17126    (use (match_operand:SF 1 "register_operand"))]
17127   "TARGET_USE_FANCY_MATH_387
17128    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17130   rtx scratch = gen_reg_rtx (HImode);
17132   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17133   emit_insn (gen_andsi3 (operands[0],
17134              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17135   DONE;
17138 ;; Block operation instructions
17140 (define_insn "cld"
17141   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17142   ""
17143   "cld"
17144   [(set_attr "length" "1")
17145    (set_attr "length_immediate" "0")
17146    (set_attr "modrm" "0")])
17148 (define_expand "movmem<mode>"
17149   [(use (match_operand:BLK 0 "memory_operand"))
17150    (use (match_operand:BLK 1 "memory_operand"))
17151    (use (match_operand:SWI48 2 "nonmemory_operand"))
17152    (use (match_operand:SWI48 3 "const_int_operand"))
17153    (use (match_operand:SI 4 "const_int_operand"))
17154    (use (match_operand:SI 5 "const_int_operand"))
17155    (use (match_operand:SI 6 ""))
17156    (use (match_operand:SI 7 ""))
17157    (use (match_operand:SI 8 ""))]
17158   ""
17160  if (ix86_expand_set_or_movmem (operands[0], operands[1],
17161                                 operands[2], NULL, operands[3],
17162                                 operands[4], operands[5],
17163                                 operands[6], operands[7],
17164                                 operands[8], false))
17165    DONE;
17166  else
17167    FAIL;
17170 ;; Most CPUs don't like single string operations
17171 ;; Handle this case here to simplify previous expander.
17173 (define_expand "strmov"
17174   [(set (match_dup 4) (match_operand 3 "memory_operand"))
17175    (set (match_operand 1 "memory_operand") (match_dup 4))
17176    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17177               (clobber (reg:CC FLAGS_REG))])
17178    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17179               (clobber (reg:CC FLAGS_REG))])]
17180   ""
17182   /* Can't use this for non-default address spaces.  */
17183   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17184     FAIL;
17186   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17188   /* If .md ever supports :P for Pmode, these can be directly
17189      in the pattern above.  */
17190   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17191   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17193   /* Can't use this if the user has appropriated esi or edi.  */
17194   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17195       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17196     {
17197       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17198                                       operands[2], operands[3],
17199                                       operands[5], operands[6]));
17200       DONE;
17201     }
17203   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17206 (define_expand "strmov_singleop"
17207   [(parallel [(set (match_operand 1 "memory_operand")
17208                    (match_operand 3 "memory_operand"))
17209               (set (match_operand 0 "register_operand")
17210                    (match_operand 4))
17211               (set (match_operand 2 "register_operand")
17212                    (match_operand 5))])]
17213   ""
17215   if (TARGET_CLD)
17216     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17219 (define_insn "*strmovdi_rex_1"
17220   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17221         (mem:DI (match_operand:P 3 "register_operand" "1")))
17222    (set (match_operand:P 0 "register_operand" "=D")
17223         (plus:P (match_dup 2)
17224                 (const_int 8)))
17225    (set (match_operand:P 1 "register_operand" "=S")
17226         (plus:P (match_dup 3)
17227                 (const_int 8)))]
17228   "TARGET_64BIT
17229    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17230    && ix86_check_no_addr_space (insn)"
17231   "%^movsq"
17232   [(set_attr "type" "str")
17233    (set_attr "memory" "both")
17234    (set_attr "mode" "DI")])
17236 (define_insn "*strmovsi_1"
17237   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17238         (mem:SI (match_operand:P 3 "register_operand" "1")))
17239    (set (match_operand:P 0 "register_operand" "=D")
17240         (plus:P (match_dup 2)
17241                 (const_int 4)))
17242    (set (match_operand:P 1 "register_operand" "=S")
17243         (plus:P (match_dup 3)
17244                 (const_int 4)))]
17245   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17246    && ix86_check_no_addr_space (insn)"
17247   "%^movs{l|d}"
17248   [(set_attr "type" "str")
17249    (set_attr "memory" "both")
17250    (set_attr "mode" "SI")])
17252 (define_insn "*strmovhi_1"
17253   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17254         (mem:HI (match_operand:P 3 "register_operand" "1")))
17255    (set (match_operand:P 0 "register_operand" "=D")
17256         (plus:P (match_dup 2)
17257                 (const_int 2)))
17258    (set (match_operand:P 1 "register_operand" "=S")
17259         (plus:P (match_dup 3)
17260                 (const_int 2)))]
17261   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17262    && ix86_check_no_addr_space (insn)"
17263   "%^movsw"
17264   [(set_attr "type" "str")
17265    (set_attr "memory" "both")
17266    (set_attr "mode" "HI")])
17268 (define_insn "*strmovqi_1"
17269   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17270         (mem:QI (match_operand:P 3 "register_operand" "1")))
17271    (set (match_operand:P 0 "register_operand" "=D")
17272         (plus:P (match_dup 2)
17273                 (const_int 1)))
17274    (set (match_operand:P 1 "register_operand" "=S")
17275         (plus:P (match_dup 3)
17276                 (const_int 1)))]
17277   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17278    && ix86_check_no_addr_space (insn)"
17279   "%^movsb"
17280   [(set_attr "type" "str")
17281    (set_attr "memory" "both")
17282    (set (attr "prefix_rex")
17283         (if_then_else
17284           (match_test "<P:MODE>mode == DImode")
17285           (const_string "0")
17286           (const_string "*")))
17287    (set_attr "mode" "QI")])
17289 (define_expand "rep_mov"
17290   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17291               (set (match_operand 0 "register_operand")
17292                    (match_operand 5))
17293               (set (match_operand 2 "register_operand")
17294                    (match_operand 6))
17295               (set (match_operand 1 "memory_operand")
17296                    (match_operand 3 "memory_operand"))
17297               (use (match_dup 4))])]
17298   ""
17300   if (TARGET_CLD)
17301     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17304 (define_insn "*rep_movdi_rex64"
17305   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17306    (set (match_operand:P 0 "register_operand" "=D")
17307         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17308                           (const_int 3))
17309                 (match_operand:P 3 "register_operand" "0")))
17310    (set (match_operand:P 1 "register_operand" "=S")
17311         (plus:P (ashift:P (match_dup 5) (const_int 3))
17312                 (match_operand:P 4 "register_operand" "1")))
17313    (set (mem:BLK (match_dup 3))
17314         (mem:BLK (match_dup 4)))
17315    (use (match_dup 5))]
17316   "TARGET_64BIT
17317    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17318    && ix86_check_no_addr_space (insn)"
17319   "%^rep{%;} movsq"
17320   [(set_attr "type" "str")
17321    (set_attr "prefix_rep" "1")
17322    (set_attr "memory" "both")
17323    (set_attr "mode" "DI")])
17325 (define_insn "*rep_movsi"
17326   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17327    (set (match_operand:P 0 "register_operand" "=D")
17328         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17329                           (const_int 2))
17330                  (match_operand:P 3 "register_operand" "0")))
17331    (set (match_operand:P 1 "register_operand" "=S")
17332         (plus:P (ashift:P (match_dup 5) (const_int 2))
17333                 (match_operand:P 4 "register_operand" "1")))
17334    (set (mem:BLK (match_dup 3))
17335         (mem:BLK (match_dup 4)))
17336    (use (match_dup 5))]
17337   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17338    && ix86_check_no_addr_space (insn)"
17339   "%^rep{%;} movs{l|d}"
17340   [(set_attr "type" "str")
17341    (set_attr "prefix_rep" "1")
17342    (set_attr "memory" "both")
17343    (set_attr "mode" "SI")])
17345 (define_insn "*rep_movqi"
17346   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17347    (set (match_operand:P 0 "register_operand" "=D")
17348         (plus:P (match_operand:P 3 "register_operand" "0")
17349                 (match_operand:P 5 "register_operand" "2")))
17350    (set (match_operand:P 1 "register_operand" "=S")
17351         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17352    (set (mem:BLK (match_dup 3))
17353         (mem:BLK (match_dup 4)))
17354    (use (match_dup 5))]
17355   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17356    && ix86_check_no_addr_space (insn)"
17357   "%^rep{%;} movsb"
17358   [(set_attr "type" "str")
17359    (set_attr "prefix_rep" "1")
17360    (set_attr "memory" "both")
17361    (set_attr "mode" "QI")])
17363 (define_expand "setmem<mode>"
17364    [(use (match_operand:BLK 0 "memory_operand"))
17365     (use (match_operand:SWI48 1 "nonmemory_operand"))
17366     (use (match_operand:QI 2 "nonmemory_operand"))
17367     (use (match_operand 3 "const_int_operand"))
17368     (use (match_operand:SI 4 "const_int_operand"))
17369     (use (match_operand:SI 5 "const_int_operand"))
17370     (use (match_operand:SI 6 ""))
17371     (use (match_operand:SI 7 ""))
17372     (use (match_operand:SI 8 ""))]
17373   ""
17375  if (ix86_expand_set_or_movmem (operands[0], NULL,
17376                                 operands[1], operands[2],
17377                                 operands[3], operands[4],
17378                                 operands[5], operands[6],
17379                                 operands[7], operands[8], true))
17380    DONE;
17381  else
17382    FAIL;
17385 ;; Most CPUs don't like single string operations
17386 ;; Handle this case here to simplify previous expander.
17388 (define_expand "strset"
17389   [(set (match_operand 1 "memory_operand")
17390         (match_operand 2 "register_operand"))
17391    (parallel [(set (match_operand 0 "register_operand")
17392                    (match_dup 3))
17393               (clobber (reg:CC FLAGS_REG))])]
17394   ""
17396   /* Can't use this for non-default address spaces.  */
17397   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17398     FAIL;
17400   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17401     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17403   /* If .md ever supports :P for Pmode, this can be directly
17404      in the pattern above.  */
17405   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17406                               GEN_INT (GET_MODE_SIZE (GET_MODE
17407                                                       (operands[2]))));
17408   /* Can't use this if the user has appropriated eax or edi.  */
17409   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17410       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17411     {
17412       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17413                                       operands[3]));
17414       DONE;
17415     }
17418 (define_expand "strset_singleop"
17419   [(parallel [(set (match_operand 1 "memory_operand")
17420                    (match_operand 2 "register_operand"))
17421               (set (match_operand 0 "register_operand")
17422                    (match_operand 3))
17423               (unspec [(const_int 0)] UNSPEC_STOS)])]
17424   ""
17426   if (TARGET_CLD)
17427     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17430 (define_insn "*strsetdi_rex_1"
17431   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17432         (match_operand:DI 2 "register_operand" "a"))
17433    (set (match_operand:P 0 "register_operand" "=D")
17434         (plus:P (match_dup 1)
17435                 (const_int 8)))
17436    (unspec [(const_int 0)] UNSPEC_STOS)]
17437   "TARGET_64BIT
17438    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17439    && ix86_check_no_addr_space (insn)"
17440   "%^stosq"
17441   [(set_attr "type" "str")
17442    (set_attr "memory" "store")
17443    (set_attr "mode" "DI")])
17445 (define_insn "*strsetsi_1"
17446   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17447         (match_operand:SI 2 "register_operand" "a"))
17448    (set (match_operand:P 0 "register_operand" "=D")
17449         (plus:P (match_dup 1)
17450                 (const_int 4)))
17451    (unspec [(const_int 0)] UNSPEC_STOS)]
17452   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17453    && ix86_check_no_addr_space (insn)"
17454   "%^stos{l|d}"
17455   [(set_attr "type" "str")
17456    (set_attr "memory" "store")
17457    (set_attr "mode" "SI")])
17459 (define_insn "*strsethi_1"
17460   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17461         (match_operand:HI 2 "register_operand" "a"))
17462    (set (match_operand:P 0 "register_operand" "=D")
17463         (plus:P (match_dup 1)
17464                 (const_int 2)))
17465    (unspec [(const_int 0)] UNSPEC_STOS)]
17466   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17467    && ix86_check_no_addr_space (insn)"
17468   "%^stosw"
17469   [(set_attr "type" "str")
17470    (set_attr "memory" "store")
17471    (set_attr "mode" "HI")])
17473 (define_insn "*strsetqi_1"
17474   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17475         (match_operand:QI 2 "register_operand" "a"))
17476    (set (match_operand:P 0 "register_operand" "=D")
17477         (plus:P (match_dup 1)
17478                 (const_int 1)))
17479    (unspec [(const_int 0)] UNSPEC_STOS)]
17480   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17481    && ix86_check_no_addr_space (insn)"
17482   "%^stosb"
17483   [(set_attr "type" "str")
17484    (set_attr "memory" "store")
17485    (set (attr "prefix_rex")
17486         (if_then_else
17487           (match_test "<P:MODE>mode == DImode")
17488           (const_string "0")
17489           (const_string "*")))
17490    (set_attr "mode" "QI")])
17492 (define_expand "rep_stos"
17493   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17494               (set (match_operand 0 "register_operand")
17495                    (match_operand 4))
17496               (set (match_operand 2 "memory_operand") (const_int 0))
17497               (use (match_operand 3 "register_operand"))
17498               (use (match_dup 1))])]
17499   ""
17501   if (TARGET_CLD)
17502     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17505 (define_insn "*rep_stosdi_rex64"
17506   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17507    (set (match_operand:P 0 "register_operand" "=D")
17508         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17509                           (const_int 3))
17510                  (match_operand:P 3 "register_operand" "0")))
17511    (set (mem:BLK (match_dup 3))
17512         (const_int 0))
17513    (use (match_operand:DI 2 "register_operand" "a"))
17514    (use (match_dup 4))]
17515   "TARGET_64BIT
17516    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17517    && ix86_check_no_addr_space (insn)"
17518   "%^rep{%;} stosq"
17519   [(set_attr "type" "str")
17520    (set_attr "prefix_rep" "1")
17521    (set_attr "memory" "store")
17522    (set_attr "mode" "DI")])
17524 (define_insn "*rep_stossi"
17525   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17526    (set (match_operand:P 0 "register_operand" "=D")
17527         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17528                           (const_int 2))
17529                  (match_operand:P 3 "register_operand" "0")))
17530    (set (mem:BLK (match_dup 3))
17531         (const_int 0))
17532    (use (match_operand:SI 2 "register_operand" "a"))
17533    (use (match_dup 4))]
17534   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17535    && ix86_check_no_addr_space (insn)"
17536   "%^rep{%;} stos{l|d}"
17537   [(set_attr "type" "str")
17538    (set_attr "prefix_rep" "1")
17539    (set_attr "memory" "store")
17540    (set_attr "mode" "SI")])
17542 (define_insn "*rep_stosqi"
17543   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17544    (set (match_operand:P 0 "register_operand" "=D")
17545         (plus:P (match_operand:P 3 "register_operand" "0")
17546                 (match_operand:P 4 "register_operand" "1")))
17547    (set (mem:BLK (match_dup 3))
17548         (const_int 0))
17549    (use (match_operand:QI 2 "register_operand" "a"))
17550    (use (match_dup 4))]
17551   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17552    && ix86_check_no_addr_space (insn)"
17553   "%^rep{%;} stosb"
17554   [(set_attr "type" "str")
17555    (set_attr "prefix_rep" "1")
17556    (set_attr "memory" "store")
17557    (set (attr "prefix_rex")
17558         (if_then_else
17559           (match_test "<P:MODE>mode == DImode")
17560           (const_string "0")
17561           (const_string "*")))
17562    (set_attr "mode" "QI")])
17564 (define_expand "cmpstrnsi"
17565   [(set (match_operand:SI 0 "register_operand")
17566         (compare:SI (match_operand:BLK 1 "general_operand")
17567                     (match_operand:BLK 2 "general_operand")))
17568    (use (match_operand 3 "general_operand"))
17569    (use (match_operand 4 "immediate_operand"))]
17570   ""
17572   rtx addr1, addr2, out, outlow, count, countreg, align;
17574   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17575     FAIL;
17577   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17578   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17579     FAIL;
17581   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17582      will have rewritten the length arg to be the minimum of the const string
17583      length and the actual length arg.  If both strings are the same and
17584      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17585      will incorrectly base the results on chars past the 0 byte.  */
17586   tree t1 = MEM_EXPR (operands[1]);
17587   tree t2 = MEM_EXPR (operands[2]);
17588   if (!((t1 && TREE_CODE (t1) == MEM_REF
17589          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17590          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17591       || (t2 && TREE_CODE (t2) == MEM_REF
17592           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17593           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17594     FAIL;
17596   out = operands[0];
17597   if (!REG_P (out))
17598     out = gen_reg_rtx (SImode);
17600   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17601   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17602   if (addr1 != XEXP (operands[1], 0))
17603     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17604   if (addr2 != XEXP (operands[2], 0))
17605     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17607   count = operands[3];
17608   countreg = ix86_zero_extend_to_Pmode (count);
17610   /* %%% Iff we are testing strict equality, we can use known alignment
17611      to good advantage.  This may be possible with combine, particularly
17612      once cc0 is dead.  */
17613   align = operands[4];
17615   if (CONST_INT_P (count))
17616     {
17617       if (INTVAL (count) == 0)
17618         {
17619           emit_move_insn (operands[0], const0_rtx);
17620           DONE;
17621         }
17622       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17623                                      operands[1], operands[2]));
17624     }
17625   else
17626     {
17627       rtx (*gen_cmp) (rtx, rtx);
17629       gen_cmp = (TARGET_64BIT
17630                  ? gen_cmpdi_1 : gen_cmpsi_1);
17632       emit_insn (gen_cmp (countreg, countreg));
17633       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17634                                   operands[1], operands[2]));
17635     }
17637   outlow = gen_lowpart (QImode, out);
17638   emit_insn (gen_cmpintqi (outlow));
17639   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17641   if (operands[0] != out)
17642     emit_move_insn (operands[0], out);
17644   DONE;
17647 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17649 (define_expand "cmpintqi"
17650   [(set (match_dup 1)
17651         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17652    (set (match_dup 2)
17653         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17654    (parallel [(set (match_operand:QI 0 "register_operand")
17655                    (minus:QI (match_dup 1)
17656                              (match_dup 2)))
17657               (clobber (reg:CC FLAGS_REG))])]
17658   ""
17660   operands[1] = gen_reg_rtx (QImode);
17661   operands[2] = gen_reg_rtx (QImode);
17664 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17665 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17667 (define_expand "cmpstrnqi_nz_1"
17668   [(parallel [(set (reg:CC FLAGS_REG)
17669                    (compare:CC (match_operand 4 "memory_operand")
17670                                (match_operand 5 "memory_operand")))
17671               (use (match_operand 2 "register_operand"))
17672               (use (match_operand:SI 3 "immediate_operand"))
17673               (clobber (match_operand 0 "register_operand"))
17674               (clobber (match_operand 1 "register_operand"))
17675               (clobber (match_dup 2))])]
17676   ""
17678   if (TARGET_CLD)
17679     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17682 (define_insn "*cmpstrnqi_nz_1"
17683   [(set (reg:CC FLAGS_REG)
17684         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17685                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17686    (use (match_operand:P 6 "register_operand" "2"))
17687    (use (match_operand:SI 3 "immediate_operand" "i"))
17688    (clobber (match_operand:P 0 "register_operand" "=S"))
17689    (clobber (match_operand:P 1 "register_operand" "=D"))
17690    (clobber (match_operand:P 2 "register_operand" "=c"))]
17691   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17692    && ix86_check_no_addr_space (insn)"
17693   "%^repz{%;} cmpsb"
17694   [(set_attr "type" "str")
17695    (set_attr "mode" "QI")
17696    (set (attr "prefix_rex")
17697         (if_then_else
17698           (match_test "<P:MODE>mode == DImode")
17699           (const_string "0")
17700           (const_string "*")))
17701    (set_attr "prefix_rep" "1")])
17703 ;; The same, but the count is not known to not be zero.
17705 (define_expand "cmpstrnqi_1"
17706   [(parallel [(set (reg:CC FLAGS_REG)
17707                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17708                                      (const_int 0))
17709                   (compare:CC (match_operand 4 "memory_operand")
17710                               (match_operand 5 "memory_operand"))
17711                   (const_int 0)))
17712               (use (match_operand:SI 3 "immediate_operand"))
17713               (use (reg:CC FLAGS_REG))
17714               (clobber (match_operand 0 "register_operand"))
17715               (clobber (match_operand 1 "register_operand"))
17716               (clobber (match_dup 2))])]
17717   ""
17719   if (TARGET_CLD)
17720     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17723 (define_insn "*cmpstrnqi_1"
17724   [(set (reg:CC FLAGS_REG)
17725         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17726                              (const_int 0))
17727           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17728                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17729           (const_int 0)))
17730    (use (match_operand:SI 3 "immediate_operand" "i"))
17731    (use (reg:CC FLAGS_REG))
17732    (clobber (match_operand:P 0 "register_operand" "=S"))
17733    (clobber (match_operand:P 1 "register_operand" "=D"))
17734    (clobber (match_operand:P 2 "register_operand" "=c"))]
17735   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17736    && ix86_check_no_addr_space (insn)"
17737   "%^repz{%;} cmpsb"
17738   [(set_attr "type" "str")
17739    (set_attr "mode" "QI")
17740    (set (attr "prefix_rex")
17741         (if_then_else
17742           (match_test "<P:MODE>mode == DImode")
17743           (const_string "0")
17744           (const_string "*")))
17745    (set_attr "prefix_rep" "1")])
17747 (define_expand "strlen<mode>"
17748   [(set (match_operand:P 0 "register_operand")
17749         (unspec:P [(match_operand:BLK 1 "general_operand")
17750                    (match_operand:QI 2 "immediate_operand")
17751                    (match_operand 3 "immediate_operand")]
17752                   UNSPEC_SCAS))]
17753   ""
17755  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17756    DONE;
17757  else
17758    FAIL;
17761 (define_expand "strlenqi_1"
17762   [(parallel [(set (match_operand 0 "register_operand")
17763                    (match_operand 2))
17764               (clobber (match_operand 1 "register_operand"))
17765               (clobber (reg:CC FLAGS_REG))])]
17766   ""
17768   if (TARGET_CLD)
17769     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17772 (define_insn "*strlenqi_1"
17773   [(set (match_operand:P 0 "register_operand" "=&c")
17774         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17775                    (match_operand:QI 2 "register_operand" "a")
17776                    (match_operand:P 3 "immediate_operand" "i")
17777                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17778    (clobber (match_operand:P 1 "register_operand" "=D"))
17779    (clobber (reg:CC FLAGS_REG))]
17780   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17781    && ix86_check_no_addr_space (insn)"
17782   "%^repnz{%;} scasb"
17783   [(set_attr "type" "str")
17784    (set_attr "mode" "QI")
17785    (set (attr "prefix_rex")
17786         (if_then_else
17787           (match_test "<P:MODE>mode == DImode")
17788           (const_string "0")
17789           (const_string "*")))
17790    (set_attr "prefix_rep" "1")])
17792 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17793 ;; handled in combine, but it is not currently up to the task.
17794 ;; When used for their truth value, the cmpstrn* expanders generate
17795 ;; code like this:
17797 ;;   repz cmpsb
17798 ;;   seta       %al
17799 ;;   setb       %dl
17800 ;;   cmpb       %al, %dl
17801 ;;   jcc        label
17803 ;; The intermediate three instructions are unnecessary.
17805 ;; This one handles cmpstrn*_nz_1...
17806 (define_peephole2
17807   [(parallel[
17808      (set (reg:CC FLAGS_REG)
17809           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17810                       (mem:BLK (match_operand 5 "register_operand"))))
17811      (use (match_operand 6 "register_operand"))
17812      (use (match_operand:SI 3 "immediate_operand"))
17813      (clobber (match_operand 0 "register_operand"))
17814      (clobber (match_operand 1 "register_operand"))
17815      (clobber (match_operand 2 "register_operand"))])
17816    (set (match_operand:QI 7 "register_operand")
17817         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17818    (set (match_operand:QI 8 "register_operand")
17819         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17820    (set (reg FLAGS_REG)
17821         (compare (match_dup 7) (match_dup 8)))
17822   ]
17823   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17824   [(parallel[
17825      (set (reg:CC FLAGS_REG)
17826           (compare:CC (mem:BLK (match_dup 4))
17827                       (mem:BLK (match_dup 5))))
17828      (use (match_dup 6))
17829      (use (match_dup 3))
17830      (clobber (match_dup 0))
17831      (clobber (match_dup 1))
17832      (clobber (match_dup 2))])])
17834 ;; ...and this one handles cmpstrn*_1.
17835 (define_peephole2
17836   [(parallel[
17837      (set (reg:CC FLAGS_REG)
17838           (if_then_else:CC (ne (match_operand 6 "register_operand")
17839                                (const_int 0))
17840             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17841                         (mem:BLK (match_operand 5 "register_operand")))
17842             (const_int 0)))
17843      (use (match_operand:SI 3 "immediate_operand"))
17844      (use (reg:CC FLAGS_REG))
17845      (clobber (match_operand 0 "register_operand"))
17846      (clobber (match_operand 1 "register_operand"))
17847      (clobber (match_operand 2 "register_operand"))])
17848    (set (match_operand:QI 7 "register_operand")
17849         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17850    (set (match_operand:QI 8 "register_operand")
17851         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17852    (set (reg FLAGS_REG)
17853         (compare (match_dup 7) (match_dup 8)))
17854   ]
17855   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17856   [(parallel[
17857      (set (reg:CC FLAGS_REG)
17858           (if_then_else:CC (ne (match_dup 6)
17859                                (const_int 0))
17860             (compare:CC (mem:BLK (match_dup 4))
17861                         (mem:BLK (match_dup 5)))
17862             (const_int 0)))
17863      (use (match_dup 3))
17864      (use (reg:CC FLAGS_REG))
17865      (clobber (match_dup 0))
17866      (clobber (match_dup 1))
17867      (clobber (match_dup 2))])])
17869 ;; Conditional move instructions.
17871 (define_expand "mov<mode>cc"
17872   [(set (match_operand:SWIM 0 "register_operand")
17873         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17874                            (match_operand:SWIM 2 "<general_operand>")
17875                            (match_operand:SWIM 3 "<general_operand>")))]
17876   ""
17877   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17879 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17880 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17881 ;; So just document what we're doing explicitly.
17883 (define_expand "x86_mov<mode>cc_0_m1"
17884   [(parallel
17885     [(set (match_operand:SWI48 0 "register_operand")
17886           (if_then_else:SWI48
17887             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17888              [(match_operand 1 "flags_reg_operand")
17889               (const_int 0)])
17890             (const_int -1)
17891             (const_int 0)))
17892      (clobber (reg:CC FLAGS_REG))])])
17894 (define_insn "*x86_mov<mode>cc_0_m1"
17895   [(set (match_operand:SWI48 0 "register_operand" "=r")
17896         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17897                              [(reg FLAGS_REG) (const_int 0)])
17898           (const_int -1)
17899           (const_int 0)))
17900    (clobber (reg:CC FLAGS_REG))]
17901   ""
17902   "sbb{<imodesuffix>}\t%0, %0"
17903   [(set_attr "type" "alu1")
17904    (set_attr "modrm_class" "op0")
17905    (set_attr "use_carry" "1")
17906    (set_attr "pent_pair" "pu")
17907    (set_attr "mode" "<MODE>")
17908    (set_attr "length_immediate" "0")])
17910 (define_insn "*x86_mov<mode>cc_0_m1_se"
17911   [(set (match_operand:SWI48 0 "register_operand" "=r")
17912         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17913                              [(reg FLAGS_REG) (const_int 0)])
17914                             (const_int 1)
17915                             (const_int 0)))
17916    (clobber (reg:CC FLAGS_REG))]
17917   ""
17918   "sbb{<imodesuffix>}\t%0, %0"
17919   [(set_attr "type" "alu1")
17920    (set_attr "modrm_class" "op0")
17921    (set_attr "use_carry" "1")
17922    (set_attr "pent_pair" "pu")
17923    (set_attr "mode" "<MODE>")
17924    (set_attr "length_immediate" "0")])
17926 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17927   [(set (match_operand:SWI48 0 "register_operand" "=r")
17928         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17929                     [(reg FLAGS_REG) (const_int 0)])))
17930    (clobber (reg:CC FLAGS_REG))]
17931   ""
17932   "sbb{<imodesuffix>}\t%0, %0"
17933   [(set_attr "type" "alu1")
17934    (set_attr "modrm_class" "op0")
17935    (set_attr "use_carry" "1")
17936    (set_attr "pent_pair" "pu")
17937    (set_attr "mode" "<MODE>")
17938    (set_attr "length_immediate" "0")])
17940 (define_insn "*mov<mode>cc_noc"
17941   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17942         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17943                                [(reg FLAGS_REG) (const_int 0)])
17944           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17945           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17946   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17947   "@
17948    cmov%O2%C1\t{%2, %0|%0, %2}
17949    cmov%O2%c1\t{%3, %0|%0, %3}"
17950   [(set_attr "type" "icmov")
17951    (set_attr "mode" "<MODE>")])
17953 (define_insn "*movsicc_noc_zext"
17954   [(set (match_operand:DI 0 "register_operand" "=r,r")
17955         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17956                            [(reg FLAGS_REG) (const_int 0)])
17957           (zero_extend:DI
17958             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17959           (zero_extend:DI
17960             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17961   "TARGET_64BIT
17962    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17963   "@
17964    cmov%O2%C1\t{%2, %k0|%k0, %2}
17965    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17966   [(set_attr "type" "icmov")
17967    (set_attr "mode" "SI")])
17969 ;; Don't do conditional moves with memory inputs.  This splitter helps
17970 ;; register starved x86_32 by forcing inputs into registers before reload.
17971 (define_split
17972   [(set (match_operand:SWI248 0 "register_operand")
17973         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17974                                [(reg FLAGS_REG) (const_int 0)])
17975           (match_operand:SWI248 2 "nonimmediate_operand")
17976           (match_operand:SWI248 3 "nonimmediate_operand")))]
17977   "!TARGET_64BIT && TARGET_CMOVE
17978    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17979    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17980    && can_create_pseudo_p ()
17981    && optimize_insn_for_speed_p ()"
17982   [(set (match_dup 0)
17983         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17985   if (MEM_P (operands[2]))
17986     operands[2] = force_reg (<MODE>mode, operands[2]);
17987   if (MEM_P (operands[3]))
17988     operands[3] = force_reg (<MODE>mode, operands[3]);
17991 (define_insn "*movqicc_noc"
17992   [(set (match_operand:QI 0 "register_operand" "=r,r")
17993         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17994                            [(reg FLAGS_REG) (const_int 0)])
17995                       (match_operand:QI 2 "register_operand" "r,0")
17996                       (match_operand:QI 3 "register_operand" "0,r")))]
17997   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17998   "#"
17999   [(set_attr "type" "icmov")
18000    (set_attr "mode" "QI")])
18002 (define_split
18003   [(set (match_operand:SWI12 0 "register_operand")
18004         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18005                               [(reg FLAGS_REG) (const_int 0)])
18006                       (match_operand:SWI12 2 "register_operand")
18007                       (match_operand:SWI12 3 "register_operand")))]
18008   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18009    && reload_completed"
18010   [(set (match_dup 0)
18011         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18013   operands[0] = gen_lowpart (SImode, operands[0]);
18014   operands[2] = gen_lowpart (SImode, operands[2]);
18015   operands[3] = gen_lowpart (SImode, operands[3]);
18018 ;; Don't do conditional moves with memory inputs
18019 (define_peephole2
18020   [(match_scratch:SWI248 4 "r")
18021    (set (match_operand:SWI248 0 "register_operand")
18022         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18023                                [(reg FLAGS_REG) (const_int 0)])
18024           (match_operand:SWI248 2 "nonimmediate_operand")
18025           (match_operand:SWI248 3 "nonimmediate_operand")))]
18026   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18027    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18028    && optimize_insn_for_speed_p ()"
18029   [(set (match_dup 4) (match_dup 5))
18030    (set (match_dup 0)
18031         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18033   if (MEM_P (operands[2]))
18034     {
18035       operands[5] = operands[2];
18036       operands[2] = operands[4];
18037     }
18038   else if (MEM_P (operands[3]))
18039     {
18040       operands[5] = operands[3];
18041       operands[3] = operands[4];
18042     }
18043   else
18044     gcc_unreachable ();
18047 (define_peephole2
18048   [(match_scratch:SI 4 "r")
18049    (set (match_operand:DI 0 "register_operand")
18050         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18051                            [(reg FLAGS_REG) (const_int 0)])
18052           (zero_extend:DI
18053             (match_operand:SI 2 "nonimmediate_operand"))
18054           (zero_extend:DI
18055             (match_operand:SI 3 "nonimmediate_operand"))))]
18056   "TARGET_64BIT
18057    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18058    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18059    && optimize_insn_for_speed_p ()"
18060   [(set (match_dup 4) (match_dup 5))
18061    (set (match_dup 0)
18062         (if_then_else:DI (match_dup 1)
18063           (zero_extend:DI (match_dup 2))
18064           (zero_extend:DI (match_dup 3))))]
18066   if (MEM_P (operands[2]))
18067     {
18068       operands[5] = operands[2];
18069       operands[2] = operands[4];
18070     }
18071   else if (MEM_P (operands[3]))
18072     {
18073       operands[5] = operands[3];
18074       operands[3] = operands[4];
18075     }
18076   else
18077     gcc_unreachable ();
18080 (define_expand "mov<mode>cc"
18081   [(set (match_operand:X87MODEF 0 "register_operand")
18082         (if_then_else:X87MODEF
18083           (match_operand 1 "comparison_operator")
18084           (match_operand:X87MODEF 2 "register_operand")
18085           (match_operand:X87MODEF 3 "register_operand")))]
18086   "(TARGET_80387 && TARGET_CMOVE)
18087    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18088   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18090 (define_insn "*movxfcc_1"
18091   [(set (match_operand:XF 0 "register_operand" "=f,f")
18092         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18093                                 [(reg FLAGS_REG) (const_int 0)])
18094                       (match_operand:XF 2 "register_operand" "f,0")
18095                       (match_operand:XF 3 "register_operand" "0,f")))]
18096   "TARGET_80387 && TARGET_CMOVE"
18097   "@
18098    fcmov%F1\t{%2, %0|%0, %2}
18099    fcmov%f1\t{%3, %0|%0, %3}"
18100   [(set_attr "type" "fcmov")
18101    (set_attr "mode" "XF")])
18103 (define_insn "*movdfcc_1"
18104   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18105         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18106                                 [(reg FLAGS_REG) (const_int 0)])
18107                       (match_operand:DF 2 "nonimmediate_operand"
18108                                                "f ,0,rm,0 ,rm,0")
18109                       (match_operand:DF 3 "nonimmediate_operand"
18110                                                "0 ,f,0 ,rm,0, rm")))]
18111   "TARGET_80387 && TARGET_CMOVE
18112    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18113   "@
18114    fcmov%F1\t{%2, %0|%0, %2}
18115    fcmov%f1\t{%3, %0|%0, %3}
18116    #
18117    #
18118    cmov%O2%C1\t{%2, %0|%0, %2}
18119    cmov%O2%c1\t{%3, %0|%0, %3}"
18120   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18121    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18122    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18124 (define_split
18125   [(set (match_operand:DF 0 "general_reg_operand")
18126         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18127                                 [(reg FLAGS_REG) (const_int 0)])
18128                       (match_operand:DF 2 "nonimmediate_operand")
18129                       (match_operand:DF 3 "nonimmediate_operand")))]
18130   "!TARGET_64BIT && reload_completed"
18131   [(set (match_dup 2)
18132         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18133    (set (match_dup 3)
18134         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18136   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18137   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18140 (define_insn "*movsfcc_1_387"
18141   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18142         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18143                                 [(reg FLAGS_REG) (const_int 0)])
18144                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18145                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18146   "TARGET_80387 && TARGET_CMOVE
18147    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18148   "@
18149    fcmov%F1\t{%2, %0|%0, %2}
18150    fcmov%f1\t{%3, %0|%0, %3}
18151    cmov%O2%C1\t{%2, %0|%0, %2}
18152    cmov%O2%c1\t{%3, %0|%0, %3}"
18153   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18154    (set_attr "mode" "SF,SF,SI,SI")])
18156 ;; Don't do conditional moves with memory inputs.  This splitter helps
18157 ;; register starved x86_32 by forcing inputs into registers before reload.
18158 (define_split
18159   [(set (match_operand:MODEF 0 "register_operand")
18160         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18161                               [(reg FLAGS_REG) (const_int 0)])
18162           (match_operand:MODEF 2 "nonimmediate_operand")
18163           (match_operand:MODEF 3 "nonimmediate_operand")))]
18164   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18165    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18166    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18167    && can_create_pseudo_p ()
18168    && optimize_insn_for_speed_p ()"
18169   [(set (match_dup 0)
18170         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18172   if (MEM_P (operands[2]))
18173     operands[2] = force_reg (<MODE>mode, operands[2]);
18174   if (MEM_P (operands[3]))
18175     operands[3] = force_reg (<MODE>mode, operands[3]);
18178 ;; Don't do conditional moves with memory inputs
18179 (define_peephole2
18180   [(match_scratch:MODEF 4 "r")
18181    (set (match_operand:MODEF 0 "general_reg_operand")
18182         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18183                               [(reg FLAGS_REG) (const_int 0)])
18184           (match_operand:MODEF 2 "nonimmediate_operand")
18185           (match_operand:MODEF 3 "nonimmediate_operand")))]
18186   "(<MODE>mode != DFmode || TARGET_64BIT)
18187    && TARGET_80387 && TARGET_CMOVE
18188    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18189    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18190    && optimize_insn_for_speed_p ()"
18191   [(set (match_dup 4) (match_dup 5))
18192    (set (match_dup 0)
18193         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18195   if (MEM_P (operands[2]))
18196     {
18197       operands[5] = operands[2];
18198       operands[2] = operands[4];
18199     }
18200   else if (MEM_P (operands[3]))
18201     {
18202       operands[5] = operands[3];
18203       operands[3] = operands[4];
18204     }
18205   else
18206     gcc_unreachable ();
18209 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18210 ;; the scalar versions to have only XMM registers as operands.
18212 ;; XOP conditional move
18213 (define_insn "*xop_pcmov_<mode>"
18214   [(set (match_operand:MODEF 0 "register_operand" "=x")
18215         (if_then_else:MODEF
18216           (match_operand:MODEF 1 "register_operand" "x")
18217           (match_operand:MODEF 2 "register_operand" "x")
18218           (match_operand:MODEF 3 "register_operand" "x")))]
18219   "TARGET_XOP"
18220   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18221   [(set_attr "type" "sse4arg")])
18223 ;; These versions of the min/max patterns are intentionally ignorant of
18224 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18225 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18226 ;; are undefined in this condition, we're certain this is correct.
18228 (define_insn "<code><mode>3"
18229   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18230         (smaxmin:MODEF
18231           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18232           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18233   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18234   "@
18235    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18236    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18237   [(set_attr "isa" "noavx,avx")
18238    (set_attr "prefix" "orig,vex")
18239    (set_attr "type" "sseadd")
18240    (set_attr "mode" "<MODE>")])
18242 ;; These versions of the min/max patterns implement exactly the operations
18243 ;;   min = (op1 < op2 ? op1 : op2)
18244 ;;   max = (!(op1 < op2) ? op1 : op2)
18245 ;; Their operands are not commutative, and thus they may be used in the
18246 ;; presence of -0.0 and NaN.
18248 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18249   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18250         (unspec:MODEF
18251           [(match_operand:MODEF 1 "register_operand" "0,v")
18252            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18253           IEEE_MAXMIN))]
18254   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18255   "@
18256    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18257    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18258   [(set_attr "isa" "noavx,avx")
18259    (set_attr "prefix" "orig,maybe_evex")
18260    (set_attr "type" "sseadd")
18261    (set_attr "mode" "<MODE>")])
18263 ;; Make two stack loads independent:
18264 ;;   fld aa              fld aa
18265 ;;   fld %st(0)     ->   fld bb
18266 ;;   fmul bb             fmul %st(1), %st
18268 ;; Actually we only match the last two instructions for simplicity.
18270 (define_peephole2
18271   [(set (match_operand 0 "fp_register_operand")
18272         (match_operand 1 "fp_register_operand"))
18273    (set (match_dup 0)
18274         (match_operator 2 "binary_fp_operator"
18275            [(match_dup 0)
18276             (match_operand 3 "memory_operand")]))]
18277   "REGNO (operands[0]) != REGNO (operands[1])"
18278   [(set (match_dup 0) (match_dup 3))
18279    (set (match_dup 0)
18280         (match_op_dup 2
18281           [(match_dup 5) (match_dup 4)]))]
18283   operands[4] = operands[0];
18284   operands[5] = operands[1];
18286   /* The % modifier is not operational anymore in peephole2's, so we have to
18287      swap the operands manually in the case of addition and multiplication. */
18288   if (COMMUTATIVE_ARITH_P (operands[2]))
18289     std::swap (operands[4], operands[5]);
18292 (define_peephole2
18293   [(set (match_operand 0 "fp_register_operand")
18294         (match_operand 1 "fp_register_operand"))
18295    (set (match_dup 0)
18296         (match_operator 2 "binary_fp_operator"
18297            [(match_operand 3 "memory_operand")
18298             (match_dup 0)]))]
18299   "REGNO (operands[0]) != REGNO (operands[1])"
18300   [(set (match_dup 0) (match_dup 3))
18301    (set (match_dup 0)
18302         (match_op_dup 2
18303           [(match_dup 4) (match_dup 5)]))]
18305   operands[4] = operands[0];
18306   operands[5] = operands[1];
18308   /* The % modifier is not operational anymore in peephole2's, so we have to
18309      swap the operands manually in the case of addition and multiplication. */
18310   if (COMMUTATIVE_ARITH_P (operands[2]))
18311     std::swap (operands[4], operands[5]);
18314 ;; Conditional addition patterns
18315 (define_expand "add<mode>cc"
18316   [(match_operand:SWI 0 "register_operand")
18317    (match_operand 1 "ordered_comparison_operator")
18318    (match_operand:SWI 2 "register_operand")
18319    (match_operand:SWI 3 "const_int_operand")]
18320   ""
18321   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18323 ;; Misc patterns (?)
18325 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18326 ;; Otherwise there will be nothing to keep
18328 ;; [(set (reg ebp) (reg esp))]
18329 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18330 ;;  (clobber (eflags)]
18331 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18333 ;; in proper program order.
18335 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18336   [(set (match_operand:P 0 "register_operand" "=r,r")
18337         (plus:P (match_operand:P 1 "register_operand" "0,r")
18338                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18339    (clobber (reg:CC FLAGS_REG))
18340    (clobber (mem:BLK (scratch)))]
18341   ""
18343   switch (get_attr_type (insn))
18344     {
18345     case TYPE_IMOV:
18346       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18348     case TYPE_ALU:
18349       gcc_assert (rtx_equal_p (operands[0], operands[1]));
18350       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18351         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18353       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18355     default:
18356       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18357       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18358     }
18360   [(set (attr "type")
18361         (cond [(and (eq_attr "alternative" "0")
18362                     (not (match_test "TARGET_OPT_AGU")))
18363                  (const_string "alu")
18364                (match_operand:<MODE> 2 "const0_operand")
18365                  (const_string "imov")
18366               ]
18367               (const_string "lea")))
18368    (set (attr "length_immediate")
18369         (cond [(eq_attr "type" "imov")
18370                  (const_string "0")
18371                (and (eq_attr "type" "alu")
18372                     (match_operand 2 "const128_operand"))
18373                  (const_string "1")
18374               ]
18375               (const_string "*")))
18376    (set_attr "mode" "<MODE>")])
18378 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18379   [(set (match_operand:P 0 "register_operand" "=r")
18380         (minus:P (match_operand:P 1 "register_operand" "0")
18381                  (match_operand:P 2 "register_operand" "r")))
18382    (clobber (reg:CC FLAGS_REG))
18383    (clobber (mem:BLK (scratch)))]
18384   ""
18385   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18386   [(set_attr "type" "alu")
18387    (set_attr "mode" "<MODE>")])
18389 (define_insn "allocate_stack_worker_probe_<mode>"
18390   [(set (match_operand:P 0 "register_operand" "=a")
18391         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18392                             UNSPECV_STACK_PROBE))
18393    (clobber (reg:CC FLAGS_REG))]
18394   "ix86_target_stack_probe ()"
18395   "call\t___chkstk_ms"
18396   [(set_attr "type" "multi")
18397    (set_attr "length" "5")])
18399 (define_expand "allocate_stack"
18400   [(match_operand 0 "register_operand")
18401    (match_operand 1 "general_operand")]
18402   "ix86_target_stack_probe ()"
18404   rtx x;
18406 #ifndef CHECK_STACK_LIMIT
18407 #define CHECK_STACK_LIMIT 0
18408 #endif
18410   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18411       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18412     x = operands[1];
18413   else
18414     {
18415       rtx (*insn) (rtx, rtx);
18417       x = copy_to_mode_reg (Pmode, operands[1]);
18419       insn = (TARGET_64BIT
18420               ? gen_allocate_stack_worker_probe_di
18421               : gen_allocate_stack_worker_probe_si);
18423       emit_insn (insn (x, x));
18424     }
18426   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18427                            stack_pointer_rtx, 0, OPTAB_DIRECT);
18429   if (x != stack_pointer_rtx)
18430     emit_move_insn (stack_pointer_rtx, x);
18432   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18433   DONE;
18436 (define_expand "probe_stack"
18437   [(match_operand 0 "memory_operand")]
18438   ""
18440   rtx (*insn) (rtx, rtx)
18441     = (GET_MODE (operands[0]) == DImode
18442        ? gen_probe_stack_di : gen_probe_stack_si);
18444   emit_insn (insn (operands[0], const0_rtx));
18445   DONE;
18448 ;; Use OR for stack probes, this is shorter.
18449 (define_insn "probe_stack_<mode>"
18450   [(set (match_operand:W 0 "memory_operand" "=m")
18451         (unspec:W [(match_operand:W 1 "const0_operand")]
18452                   UNSPEC_PROBE_STACK))
18453    (clobber (reg:CC FLAGS_REG))]
18454   ""
18455   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18456   [(set_attr "type" "alu1")
18457    (set_attr "mode" "<MODE>")
18458    (set_attr "length_immediate" "1")])
18459   
18460 (define_insn "adjust_stack_and_probe<mode>"
18461   [(set (match_operand:P 0 "register_operand" "=r")
18462         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18463                             UNSPECV_PROBE_STACK_RANGE))
18464    (set (reg:P SP_REG)
18465         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18466    (clobber (reg:CC FLAGS_REG))
18467    (clobber (mem:BLK (scratch)))]
18468   ""
18469   "* return output_adjust_stack_and_probe (operands[0]);"
18470   [(set_attr "type" "multi")])
18472 (define_insn "probe_stack_range<mode>"
18473   [(set (match_operand:P 0 "register_operand" "=r")
18474         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18475                             (match_operand:P 2 "const_int_operand" "n")]
18476                             UNSPECV_PROBE_STACK_RANGE))
18477    (clobber (reg:CC FLAGS_REG))]
18478   ""
18479   "* return output_probe_stack_range (operands[0], operands[2]);"
18480   [(set_attr "type" "multi")])
18482 (define_expand "builtin_setjmp_receiver"
18483   [(label_ref (match_operand 0))]
18484   "!TARGET_64BIT && flag_pic"
18486 #if TARGET_MACHO
18487   if (TARGET_MACHO)
18488     {
18489       rtx xops[3];
18490       rtx_code_label *label_rtx = gen_label_rtx ();
18491       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18492       xops[0] = xops[1] = pic_offset_table_rtx;
18493       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18494       ix86_expand_binary_operator (MINUS, SImode, xops);
18495     }
18496   else
18497 #endif
18498     emit_insn (gen_set_got (pic_offset_table_rtx));
18499   DONE;
18502 (define_expand "save_stack_nonlocal"
18503   [(set (match_operand 0 "memory_operand")
18504         (match_operand 1 "register_operand"))]
18505   ""
18507   rtx stack_slot;
18508   if ((flag_cf_protection & CF_RETURN))
18509     {
18510       /* Copy shadow stack pointer to the first slot and stack ppointer
18511          to the second slot.  */
18512       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18513       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18514       rtx ssp = gen_reg_rtx (word_mode);
18515       emit_insn ((word_mode == SImode)
18516                  ? gen_rdsspsi (ssp)
18517                  : gen_rdsspdi (ssp));
18518       emit_move_insn (ssp_slot, ssp);
18519     }
18520   else
18521     stack_slot = adjust_address (operands[0], Pmode, 0);
18522   emit_move_insn (stack_slot, operands[1]);
18523   DONE;
18526 (define_expand "restore_stack_nonlocal"
18527   [(set (match_operand 0 "register_operand" "")
18528         (match_operand 1 "memory_operand" ""))]
18529   ""
18531   rtx stack_slot;
18532   if ((flag_cf_protection & CF_RETURN))
18533     {
18534       /* Restore shadow stack pointer from the first slot and stack
18535          pointer from the second slot.  */
18536       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18537       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18539       rtx flags, jump, noadj_label, inc_label, loop_label;
18540       rtx reg_adj, reg_ssp, tmp, clob;
18542       /* Get the current shadow stack pointer.  The code below will check if
18543          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18544          is a NOP.  */
18545       reg_ssp = gen_reg_rtx (word_mode);
18546       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18547       emit_insn ((word_mode == SImode)
18548                  ? gen_rdsspsi (reg_ssp)
18549                  : gen_rdsspdi (reg_ssp));
18551       /* Compare through substraction the saved and the current ssp to decide
18552          if ssp has to be adjusted.  */
18553       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18554                                                  ssp_slot));
18555       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18556       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18557       emit_insn (tmp);
18559       /* Compare and jump over adjustment code.  */
18560       noadj_label = gen_label_rtx ();
18561       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18562       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18563       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18564                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18565                                   pc_rtx);
18566       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18567       JUMP_LABEL (jump) = noadj_label;
18569       /* Compute the numebr of frames to adjust.  */
18570       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18571       tmp = gen_rtx_SET (reg_adj,
18572                          gen_rtx_LSHIFTRT (ptr_mode,
18573                                            negate_rtx (ptr_mode, reg_adj),
18574                                            GEN_INT ((word_mode == SImode)
18575                                                     ? 2
18576                                                     : 3)));
18577       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18578       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18579       emit_insn (tmp);
18581       /* Check if number of frames <= 255 so no loop is needed.  */
18582       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18583       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18584       emit_insn (gen_rtx_SET (flags, tmp));
18586       inc_label = gen_label_rtx ();
18587       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18588       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18589                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
18590                                   pc_rtx);
18591       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18592       JUMP_LABEL (jump) = inc_label;
18594       rtx reg_255 = gen_reg_rtx (word_mode);
18595       emit_move_insn (reg_255, GEN_INT (255));
18597       /* Adjust the ssp in a loop.  */
18598       loop_label = gen_label_rtx ();
18599       emit_label (loop_label);
18600       LABEL_NUSES (loop_label) = 1;
18602       emit_insn ((word_mode == SImode)
18603                  ? gen_incsspsi (reg_255)
18604                  : gen_incsspdi (reg_255));
18605       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18606                                                  reg_adj,
18607                                                  GEN_INT (255)));
18608       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18609       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18610       emit_insn (tmp);
18612       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18613       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18614       emit_insn (gen_rtx_SET (flags, tmp));
18616       /* Jump to the loop label.  */
18617       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18618       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18619                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
18620                                   pc_rtx);
18621       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18622       JUMP_LABEL (jump) = loop_label;
18624       emit_label (inc_label);
18625       LABEL_NUSES (inc_label) = 1;
18626       emit_insn ((word_mode == SImode)
18627                  ? gen_incsspsi (reg_ssp)
18628                  : gen_incsspdi (reg_ssp));
18630       emit_label (noadj_label);
18631       LABEL_NUSES (noadj_label) = 1;
18632     }
18633   else
18634     stack_slot = adjust_address (operands[1], Pmode, 0);
18635   emit_move_insn (operands[0], stack_slot);
18636   DONE;
18640 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18641 ;; Do not split instructions with mask registers.
18642 (define_split
18643   [(set (match_operand 0 "general_reg_operand")
18644         (match_operator 3 "promotable_binary_operator"
18645            [(match_operand 1 "general_reg_operand")
18646             (match_operand 2 "aligned_operand")]))
18647    (clobber (reg:CC FLAGS_REG))]
18648   "! TARGET_PARTIAL_REG_STALL && reload_completed
18649    && ((GET_MODE (operands[0]) == HImode
18650         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18651             /* ??? next two lines just !satisfies_constraint_K (...) */
18652             || !CONST_INT_P (operands[2])
18653             || satisfies_constraint_K (operands[2])))
18654        || (GET_MODE (operands[0]) == QImode
18655            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18656   [(parallel [(set (match_dup 0)
18657                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18658               (clobber (reg:CC FLAGS_REG))])]
18660   operands[0] = gen_lowpart (SImode, operands[0]);
18661   operands[1] = gen_lowpart (SImode, operands[1]);
18662   if (GET_CODE (operands[3]) != ASHIFT)
18663     operands[2] = gen_lowpart (SImode, operands[2]);
18664   operands[3] = shallow_copy_rtx (operands[3]);
18665   PUT_MODE (operands[3], SImode);
18668 ; Promote the QImode tests, as i386 has encoding of the AND
18669 ; instruction with 32-bit sign-extended immediate and thus the
18670 ; instruction size is unchanged, except in the %eax case for
18671 ; which it is increased by one byte, hence the ! optimize_size.
18672 (define_split
18673   [(set (match_operand 0 "flags_reg_operand")
18674         (match_operator 2 "compare_operator"
18675           [(and (match_operand 3 "aligned_operand")
18676                 (match_operand 4 "const_int_operand"))
18677            (const_int 0)]))
18678    (set (match_operand 1 "register_operand")
18679         (and (match_dup 3) (match_dup 4)))]
18680   "! TARGET_PARTIAL_REG_STALL && reload_completed
18681    && optimize_insn_for_speed_p ()
18682    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18683        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18684    /* Ensure that the operand will remain sign-extended immediate.  */
18685    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18686   [(parallel [(set (match_dup 0)
18687                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18688                                     (const_int 0)]))
18689               (set (match_dup 1)
18690                    (and:SI (match_dup 3) (match_dup 4)))])]
18692   operands[4]
18693     = gen_int_mode (INTVAL (operands[4])
18694                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18695   operands[1] = gen_lowpart (SImode, operands[1]);
18696   operands[3] = gen_lowpart (SImode, operands[3]);
18699 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18700 ; the TEST instruction with 32-bit sign-extended immediate and thus
18701 ; the instruction size would at least double, which is not what we
18702 ; want even with ! optimize_size.
18703 (define_split
18704   [(set (match_operand 0 "flags_reg_operand")
18705         (match_operator 1 "compare_operator"
18706           [(and (match_operand:HI 2 "aligned_operand")
18707                 (match_operand:HI 3 "const_int_operand"))
18708            (const_int 0)]))]
18709   "! TARGET_PARTIAL_REG_STALL && reload_completed
18710    && ! TARGET_FAST_PREFIX
18711    && optimize_insn_for_speed_p ()
18712    /* Ensure that the operand will remain sign-extended immediate.  */
18713    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18714   [(set (match_dup 0)
18715         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18716                          (const_int 0)]))]
18718   operands[3]
18719     = gen_int_mode (INTVAL (operands[3])
18720                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18721   operands[2] = gen_lowpart (SImode, operands[2]);
18724 (define_split
18725   [(set (match_operand 0 "register_operand")
18726         (neg (match_operand 1 "register_operand")))
18727    (clobber (reg:CC FLAGS_REG))]
18728   "! TARGET_PARTIAL_REG_STALL && reload_completed
18729    && (GET_MODE (operands[0]) == HImode
18730        || (GET_MODE (operands[0]) == QImode
18731            && (TARGET_PROMOTE_QImode
18732                || optimize_insn_for_size_p ())))"
18733   [(parallel [(set (match_dup 0)
18734                    (neg:SI (match_dup 1)))
18735               (clobber (reg:CC FLAGS_REG))])]
18737   operands[0] = gen_lowpart (SImode, operands[0]);
18738   operands[1] = gen_lowpart (SImode, operands[1]);
18741 ;; Do not split instructions with mask regs.
18742 (define_split
18743   [(set (match_operand 0 "general_reg_operand")
18744         (not (match_operand 1 "general_reg_operand")))]
18745   "! TARGET_PARTIAL_REG_STALL && reload_completed
18746    && (GET_MODE (operands[0]) == HImode
18747        || (GET_MODE (operands[0]) == QImode
18748            && (TARGET_PROMOTE_QImode
18749                || optimize_insn_for_size_p ())))"
18750   [(set (match_dup 0)
18751         (not:SI (match_dup 1)))]
18753   operands[0] = gen_lowpart (SImode, operands[0]);
18754   operands[1] = gen_lowpart (SImode, operands[1]);
18757 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18758 ;; transform a complex memory operation into two memory to register operations.
18760 ;; Don't push memory operands
18761 (define_peephole2
18762   [(set (match_operand:SWI 0 "push_operand")
18763         (match_operand:SWI 1 "memory_operand"))
18764    (match_scratch:SWI 2 "<r>")]
18765   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18766    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18767   [(set (match_dup 2) (match_dup 1))
18768    (set (match_dup 0) (match_dup 2))])
18770 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18771 ;; SImode pushes.
18772 (define_peephole2
18773   [(set (match_operand:SF 0 "push_operand")
18774         (match_operand:SF 1 "memory_operand"))
18775    (match_scratch:SF 2 "r")]
18776   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18777    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18778   [(set (match_dup 2) (match_dup 1))
18779    (set (match_dup 0) (match_dup 2))])
18781 ;; Don't move an immediate directly to memory when the instruction
18782 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18783 (define_peephole2
18784   [(match_scratch:SWI124 1 "<r>")
18785    (set (match_operand:SWI124 0 "memory_operand")
18786         (const_int 0))]
18787   "optimize_insn_for_speed_p ()
18788    && ((<MODE>mode == HImode
18789        && TARGET_LCP_STALL)
18790        || (!TARGET_USE_MOV0
18791           && TARGET_SPLIT_LONG_MOVES
18792           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18793    && peep2_regno_dead_p (0, FLAGS_REG)"
18794   [(parallel [(set (match_dup 2) (const_int 0))
18795               (clobber (reg:CC FLAGS_REG))])
18796    (set (match_dup 0) (match_dup 1))]
18797   "operands[2] = gen_lowpart (SImode, operands[1]);")
18799 (define_peephole2
18800   [(match_scratch:SWI124 2 "<r>")
18801    (set (match_operand:SWI124 0 "memory_operand")
18802         (match_operand:SWI124 1 "immediate_operand"))]
18803   "optimize_insn_for_speed_p ()
18804    && ((<MODE>mode == HImode
18805        && TARGET_LCP_STALL)
18806        || (TARGET_SPLIT_LONG_MOVES
18807           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18808   [(set (match_dup 2) (match_dup 1))
18809    (set (match_dup 0) (match_dup 2))])
18811 ;; Don't compare memory with zero, load and use a test instead.
18812 (define_peephole2
18813   [(set (match_operand 0 "flags_reg_operand")
18814         (match_operator 1 "compare_operator"
18815           [(match_operand:SI 2 "memory_operand")
18816            (const_int 0)]))
18817    (match_scratch:SI 3 "r")]
18818   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18819   [(set (match_dup 3) (match_dup 2))
18820    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18822 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18823 ;; Don't split NOTs with a displacement operand, because resulting XOR
18824 ;; will not be pairable anyway.
18826 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18827 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18828 ;; so this split helps here as well.
18830 ;; Note: Can't do this as a regular split because we can't get proper
18831 ;; lifetime information then.
18833 (define_peephole2
18834   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18835         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18836   "optimize_insn_for_speed_p ()
18837    && ((TARGET_NOT_UNPAIRABLE
18838         && (!MEM_P (operands[0])
18839             || !memory_displacement_operand (operands[0], <MODE>mode)))
18840        || (TARGET_NOT_VECTORMODE
18841            && long_memory_operand (operands[0], <MODE>mode)))
18842    && peep2_regno_dead_p (0, FLAGS_REG)"
18843   [(parallel [(set (match_dup 0)
18844                    (xor:SWI124 (match_dup 1) (const_int -1)))
18845               (clobber (reg:CC FLAGS_REG))])])
18847 ;; Non pairable "test imm, reg" instructions can be translated to
18848 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18849 ;; byte opcode instead of two, have a short form for byte operands),
18850 ;; so do it for other CPUs as well.  Given that the value was dead,
18851 ;; this should not create any new dependencies.  Pass on the sub-word
18852 ;; versions if we're concerned about partial register stalls.
18854 (define_peephole2
18855   [(set (match_operand 0 "flags_reg_operand")
18856         (match_operator 1 "compare_operator"
18857           [(and:SI (match_operand:SI 2 "register_operand")
18858                    (match_operand:SI 3 "immediate_operand"))
18859            (const_int 0)]))]
18860   "ix86_match_ccmode (insn, CCNOmode)
18861    && (REGNO (operands[2]) != AX_REG
18862        || satisfies_constraint_K (operands[3]))
18863    && peep2_reg_dead_p (1, operands[2])"
18864   [(parallel
18865      [(set (match_dup 0)
18866            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18867                             (const_int 0)]))
18868       (set (match_dup 2)
18869            (and:SI (match_dup 2) (match_dup 3)))])])
18871 ;; We don't need to handle HImode case, because it will be promoted to SImode
18872 ;; on ! TARGET_PARTIAL_REG_STALL
18874 (define_peephole2
18875   [(set (match_operand 0 "flags_reg_operand")
18876         (match_operator 1 "compare_operator"
18877           [(and:QI (match_operand:QI 2 "register_operand")
18878                    (match_operand:QI 3 "immediate_operand"))
18879            (const_int 0)]))]
18880   "! TARGET_PARTIAL_REG_STALL
18881    && ix86_match_ccmode (insn, CCNOmode)
18882    && REGNO (operands[2]) != AX_REG
18883    && peep2_reg_dead_p (1, operands[2])"
18884   [(parallel
18885      [(set (match_dup 0)
18886            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18887                             (const_int 0)]))
18888       (set (match_dup 2)
18889            (and:QI (match_dup 2) (match_dup 3)))])])
18891 (define_peephole2
18892   [(set (match_operand 0 "flags_reg_operand")
18893         (match_operator 1 "compare_operator"
18894           [(and:QI
18895              (subreg:QI
18896                (zero_extract:SI (match_operand 2 "QIreg_operand")
18897                                 (const_int 8)
18898                                 (const_int 8)) 0)
18899              (match_operand 3 "const_int_operand"))
18900            (const_int 0)]))]
18901   "! TARGET_PARTIAL_REG_STALL
18902    && ix86_match_ccmode (insn, CCNOmode)
18903    && REGNO (operands[2]) != AX_REG
18904    && peep2_reg_dead_p (1, operands[2])"
18905   [(parallel
18906      [(set (match_dup 0)
18907            (match_op_dup 1
18908              [(and:QI
18909                 (subreg:QI
18910                   (zero_extract:SI (match_dup 2)
18911                                    (const_int 8)
18912                                    (const_int 8)) 0)
18913                 (match_dup 3))
18914               (const_int 0)]))
18915       (set (zero_extract:SI (match_dup 2)
18916                             (const_int 8)
18917                             (const_int 8))
18918            (subreg:SI
18919              (and:QI
18920                (subreg:QI
18921                  (zero_extract:SI (match_dup 2)
18922                                   (const_int 8)
18923                                   (const_int 8)) 0)
18924                (match_dup 3)) 0))])])
18926 ;; Don't do logical operations with memory inputs.
18927 (define_peephole2
18928   [(match_scratch:SWI 2 "<r>")
18929    (parallel [(set (match_operand:SWI 0 "register_operand")
18930                    (match_operator:SWI 3 "arith_or_logical_operator"
18931                      [(match_dup 0)
18932                       (match_operand:SWI 1 "memory_operand")]))
18933               (clobber (reg:CC FLAGS_REG))])]
18934   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18935   [(set (match_dup 2) (match_dup 1))
18936    (parallel [(set (match_dup 0)
18937                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18938               (clobber (reg:CC FLAGS_REG))])])
18940 (define_peephole2
18941   [(match_scratch:SWI 2 "<r>")
18942    (parallel [(set (match_operand:SWI 0 "register_operand")
18943                    (match_operator:SWI 3 "arith_or_logical_operator"
18944                      [(match_operand:SWI 1 "memory_operand")
18945                       (match_dup 0)]))
18946               (clobber (reg:CC FLAGS_REG))])]
18947   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18948   [(set (match_dup 2) (match_dup 1))
18949    (parallel [(set (match_dup 0)
18950                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18951               (clobber (reg:CC FLAGS_REG))])])
18953 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18954 ;; the memory address refers to the destination of the load!
18956 (define_peephole2
18957   [(set (match_operand:SWI 0 "general_reg_operand")
18958         (match_operand:SWI 1 "general_reg_operand"))
18959    (parallel [(set (match_dup 0)
18960                    (match_operator:SWI 3 "commutative_operator"
18961                      [(match_dup 0)
18962                       (match_operand:SWI 2 "memory_operand")]))
18963               (clobber (reg:CC FLAGS_REG))])]
18964   "REGNO (operands[0]) != REGNO (operands[1])
18965    && (<MODE>mode != QImode
18966        || any_QIreg_operand (operands[1], QImode))"
18967   [(set (match_dup 0) (match_dup 4))
18968    (parallel [(set (match_dup 0)
18969                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18970               (clobber (reg:CC FLAGS_REG))])]
18971   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18973 (define_peephole2
18974   [(set (match_operand 0 "mmx_reg_operand")
18975         (match_operand 1 "mmx_reg_operand"))
18976    (set (match_dup 0)
18977         (match_operator 3 "commutative_operator"
18978           [(match_dup 0)
18979            (match_operand 2 "memory_operand")]))]
18980   "REGNO (operands[0]) != REGNO (operands[1])"
18981   [(set (match_dup 0) (match_dup 2))
18982    (set (match_dup 0)
18983         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18985 (define_peephole2
18986   [(set (match_operand 0 "sse_reg_operand")
18987         (match_operand 1 "sse_reg_operand"))
18988    (set (match_dup 0)
18989         (match_operator 3 "commutative_operator"
18990           [(match_dup 0)
18991            (match_operand 2 "memory_operand")]))]
18992   "REGNO (operands[0]) != REGNO (operands[1])"
18993   [(set (match_dup 0) (match_dup 2))
18994    (set (match_dup 0)
18995         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18997 ; Don't do logical operations with memory outputs
18999 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19000 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19001 ; the same decoder scheduling characteristics as the original.
19003 (define_peephole2
19004   [(match_scratch:SWI 2 "<r>")
19005    (parallel [(set (match_operand:SWI 0 "memory_operand")
19006                    (match_operator:SWI 3 "arith_or_logical_operator"
19007                      [(match_dup 0)
19008                       (match_operand:SWI 1 "<nonmemory_operand>")]))
19009               (clobber (reg:CC FLAGS_REG))])]
19010   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19011   [(set (match_dup 2) (match_dup 0))
19012    (parallel [(set (match_dup 2)
19013                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19014               (clobber (reg:CC FLAGS_REG))])
19015    (set (match_dup 0) (match_dup 2))])
19017 (define_peephole2
19018   [(match_scratch:SWI 2 "<r>")
19019    (parallel [(set (match_operand:SWI 0 "memory_operand")
19020                    (match_operator:SWI 3 "arith_or_logical_operator"
19021                      [(match_operand:SWI 1 "<nonmemory_operand>")
19022                       (match_dup 0)]))
19023               (clobber (reg:CC FLAGS_REG))])]
19024   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19025   [(set (match_dup 2) (match_dup 0))
19026    (parallel [(set (match_dup 2)
19027                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19028               (clobber (reg:CC FLAGS_REG))])
19029    (set (match_dup 0) (match_dup 2))])
19031 ;; Attempt to use arith or logical operations with memory outputs with
19032 ;; setting of flags.
19033 (define_peephole2
19034   [(set (match_operand:SWI 0 "register_operand")
19035         (match_operand:SWI 1 "memory_operand"))
19036    (parallel [(set (match_dup 0)
19037                    (match_operator:SWI 3 "plusminuslogic_operator"
19038                      [(match_dup 0)
19039                       (match_operand:SWI 2 "<nonmemory_operand>")]))
19040               (clobber (reg:CC FLAGS_REG))])
19041    (set (match_dup 1) (match_dup 0))
19042    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19043   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19044    && peep2_reg_dead_p (4, operands[0])
19045    && !reg_overlap_mentioned_p (operands[0], operands[1])
19046    && !reg_overlap_mentioned_p (operands[0], operands[2])
19047    && (<MODE>mode != QImode
19048        || immediate_operand (operands[2], QImode)
19049        || any_QIreg_operand (operands[2], QImode))
19050    && ix86_match_ccmode (peep2_next_insn (3),
19051                          (GET_CODE (operands[3]) == PLUS
19052                           || GET_CODE (operands[3]) == MINUS)
19053                          ? CCGOCmode : CCNOmode)"
19054   [(parallel [(set (match_dup 4) (match_dup 6))
19055               (set (match_dup 1) (match_dup 5))])]
19057   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19058   operands[5]
19059     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19060                       copy_rtx (operands[1]),
19061                       operands[2]);
19062   operands[6]
19063     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19064                        copy_rtx (operands[5]),
19065                        const0_rtx);
19068 ;; Likewise for instances where we have a lea pattern.
19069 (define_peephole2
19070   [(set (match_operand:SWI 0 "register_operand")
19071         (match_operand:SWI 1 "memory_operand"))
19072    (set (match_operand:SWI 3 "register_operand")
19073         (plus:SWI (match_dup 0)
19074                   (match_operand:SWI 2 "<nonmemory_operand>")))
19075    (set (match_dup 1) (match_dup 3))
19076    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19077   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19078    && peep2_reg_dead_p (4, operands[3])
19079    && (rtx_equal_p (operands[0], operands[3])
19080        || peep2_reg_dead_p (2, operands[0]))
19081    && !reg_overlap_mentioned_p (operands[0], operands[1])
19082    && !reg_overlap_mentioned_p (operands[3], operands[1])
19083    && !reg_overlap_mentioned_p (operands[0], operands[2])
19084    && (<MODE>mode != QImode
19085        || immediate_operand (operands[2], QImode)
19086        || any_QIreg_operand (operands[2], QImode))
19087    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19088   [(parallel [(set (match_dup 4) (match_dup 6))
19089               (set (match_dup 1) (match_dup 5))])]
19091   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19092   operands[5]
19093     = gen_rtx_PLUS (<MODE>mode,
19094                     copy_rtx (operands[1]),
19095                     operands[2]);
19096   operands[6]
19097     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19098                        copy_rtx (operands[5]),
19099                        const0_rtx);
19102 (define_peephole2
19103   [(parallel [(set (match_operand:SWI 0 "register_operand")
19104                    (match_operator:SWI 2 "plusminuslogic_operator"
19105                      [(match_dup 0)
19106                       (match_operand:SWI 1 "memory_operand")]))
19107               (clobber (reg:CC FLAGS_REG))])
19108    (set (match_dup 1) (match_dup 0))
19109    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19110   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19111    && GET_CODE (operands[2]) != MINUS
19112    && peep2_reg_dead_p (3, operands[0])
19113    && !reg_overlap_mentioned_p (operands[0], operands[1])
19114    && ix86_match_ccmode (peep2_next_insn (2),
19115                          GET_CODE (operands[2]) == PLUS
19116                          ? CCGOCmode : CCNOmode)"
19117   [(parallel [(set (match_dup 3) (match_dup 5))
19118               (set (match_dup 1) (match_dup 4))])]
19120   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19121   operands[4]
19122     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19123                       copy_rtx (operands[1]),
19124                       operands[0]);
19125   operands[5]
19126     = gen_rtx_COMPARE (GET_MODE (operands[3]),
19127                        copy_rtx (operands[4]),
19128                        const0_rtx);
19131 (define_peephole2
19132   [(set (match_operand:SWI12 0 "register_operand")
19133         (match_operand:SWI12 1 "memory_operand"))
19134    (parallel [(set (match_operand:SI 4 "register_operand")
19135                    (match_operator:SI 3 "plusminuslogic_operator"
19136                      [(match_dup 4)
19137                       (match_operand:SI 2 "nonmemory_operand")]))
19138               (clobber (reg:CC FLAGS_REG))])
19139    (set (match_dup 1) (match_dup 0))
19140    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19141   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19142    && REGNO (operands[0]) == REGNO (operands[4])
19143    && peep2_reg_dead_p (4, operands[0])
19144    && (<MODE>mode != QImode
19145        || immediate_operand (operands[2], SImode)
19146        || any_QIreg_operand (operands[2], SImode))
19147    && !reg_overlap_mentioned_p (operands[0], operands[1])
19148    && !reg_overlap_mentioned_p (operands[0], operands[2])
19149    && ix86_match_ccmode (peep2_next_insn (3),
19150                          (GET_CODE (operands[3]) == PLUS
19151                           || GET_CODE (operands[3]) == MINUS)
19152                          ? CCGOCmode : CCNOmode)"
19153   [(parallel [(set (match_dup 4) (match_dup 6))
19154               (set (match_dup 1) (match_dup 5))])]
19156   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19157   operands[5]
19158     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19159                       copy_rtx (operands[1]),
19160                       gen_lowpart (<MODE>mode, operands[2]));
19161   operands[6]
19162     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19163                        copy_rtx (operands[5]),
19164                        const0_rtx);
19167 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19168 (define_peephole2
19169   [(set (match_operand 0 "general_reg_operand")
19170         (match_operand 1 "const0_operand"))]
19171   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19172    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19173    && peep2_regno_dead_p (0, FLAGS_REG)"
19174   [(parallel [(set (match_dup 0) (const_int 0))
19175               (clobber (reg:CC FLAGS_REG))])]
19176   "operands[0] = gen_lowpart (word_mode, operands[0]);")
19178 (define_peephole2
19179   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19180         (const_int 0))]
19181   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19182    && peep2_regno_dead_p (0, FLAGS_REG)"
19183   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19184               (clobber (reg:CC FLAGS_REG))])])
19186 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19187 (define_peephole2
19188   [(set (match_operand:SWI248 0 "general_reg_operand")
19189         (const_int -1))]
19190   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19191    && peep2_regno_dead_p (0, FLAGS_REG)"
19192   [(parallel [(set (match_dup 0) (const_int -1))
19193               (clobber (reg:CC FLAGS_REG))])]
19195   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19196     operands[0] = gen_lowpart (SImode, operands[0]);
19199 ;; Attempt to convert simple lea to add/shift.
19200 ;; These can be created by move expanders.
19201 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19202 ;; relevant lea instructions were already split.
19204 (define_peephole2
19205   [(set (match_operand:SWI48 0 "register_operand")
19206         (plus:SWI48 (match_dup 0)
19207                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
19208   "!TARGET_OPT_AGU
19209    && peep2_regno_dead_p (0, FLAGS_REG)"
19210   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19211               (clobber (reg:CC FLAGS_REG))])])
19213 (define_peephole2
19214   [(set (match_operand:SWI48 0 "register_operand")
19215         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19216                     (match_dup 0)))]
19217   "!TARGET_OPT_AGU
19218    && peep2_regno_dead_p (0, FLAGS_REG)"
19219   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19220               (clobber (reg:CC FLAGS_REG))])])
19222 (define_peephole2
19223   [(set (match_operand:DI 0 "register_operand")
19224         (zero_extend:DI
19225           (plus:SI (match_operand:SI 1 "register_operand")
19226                    (match_operand:SI 2 "nonmemory_operand"))))]
19227   "TARGET_64BIT && !TARGET_OPT_AGU
19228    && REGNO (operands[0]) == REGNO (operands[1])
19229    && peep2_regno_dead_p (0, FLAGS_REG)"
19230   [(parallel [(set (match_dup 0)
19231                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19232               (clobber (reg:CC FLAGS_REG))])])
19234 (define_peephole2
19235   [(set (match_operand:DI 0 "register_operand")
19236         (zero_extend:DI
19237           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19238                    (match_operand:SI 2 "register_operand"))))]
19239   "TARGET_64BIT && !TARGET_OPT_AGU
19240    && REGNO (operands[0]) == REGNO (operands[2])
19241    && peep2_regno_dead_p (0, FLAGS_REG)"
19242   [(parallel [(set (match_dup 0)
19243                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19244               (clobber (reg:CC FLAGS_REG))])])
19246 (define_peephole2
19247   [(set (match_operand:SWI48 0 "register_operand")
19248         (mult:SWI48 (match_dup 0)
19249                     (match_operand:SWI48 1 "const_int_operand")))]
19250   "pow2p_hwi (INTVAL (operands[1]))
19251    && peep2_regno_dead_p (0, FLAGS_REG)"
19252   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19253               (clobber (reg:CC FLAGS_REG))])]
19254   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19256 (define_peephole2
19257   [(set (match_operand:DI 0 "register_operand")
19258         (zero_extend:DI
19259           (mult:SI (match_operand:SI 1 "register_operand")
19260                    (match_operand:SI 2 "const_int_operand"))))]
19261   "TARGET_64BIT
19262    && pow2p_hwi (INTVAL (operands[2]))
19263    && REGNO (operands[0]) == REGNO (operands[1])
19264    && peep2_regno_dead_p (0, FLAGS_REG)"
19265   [(parallel [(set (match_dup 0)
19266                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19267               (clobber (reg:CC FLAGS_REG))])]
19268   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19270 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19271 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19272 ;; On many CPUs it is also faster, since special hardware to avoid esp
19273 ;; dependencies is present.
19275 ;; While some of these conversions may be done using splitters, we use
19276 ;; peepholes in order to allow combine_stack_adjustments pass to see
19277 ;; nonobfuscated RTL.
19279 ;; Convert prologue esp subtractions to push.
19280 ;; We need register to push.  In order to keep verify_flow_info happy we have
19281 ;; two choices
19282 ;; - use scratch and clobber it in order to avoid dependencies
19283 ;; - use already live register
19284 ;; We can't use the second way right now, since there is no reliable way how to
19285 ;; verify that given register is live.  First choice will also most likely in
19286 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19287 ;; call clobbered registers are dead.  We may want to use base pointer as an
19288 ;; alternative when no register is available later.
19290 (define_peephole2
19291   [(match_scratch:W 1 "r")
19292    (parallel [(set (reg:P SP_REG)
19293                    (plus:P (reg:P SP_REG)
19294                            (match_operand:P 0 "const_int_operand")))
19295               (clobber (reg:CC FLAGS_REG))
19296               (clobber (mem:BLK (scratch)))])]
19297   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19298    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19299    && ix86_red_zone_size == 0"
19300   [(clobber (match_dup 1))
19301    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19302               (clobber (mem:BLK (scratch)))])])
19304 (define_peephole2
19305   [(match_scratch:W 1 "r")
19306    (parallel [(set (reg:P SP_REG)
19307                    (plus:P (reg:P SP_REG)
19308                            (match_operand:P 0 "const_int_operand")))
19309               (clobber (reg:CC FLAGS_REG))
19310               (clobber (mem:BLK (scratch)))])]
19311   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19312    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19313    && ix86_red_zone_size == 0"
19314   [(clobber (match_dup 1))
19315    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19316    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19317               (clobber (mem:BLK (scratch)))])])
19319 ;; Convert esp subtractions to push.
19320 (define_peephole2
19321   [(match_scratch:W 1 "r")
19322    (parallel [(set (reg:P SP_REG)
19323                    (plus:P (reg:P SP_REG)
19324                            (match_operand:P 0 "const_int_operand")))
19325               (clobber (reg:CC FLAGS_REG))])]
19326   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19327    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19328    && ix86_red_zone_size == 0"
19329   [(clobber (match_dup 1))
19330    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19332 (define_peephole2
19333   [(match_scratch:W 1 "r")
19334    (parallel [(set (reg:P SP_REG)
19335                    (plus:P (reg:P SP_REG)
19336                            (match_operand:P 0 "const_int_operand")))
19337               (clobber (reg:CC FLAGS_REG))])]
19338   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19339    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19340    && ix86_red_zone_size == 0"
19341   [(clobber (match_dup 1))
19342    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19343    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19345 ;; Convert epilogue deallocator to pop.
19346 (define_peephole2
19347   [(match_scratch:W 1 "r")
19348    (parallel [(set (reg:P SP_REG)
19349                    (plus:P (reg:P SP_REG)
19350                            (match_operand:P 0 "const_int_operand")))
19351               (clobber (reg:CC FLAGS_REG))
19352               (clobber (mem:BLK (scratch)))])]
19353   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19354    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19355   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19356               (clobber (mem:BLK (scratch)))])])
19358 ;; Two pops case is tricky, since pop causes dependency
19359 ;; on destination register.  We use two registers if available.
19360 (define_peephole2
19361   [(match_scratch:W 1 "r")
19362    (match_scratch:W 2 "r")
19363    (parallel [(set (reg:P SP_REG)
19364                    (plus:P (reg:P SP_REG)
19365                            (match_operand:P 0 "const_int_operand")))
19366               (clobber (reg:CC FLAGS_REG))
19367               (clobber (mem:BLK (scratch)))])]
19368   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19369    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19370   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19371               (clobber (mem:BLK (scratch)))])
19372    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19374 (define_peephole2
19375   [(match_scratch:W 1 "r")
19376    (parallel [(set (reg:P SP_REG)
19377                    (plus:P (reg:P SP_REG)
19378                            (match_operand:P 0 "const_int_operand")))
19379               (clobber (reg:CC FLAGS_REG))
19380               (clobber (mem:BLK (scratch)))])]
19381   "optimize_insn_for_size_p ()
19382    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19383   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19384               (clobber (mem:BLK (scratch)))])
19385    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19387 ;; Convert esp additions to pop.
19388 (define_peephole2
19389   [(match_scratch:W 1 "r")
19390    (parallel [(set (reg:P SP_REG)
19391                    (plus:P (reg:P SP_REG)
19392                            (match_operand:P 0 "const_int_operand")))
19393               (clobber (reg:CC FLAGS_REG))])]
19394   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19395   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19397 ;; Two pops case is tricky, since pop causes dependency
19398 ;; on destination register.  We use two registers if available.
19399 (define_peephole2
19400   [(match_scratch:W 1 "r")
19401    (match_scratch:W 2 "r")
19402    (parallel [(set (reg:P SP_REG)
19403                    (plus:P (reg:P SP_REG)
19404                            (match_operand:P 0 "const_int_operand")))
19405               (clobber (reg:CC FLAGS_REG))])]
19406   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19407   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19408    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19410 (define_peephole2
19411   [(match_scratch:W 1 "r")
19412    (parallel [(set (reg:P SP_REG)
19413                    (plus:P (reg:P SP_REG)
19414                            (match_operand:P 0 "const_int_operand")))
19415               (clobber (reg:CC FLAGS_REG))])]
19416   "optimize_insn_for_size_p ()
19417    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19418   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19419    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19421 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19422 ;; required and register dies.  Similarly for 128 to -128.
19423 (define_peephole2
19424   [(set (match_operand 0 "flags_reg_operand")
19425         (match_operator 1 "compare_operator"
19426           [(match_operand 2 "register_operand")
19427            (match_operand 3 "const_int_operand")]))]
19428   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19429      && incdec_operand (operands[3], GET_MODE (operands[3])))
19430     || (!TARGET_FUSE_CMP_AND_BRANCH
19431         && INTVAL (operands[3]) == 128))
19432    && ix86_match_ccmode (insn, CCGCmode)
19433    && peep2_reg_dead_p (1, operands[2])"
19434   [(parallel [(set (match_dup 0)
19435                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19436               (clobber (match_dup 2))])])
19438 ;; Convert imul by three, five and nine into lea
19439 (define_peephole2
19440   [(parallel
19441     [(set (match_operand:SWI48 0 "register_operand")
19442           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19443                       (match_operand:SWI48 2 "const359_operand")))
19444      (clobber (reg:CC FLAGS_REG))])]
19445   "!TARGET_PARTIAL_REG_STALL
19446    || <MODE>mode == SImode
19447    || optimize_function_for_size_p (cfun)"
19448   [(set (match_dup 0)
19449         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19450                     (match_dup 1)))]
19451   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19453 (define_peephole2
19454   [(parallel
19455     [(set (match_operand:SWI48 0 "register_operand")
19456           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19457                       (match_operand:SWI48 2 "const359_operand")))
19458      (clobber (reg:CC FLAGS_REG))])]
19459   "optimize_insn_for_speed_p ()
19460    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19461   [(set (match_dup 0) (match_dup 1))
19462    (set (match_dup 0)
19463         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19464                     (match_dup 0)))]
19465   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19467 ;; imul $32bit_imm, mem, reg is vector decoded, while
19468 ;; imul $32bit_imm, reg, reg is direct decoded.
19469 (define_peephole2
19470   [(match_scratch:SWI48 3 "r")
19471    (parallel [(set (match_operand:SWI48 0 "register_operand")
19472                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19473                                (match_operand:SWI48 2 "immediate_operand")))
19474               (clobber (reg:CC FLAGS_REG))])]
19475   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19476    && !satisfies_constraint_K (operands[2])"
19477   [(set (match_dup 3) (match_dup 1))
19478    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19479               (clobber (reg:CC FLAGS_REG))])])
19481 (define_peephole2
19482   [(match_scratch:SI 3 "r")
19483    (parallel [(set (match_operand:DI 0 "register_operand")
19484                    (zero_extend:DI
19485                      (mult:SI (match_operand:SI 1 "memory_operand")
19486                               (match_operand:SI 2 "immediate_operand"))))
19487               (clobber (reg:CC FLAGS_REG))])]
19488   "TARGET_64BIT
19489    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19490    && !satisfies_constraint_K (operands[2])"
19491   [(set (match_dup 3) (match_dup 1))
19492    (parallel [(set (match_dup 0)
19493                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19494               (clobber (reg:CC FLAGS_REG))])])
19496 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19497 ;; Convert it into imul reg, reg
19498 ;; It would be better to force assembler to encode instruction using long
19499 ;; immediate, but there is apparently no way to do so.
19500 (define_peephole2
19501   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19502                    (mult:SWI248
19503                     (match_operand:SWI248 1 "nonimmediate_operand")
19504                     (match_operand:SWI248 2 "const_int_operand")))
19505               (clobber (reg:CC FLAGS_REG))])
19506    (match_scratch:SWI248 3 "r")]
19507   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19508    && satisfies_constraint_K (operands[2])"
19509   [(set (match_dup 3) (match_dup 2))
19510    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19511               (clobber (reg:CC FLAGS_REG))])]
19513   if (!rtx_equal_p (operands[0], operands[1]))
19514     emit_move_insn (operands[0], operands[1]);
19517 ;; After splitting up read-modify operations, array accesses with memory
19518 ;; operands might end up in form:
19519 ;;  sall    $2, %eax
19520 ;;  movl    4(%esp), %edx
19521 ;;  addl    %edx, %eax
19522 ;; instead of pre-splitting:
19523 ;;  sall    $2, %eax
19524 ;;  addl    4(%esp), %eax
19525 ;; Turn it into:
19526 ;;  movl    4(%esp), %edx
19527 ;;  leal    (%edx,%eax,4), %eax
19529 (define_peephole2
19530   [(match_scratch:W 5 "r")
19531    (parallel [(set (match_operand 0 "register_operand")
19532                    (ashift (match_operand 1 "register_operand")
19533                            (match_operand 2 "const_int_operand")))
19534                (clobber (reg:CC FLAGS_REG))])
19535    (parallel [(set (match_operand 3 "register_operand")
19536                    (plus (match_dup 0)
19537                          (match_operand 4 "x86_64_general_operand")))
19538                    (clobber (reg:CC FLAGS_REG))])]
19539   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19540    /* Validate MODE for lea.  */
19541    && ((!TARGET_PARTIAL_REG_STALL
19542         && (GET_MODE (operands[0]) == QImode
19543             || GET_MODE (operands[0]) == HImode))
19544        || GET_MODE (operands[0]) == SImode
19545        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19546    && (rtx_equal_p (operands[0], operands[3])
19547        || peep2_reg_dead_p (2, operands[0]))
19548    /* We reorder load and the shift.  */
19549    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19550   [(set (match_dup 5) (match_dup 4))
19551    (set (match_dup 0) (match_dup 1))]
19553   machine_mode op1mode = GET_MODE (operands[1]);
19554   machine_mode mode = op1mode == DImode ? DImode : SImode;
19555   int scale = 1 << INTVAL (operands[2]);
19556   rtx index = gen_lowpart (word_mode, operands[1]);
19557   rtx base = gen_lowpart (word_mode, operands[5]);
19558   rtx dest = gen_lowpart (mode, operands[3]);
19560   operands[1] = gen_rtx_PLUS (word_mode, base,
19561                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19562   if (mode != word_mode)
19563     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19565   operands[5] = base;
19566   if (op1mode != word_mode)
19567     operands[5] = gen_lowpart (op1mode, operands[5]);
19569   operands[0] = dest;
19572 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19573 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19574 ;; caught for use by garbage collectors and the like.  Using an insn that
19575 ;; maps to SIGILL makes it more likely the program will rightfully die.
19576 ;; Keeping with tradition, "6" is in honor of #UD.
19577 (define_insn "trap"
19578   [(trap_if (const_int 1) (const_int 6))]
19579   ""
19581 #ifdef HAVE_AS_IX86_UD2
19582   return "ud2";
19583 #else
19584   return ASM_SHORT "0x0b0f";
19585 #endif
19587   [(set_attr "length" "2")])
19589 (define_insn "ud2"
19590   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19591   ""
19593 #ifdef HAVE_AS_IX86_UD2
19594   return "ud2";
19595 #else
19596   return ASM_SHORT "0x0b0f";
19597 #endif
19599   [(set_attr "length" "2")])
19601 (define_expand "prefetch"
19602   [(prefetch (match_operand 0 "address_operand")
19603              (match_operand:SI 1 "const_int_operand")
19604              (match_operand:SI 2 "const_int_operand"))]
19605   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19607   bool write = INTVAL (operands[1]) != 0;
19608   int locality = INTVAL (operands[2]);
19610   gcc_assert (IN_RANGE (locality, 0, 3));
19612   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19613      supported by SSE counterpart (non-SSE2 athlon machines) or the
19614      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19615      prefetch as it allows specifying of locality.  */
19617   if (write)
19618     {
19619       if (TARGET_PREFETCHWT1)
19620         operands[2] = GEN_INT (MAX (locality, 2)); 
19621       else if (TARGET_PRFCHW)
19622         operands[2] = GEN_INT (3);
19623       else if (TARGET_3DNOW && !TARGET_SSE2)
19624         operands[2] = GEN_INT (3);
19625       else if (TARGET_PREFETCH_SSE)
19626         operands[1] = const0_rtx;
19627       else
19628         {
19629           gcc_assert (TARGET_3DNOW);
19630           operands[2] = GEN_INT (3);
19631         }
19632     }
19633   else
19634     {
19635       if (TARGET_PREFETCH_SSE)
19636         ;
19637       else
19638         {
19639           gcc_assert (TARGET_3DNOW);
19640           operands[2] = GEN_INT (3);
19641         }
19642     }
19645 (define_insn "*prefetch_sse"
19646   [(prefetch (match_operand 0 "address_operand" "p")
19647              (const_int 0)
19648              (match_operand:SI 1 "const_int_operand"))]
19649   "TARGET_PREFETCH_SSE"
19651   static const char * const patterns[4] = {
19652    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19653   };
19655   int locality = INTVAL (operands[1]);
19656   gcc_assert (IN_RANGE (locality, 0, 3));
19658   return patterns[locality];
19660   [(set_attr "type" "sse")
19661    (set_attr "atom_sse_attr" "prefetch")
19662    (set (attr "length_address")
19663         (symbol_ref "memory_address_length (operands[0], false)"))
19664    (set_attr "memory" "none")])
19666 (define_insn "*prefetch_3dnow"
19667   [(prefetch (match_operand 0 "address_operand" "p")
19668              (match_operand:SI 1 "const_int_operand" "n")
19669              (const_int 3))]
19670   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19672   if (INTVAL (operands[1]) == 0)
19673     return "prefetch\t%a0";
19674   else
19675     return "prefetchw\t%a0";
19677   [(set_attr "type" "mmx")
19678    (set (attr "length_address")
19679         (symbol_ref "memory_address_length (operands[0], false)"))
19680    (set_attr "memory" "none")])
19682 (define_insn "*prefetch_prefetchwt1"
19683   [(prefetch (match_operand 0 "address_operand" "p")
19684              (const_int 1)
19685              (const_int 2))]
19686   "TARGET_PREFETCHWT1"
19687   "prefetchwt1\t%a0";
19688   [(set_attr "type" "sse")
19689    (set (attr "length_address")
19690         (symbol_ref "memory_address_length (operands[0], false)"))
19691    (set_attr "memory" "none")])
19693 (define_expand "stack_protect_set"
19694   [(match_operand 0 "memory_operand")
19695    (match_operand 1 "memory_operand")]
19696   "TARGET_SSP_TLS_GUARD"
19698   rtx (*insn)(rtx, rtx);
19700   insn = (TARGET_LP64
19701           ? gen_stack_protect_set_di
19702           : gen_stack_protect_set_si);
19704   emit_insn (insn (operands[0], operands[1]));
19705   DONE;
19708 (define_insn "stack_protect_set_<mode>"
19709   [(set (match_operand:PTR 0 "memory_operand" "=m")
19710         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19711                     UNSPEC_SP_SET))
19712    (set (match_scratch:PTR 2 "=&r") (const_int 0))
19713    (clobber (reg:CC FLAGS_REG))]
19714   "TARGET_SSP_TLS_GUARD"
19715   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19716   [(set_attr "type" "multi")])
19718 (define_expand "stack_protect_test"
19719   [(match_operand 0 "memory_operand")
19720    (match_operand 1 "memory_operand")
19721    (match_operand 2)]
19722   "TARGET_SSP_TLS_GUARD"
19724   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19726   rtx (*insn)(rtx, rtx, rtx);
19728   insn = (TARGET_LP64
19729           ? gen_stack_protect_test_di
19730           : gen_stack_protect_test_si);
19732   emit_insn (insn (flags, operands[0], operands[1]));
19734   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19735                                   flags, const0_rtx, operands[2]));
19736   DONE;
19739 (define_insn "stack_protect_test_<mode>"
19740   [(set (match_operand:CCZ 0 "flags_reg_operand")
19741         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19742                      (match_operand:PTR 2 "memory_operand" "m")]
19743                     UNSPEC_SP_TEST))
19744    (clobber (match_scratch:PTR 3 "=&r"))]
19745   "TARGET_SSP_TLS_GUARD"
19746   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19747   [(set_attr "type" "multi")])
19749 (define_insn "sse4_2_crc32<mode>"
19750   [(set (match_operand:SI 0 "register_operand" "=r")
19751         (unspec:SI
19752           [(match_operand:SI 1 "register_operand" "0")
19753            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19754           UNSPEC_CRC32))]
19755   "TARGET_SSE4_2 || TARGET_CRC32"
19756   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19757   [(set_attr "type" "sselog1")
19758    (set_attr "prefix_rep" "1")
19759    (set_attr "prefix_extra" "1")
19760    (set (attr "prefix_data16")
19761      (if_then_else (match_operand:HI 2)
19762        (const_string "1")
19763        (const_string "*")))
19764    (set (attr "prefix_rex")
19765      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19766        (const_string "1")
19767        (const_string "*")))
19768    (set_attr "mode" "SI")])
19770 (define_insn "sse4_2_crc32di"
19771   [(set (match_operand:DI 0 "register_operand" "=r")
19772         (unspec:DI
19773           [(match_operand:DI 1 "register_operand" "0")
19774            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19775           UNSPEC_CRC32))]
19776   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19777   "crc32{q}\t{%2, %0|%0, %2}"
19778   [(set_attr "type" "sselog1")
19779    (set_attr "prefix_rep" "1")
19780    (set_attr "prefix_extra" "1")
19781    (set_attr "mode" "DI")])
19783 (define_insn "rdpmc"
19784   [(set (match_operand:DI 0 "register_operand" "=A")
19785         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19786                             UNSPECV_RDPMC))]
19787   "!TARGET_64BIT"
19788   "rdpmc"
19789   [(set_attr "type" "other")
19790    (set_attr "length" "2")])
19792 (define_insn "rdpmc_rex64"
19793   [(set (match_operand:DI 0 "register_operand" "=a")
19794         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19795                             UNSPECV_RDPMC))
19796    (set (match_operand:DI 1 "register_operand" "=d")
19797         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19798   "TARGET_64BIT"
19799   "rdpmc"
19800   [(set_attr "type" "other")
19801    (set_attr "length" "2")])
19803 (define_insn "rdtsc"
19804   [(set (match_operand:DI 0 "register_operand" "=A")
19805         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19806   "!TARGET_64BIT"
19807   "rdtsc"
19808   [(set_attr "type" "other")
19809    (set_attr "length" "2")])
19811 (define_insn "rdtsc_rex64"
19812   [(set (match_operand:DI 0 "register_operand" "=a")
19813         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19814    (set (match_operand:DI 1 "register_operand" "=d")
19815         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19816   "TARGET_64BIT"
19817   "rdtsc"
19818   [(set_attr "type" "other")
19819    (set_attr "length" "2")])
19821 (define_insn "rdtscp"
19822   [(set (match_operand:DI 0 "register_operand" "=A")
19823         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19824    (set (match_operand:SI 1 "register_operand" "=c")
19825         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19826   "!TARGET_64BIT"
19827   "rdtscp"
19828   [(set_attr "type" "other")
19829    (set_attr "length" "3")])
19831 (define_insn "rdtscp_rex64"
19832   [(set (match_operand:DI 0 "register_operand" "=a")
19833         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19834    (set (match_operand:DI 1 "register_operand" "=d")
19835         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19836    (set (match_operand:SI 2 "register_operand" "=c")
19837         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19838   "TARGET_64BIT"
19839   "rdtscp"
19840   [(set_attr "type" "other")
19841    (set_attr "length" "3")])
19843 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19845 ;; FXSR, XSAVE and XSAVEOPT instructions
19847 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19849 (define_insn "fxsave"
19850   [(set (match_operand:BLK 0 "memory_operand" "=m")
19851         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19852   "TARGET_FXSR"
19853   "fxsave\t%0"
19854   [(set_attr "type" "other")
19855    (set_attr "memory" "store")
19856    (set (attr "length")
19857         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19859 (define_insn "fxsave64"
19860   [(set (match_operand:BLK 0 "memory_operand" "=m")
19861         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19862   "TARGET_64BIT && TARGET_FXSR"
19863   "fxsave64\t%0"
19864   [(set_attr "type" "other")
19865    (set_attr "memory" "store")
19866    (set (attr "length")
19867         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19869 (define_insn "fxrstor"
19870   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19871                     UNSPECV_FXRSTOR)]
19872   "TARGET_FXSR"
19873   "fxrstor\t%0"
19874   [(set_attr "type" "other")
19875    (set_attr "memory" "load")
19876    (set (attr "length")
19877         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19879 (define_insn "fxrstor64"
19880   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19881                     UNSPECV_FXRSTOR64)]
19882   "TARGET_64BIT && TARGET_FXSR"
19883   "fxrstor64\t%0"
19884   [(set_attr "type" "other")
19885    (set_attr "memory" "load")
19886    (set (attr "length")
19887         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19889 (define_int_iterator ANY_XSAVE
19890         [UNSPECV_XSAVE
19891          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19892          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19893          (UNSPECV_XSAVES "TARGET_XSAVES")])
19895 (define_int_iterator ANY_XSAVE64
19896         [UNSPECV_XSAVE64
19897          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19898          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19899          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19901 (define_int_attr xsave
19902         [(UNSPECV_XSAVE "xsave")
19903          (UNSPECV_XSAVE64 "xsave64")
19904          (UNSPECV_XSAVEOPT "xsaveopt")
19905          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19906          (UNSPECV_XSAVEC "xsavec")
19907          (UNSPECV_XSAVEC64 "xsavec64")
19908          (UNSPECV_XSAVES "xsaves")
19909          (UNSPECV_XSAVES64 "xsaves64")])
19911 (define_int_iterator ANY_XRSTOR
19912         [UNSPECV_XRSTOR
19913          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19915 (define_int_iterator ANY_XRSTOR64
19916         [UNSPECV_XRSTOR64
19917          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19919 (define_int_attr xrstor
19920         [(UNSPECV_XRSTOR "xrstor")
19921          (UNSPECV_XRSTOR64 "xrstor")
19922          (UNSPECV_XRSTORS "xrstors")
19923          (UNSPECV_XRSTORS64 "xrstors")])
19925 (define_insn "<xsave>"
19926   [(set (match_operand:BLK 0 "memory_operand" "=m")
19927         (unspec_volatile:BLK
19928          [(match_operand:DI 1 "register_operand" "A")]
19929          ANY_XSAVE))]
19930   "!TARGET_64BIT && TARGET_XSAVE"
19931   "<xsave>\t%0"
19932   [(set_attr "type" "other")
19933    (set_attr "memory" "store")
19934    (set (attr "length")
19935         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19937 (define_insn "<xsave>_rex64"
19938   [(set (match_operand:BLK 0 "memory_operand" "=m")
19939         (unspec_volatile:BLK
19940          [(match_operand:SI 1 "register_operand" "a")
19941           (match_operand:SI 2 "register_operand" "d")]
19942          ANY_XSAVE))]
19943   "TARGET_64BIT && TARGET_XSAVE"
19944   "<xsave>\t%0"
19945   [(set_attr "type" "other")
19946    (set_attr "memory" "store")
19947    (set (attr "length")
19948         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19950 (define_insn "<xsave>"
19951   [(set (match_operand:BLK 0 "memory_operand" "=m")
19952         (unspec_volatile:BLK
19953          [(match_operand:SI 1 "register_operand" "a")
19954           (match_operand:SI 2 "register_operand" "d")]
19955          ANY_XSAVE64))]
19956   "TARGET_64BIT && TARGET_XSAVE"
19957   "<xsave>\t%0"
19958   [(set_attr "type" "other")
19959    (set_attr "memory" "store")
19960    (set (attr "length")
19961         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19963 (define_insn "<xrstor>"
19964    [(unspec_volatile:BLK
19965      [(match_operand:BLK 0 "memory_operand" "m")
19966       (match_operand:DI 1 "register_operand" "A")]
19967      ANY_XRSTOR)]
19968   "!TARGET_64BIT && TARGET_XSAVE"
19969   "<xrstor>\t%0"
19970   [(set_attr "type" "other")
19971    (set_attr "memory" "load")
19972    (set (attr "length")
19973         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19975 (define_insn "<xrstor>_rex64"
19976    [(unspec_volatile:BLK
19977      [(match_operand:BLK 0 "memory_operand" "m")
19978       (match_operand:SI 1 "register_operand" "a")
19979       (match_operand:SI 2 "register_operand" "d")]
19980      ANY_XRSTOR)]
19981   "TARGET_64BIT && TARGET_XSAVE"
19982   "<xrstor>\t%0"
19983   [(set_attr "type" "other")
19984    (set_attr "memory" "load")
19985    (set (attr "length")
19986         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19988 (define_insn "<xrstor>64"
19989    [(unspec_volatile:BLK
19990      [(match_operand:BLK 0 "memory_operand" "m")
19991       (match_operand:SI 1 "register_operand" "a")
19992       (match_operand:SI 2 "register_operand" "d")]
19993      ANY_XRSTOR64)]
19994   "TARGET_64BIT && TARGET_XSAVE"
19995   "<xrstor>64\t%0"
19996   [(set_attr "type" "other")
19997    (set_attr "memory" "load")
19998    (set (attr "length")
19999         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20001 (define_insn "xsetbv"
20002   [(unspec_volatile:SI
20003          [(match_operand:SI 0 "register_operand" "c")
20004           (match_operand:DI 1 "register_operand" "A")]
20005          UNSPECV_XSETBV)]
20006   "!TARGET_64BIT && TARGET_XSAVE"
20007   "xsetbv"
20008   [(set_attr "type" "other")])
20010 (define_insn "xsetbv_rex64"
20011   [(unspec_volatile:SI
20012          [(match_operand:SI 0 "register_operand" "c")
20013           (match_operand:SI 1 "register_operand" "a")
20014           (match_operand:SI 2 "register_operand" "d")]
20015          UNSPECV_XSETBV)]
20016   "TARGET_64BIT && TARGET_XSAVE"
20017   "xsetbv"
20018   [(set_attr "type" "other")])
20020 (define_insn "xgetbv"
20021   [(set (match_operand:DI 0 "register_operand" "=A")
20022         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20023                             UNSPECV_XGETBV))]
20024   "!TARGET_64BIT && TARGET_XSAVE"
20025   "xgetbv"
20026   [(set_attr "type" "other")])
20028 (define_insn "xgetbv_rex64"
20029   [(set (match_operand:DI 0 "register_operand" "=a")
20030         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20031                             UNSPECV_XGETBV))
20032    (set (match_operand:DI 1 "register_operand" "=d")
20033         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20034   "TARGET_64BIT && TARGET_XSAVE"
20035   "xgetbv"
20036   [(set_attr "type" "other")])
20038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20040 ;; Floating-point instructions for atomic compound assignments
20042 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20044 ; Clobber all floating-point registers on environment save and restore
20045 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20046 (define_insn "fnstenv"
20047   [(set (match_operand:BLK 0 "memory_operand" "=m")
20048         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20049    (clobber (reg:HI FPCR_REG))
20050    (clobber (reg:XF ST0_REG))
20051    (clobber (reg:XF ST1_REG))
20052    (clobber (reg:XF ST2_REG))
20053    (clobber (reg:XF ST3_REG))
20054    (clobber (reg:XF ST4_REG))
20055    (clobber (reg:XF ST5_REG))
20056    (clobber (reg:XF ST6_REG))
20057    (clobber (reg:XF ST7_REG))]
20058   "TARGET_80387"
20059   "fnstenv\t%0"
20060   [(set_attr "type" "other")
20061    (set_attr "memory" "store")
20062    (set (attr "length")
20063         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20065 (define_insn "fldenv"
20066   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20067                     UNSPECV_FLDENV)
20068    (clobber (reg:CCFP FPSR_REG))
20069    (clobber (reg:HI FPCR_REG))
20070    (clobber (reg:XF ST0_REG))
20071    (clobber (reg:XF ST1_REG))
20072    (clobber (reg:XF ST2_REG))
20073    (clobber (reg:XF ST3_REG))
20074    (clobber (reg:XF ST4_REG))
20075    (clobber (reg:XF ST5_REG))
20076    (clobber (reg:XF ST6_REG))
20077    (clobber (reg:XF ST7_REG))]
20078   "TARGET_80387"
20079   "fldenv\t%0"
20080   [(set_attr "type" "other")
20081    (set_attr "memory" "load")
20082    (set (attr "length")
20083         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20085 (define_insn "fnstsw"
20086   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20087         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20088   "TARGET_80387"
20089   "fnstsw\t%0"
20090   [(set_attr "type" "other,other")
20091    (set_attr "memory" "none,store")
20092    (set (attr "length")
20093         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20095 (define_insn "fnclex"
20096   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20097   "TARGET_80387"
20098   "fnclex"
20099   [(set_attr "type" "other")
20100    (set_attr "memory" "none")
20101    (set_attr "length" "2")])
20103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20105 ;; LWP instructions
20107 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20109 (define_expand "lwp_llwpcb"
20110   [(unspec_volatile [(match_operand 0 "register_operand")]
20111                     UNSPECV_LLWP_INTRINSIC)]
20112   "TARGET_LWP")
20114 (define_insn "*lwp_llwpcb<mode>1"
20115   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20116                     UNSPECV_LLWP_INTRINSIC)]
20117   "TARGET_LWP"
20118   "llwpcb\t%0"
20119   [(set_attr "type" "lwp")
20120    (set_attr "mode" "<MODE>")
20121    (set_attr "length" "5")])
20123 (define_expand "lwp_slwpcb"
20124   [(set (match_operand 0 "register_operand")
20125         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20126   "TARGET_LWP"
20128   rtx (*insn)(rtx);
20130   insn = (Pmode == DImode
20131           ? gen_lwp_slwpcbdi
20132           : gen_lwp_slwpcbsi);
20134   emit_insn (insn (operands[0]));
20135   DONE;
20138 (define_insn "lwp_slwpcb<mode>"
20139   [(set (match_operand:P 0 "register_operand" "=r")
20140         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20141   "TARGET_LWP"
20142   "slwpcb\t%0"
20143   [(set_attr "type" "lwp")
20144    (set_attr "mode" "<MODE>")
20145    (set_attr "length" "5")])
20147 (define_expand "lwp_lwpval<mode>3"
20148   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20149                      (match_operand:SI 2 "nonimmediate_operand")
20150                      (match_operand:SI 3 "const_int_operand")]
20151                     UNSPECV_LWPVAL_INTRINSIC)]
20152   "TARGET_LWP"
20153   ;; Avoid unused variable warning.
20154   "(void) operands[0];")
20156 (define_insn "*lwp_lwpval<mode>3_1"
20157   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20158                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20159                      (match_operand:SI 2 "const_int_operand" "i")]
20160                     UNSPECV_LWPVAL_INTRINSIC)]
20161   "TARGET_LWP"
20162   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20163   [(set_attr "type" "lwp")
20164    (set_attr "mode" "<MODE>")
20165    (set (attr "length")
20166         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20168 (define_expand "lwp_lwpins<mode>3"
20169   [(set (reg:CCC FLAGS_REG)
20170         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20171                               (match_operand:SI 2 "nonimmediate_operand")
20172                               (match_operand:SI 3 "const_int_operand")]
20173                              UNSPECV_LWPINS_INTRINSIC))
20174    (set (match_operand:QI 0 "nonimmediate_operand")
20175         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20176   "TARGET_LWP")
20178 (define_insn "*lwp_lwpins<mode>3_1"
20179   [(set (reg:CCC FLAGS_REG)
20180         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20181                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20182                               (match_operand:SI 2 "const_int_operand" "i")]
20183                              UNSPECV_LWPINS_INTRINSIC))]
20184   "TARGET_LWP"
20185   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20186   [(set_attr "type" "lwp")
20187    (set_attr "mode" "<MODE>")
20188    (set (attr "length")
20189         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20191 (define_int_iterator RDFSGSBASE
20192         [UNSPECV_RDFSBASE
20193          UNSPECV_RDGSBASE])
20195 (define_int_iterator WRFSGSBASE
20196         [UNSPECV_WRFSBASE
20197          UNSPECV_WRGSBASE])
20199 (define_int_attr fsgs
20200         [(UNSPECV_RDFSBASE "fs")
20201          (UNSPECV_RDGSBASE "gs")
20202          (UNSPECV_WRFSBASE "fs")
20203          (UNSPECV_WRGSBASE "gs")])
20205 (define_insn "rd<fsgs>base<mode>"
20206   [(set (match_operand:SWI48 0 "register_operand" "=r")
20207         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20208   "TARGET_64BIT && TARGET_FSGSBASE"
20209   "rd<fsgs>base\t%0"
20210   [(set_attr "type" "other")
20211    (set_attr "prefix_extra" "2")])
20213 (define_insn "wr<fsgs>base<mode>"
20214   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20215                     WRFSGSBASE)]
20216   "TARGET_64BIT && TARGET_FSGSBASE"
20217   "wr<fsgs>base\t%0"
20218   [(set_attr "type" "other")
20219    (set_attr "prefix_extra" "2")])
20221 (define_insn "rdrand<mode>_1"
20222   [(set (match_operand:SWI248 0 "register_operand" "=r")
20223         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20224    (set (reg:CCC FLAGS_REG)
20225         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20226   "TARGET_RDRND"
20227   "rdrand\t%0"
20228   [(set_attr "type" "other")
20229    (set_attr "prefix_extra" "1")])
20231 (define_insn "rdseed<mode>_1"
20232   [(set (match_operand:SWI248 0 "register_operand" "=r")
20233         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20234    (set (reg:CCC FLAGS_REG)
20235         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20236   "TARGET_RDSEED"
20237   "rdseed\t%0"
20238   [(set_attr "type" "other")
20239    (set_attr "prefix_extra" "1")])
20241 (define_expand "pause"
20242   [(set (match_dup 0)
20243         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20244   ""
20246   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20247   MEM_VOLATILE_P (operands[0]) = 1;
20250 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20251 ;; They have the same encoding.
20252 (define_insn "*pause"
20253   [(set (match_operand:BLK 0)
20254         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20255   ""
20256   "rep%; nop"
20257   [(set_attr "length" "2")
20258    (set_attr "memory" "unknown")])
20260 ;; CET instructions
20261 (define_insn "rdssp<mode>"
20262   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20263         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20264   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20265   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20266   [(set_attr "length" "6")
20267    (set_attr "type" "other")])
20269 (define_insn "incssp<mode>"
20270   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20271                    UNSPECV_INCSSP)]
20272   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20273   "incssp<mskmodesuffix>\t%0"
20274   [(set_attr "length" "4")
20275    (set_attr "type" "other")])
20277 (define_insn "saveprevssp"
20278   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20279   "TARGET_SHSTK"
20280   "saveprevssp"
20281   [(set_attr "length" "5")
20282    (set_attr "type" "other")])
20284 (define_insn "rstorssp"
20285   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20286                    UNSPECV_RSTORSSP)]
20287   "TARGET_SHSTK"
20288   "rstorssp\t%0"
20289   [(set_attr "length" "5")
20290    (set_attr "type" "other")])
20292 (define_insn "wrss<mode>"
20293   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20294                      (match_operand:SWI48x 1 "memory_operand" "m")]
20295                    UNSPECV_WRSS)]
20296   "TARGET_SHSTK"
20297   "wrss<mskmodesuffix>\t%0, %1"
20298   [(set_attr "length" "3")
20299    (set_attr "type" "other")])
20301 (define_insn "wruss<mode>"
20302   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20303                      (match_operand:SWI48x 1 "memory_operand" "m")]
20304                    UNSPECV_WRUSS)]
20305   "TARGET_SHSTK"
20306   "wruss<mskmodesuffix>\t%0, %1"
20307   [(set_attr "length" "4")
20308    (set_attr "type" "other")])
20310 (define_insn "setssbsy"
20311   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20312   "TARGET_SHSTK"
20313   "setssbsy"
20314   [(set_attr "length" "4")
20315    (set_attr "type" "other")])
20317 (define_insn "clrssbsy"
20318   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20319                    UNSPECV_CLRSSBSY)]
20320   "TARGET_SHSTK"
20321   "clrssbsy\t%0"
20322   [(set_attr "length" "4")
20323    (set_attr "type" "other")])
20325 (define_insn "nop_endbr"
20326   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20327   "(flag_cf_protection & CF_BRANCH)"
20328   "*
20329 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20330   [(set_attr "length" "4")
20331    (set_attr "length_immediate" "0")
20332    (set_attr "modrm" "0")])
20334 ;; For RTM support
20335 (define_expand "xbegin"
20336   [(set (match_operand:SI 0 "register_operand")
20337         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20338   "TARGET_RTM"
20340   rtx_code_label *label = gen_label_rtx ();
20342   /* xbegin is emitted as jump_insn, so reload won't be able
20343      to reload its operand.  Force the value into AX hard register.  */
20344   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20345   emit_move_insn (ax_reg, constm1_rtx);
20347   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20349   emit_label (label);
20350   LABEL_NUSES (label) = 1;
20352   emit_move_insn (operands[0], ax_reg);
20354   DONE;
20357 (define_insn "xbegin_1"
20358   [(set (pc)
20359         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20360                           (const_int 0))
20361                       (label_ref (match_operand 1))
20362                       (pc)))
20363    (set (match_operand:SI 0 "register_operand" "+a")
20364         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20365   "TARGET_RTM"
20366   "xbegin\t%l1"
20367   [(set_attr "type" "other")
20368    (set_attr "length" "6")])
20370 (define_insn "xend"
20371   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20372   "TARGET_RTM"
20373   "xend"
20374   [(set_attr "type" "other")
20375    (set_attr "length" "3")])
20377 (define_insn "xabort"
20378   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20379                     UNSPECV_XABORT)]
20380   "TARGET_RTM"
20381   "xabort\t%0"
20382   [(set_attr "type" "other")
20383    (set_attr "length" "3")])
20385 (define_expand "xtest"
20386   [(set (match_operand:QI 0 "register_operand")
20387         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20388   "TARGET_RTM"
20390   emit_insn (gen_xtest_1 ());
20392   ix86_expand_setcc (operands[0], NE,
20393                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20394   DONE;
20397 (define_insn "xtest_1"
20398   [(set (reg:CCZ FLAGS_REG)
20399         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20400   "TARGET_RTM"
20401   "xtest"
20402   [(set_attr "type" "other")
20403    (set_attr "length" "3")])
20405 (define_insn "clwb"
20406   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20407                    UNSPECV_CLWB)]
20408   "TARGET_CLWB"
20409   "clwb\t%a0"
20410   [(set_attr "type" "sse")
20411    (set_attr "atom_sse_attr" "fence")
20412    (set_attr "memory" "unknown")])
20414 (define_insn "clflushopt"
20415   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20416                    UNSPECV_CLFLUSHOPT)]
20417   "TARGET_CLFLUSHOPT"
20418   "clflushopt\t%a0"
20419   [(set_attr "type" "sse")
20420    (set_attr "atom_sse_attr" "fence")
20421    (set_attr "memory" "unknown")])
20423 ;; MONITORX and MWAITX
20424 (define_insn "mwaitx"
20425   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20426                      (match_operand:SI 1 "register_operand" "a")
20427                      (match_operand:SI 2 "register_operand" "b")]
20428                    UNSPECV_MWAITX)]
20429   "TARGET_MWAITX"
20430 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20431 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20432 ;; we only need to set up 32bit registers.
20433   "mwaitx"
20434   [(set_attr "length" "3")])
20436 (define_insn "monitorx_<mode>"
20437   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20438                      (match_operand:SI 1 "register_operand" "c")
20439                      (match_operand:SI 2 "register_operand" "d")]
20440                    UNSPECV_MONITORX)]
20441   "TARGET_MWAITX"
20442 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20443 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20444 ;; zero extended to 64bit, we only need to set up 32bit registers.
20445   "%^monitorx"
20446   [(set (attr "length")
20447      (symbol_ref ("(Pmode != word_mode) + 3")))])
20449 ;; CLZERO
20450 (define_insn "clzero_<mode>"
20451   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20452                    UNSPECV_CLZERO)]
20453   "TARGET_CLZERO"
20454   "clzero"
20455   [(set_attr "length" "3")
20456   (set_attr "memory" "unknown")])
20458 ;; MPX instructions
20460 (define_expand "<mode>_mk"
20461   [(set (match_operand:BND 0 "register_operand")
20462         (unspec:BND
20463           [(mem:<bnd_ptr>
20464            (match_par_dup 3
20465              [(match_operand:<bnd_ptr> 1 "register_operand")
20466               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20467           UNSPEC_BNDMK))]
20468   "TARGET_MPX"
20470   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20471                                                   operands[2]),
20472                                 UNSPEC_BNDMK_ADDR);
20475 (define_insn "*<mode>_mk"
20476   [(set (match_operand:BND 0 "register_operand" "=w")
20477         (unspec:BND
20478           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20479              [(unspec:<bnd_ptr>
20480                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20481                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20482                 UNSPEC_BNDMK_ADDR)])]
20483           UNSPEC_BNDMK))]
20484   "TARGET_MPX"
20485   "bndmk\t{%3, %0|%0, %3}"
20486   [(set_attr "type" "mpxmk")])
20488 (define_expand "mov<mode>"
20489   [(set (match_operand:BND 0 "general_operand")
20490         (match_operand:BND 1 "general_operand"))]
20491   "TARGET_MPX"
20492   "ix86_expand_move (<MODE>mode, operands); DONE;")
20494 (define_insn "*mov<mode>_internal_mpx"
20495   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20496         (match_operand:BND 1 "general_operand" "wm,w"))]
20497   "TARGET_MPX"
20498   "bndmov\t{%1, %0|%0, %1}"
20499   [(set_attr "type" "mpxmov")])
20501 (define_expand "<mode>_<bndcheck>"
20502   [(parallel
20503      [(unspec
20504         [(match_operand:BND 0 "register_operand")
20505          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20506       (set (match_dup 2)
20507            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20508   "TARGET_MPX"
20510   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20511   MEM_VOLATILE_P (operands[2]) = 1;
20514 (define_insn "*<mode>_<bndcheck>"
20515   [(unspec
20516      [(match_operand:BND 0 "register_operand" "w")
20517       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20518    (set (match_operand:BLK 2 "bnd_mem_operator")
20519         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20520   "TARGET_MPX"
20521   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20522   [(set_attr "type" "mpxchk")])
20524 (define_expand "<mode>_ldx"
20525   [(parallel
20526      [(set (match_operand:BND 0 "register_operand")
20527            (unspec:BND
20528              [(mem:<bnd_ptr>
20529                 (match_par_dup 3
20530                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20531                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
20532              UNSPEC_BNDLDX))
20533       (use (mem:BLK (match_dup 1)))])]
20534   "TARGET_MPX"
20536   /* Avoid registers which cannot be used as index.  */
20537   if (!index_register_operand (operands[2], Pmode))
20538     operands[2] = copy_addr_to_reg (operands[2]);
20540   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20541                                                   operands[2]),
20542                                 UNSPEC_BNDLDX_ADDR);
20545 (define_insn "*<mode>_ldx"
20546   [(set (match_operand:BND 0 "register_operand" "=w")
20547         (unspec:BND
20548           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20549              [(unspec:<bnd_ptr>
20550                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20551                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20552                 UNSPEC_BNDLDX_ADDR)])]
20553           UNSPEC_BNDLDX))
20554    (use (mem:BLK (match_dup 1)))]
20555   "TARGET_MPX"
20556   "bndldx\t{%3, %0|%0, %3}"
20557   [(set_attr "type" "mpxld")])
20559 (define_expand "<mode>_stx"
20560   [(parallel
20561      [(unspec
20562         [(mem:<bnd_ptr>
20563            (match_par_dup 3
20564              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20565               (match_operand:<bnd_ptr> 1 "register_operand")]))
20566          (match_operand:BND 2 "register_operand")]
20567         UNSPEC_BNDSTX)
20568       (set (match_dup 4)
20569            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20570   "TARGET_MPX"
20572   /* Avoid registers which cannot be used as index.  */
20573   if (!index_register_operand (operands[1], Pmode))
20574     operands[1] = copy_addr_to_reg (operands[1]);
20576   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20577                                                   operands[1]),
20578                                 UNSPEC_BNDLDX_ADDR);
20579   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20580   MEM_VOLATILE_P (operands[4]) = 1;
20583 (define_insn "*<mode>_stx"
20584   [(unspec
20585      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20586         [(unspec:<bnd_ptr>
20587            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20588             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20589            UNSPEC_BNDLDX_ADDR)])
20590          (match_operand:BND 2 "register_operand" "w")]
20591         UNSPEC_BNDSTX)
20592    (set (match_operand:BLK 4 "bnd_mem_operator")
20593         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20594   "TARGET_MPX"
20595   "bndstx\t{%2, %3|%3, %2}"
20596   [(set_attr "type" "mpxst")])
20598 (define_insn "move_size_reloc_<mode>"
20599   [(set (match_operand:SWI48 0 "register_operand" "=r")
20600         (unspec:SWI48
20601           [(match_operand:SWI48 1 "symbol_operand")]
20602         UNSPEC_SIZEOF))]
20603   "TARGET_MPX"
20605   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20606     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20607   else
20608     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20610   [(set_attr "type" "imov")
20611    (set_attr "mode" "<MODE>")])
20613 ;; RDPKRU and WRPKRU
20615 (define_expand "rdpkru"
20616   [(parallel
20617      [(set (match_operand:SI 0 "register_operand")
20618            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20619       (set (match_dup 2) (const_int 0))])]
20620   "TARGET_PKU"
20622   operands[1] = force_reg (SImode, const0_rtx);
20623   operands[2] = gen_reg_rtx (SImode);
20626 (define_insn "*rdpkru"
20627   [(set (match_operand:SI 0 "register_operand" "=a")
20628         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20629                             UNSPECV_PKU))
20630    (set (match_operand:SI 1 "register_operand" "=d")
20631         (const_int 0))]
20632   "TARGET_PKU"
20633   "rdpkru"
20634   [(set_attr "type" "other")])
20636 (define_expand "wrpkru"
20637   [(unspec_volatile:SI
20638      [(match_operand:SI 0 "register_operand")
20639       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20640   "TARGET_PKU"
20642   operands[1] = force_reg (SImode, const0_rtx);
20643   operands[2] = force_reg (SImode, const0_rtx);
20646 (define_insn "*wrpkru"
20647   [(unspec_volatile:SI
20648      [(match_operand:SI 0 "register_operand" "a")
20649       (match_operand:SI 1 "register_operand" "d")
20650       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20651   "TARGET_PKU"
20652   "wrpkru"
20653   [(set_attr "type" "other")])
20655 (define_insn "rdpid"
20656   [(set (match_operand:SI 0 "register_operand" "=r")
20657         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20658   "!TARGET_64BIT && TARGET_RDPID"
20659   "rdpid\t%0"
20660   [(set_attr "type" "other")])
20662 (define_insn "rdpid_rex64"
20663   [(set (match_operand:DI 0 "register_operand" "=r")
20664         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20665   "TARGET_64BIT && TARGET_RDPID"
20666   "rdpid\t%0"
20667   [(set_attr "type" "other")])
20669 ;; Intirinsics for > i486
20671 (define_insn "wbinvd"
20672   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20673   ""
20674   "wbinvd"
20675   [(set_attr "type" "other")])
20677 (define_insn "wbnoinvd"
20678   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20679   "TARGET_WBNOINVD"
20680   "wbnoinvd"
20681   [(set_attr "type" "other")])
20683 (define_insn "movdiri<mode>"
20684   [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20685         (match_operand:SWI48 1 "register_operand" "r")]
20686                    UNSPECV_MOVDIRI)]
20687   "TARGET_MOVDIRI"
20688   "movdiri\t{%1, %0|%0, %1}"
20689   [(set_attr "type" "other")])
20691 (define_insn "movdir64b_<mode>"
20692   [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20693         (match_operand:XI 1 "memory_operand")]
20694                  UNSPECV_MOVDIR64B)]
20695   "TARGET_MOVDIR64B"
20696   "movdir64b\t{%1, %0|%0, %1}"
20697   [(set_attr "type" "other")])
20699 (include "mmx.md")
20700 (include "sse.md")
20701 (include "sync.md")