Add GCC support to ENQCMD.
[official-gcc.git] / gcc / config / i386 / i386.md
blob977fbc6e632b37493919a5a6d7497b611ec324c7
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2019 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 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_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
115   UNSPEC_SBB
117   ;; For SSE/MMX support:
118   UNSPEC_FIX_NOTRUNC
119   UNSPEC_MASKMOV
120   UNSPEC_MOVMSK
121   UNSPEC_RCP
122   UNSPEC_RSQRT
123   UNSPEC_PSADBW
125   ;; Generic math support
126   UNSPEC_COPYSIGN
127   UNSPEC_XORSIGN
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_FIST_FLOOR
148   UNSPEC_FIST_CEIL
150   ;; x87 Double output FP
151   UNSPEC_SINCOS_COS
152   UNSPEC_SINCOS_SIN
153   UNSPEC_XTRACT_FRACT
154   UNSPEC_XTRACT_EXP
155   UNSPEC_FSCALE_FRACT
156   UNSPEC_FSCALE_EXP
157   UNSPEC_FPREM_F
158   UNSPEC_FPREM_U
159   UNSPEC_FPREM1_F
160   UNSPEC_FPREM1_U
162   UNSPEC_C2_FLAG
163   UNSPEC_FXAM_MEM
165   ;; SSP patterns
166   UNSPEC_SP_SET
167   UNSPEC_SP_TEST
169   ;; For ROUND support
170   UNSPEC_ROUND
172   ;; For CRC32 support
173   UNSPEC_CRC32
175   ;; For LZCNT suppoprt
176   UNSPEC_LZCNT
178   ;; For BMI support
179   UNSPEC_TZCNT
180   UNSPEC_BEXTR
182   ;; For BMI2 support
183   UNSPEC_PDEP
184   UNSPEC_PEXT
186   ;; IRET support
187   UNSPEC_INTERRUPT_RETURN
190 (define_c_enum "unspecv" [
191   UNSPECV_UD2
192   UNSPECV_BLOCKAGE
193   UNSPECV_STACK_PROBE
194   UNSPECV_PROBE_STACK_RANGE
195   UNSPECV_ALIGN
196   UNSPECV_PROLOGUE_USE
197   UNSPECV_SPLIT_STACK_RETURN
198   UNSPECV_CLD
199   UNSPECV_NOPS
200   UNSPECV_RDTSC
201   UNSPECV_RDTSCP
202   UNSPECV_RDPMC
203   UNSPECV_LLWP_INTRINSIC
204   UNSPECV_SLWP_INTRINSIC
205   UNSPECV_LWPVAL_INTRINSIC
206   UNSPECV_LWPINS_INTRINSIC
207   UNSPECV_RDFSBASE
208   UNSPECV_RDGSBASE
209   UNSPECV_WRFSBASE
210   UNSPECV_WRGSBASE
211   UNSPECV_FXSAVE
212   UNSPECV_FXRSTOR
213   UNSPECV_FXSAVE64
214   UNSPECV_FXRSTOR64
215   UNSPECV_XSAVE
216   UNSPECV_XRSTOR
217   UNSPECV_XSAVE64
218   UNSPECV_XRSTOR64
219   UNSPECV_XSAVEOPT
220   UNSPECV_XSAVEOPT64
221   UNSPECV_XSAVES
222   UNSPECV_XRSTORS
223   UNSPECV_XSAVES64
224   UNSPECV_XRSTORS64
225   UNSPECV_XSAVEC
226   UNSPECV_XSAVEC64
227   UNSPECV_XGETBV
228   UNSPECV_XSETBV
229   UNSPECV_WBINVD
230   UNSPECV_WBNOINVD
232   ;; For atomic compound assignments.
233   UNSPECV_FNSTENV
234   UNSPECV_FLDENV
235   UNSPECV_FNSTSW
236   UNSPECV_FNCLEX
238   ;; For RDRAND support
239   UNSPECV_RDRAND
241   ;; For RDSEED support
242   UNSPECV_RDSEED
244   ;; For RTM support
245   UNSPECV_XBEGIN
246   UNSPECV_XEND
247   UNSPECV_XABORT
248   UNSPECV_XTEST
250   UNSPECV_NLGR
252   ;; For CLWB support
253   UNSPECV_CLWB
255   ;; For CLFLUSHOPT support
256   UNSPECV_CLFLUSHOPT
258   ;; For MONITORX and MWAITX support 
259   UNSPECV_MONITORX
260   UNSPECV_MWAITX
262   ;; For CLZERO support
263   UNSPECV_CLZERO
265   ;; For RDPKRU and WRPKRU support
266   UNSPECV_PKU
268   ;; For RDPID support
269   UNSPECV_RDPID
271   ;; For CET support
272   UNSPECV_NOP_ENDBR
273   UNSPECV_NOP_RDSSP
274   UNSPECV_INCSSP
275   UNSPECV_SAVEPREVSSP
276   UNSPECV_RSTORSSP
277   UNSPECV_WRSS
278   UNSPECV_WRUSS
279   UNSPECV_SETSSBSY
280   UNSPECV_CLRSSBSY
282   ;; For MOVDIRI and MOVDIR64B support
283   UNSPECV_MOVDIRI
284   UNSPECV_MOVDIR64B
286   ;; For WAITPKG support
287   UNSPECV_UMWAIT
288   UNSPECV_UMONITOR
289   UNSPECV_TPAUSE
291   ;; For CLDEMOTE support
292   UNSPECV_CLDEMOTE
294   ;; For Speculation Barrier support
295   UNSPECV_SPECULATION_BARRIER
297   UNSPECV_PTWRITE
299   ;; For ENQCMD and ENQCMDS support
300   UNSPECV_ENQCMD
301   UNSPECV_ENQCMDS
304 ;; Constants to represent rounding modes in the ROUND instruction
305 (define_constants
306   [(ROUND_FLOOR                 0x1)
307    (ROUND_CEIL                  0x2)
308    (ROUND_TRUNC                 0x3)
309    (ROUND_MXCSR                 0x4)
310    (ROUND_NO_EXC                0x8)
311   ])
313 ;; Constants to represent AVX512F embeded rounding
314 (define_constants
315   [(ROUND_NEAREST_INT                   0)
316    (ROUND_NEG_INF                       1)
317    (ROUND_POS_INF                       2)
318    (ROUND_ZERO                          3)
319    (NO_ROUND                            4)
320    (ROUND_SAE                           8)
321   ])
323 ;; Constants to represent pcomtrue/pcomfalse variants
324 (define_constants
325   [(PCOM_FALSE                  0)
326    (PCOM_TRUE                   1)
327    (COM_FALSE_S                 2)
328    (COM_FALSE_P                 3)
329    (COM_TRUE_S                  4)
330    (COM_TRUE_P                  5)
331   ])
333 ;; Constants used in the XOP pperm instruction
334 (define_constants
335   [(PPERM_SRC                   0x00)   /* copy source */
336    (PPERM_INVERT                0x20)   /* invert source */
337    (PPERM_REVERSE               0x40)   /* bit reverse source */
338    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
339    (PPERM_ZERO                  0x80)   /* all 0's */
340    (PPERM_ONES                  0xa0)   /* all 1's */
341    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
342    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
343    (PPERM_SRC1                  0x00)   /* use first source byte */
344    (PPERM_SRC2                  0x10)   /* use second source byte */
345    ])
347 ;; Registers by name.
348 (define_constants
349   [(AX_REG                       0)
350    (DX_REG                       1)
351    (CX_REG                       2)
352    (BX_REG                       3)
353    (SI_REG                       4)
354    (DI_REG                       5)
355    (BP_REG                       6)
356    (SP_REG                       7)
357    (ST0_REG                      8)
358    (ST1_REG                      9)
359    (ST2_REG                     10)
360    (ST3_REG                     11)
361    (ST4_REG                     12)
362    (ST5_REG                     13)
363    (ST6_REG                     14)
364    (ST7_REG                     15)
365    (ARGP_REG                    16)
366    (FLAGS_REG                   17)
367    (FPSR_REG                    18)
368    (FRAME_REG                   19)
369    (XMM0_REG                    20)
370    (XMM1_REG                    21)
371    (XMM2_REG                    22)
372    (XMM3_REG                    23)
373    (XMM4_REG                    24)
374    (XMM5_REG                    25)
375    (XMM6_REG                    26)
376    (XMM7_REG                    27)
377    (MM0_REG                     28)
378    (MM1_REG                     29)
379    (MM2_REG                     30)
380    (MM3_REG                     31)
381    (MM4_REG                     32)
382    (MM5_REG                     33)
383    (MM6_REG                     34)
384    (MM7_REG                     35)
385    (R8_REG                      36)
386    (R9_REG                      37)
387    (R10_REG                     38)
388    (R11_REG                     39)
389    (R12_REG                     40)
390    (R13_REG                     41)
391    (R14_REG                     42)
392    (R15_REG                     43)
393    (XMM8_REG                    44)
394    (XMM9_REG                    45)
395    (XMM10_REG                   46)
396    (XMM11_REG                   47)
397    (XMM12_REG                   48)
398    (XMM13_REG                   49)
399    (XMM14_REG                   50)
400    (XMM15_REG                   51)
401    (XMM16_REG                   52)
402    (XMM17_REG                   53)
403    (XMM18_REG                   54)
404    (XMM19_REG                   55)
405    (XMM20_REG                   56)
406    (XMM21_REG                   57)
407    (XMM22_REG                   58)
408    (XMM23_REG                   59)
409    (XMM24_REG                   60)
410    (XMM25_REG                   61)
411    (XMM26_REG                   62)
412    (XMM27_REG                   63)
413    (XMM28_REG                   64)
414    (XMM29_REG                   65)
415    (XMM30_REG                   66)
416    (XMM31_REG                   67)
417    (MASK0_REG                   68)
418    (MASK1_REG                   69)
419    (MASK2_REG                   70)
420    (MASK3_REG                   71)
421    (MASK4_REG                   72)
422    (MASK5_REG                   73)
423    (MASK6_REG                   74)
424    (MASK7_REG                   75)
425    (FIRST_PSEUDO_REG            76)
426   ])
428 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
429 ;; from i386.c.
431 ;; In C guard expressions, put expressions which may be compile-time
432 ;; constants first.  This allows for better optimization.  For
433 ;; example, write "TARGET_64BIT && reload_completed", not
434 ;; "reload_completed && TARGET_64BIT".
437 ;; Processor type.
438 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
439                     atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
440                     bdver4,btver2,znver1,znver2"
441   (const (symbol_ref "ix86_schedule")))
443 ;; A basic instruction type.  Refinements due to arguments to be
444 ;; provided in other attributes.
445 (define_attr "type"
446   "other,multi,
447    alu,alu1,negnot,imov,imovx,lea,
448    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
449    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
450    push,pop,call,callv,leave,
451    str,bitmanip,
452    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453    fxch,fistp,fisttp,frndint,
454    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
455    ssemul,sseimul,ssediv,sselog,sselog1,
456    sseishft,sseishft1,ssecmp,ssecomi,
457    ssecvt,ssecvt1,sseicvt,sseins,
458    sseshuf,sseshuf1,ssemuladd,sse4arg,
459    lwp,mskmov,msklog,
460    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
461   (const_string "other"))
463 ;; Main data type used by the insn
464 (define_attr "mode"
465   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
466   V2DF,V2SF,V1DF,V8DF"
467   (const_string "unknown"))
469 ;; The CPU unit operations uses.
470 (define_attr "unit" "integer,i387,sse,mmx,unknown"
471   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
472                           fxch,fistp,fisttp,frndint")
473            (const_string "i387")
474          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
475                           ssemul,sseimul,ssediv,sselog,sselog1,
476                           sseishft,sseishft1,ssecmp,ssecomi,
477                           ssecvt,ssecvt1,sseicvt,sseins,
478                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
479            (const_string "sse")
480          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
481            (const_string "mmx")
482          (eq_attr "type" "other")
483            (const_string "unknown")]
484          (const_string "integer")))
486 ;; The (bounding maximum) length of an instruction immediate.
487 (define_attr "length_immediate" ""
488   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
489                           bitmanip,imulx,msklog,mskmov")
490            (const_int 0)
491          (eq_attr "unit" "i387,sse,mmx")
492            (const_int 0)
493          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
494                           rotate,rotatex,rotate1,imul,icmp,push,pop")
495            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
496          (eq_attr "type" "imov,test")
497            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
498          (eq_attr "type" "call")
499            (if_then_else (match_operand 0 "constant_call_address_operand")
500              (const_int 4)
501              (const_int 0))
502          (eq_attr "type" "callv")
503            (if_then_else (match_operand 1 "constant_call_address_operand")
504              (const_int 4)
505              (const_int 0))
506          ;; We don't know the size before shorten_branches.  Expect
507          ;; the instruction to fit for better scheduling.
508          (eq_attr "type" "ibr")
509            (const_int 1)
510          ]
511          (symbol_ref "/* Update immediate_length and other attributes! */
512                       gcc_unreachable (),1")))
514 ;; The (bounding maximum) length of an instruction address.
515 (define_attr "length_address" ""
516   (cond [(eq_attr "type" "str,other,multi,fxch")
517            (const_int 0)
518          (and (eq_attr "type" "call")
519               (match_operand 0 "constant_call_address_operand"))
520              (const_int 0)
521          (and (eq_attr "type" "callv")
522               (match_operand 1 "constant_call_address_operand"))
523              (const_int 0)
524          ]
525          (symbol_ref "ix86_attr_length_address_default (insn)")))
527 ;; Set when length prefix is used.
528 (define_attr "prefix_data16" ""
529   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
530            (const_int 0)
531          (eq_attr "mode" "HI")
532            (const_int 1)
533          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
534            (const_int 1)
535         ]
536         (const_int 0)))
538 ;; Set when string REP prefix is used.
539 (define_attr "prefix_rep" ""
540   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
541            (const_int 0)
542          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
543            (const_int 1)
544         ]
545         (const_int 0)))
547 ;; Set when 0f opcode prefix is used.
548 (define_attr "prefix_0f" ""
549   (if_then_else
550     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
551          (eq_attr "unit" "sse,mmx"))
552     (const_int 1)
553     (const_int 0)))
555 ;; Set when REX opcode prefix is used.
556 (define_attr "prefix_rex" ""
557   (cond [(not (match_test "TARGET_64BIT"))
558            (const_int 0)
559          (and (eq_attr "mode" "DI")
560               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
561                    (eq_attr "unit" "!mmx")))
562            (const_int 1)
563          (and (eq_attr "mode" "QI")
564               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
565            (const_int 1)
566          (match_test "x86_extended_reg_mentioned_p (insn)")
567            (const_int 1)
568          (and (eq_attr "type" "imovx")
569               (match_operand:QI 1 "ext_QIreg_operand"))
570            (const_int 1)
571         ]
572         (const_int 0)))
574 ;; There are also additional prefixes in 3DNOW, SSSE3.
575 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
576 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
577 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
578 (define_attr "prefix_extra" ""
579   (cond [(eq_attr "type" "ssemuladd,sse4arg")
580            (const_int 2)
581          (eq_attr "type" "sseiadd1,ssecvt1")
582            (const_int 1)
583         ]
584         (const_int 0)))
586 ;; Prefix used: original, VEX or maybe VEX.
587 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
588   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
589            (const_string "vex")
590          (eq_attr "mode" "XI,V16SF,V8DF")
591            (const_string "evex")
592         ]
593         (const_string "orig")))
595 ;; VEX W bit is used.
596 (define_attr "prefix_vex_w" "" (const_int 0))
598 ;; The length of VEX prefix
599 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
600 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
601 ;; still prefix_0f 1, with prefix_extra 1.
602 (define_attr "length_vex" ""
603   (if_then_else (and (eq_attr "prefix_0f" "1")
604                      (eq_attr "prefix_extra" "0"))
605     (if_then_else (eq_attr "prefix_vex_w" "1")
606       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
607       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
608     (if_then_else (eq_attr "prefix_vex_w" "1")
609       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
610       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
612 ;; 4-bytes evex prefix and 1 byte opcode.
613 (define_attr "length_evex" "" (const_int 5))
615 ;; Set when modrm byte is used.
616 (define_attr "modrm" ""
617   (cond [(eq_attr "type" "str,leave")
618            (const_int 0)
619          (eq_attr "unit" "i387")
620            (const_int 0)
621          (and (eq_attr "type" "incdec")
622               (and (not (match_test "TARGET_64BIT"))
623                    (ior (match_operand:SI 1 "register_operand")
624                         (match_operand:HI 1 "register_operand"))))
625            (const_int 0)
626          (and (eq_attr "type" "push")
627               (not (match_operand 1 "memory_operand")))
628            (const_int 0)
629          (and (eq_attr "type" "pop")
630               (not (match_operand 0 "memory_operand")))
631            (const_int 0)
632          (and (eq_attr "type" "imov")
633               (and (not (eq_attr "mode" "DI"))
634                    (ior (and (match_operand 0 "register_operand")
635                              (match_operand 1 "immediate_operand"))
636                         (ior (and (match_operand 0 "ax_reg_operand")
637                                   (match_operand 1 "memory_displacement_only_operand"))
638                              (and (match_operand 0 "memory_displacement_only_operand")
639                                   (match_operand 1 "ax_reg_operand"))))))
640            (const_int 0)
641          (and (eq_attr "type" "call")
642               (match_operand 0 "constant_call_address_operand"))
643              (const_int 0)
644          (and (eq_attr "type" "callv")
645               (match_operand 1 "constant_call_address_operand"))
646              (const_int 0)
647          (and (eq_attr "type" "alu,alu1,icmp,test")
648               (match_operand 0 "ax_reg_operand"))
649              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
650          ]
651          (const_int 1)))
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
656 ;; other insns.
657 (define_attr "length" ""
658   (cond [(eq_attr "type" "other,multi,fistp,frndint")
659            (const_int 16)
660          (eq_attr "type" "fcmp")
661            (const_int 4)
662          (eq_attr "unit" "i387")
663            (plus (const_int 2)
664                  (plus (attr "prefix_data16")
665                        (attr "length_address")))
666          (ior (eq_attr "prefix" "evex")
667               (and (ior (eq_attr "prefix" "maybe_evex")
668                         (eq_attr "prefix" "maybe_vex"))
669                    (match_test "TARGET_AVX512F")))
670            (plus (attr "length_evex")
671                  (plus (attr "length_immediate")
672                        (plus (attr "modrm")
673                              (attr "length_address"))))
674          (ior (eq_attr "prefix" "vex")
675               (and (ior (eq_attr "prefix" "maybe_vex")
676                         (eq_attr "prefix" "maybe_evex"))
677                    (match_test "TARGET_AVX")))
678            (plus (attr "length_vex")
679                  (plus (attr "length_immediate")
680                        (plus (attr "modrm")
681                              (attr "length_address"))))]
682          (plus (plus (attr "modrm")
683                      (plus (attr "prefix_0f")
684                            (plus (attr "prefix_rex")
685                                  (plus (attr "prefix_extra")
686                                        (const_int 1)))))
687                (plus (attr "prefix_rep")
688                      (plus (attr "prefix_data16")
689                            (plus (attr "length_immediate")
690                                  (attr "length_address")))))))
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
696 (define_attr "memory" "none,load,store,both,unknown"
697   (cond [(eq_attr "type" "other,multi,str,lwp")
698            (const_string "unknown")
699          (eq_attr "type" "lea,fcmov,fpspc")
700            (const_string "none")
701          (eq_attr "type" "fistp,leave")
702            (const_string "both")
703          (eq_attr "type" "frndint")
704            (const_string "load")
705          (eq_attr "type" "push")
706            (if_then_else (match_operand 1 "memory_operand")
707              (const_string "both")
708              (const_string "store"))
709          (eq_attr "type" "pop")
710            (if_then_else (match_operand 0 "memory_operand")
711              (const_string "both")
712              (const_string "load"))
713          (eq_attr "type" "setcc")
714            (if_then_else (match_operand 0 "memory_operand")
715              (const_string "store")
716              (const_string "none"))
717          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
718            (if_then_else (ior (match_operand 0 "memory_operand")
719                               (match_operand 1 "memory_operand"))
720              (const_string "load")
721              (const_string "none"))
722          (eq_attr "type" "ibr")
723            (if_then_else (match_operand 0 "memory_operand")
724              (const_string "load")
725              (const_string "none"))
726          (eq_attr "type" "call")
727            (if_then_else (match_operand 0 "constant_call_address_operand")
728              (const_string "none")
729              (const_string "load"))
730          (eq_attr "type" "callv")
731            (if_then_else (match_operand 1 "constant_call_address_operand")
732              (const_string "none")
733              (const_string "load"))
734          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
735               (match_operand 1 "memory_operand"))
736            (const_string "both")
737          (and (match_operand 0 "memory_operand")
738               (match_operand 1 "memory_operand"))
739            (const_string "both")
740          (match_operand 0 "memory_operand")
741            (const_string "store")
742          (match_operand 1 "memory_operand")
743            (const_string "load")
744          (and (eq_attr "type"
745                  "!alu1,negnot,ishift1,rotate1,
746                    imov,imovx,icmp,test,bitmanip,
747                    fmov,fcmp,fsgn,
748                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
749                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
750                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
751               (match_operand 2 "memory_operand"))
752            (const_string "load")
753          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
754               (match_operand 3 "memory_operand"))
755            (const_string "load")
756         ]
757         (const_string "none")))
759 ;; Indicates if an instruction has both an immediate and a displacement.
761 (define_attr "imm_disp" "false,true,unknown"
762   (cond [(eq_attr "type" "other,multi")
763            (const_string "unknown")
764          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
765               (and (match_operand 0 "memory_displacement_operand")
766                    (match_operand 1 "immediate_operand")))
767            (const_string "true")
768          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
769               (and (match_operand 0 "memory_displacement_operand")
770                    (match_operand 2 "immediate_operand")))
771            (const_string "true")
772         ]
773         (const_string "false")))
775 ;; Indicates if an FP operation has an integer source.
777 (define_attr "fp_int_src" "false,true"
778   (const_string "false"))
780 ;; Defines rounding mode of an FP operation.
782 (define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
783   (const_string "any"))
785 ;; Define attribute to indicate AVX insns with partial XMM register update.
786 (define_attr "avx_partial_xmm_update" "false,true"
787   (const_string "false"))
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799                     avx512bw,noavx512bw,avx512dq,noavx512dq,
800                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
801   (const_string "base"))
803 ;; Define instruction set of MMX instructions
804 (define_attr "mmx_isa" "base,native,x64,x64_noavx,x64_avx"
805   (const_string "base"))
807 (define_attr "enabled" ""
808   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
809          (eq_attr "isa" "x64_sse2")
810            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
811          (eq_attr "isa" "x64_sse4")
812            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
813          (eq_attr "isa" "x64_sse4_noavx")
814            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
815          (eq_attr "isa" "x64_avx")
816            (symbol_ref "TARGET_64BIT && TARGET_AVX")
817          (eq_attr "isa" "x64_avx512dq")
818            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
819          (eq_attr "isa" "x64_avx512bw")
820            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
821          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
822          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
823          (eq_attr "isa" "sse2_noavx")
824            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
825          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
826          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
827          (eq_attr "isa" "sse4_noavx")
828            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
829          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
830          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
831          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
832          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
833          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
834          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
835          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
836          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
837          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
838          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
839          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
840          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
841          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
842          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
843          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
844          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
846          (eq_attr "mmx_isa" "native")
847            (symbol_ref "!TARGET_MMX_WITH_SSE")
848          (eq_attr "mmx_isa" "x64")
849            (symbol_ref "TARGET_MMX_WITH_SSE")
850          (eq_attr "mmx_isa" "x64_avx")
851            (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
852          (eq_attr "mmx_isa" "x64_noavx")
853            (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
854         ]
855         (const_int 1)))
857 (define_attr "preferred_for_size" "" (const_int 1))
858 (define_attr "preferred_for_speed" "" (const_int 1))
860 ;; Describe a user's asm statement.
861 (define_asm_attributes
862   [(set_attr "length" "128")
863    (set_attr "type" "multi")])
865 (define_code_iterator plusminus [plus minus])
867 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
869 (define_code_iterator multdiv [mult div])
871 ;; Base name for define_insn
872 (define_code_attr plusminus_insn
873   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
874    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
876 ;; Base name for insn mnemonic.
877 (define_code_attr plusminus_mnemonic
878   [(plus "add") (ss_plus "adds") (us_plus "addus")
879    (minus "sub") (ss_minus "subs") (us_minus "subus")])
880 (define_code_attr multdiv_mnemonic
881   [(mult "mul") (div "div")])
883 ;; Mark commutative operators as such in constraints.
884 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
885                         (minus "") (ss_minus "") (us_minus "")])
887 ;; Mapping of max and min
888 (define_code_iterator maxmin [smax smin umax umin])
890 ;; Mapping of signed max and min
891 (define_code_iterator smaxmin [smax smin])
893 ;; Mapping of unsigned max and min
894 (define_code_iterator umaxmin [umax umin])
896 ;; Base name for integer and FP insn mnemonic
897 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
898                               (umax "maxu") (umin "minu")])
899 (define_code_attr maxmin_float [(smax "max") (smin "min")])
901 (define_int_iterator IEEE_MAXMIN
902         [UNSPEC_IEEE_MAX
903          UNSPEC_IEEE_MIN])
905 (define_int_attr ieee_maxmin
906         [(UNSPEC_IEEE_MAX "max")
907          (UNSPEC_IEEE_MIN "min")])
909 ;; Mapping of logic operators
910 (define_code_iterator any_logic [and ior xor])
911 (define_code_iterator any_or [ior xor])
912 (define_code_iterator fpint_logic [and xor])
914 ;; Base name for insn mnemonic.
915 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
917 ;; Mapping of logic-shift operators
918 (define_code_iterator any_lshift [ashift lshiftrt])
920 ;; Mapping of shift-right operators
921 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
923 ;; Mapping of all shift operators
924 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
926 ;; Base name for define_insn
927 (define_code_attr shift_insn
928   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
930 ;; Base name for insn mnemonic.
931 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
932 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
934 ;; Mapping of rotate operators
935 (define_code_iterator any_rotate [rotate rotatert])
937 ;; Base name for define_insn
938 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
943 ;; Mapping of abs neg operators
944 (define_code_iterator absneg [abs neg])
946 ;; Base name for x87 insn mnemonic.
947 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
949 ;; Used in signed and unsigned widening multiplications.
950 (define_code_iterator any_extend [sign_extend zero_extend])
952 ;; Prefix for insn menmonic.
953 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
954                              (div "i") (udiv "")])
955 ;; Prefix for define_insn
956 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
957 (define_code_attr u [(sign_extend "") (zero_extend "u")
958                      (div "") (udiv "u")])
959 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
960                           (div "false") (udiv "true")])
962 ;; Used in signed and unsigned truncations.
963 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
964 ;; Instruction suffix for truncations.
965 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
967 ;; Used in signed and unsigned fix.
968 (define_code_iterator any_fix [fix unsigned_fix])
969 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
970 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
971 (define_code_attr fixprefix [(fix "s") (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")])
976 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
977 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
979 ;; All integer modes.
980 (define_mode_iterator SWI1248x [QI HI SI DI])
982 ;; All integer modes without QImode.
983 (define_mode_iterator SWI248x [HI SI DI])
985 ;; All integer modes without QImode and HImode.
986 (define_mode_iterator SWI48x [SI DI])
988 ;; All integer modes without SImode and DImode.
989 (define_mode_iterator SWI12 [QI HI])
991 ;; All integer modes without DImode.
992 (define_mode_iterator SWI124 [QI HI SI])
994 ;; All integer modes without QImode and DImode.
995 (define_mode_iterator SWI24 [HI SI])
997 ;; Single word integer modes.
998 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1000 ;; Single word integer modes without QImode.
1001 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1003 ;; Single word integer modes without QImode and HImode.
1004 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1006 ;; All math-dependant single and double word integer modes.
1007 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1008                              (HI "TARGET_HIMODE_MATH")
1009                              SI DI (TI "TARGET_64BIT")])
1011 ;; Math-dependant single word integer modes.
1012 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1013                             (HI "TARGET_HIMODE_MATH")
1014                             SI (DI "TARGET_64BIT")])
1016 ;; Math-dependant integer modes without DImode.
1017 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1018                                (HI "TARGET_HIMODE_MATH")
1019                                SI])
1021 ;; Math-dependant integer modes with DImode.
1022 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1023                                  (HI "TARGET_HIMODE_MATH")
1024                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1026 ;; Math-dependant single word integer modes without QImode.
1027 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1028                                SI (DI "TARGET_64BIT")])
1030 ;; Double word integer modes.
1031 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1032                            (TI "TARGET_64BIT")])
1034 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1035 ;; compile time constant, it is faster to use <MODE_SIZE> than
1036 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1037 ;; command line options just use GET_MODE_SIZE macro.
1038 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1039                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1040                              (V16QI "16") (V32QI "32") (V64QI "64")
1041                              (V8HI "16") (V16HI "32") (V32HI "64")
1042                              (V4SI "16") (V8SI "32") (V16SI "64")
1043                              (V2DI "16") (V4DI "32") (V8DI "64")
1044                              (V1TI "16") (V2TI "32") (V4TI "64")
1045                              (V2DF "16") (V4DF "32") (V8DF "64")
1046                              (V4SF "16") (V8SF "32") (V16SF "64")])
1048 ;; Double word integer modes as mode attribute.
1049 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1050 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1052 ;; LEA mode corresponding to an integer mode
1053 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1055 ;; Half mode for double word integer modes.
1056 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1057                             (DI "TARGET_64BIT")])
1059 ;; Instruction suffix for integer modes.
1060 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1062 ;; Instruction suffix for masks.
1063 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1065 ;; Pointer size prefix for integer modes (Intel asm dialect)
1066 (define_mode_attr iptrsize [(QI "BYTE")
1067                             (HI "WORD")
1068                             (SI "DWORD")
1069                             (DI "QWORD")])
1071 ;; Register class for integer modes.
1072 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1074 ;; Immediate operand constraint for integer modes.
1075 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1077 ;; General operand constraint for word modes.
1078 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1080 ;; Immediate operand constraint for double integer modes.
1081 (define_mode_attr di [(SI "nF") (DI "Wd")])
1083 ;; Immediate operand constraint for shifts.
1084 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1086 ;; Print register name in the specified mode.
1087 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1089 ;; General operand predicate for integer modes.
1090 (define_mode_attr general_operand
1091         [(QI "general_operand")
1092          (HI "general_operand")
1093          (SI "x86_64_general_operand")
1094          (DI "x86_64_general_operand")
1095          (TI "x86_64_general_operand")])
1097 ;; General operand predicate for integer modes, where for TImode
1098 ;; we need both words of the operand to be general operands.
1099 (define_mode_attr general_hilo_operand
1100         [(QI "general_operand")
1101          (HI "general_operand")
1102          (SI "x86_64_general_operand")
1103          (DI "x86_64_general_operand")
1104          (TI "x86_64_hilo_general_operand")])
1106 ;; General sign extend operand predicate for integer modes,
1107 ;; which disallows VOIDmode operands and thus it is suitable
1108 ;; for use inside sign_extend.
1109 (define_mode_attr general_sext_operand
1110         [(QI "sext_operand")
1111          (HI "sext_operand")
1112          (SI "x86_64_sext_operand")
1113          (DI "x86_64_sext_operand")])
1115 ;; General sign/zero extend operand predicate for integer modes.
1116 (define_mode_attr general_szext_operand
1117         [(QI "general_operand")
1118          (HI "general_operand")
1119          (SI "x86_64_szext_general_operand")
1120          (DI "x86_64_szext_general_operand")])
1122 ;; Immediate operand predicate for integer modes.
1123 (define_mode_attr immediate_operand
1124         [(QI "immediate_operand")
1125          (HI "immediate_operand")
1126          (SI "x86_64_immediate_operand")
1127          (DI "x86_64_immediate_operand")])
1129 ;; Nonmemory operand predicate for integer modes.
1130 (define_mode_attr nonmemory_operand
1131         [(QI "nonmemory_operand")
1132          (HI "nonmemory_operand")
1133          (SI "x86_64_nonmemory_operand")
1134          (DI "x86_64_nonmemory_operand")])
1136 ;; Operand predicate for shifts.
1137 (define_mode_attr shift_operand
1138         [(QI "nonimmediate_operand")
1139          (HI "nonimmediate_operand")
1140          (SI "nonimmediate_operand")
1141          (DI "shiftdi_operand")
1142          (TI "register_operand")])
1144 ;; Operand predicate for shift argument.
1145 (define_mode_attr shift_immediate_operand
1146         [(QI "const_1_to_31_operand")
1147          (HI "const_1_to_31_operand")
1148          (SI "const_1_to_31_operand")
1149          (DI "const_1_to_63_operand")])
1151 ;; Input operand predicate for arithmetic left shifts.
1152 (define_mode_attr ashl_input_operand
1153         [(QI "nonimmediate_operand")
1154          (HI "nonimmediate_operand")
1155          (SI "nonimmediate_operand")
1156          (DI "ashldi_input_operand")
1157          (TI "reg_or_pm1_operand")])
1159 ;; SSE and x87 SFmode and DFmode floating point modes
1160 (define_mode_iterator MODEF [SF DF])
1162 ;; All x87 floating point modes
1163 (define_mode_iterator X87MODEF [SF DF XF])
1165 ;; SSE instruction suffix for various modes
1166 (define_mode_attr ssemodesuffix
1167   [(SF "ss") (DF "sd")
1168    (V16SF "ps") (V8DF "pd")
1169    (V8SF "ps") (V4DF "pd")
1170    (V4SF "ps") (V2DF "pd")
1171    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1172    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1173    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1175 ;; SSE vector suffix for floating point modes
1176 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1178 ;; SSE vector mode corresponding to a scalar mode
1179 (define_mode_attr ssevecmode
1180   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1181 (define_mode_attr ssevecmodelower
1182   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1184 ;; AVX512F vector mode corresponding to a scalar mode
1185 (define_mode_attr avx512fvecmode
1186   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1188 ;; Instruction suffix for REX 64bit operators.
1189 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1190 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1192 ;; This mode iterator allows :P to be used for patterns that operate on
1193 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1194 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1196 ;; This mode iterator allows :W to be used for patterns that operate on
1197 ;; word_mode sized quantities.
1198 (define_mode_iterator W
1199   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1201 ;; This mode iterator allows :PTR to be used for patterns that operate on
1202 ;; ptr_mode sized quantities.
1203 (define_mode_iterator PTR
1204   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1206 ;; Scheduling descriptions
1208 (include "pentium.md")
1209 (include "ppro.md")
1210 (include "k6.md")
1211 (include "athlon.md")
1212 (include "bdver1.md")
1213 (include "bdver3.md")
1214 (include "btver2.md")
1215 (include "znver1.md")
1216 (include "geode.md")
1217 (include "atom.md")
1218 (include "slm.md")
1219 (include "glm.md")
1220 (include "core2.md")
1221 (include "haswell.md")
1224 ;; Operand and operator predicates and constraints
1226 (include "predicates.md")
1227 (include "constraints.md")
1230 ;; Compare and branch/compare and store instructions.
1232 (define_expand "cbranch<mode>4"
1233   [(set (reg:CC FLAGS_REG)
1234         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1235                     (match_operand:SDWIM 2 "<general_operand>")))
1236    (set (pc) (if_then_else
1237                (match_operator 0 "ordered_comparison_operator"
1238                 [(reg:CC FLAGS_REG) (const_int 0)])
1239                (label_ref (match_operand 3))
1240                (pc)))]
1241   ""
1243   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1244     operands[1] = force_reg (<MODE>mode, operands[1]);
1245   ix86_expand_branch (GET_CODE (operands[0]),
1246                       operands[1], operands[2], operands[3]);
1247   DONE;
1250 (define_expand "cstore<mode>4"
1251   [(set (reg:CC FLAGS_REG)
1252         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1253                     (match_operand:SWIM 3 "<general_operand>")))
1254    (set (match_operand:QI 0 "register_operand")
1255         (match_operator 1 "ordered_comparison_operator"
1256           [(reg:CC FLAGS_REG) (const_int 0)]))]
1257   ""
1259   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1260     operands[2] = force_reg (<MODE>mode, operands[2]);
1261   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1262                      operands[2], operands[3]);
1263   DONE;
1266 (define_expand "cmp<mode>_1"
1267   [(set (reg:CC FLAGS_REG)
1268         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1269                     (match_operand:SWI48 1 "<general_operand>")))])
1271 (define_mode_iterator SWI1248_AVX512BWDQ_64
1272   [(QI "TARGET_AVX512DQ") HI
1273    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1275 (define_insn "*cmp<mode>_ccz_1"
1276   [(set (reg FLAGS_REG)
1277         (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1278                         "nonimmediate_operand" "<r>,?m<r>,$k")
1279                  (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1280   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1281   "@
1282    test{<imodesuffix>}\t%0, %0
1283    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1284    kortest<mskmodesuffix>\t%0, %0"
1285   [(set_attr "type" "test,icmp,msklog")
1286    (set_attr "length_immediate" "0,1,*")
1287    (set_attr "prefix" "*,*,vex")
1288    (set_attr "mode" "<MODE>")])
1290 (define_insn "*cmp<mode>_ccno_1"
1291   [(set (reg FLAGS_REG)
1292         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1293                  (match_operand:SWI 1 "const0_operand")))]
1294   "ix86_match_ccmode (insn, CCNOmode)"
1295   "@
1296    test{<imodesuffix>}\t%0, %0
1297    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1298   [(set_attr "type" "test,icmp")
1299    (set_attr "length_immediate" "0,1")
1300    (set_attr "mode" "<MODE>")])
1302 (define_insn "*cmp<mode>_1"
1303   [(set (reg FLAGS_REG)
1304         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1305                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1306   "ix86_match_ccmode (insn, CCmode)"
1307   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1308   [(set_attr "type" "icmp")
1309    (set_attr "mode" "<MODE>")])
1311 (define_insn "*cmp<mode>_minus_1"
1312   [(set (reg FLAGS_REG)
1313         (compare
1314           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1315                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1316           (const_int 0)))]
1317   "ix86_match_ccmode (insn, CCGOCmode)"
1318   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1319   [(set_attr "type" "icmp")
1320    (set_attr "mode" "<MODE>")])
1322 (define_insn "*cmpqi_ext_1"
1323   [(set (reg FLAGS_REG)
1324         (compare
1325           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1326           (subreg:QI
1327             (zero_extract:SI
1328               (match_operand 1 "ext_register_operand" "Q,Q")
1329               (const_int 8)
1330               (const_int 8)) 0)))]
1331   "ix86_match_ccmode (insn, CCmode)"
1332   "cmp{b}\t{%h1, %0|%0, %h1}"
1333   [(set_attr "isa" "*,nox64")
1334    (set_attr "type" "icmp")
1335    (set_attr "mode" "QI")])
1337 (define_insn "*cmpqi_ext_2"
1338   [(set (reg FLAGS_REG)
1339         (compare
1340           (subreg:QI
1341             (zero_extract:SI
1342               (match_operand 0 "ext_register_operand" "Q")
1343               (const_int 8)
1344               (const_int 8)) 0)
1345           (match_operand:QI 1 "const0_operand")))]
1346   "ix86_match_ccmode (insn, CCNOmode)"
1347   "test{b}\t%h0, %h0"
1348   [(set_attr "type" "test")
1349    (set_attr "length_immediate" "0")
1350    (set_attr "mode" "QI")])
1352 (define_expand "cmpqi_ext_3"
1353   [(set (reg:CC FLAGS_REG)
1354         (compare:CC
1355           (subreg:QI
1356             (zero_extract:SI
1357               (match_operand 0 "ext_register_operand")
1358               (const_int 8)
1359               (const_int 8)) 0)
1360           (match_operand:QI 1 "const_int_operand")))])
1362 (define_insn "*cmpqi_ext_3"
1363   [(set (reg FLAGS_REG)
1364         (compare
1365           (subreg:QI
1366             (zero_extract:SI
1367               (match_operand 0 "ext_register_operand" "Q,Q")
1368               (const_int 8)
1369               (const_int 8)) 0)
1370           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1371   "ix86_match_ccmode (insn, CCmode)"
1372   "cmp{b}\t{%1, %h0|%h0, %1}"
1373   [(set_attr "isa" "*,nox64")
1374    (set_attr "type" "icmp")
1375    (set_attr "mode" "QI")])
1377 (define_insn "*cmpqi_ext_4"
1378   [(set (reg FLAGS_REG)
1379         (compare
1380           (subreg:QI
1381             (zero_extract:SI
1382               (match_operand 0 "ext_register_operand" "Q")
1383               (const_int 8)
1384               (const_int 8)) 0)
1385           (subreg:QI
1386             (zero_extract:SI
1387               (match_operand 1 "ext_register_operand" "Q")
1388               (const_int 8)
1389               (const_int 8)) 0)))]
1390   "ix86_match_ccmode (insn, CCmode)"
1391   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1392   [(set_attr "type" "icmp")
1393    (set_attr "mode" "QI")])
1395 ;; These implement float point compares.
1396 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1397 ;; which would allow mix and match FP modes on the compares.  Which is what
1398 ;; the old patterns did, but with many more of them.
1400 (define_expand "cbranchxf4"
1401   [(set (reg:CC FLAGS_REG)
1402         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1403                     (match_operand:XF 2 "nonmemory_operand")))
1404    (set (pc) (if_then_else
1405               (match_operator 0 "ix86_fp_comparison_operator"
1406                [(reg:CC FLAGS_REG)
1407                 (const_int 0)])
1408               (label_ref (match_operand 3))
1409               (pc)))]
1410   "TARGET_80387"
1412   ix86_expand_branch (GET_CODE (operands[0]),
1413                       operands[1], operands[2], operands[3]);
1414   DONE;
1417 (define_expand "cstorexf4"
1418   [(set (reg:CC FLAGS_REG)
1419         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1420                     (match_operand:XF 3 "nonmemory_operand")))
1421    (set (match_operand:QI 0 "register_operand")
1422               (match_operator 1 "ix86_fp_comparison_operator"
1423                [(reg:CC FLAGS_REG)
1424                 (const_int 0)]))]
1425   "TARGET_80387"
1427   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1428                      operands[2], operands[3]);
1429   DONE;
1432 (define_expand "cbranch<mode>4"
1433   [(set (reg:CC FLAGS_REG)
1434         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1435                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1436    (set (pc) (if_then_else
1437               (match_operator 0 "ix86_fp_comparison_operator"
1438                [(reg:CC FLAGS_REG)
1439                 (const_int 0)])
1440               (label_ref (match_operand 3))
1441               (pc)))]
1442   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1444   ix86_expand_branch (GET_CODE (operands[0]),
1445                       operands[1], operands[2], operands[3]);
1446   DONE;
1449 (define_expand "cstore<mode>4"
1450   [(set (reg:CC FLAGS_REG)
1451         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1452                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1453    (set (match_operand:QI 0 "register_operand")
1454               (match_operator 1 "ix86_fp_comparison_operator"
1455                [(reg:CC FLAGS_REG)
1456                 (const_int 0)]))]
1457   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1459   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1460                      operands[2], operands[3]);
1461   DONE;
1464 (define_expand "cbranchcc4"
1465   [(set (pc) (if_then_else
1466               (match_operator 0 "comparison_operator"
1467                [(match_operand 1 "flags_reg_operand")
1468                 (match_operand 2 "const0_operand")])
1469               (label_ref (match_operand 3))
1470               (pc)))]
1471   ""
1473   ix86_expand_branch (GET_CODE (operands[0]),
1474                       operands[1], operands[2], operands[3]);
1475   DONE;
1478 (define_expand "cstorecc4"
1479   [(set (match_operand:QI 0 "register_operand")
1480               (match_operator 1 "comparison_operator"
1481                [(match_operand 2 "flags_reg_operand")
1482                 (match_operand 3 "const0_operand")]))]
1483   ""
1485   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1486                      operands[2], operands[3]);
1487   DONE;
1490 ;; FP compares, step 1:
1491 ;; Set the FP condition codes and move fpsr to ax.
1493 ;; We may not use "#" to split and emit these
1494 ;; due to reg-stack pops killing fpsr.
1496 (define_insn "*cmpxf_i387"
1497   [(set (match_operand:HI 0 "register_operand" "=a")
1498         (unspec:HI
1499           [(compare:CCFP
1500              (match_operand:XF 1 "register_operand" "f")
1501              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1502           UNSPEC_FNSTSW))]
1503   "TARGET_80387"
1504   "* return output_fp_compare (insn, operands, false, false);"
1505   [(set_attr "type" "multi")
1506    (set_attr "unit" "i387")
1507    (set_attr "mode" "XF")])
1509 (define_insn "*cmp<mode>_i387"
1510   [(set (match_operand:HI 0 "register_operand" "=a")
1511         (unspec:HI
1512           [(compare:CCFP
1513              (match_operand:MODEF 1 "register_operand" "f")
1514              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1515           UNSPEC_FNSTSW))]
1516   "TARGET_80387"
1517   "* return output_fp_compare (insn, operands, false, false);"
1518   [(set_attr "type" "multi")
1519    (set_attr "unit" "i387")
1520    (set_attr "mode" "<MODE>")])
1522 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1523   [(set (match_operand:HI 0 "register_operand" "=a")
1524         (unspec:HI
1525           [(compare:CCFP
1526              (match_operand:X87MODEF 1 "register_operand" "f")
1527              (float:X87MODEF
1528                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1529           UNSPEC_FNSTSW))]
1530   "TARGET_80387
1531    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1532        || optimize_function_for_size_p (cfun))"
1533   "* return output_fp_compare (insn, operands, false, false);"
1534   [(set_attr "type" "multi")
1535    (set_attr "unit" "i387")
1536    (set_attr "fp_int_src" "true")
1537    (set_attr "mode" "<SWI24:MODE>")])
1539 (define_insn "*cmpu<mode>_i387"
1540   [(set (match_operand:HI 0 "register_operand" "=a")
1541         (unspec:HI
1542           [(unspec:CCFP
1543              [(compare:CCFP
1544                 (match_operand:X87MODEF 1 "register_operand" "f")
1545                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1546              UNSPEC_NOTRAP)]
1547           UNSPEC_FNSTSW))]
1548   "TARGET_80387"
1549   "* return output_fp_compare (insn, operands, false, true);"
1550   [(set_attr "type" "multi")
1551    (set_attr "unit" "i387")
1552    (set_attr "mode" "<MODE>")])
1554 ;; FP compares, step 2:
1555 ;; Get ax into flags, general case.
1557 (define_insn "x86_sahf_1"
1558   [(set (reg:CC FLAGS_REG)
1559         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1560                    UNSPEC_SAHF))]
1561   "TARGET_SAHF"
1563 #ifndef HAVE_AS_IX86_SAHF
1564   if (TARGET_64BIT)
1565     return ASM_BYTE "0x9e";
1566   else
1567 #endif
1568   return "sahf";
1570   [(set_attr "length" "1")
1571    (set_attr "athlon_decode" "vector")
1572    (set_attr "amdfam10_decode" "direct")
1573    (set_attr "bdver1_decode" "direct")
1574    (set_attr "mode" "SI")])
1576 ;; Pentium Pro can do both steps in one go.
1577 ;; (these instructions set flags directly)
1579 (define_subst_attr "unord" "unord_subst" "" "u")
1580 (define_subst_attr "unordered" "unord_subst" "false" "true")
1582 (define_subst "unord_subst"
1583   [(set (match_operand:CCFP 0)
1584         (match_operand:CCFP 1))]
1585   ""
1586   [(set (match_dup 0)
1587         (unspec:CCFP
1588           [(match_dup 1)]
1589           UNSPEC_NOTRAP))])
1591 (define_insn "*cmpi<unord>xf_i387"
1592   [(set (reg:CCFP FLAGS_REG)
1593         (compare:CCFP
1594           (match_operand:XF 0 "register_operand" "f")
1595           (match_operand:XF 1 "register_operand" "f")))]
1596   "TARGET_80387 && TARGET_CMOVE"
1597   "* return output_fp_compare (insn, operands, true, <unordered>);"
1598   [(set_attr "type" "fcmp")
1599    (set_attr "mode" "XF")
1600    (set_attr "athlon_decode" "vector")
1601    (set_attr "amdfam10_decode" "direct")
1602    (set_attr "bdver1_decode" "double")
1603    (set_attr "znver1_decode" "double")])
1605 (define_insn "*cmpi<unord><MODEF:mode>"
1606   [(set (reg:CCFP FLAGS_REG)
1607         (compare:CCFP
1608           (match_operand:MODEF 0 "register_operand" "f,v")
1609           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1610   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1611    || (TARGET_80387 && TARGET_CMOVE)"
1612   "@
1613    * return output_fp_compare (insn, operands, true, <unordered>);
1614    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1615   [(set_attr "type" "fcmp,ssecomi")
1616    (set_attr "prefix" "orig,maybe_vex")
1617    (set_attr "mode" "<MODEF:MODE>")
1618    (set_attr "prefix_rep" "*,0")
1619    (set (attr "prefix_data16")
1620         (cond [(eq_attr "alternative" "0")
1621                  (const_string "*")
1622                (eq_attr "mode" "DF")
1623                  (const_string "1")
1624               ]
1625               (const_string "0")))
1626    (set_attr "athlon_decode" "vector")
1627    (set_attr "amdfam10_decode" "direct")
1628    (set_attr "bdver1_decode" "double")
1629    (set_attr "znver1_decode" "double")
1630    (set (attr "enabled")
1631      (if_then_else
1632        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1633        (if_then_else
1634          (eq_attr "alternative" "0")
1635          (symbol_ref "TARGET_MIX_SSE_I387")
1636          (symbol_ref "true"))
1637        (if_then_else
1638          (eq_attr "alternative" "0")
1639          (symbol_ref "true")
1640          (symbol_ref "false"))))])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645   [(set (match_operand:DWI 0 "push_operand" "=<")
1646         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1647   ""
1648   "#"
1649   [(set_attr "type" "multi")
1650    (set_attr "mode" "<MODE>")])
1652 (define_split
1653   [(set (match_operand:DWI 0 "push_operand")
1654         (match_operand:DWI 1 "general_gr_operand"))]
1655   "reload_completed"
1656   [(const_int 0)]
1657   "ix86_split_long_move (operands); DONE;")
1659 (define_insn "*pushdi2_rex64"
1660   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1661         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1662   "TARGET_64BIT"
1663   "@
1664    push{q}\t%1
1665    #"
1666   [(set_attr "type" "push,multi")
1667    (set_attr "mode" "DI")])
1669 ;; Convert impossible pushes of immediate to existing instructions.
1670 ;; First try to get scratch register and go through it.  In case this
1671 ;; fails, push sign extended lower part first and then overwrite
1672 ;; upper part by 32bit move.
1673 (define_peephole2
1674   [(match_scratch:DI 2 "r")
1675    (set (match_operand:DI 0 "push_operand")
1676         (match_operand:DI 1 "immediate_operand"))]
1677   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1678    && !x86_64_immediate_operand (operands[1], DImode)"
1679   [(set (match_dup 2) (match_dup 1))
1680    (set (match_dup 0) (match_dup 2))])
1682 ;; We need to define this as both peepholer and splitter for case
1683 ;; peephole2 pass is not run.
1684 ;; "&& 1" is needed to keep it from matching the previous pattern.
1685 (define_peephole2
1686   [(set (match_operand:DI 0 "push_operand")
1687         (match_operand:DI 1 "immediate_operand"))]
1688   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1689    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1690   [(set (match_dup 0) (match_dup 1))
1691    (set (match_dup 2) (match_dup 3))]
1693   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1695   operands[1] = gen_lowpart (DImode, operands[2]);
1696   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1697                                                    GEN_INT (4)));
1700 (define_split
1701   [(set (match_operand:DI 0 "push_operand")
1702         (match_operand:DI 1 "immediate_operand"))]
1703   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1704                     ? epilogue_completed : reload_completed)
1705    && !symbolic_operand (operands[1], DImode)
1706    && !x86_64_immediate_operand (operands[1], DImode)"
1707   [(set (match_dup 0) (match_dup 1))
1708    (set (match_dup 2) (match_dup 3))]
1710   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1712   operands[1] = gen_lowpart (DImode, operands[2]);
1713   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1714                                                    GEN_INT (4)));
1717 (define_insn "*pushsi2"
1718   [(set (match_operand:SI 0 "push_operand" "=<")
1719         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1720   "!TARGET_64BIT"
1721   "push{l}\t%1"
1722   [(set_attr "type" "push")
1723    (set_attr "mode" "SI")])
1725 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1726 ;; "push a byte/word".  But actually we use pushl, which has the effect
1727 ;; of rounding the amount pushed up to a word.
1729 ;; For TARGET_64BIT we always round up to 8 bytes.
1730 (define_insn "*push<mode>2_rex64"
1731   [(set (match_operand:SWI124 0 "push_operand" "=X")
1732         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1733   "TARGET_64BIT"
1734   "push{q}\t%q1"
1735   [(set_attr "type" "push")
1736    (set_attr "mode" "DI")])
1738 (define_insn "*push<mode>2"
1739   [(set (match_operand:SWI12 0 "push_operand" "=X")
1740         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1741   "!TARGET_64BIT"
1742   "push{l}\t%k1"
1743   [(set_attr "type" "push")
1744    (set_attr "mode" "SI")])
1746 (define_insn "*push<mode>2_prologue"
1747   [(set (match_operand:W 0 "push_operand" "=<")
1748         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1749    (clobber (mem:BLK (scratch)))]
1750   ""
1751   "push{<imodesuffix>}\t%1"
1752   [(set_attr "type" "push")
1753    (set_attr "mode" "<MODE>")])
1755 (define_insn "*pop<mode>1"
1756   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1757         (match_operand:W 1 "pop_operand" ">"))]
1758   ""
1759   "pop{<imodesuffix>}\t%0"
1760   [(set_attr "type" "pop")
1761    (set_attr "mode" "<MODE>")])
1763 (define_insn "*pop<mode>1_epilogue"
1764   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1765         (match_operand:W 1 "pop_operand" ">"))
1766    (clobber (mem:BLK (scratch)))]
1767   ""
1768   "pop{<imodesuffix>}\t%0"
1769   [(set_attr "type" "pop")
1770    (set_attr "mode" "<MODE>")])
1772 (define_insn "*pushfl<mode>2"
1773   [(set (match_operand:W 0 "push_operand" "=<")
1774         (match_operand:W 1 "flags_reg_operand"))]
1775   ""
1776   "pushf{<imodesuffix>}"
1777   [(set_attr "type" "push")
1778    (set_attr "mode" "<MODE>")])
1780 (define_insn "*popfl<mode>1"
1781   [(set (match_operand:W 0 "flags_reg_operand")
1782         (match_operand:W 1 "pop_operand" ">"))]
1783   ""
1784   "popf{<imodesuffix>}"
1785   [(set_attr "type" "pop")
1786    (set_attr "mode" "<MODE>")])
1789 ;; Reload patterns to support multi-word load/store
1790 ;; with non-offsetable address.
1791 (define_expand "reload_noff_store"
1792   [(parallel [(match_operand 0 "memory_operand" "=m")
1793               (match_operand 1 "register_operand" "r")
1794               (match_operand:DI 2 "register_operand" "=&r")])]
1795   "TARGET_64BIT"
1797   rtx mem = operands[0];
1798   rtx addr = XEXP (mem, 0);
1800   emit_move_insn (operands[2], addr);
1801   mem = replace_equiv_address_nv (mem, operands[2]);
1803   emit_insn (gen_rtx_SET (mem, operands[1]));
1804   DONE;
1807 (define_expand "reload_noff_load"
1808   [(parallel [(match_operand 0 "register_operand" "=r")
1809               (match_operand 1 "memory_operand" "m")
1810               (match_operand:DI 2 "register_operand" "=r")])]
1811   "TARGET_64BIT"
1813   rtx mem = operands[1];
1814   rtx addr = XEXP (mem, 0);
1816   emit_move_insn (operands[2], addr);
1817   mem = replace_equiv_address_nv (mem, operands[2]);
1819   emit_insn (gen_rtx_SET (operands[0], mem));
1820   DONE;
1823 ;; Move instructions.
1825 (define_expand "movxi"
1826   [(set (match_operand:XI 0 "nonimmediate_operand")
1827         (match_operand:XI 1 "general_operand"))]
1828   "TARGET_AVX512F"
1829   "ix86_expand_vector_move (XImode, operands); DONE;")
1831 (define_expand "movoi"
1832   [(set (match_operand:OI 0 "nonimmediate_operand")
1833         (match_operand:OI 1 "general_operand"))]
1834   "TARGET_AVX"
1835   "ix86_expand_vector_move (OImode, operands); DONE;")
1837 (define_expand "movti"
1838   [(set (match_operand:TI 0 "nonimmediate_operand")
1839         (match_operand:TI 1 "general_operand"))]
1840   "TARGET_64BIT || TARGET_SSE"
1842   if (TARGET_64BIT)
1843     ix86_expand_move (TImode, operands);
1844   else
1845     ix86_expand_vector_move (TImode, operands);
1846   DONE;
1849 ;; This expands to what emit_move_complex would generate if we didn't
1850 ;; have a movti pattern.  Having this avoids problems with reload on
1851 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1852 ;; to have around all the time.
1853 (define_expand "movcdi"
1854   [(set (match_operand:CDI 0 "nonimmediate_operand")
1855         (match_operand:CDI 1 "general_operand"))]
1856   ""
1858   if (push_operand (operands[0], CDImode))
1859     emit_move_complex_push (CDImode, operands[0], operands[1]);
1860   else
1861     emit_move_complex_parts (operands[0], operands[1]);
1862   DONE;
1865 (define_expand "mov<mode>"
1866   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1867         (match_operand:SWI1248x 1 "general_operand"))]
1868   ""
1869   "ix86_expand_move (<MODE>mode, operands); DONE;")
1871 (define_insn "*mov<mode>_xor"
1872   [(set (match_operand:SWI48 0 "register_operand" "=r")
1873         (match_operand:SWI48 1 "const0_operand"))
1874    (clobber (reg:CC FLAGS_REG))]
1875   "reload_completed"
1876   "xor{l}\t%k0, %k0"
1877   [(set_attr "type" "alu1")
1878    (set_attr "mode" "SI")
1879    (set_attr "length_immediate" "0")])
1881 (define_insn "*mov<mode>_or"
1882   [(set (match_operand:SWI48 0 "register_operand" "=r")
1883         (match_operand:SWI48 1 "constm1_operand"))
1884    (clobber (reg:CC FLAGS_REG))]
1885   "reload_completed"
1886   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1887   [(set_attr "type" "alu1")
1888    (set_attr "mode" "<MODE>")
1889    (set_attr "length_immediate" "1")])
1891 (define_insn "*movxi_internal_avx512f"
1892   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
1893         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1894   "TARGET_AVX512F
1895    && (register_operand (operands[0], XImode)
1896        || register_operand (operands[1], XImode))"
1898   switch (get_attr_type (insn))
1899     {
1900     case TYPE_SSELOG1:
1901       return standard_sse_constant_opcode (insn, operands);
1903     case TYPE_SSEMOV:
1904       if (misaligned_operand (operands[0], XImode)
1905           || misaligned_operand (operands[1], XImode))
1906         return "vmovdqu32\t{%1, %0|%0, %1}";
1907       else
1908         return "vmovdqa32\t{%1, %0|%0, %1}";
1910     default:
1911       gcc_unreachable ();
1912     }
1914   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1915    (set_attr "prefix" "evex")
1916    (set_attr "mode" "XI")])
1918 (define_insn "*movoi_internal_avx"
1919   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
1920         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1921   "TARGET_AVX
1922    && (register_operand (operands[0], OImode)
1923        || register_operand (operands[1], OImode))"
1925   switch (get_attr_type (insn))
1926     {
1927     case TYPE_SSELOG1:
1928       return standard_sse_constant_opcode (insn, operands);
1930     case TYPE_SSEMOV:
1931       if (misaligned_operand (operands[0], OImode)
1932           || misaligned_operand (operands[1], OImode))
1933         {
1934           if (get_attr_mode (insn) == MODE_V8SF)
1935             return "vmovups\t{%1, %0|%0, %1}";
1936           else if (get_attr_mode (insn) == MODE_XI)
1937             return "vmovdqu32\t{%1, %0|%0, %1}";
1938           else
1939             return "vmovdqu\t{%1, %0|%0, %1}";
1940         }
1941       else
1942         {
1943           if (get_attr_mode (insn) == MODE_V8SF)
1944             return "vmovaps\t{%1, %0|%0, %1}";
1945           else if (get_attr_mode (insn) == MODE_XI)
1946             return "vmovdqa32\t{%1, %0|%0, %1}";
1947           else
1948             return "vmovdqa\t{%1, %0|%0, %1}";
1949         }
1951     default:
1952       gcc_unreachable ();
1953     }
1955   [(set_attr "isa" "*,avx2,*,*")
1956    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1957    (set_attr "prefix" "vex")
1958    (set (attr "mode")
1959         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1960                     (match_operand 1 "ext_sse_reg_operand"))
1961                  (const_string "XI")
1962                (and (eq_attr "alternative" "1")
1963                     (match_test "TARGET_AVX512VL"))
1964                  (const_string "XI")
1965                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1966                     (and (eq_attr "alternative" "3")
1967                          (match_test "TARGET_SSE_TYPELESS_STORES")))
1968                  (const_string "V8SF")
1969               ]
1970               (const_string "OI")))])
1972 (define_insn "*movti_internal"
1973   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1974         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
1975   "(TARGET_64BIT
1976     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1977    || (TARGET_SSE
1978        && nonimmediate_or_sse_const_operand (operands[1], TImode)
1979        && (register_operand (operands[0], TImode)
1980            || register_operand (operands[1], TImode)))"
1982   switch (get_attr_type (insn))
1983     {
1984     case TYPE_MULTI:
1985       return "#";
1987     case TYPE_SSELOG1:
1988       return standard_sse_constant_opcode (insn, operands);
1990     case TYPE_SSEMOV:
1991       /* TDmode values are passed as TImode on the stack.  Moving them
1992          to stack may result in unaligned memory access.  */
1993       if (misaligned_operand (operands[0], TImode)
1994           || misaligned_operand (operands[1], TImode))
1995         {
1996           if (get_attr_mode (insn) == MODE_V4SF)
1997             return "%vmovups\t{%1, %0|%0, %1}";
1998           else if (get_attr_mode (insn) == MODE_XI)
1999             return "vmovdqu32\t{%1, %0|%0, %1}";
2000           else
2001             return "%vmovdqu\t{%1, %0|%0, %1}";
2002         }
2003       else
2004         {
2005           if (get_attr_mode (insn) == MODE_V4SF)
2006             return "%vmovaps\t{%1, %0|%0, %1}";
2007           else if (get_attr_mode (insn) == MODE_XI)
2008             return "vmovdqa32\t{%1, %0|%0, %1}";
2009           else
2010             return "%vmovdqa\t{%1, %0|%0, %1}";
2011         }
2013     default:
2014       gcc_unreachable ();
2015     }
2017   [(set (attr "isa")
2018      (cond [(eq_attr "alternative" "0,1,6,7")
2019               (const_string "x64")
2020             (eq_attr "alternative" "3")
2021               (const_string "sse2")
2022            ]
2023            (const_string "*")))
2024    (set (attr "type")
2025      (cond [(eq_attr "alternative" "0,1,6,7")
2026               (const_string "multi")
2027             (eq_attr "alternative" "2,3")
2028               (const_string "sselog1")
2029            ]
2030            (const_string "ssemov")))
2031    (set (attr "prefix")
2032      (if_then_else (eq_attr "type" "sselog1,ssemov")
2033        (const_string "maybe_vex")
2034        (const_string "orig")))
2035    (set (attr "mode")
2036         (cond [(eq_attr "alternative" "0,1")
2037                  (const_string "DI")
2038                (ior (match_operand 0 "ext_sse_reg_operand")
2039                     (match_operand 1 "ext_sse_reg_operand"))
2040                  (const_string "XI")
2041                (and (eq_attr "alternative" "3")
2042                     (match_test "TARGET_AVX512VL"))
2043                  (const_string "XI")
2044                (ior (not (match_test "TARGET_SSE2"))
2045                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2046                          (and (eq_attr "alternative" "5")
2047                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2048                  (const_string "V4SF")
2049                (match_test "TARGET_AVX")
2050                  (const_string "TI")
2051                (match_test "optimize_function_for_size_p (cfun)")
2052                  (const_string "V4SF")
2053                ]
2054                (const_string "TI")))
2055    (set (attr "preferred_for_speed")
2056      (cond [(eq_attr "alternative" "6")
2057               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2058             (eq_attr "alternative" "7")
2059               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2060            ]
2061            (symbol_ref "true")))])
2063 (define_split
2064   [(set (match_operand:TI 0 "sse_reg_operand")
2065         (match_operand:TI 1 "general_reg_operand"))]
2066   "TARGET_64BIT && TARGET_SSE4_1
2067    && reload_completed"
2068   [(set (match_dup 2)
2069         (vec_merge:V2DI
2070           (vec_duplicate:V2DI (match_dup 3))
2071           (match_dup 2)
2072           (const_int 2)))]
2074   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2075   operands[3] = gen_highpart (DImode, operands[1]);
2077   emit_move_insn (gen_lowpart (DImode, operands[0]),
2078                   gen_lowpart (DImode, operands[1]));
2081 (define_insn "*movdi_internal"
2082   [(set (match_operand:DI 0 "nonimmediate_operand"
2083     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
2084         (match_operand:DI 1 "general_operand"
2085     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,v,*Yd,r   ,*v,r  ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2086   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2088   switch (get_attr_type (insn))
2089     {
2090     case TYPE_MSKMOV:
2091       return "kmovq\t{%1, %0|%0, %1}";
2093     case TYPE_MSKLOG:
2094       if (operands[1] == const0_rtx)
2095         return "kxorq\t%0, %0, %0";
2096       else if (operands[1] == constm1_rtx)
2097         return "kxnorq\t%0, %0, %0";
2098       gcc_unreachable ();
2100     case TYPE_MULTI:
2101       return "#";
2103     case TYPE_MMX:
2104       return "pxor\t%0, %0";
2106     case TYPE_MMXMOV:
2107       /* Handle broken assemblers that require movd instead of movq.  */
2108       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2109           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2110         return "movd\t{%1, %0|%0, %1}";
2111       return "movq\t{%1, %0|%0, %1}";
2113     case TYPE_SSELOG1:
2114       return standard_sse_constant_opcode (insn, operands);
2116     case TYPE_SSEMOV:
2117       switch (get_attr_mode (insn))
2118         {
2119         case MODE_DI:
2120           /* Handle broken assemblers that require movd instead of movq.  */
2121           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2122               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2123             return "%vmovd\t{%1, %0|%0, %1}";
2124           return "%vmovq\t{%1, %0|%0, %1}";
2126         case MODE_TI:
2127           /* Handle AVX512 registers set.  */
2128           if (EXT_REX_SSE_REG_P (operands[0])
2129               || EXT_REX_SSE_REG_P (operands[1]))
2130             return "vmovdqa64\t{%1, %0|%0, %1}";
2131           return "%vmovdqa\t{%1, %0|%0, %1}";
2133         case MODE_V2SF:
2134           gcc_assert (!TARGET_AVX);
2135           return "movlps\t{%1, %0|%0, %1}";
2136         case MODE_V4SF:
2137           return "%vmovaps\t{%1, %0|%0, %1}";
2139         default:
2140           gcc_unreachable ();
2141         }
2143     case TYPE_SSECVT:
2144       if (SSE_REG_P (operands[0]))
2145         return "movq2dq\t{%1, %0|%0, %1}";
2146       else
2147         return "movdq2q\t{%1, %0|%0, %1}";
2149     case TYPE_LEA:
2150       return "lea{q}\t{%E1, %0|%0, %E1}";
2152     case TYPE_IMOV:
2153       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2154       if (get_attr_mode (insn) == MODE_SI)
2155         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2156       else if (which_alternative == 4)
2157         return "movabs{q}\t{%1, %0|%0, %1}";
2158       else if (ix86_use_lea_for_mov (insn, operands))
2159         return "lea{q}\t{%E1, %0|%0, %E1}";
2160       else
2161         return "mov{q}\t{%1, %0|%0, %1}";
2163     default:
2164       gcc_unreachable ();
2165     }
2167   [(set (attr "isa")
2168      (cond [(eq_attr "alternative" "0,1,17,18")
2169               (const_string "nox64")
2170             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2171               (const_string "x64")
2172             (eq_attr "alternative" "19,20")
2173               (const_string "x64_sse2")
2174             (eq_attr "alternative" "21,22")
2175               (const_string "sse2")
2176            ]
2177            (const_string "*")))
2178    (set (attr "type")
2179      (cond [(eq_attr "alternative" "0,1,17,18")
2180               (const_string "multi")
2181             (eq_attr "alternative" "6")
2182               (const_string "mmx")
2183             (eq_attr "alternative" "7,8,9,10,11")
2184               (const_string "mmxmov")
2185             (eq_attr "alternative" "12")
2186               (const_string "sselog1")
2187             (eq_attr "alternative" "13,14,15,16,19,20")
2188               (const_string "ssemov")
2189             (eq_attr "alternative" "21,22")
2190               (const_string "ssecvt")
2191             (eq_attr "alternative" "23,24,25,26")
2192               (const_string "mskmov")
2193             (eq_attr "alternative" "27")
2194               (const_string "msklog")
2195             (and (match_operand 0 "register_operand")
2196                  (match_operand 1 "pic_32bit_operand"))
2197               (const_string "lea")
2198            ]
2199            (const_string "imov")))
2200    (set (attr "modrm")
2201      (if_then_else
2202        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2203        (const_string "0")
2204        (const_string "*")))
2205    (set (attr "length_immediate")
2206      (if_then_else
2207        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2208        (const_string "8")
2209        (const_string "*")))
2210    (set (attr "prefix_rex")
2211      (if_then_else
2212        (eq_attr "alternative" "10,11,19,20")
2213        (const_string "1")
2214        (const_string "*")))
2215    (set (attr "prefix")
2216      (if_then_else (eq_attr "type" "sselog1,ssemov")
2217        (const_string "maybe_vex")
2218        (const_string "orig")))
2219    (set (attr "prefix_data16")
2220      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2221        (const_string "1")
2222        (const_string "*")))
2223    (set (attr "mode")
2224      (cond [(eq_attr "alternative" "2")
2225               (const_string "SI")
2226             (eq_attr "alternative" "12,13")
2227               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2228                           (match_operand 1 "ext_sse_reg_operand"))
2229                        (const_string "TI")
2230                      (ior (not (match_test "TARGET_SSE2"))
2231                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2232                        (const_string "V4SF")
2233                      (match_test "TARGET_AVX")
2234                        (const_string "TI")
2235                      (match_test "optimize_function_for_size_p (cfun)")
2236                        (const_string "V4SF")
2237                     ]
2238                     (const_string "TI"))
2240             (and (eq_attr "alternative" "14,15,16")
2241                  (not (match_test "TARGET_SSE2")))
2242               (const_string "V2SF")
2243            ]
2244            (const_string "DI")))
2245    (set (attr "preferred_for_speed")
2246      (cond [(eq_attr "alternative" "10,17,19")
2247               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2248             (eq_attr "alternative" "11,18,20")
2249               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2250            ]
2251            (symbol_ref "true")))
2252    (set (attr "enabled")
2253      (cond [(eq_attr "alternative" "15")
2254               (if_then_else
2255                 (match_test "TARGET_STV && TARGET_SSE2")
2256                 (symbol_ref "false")
2257                 (const_string "*"))
2258             (eq_attr "alternative" "16")
2259               (if_then_else
2260                 (match_test "TARGET_STV && TARGET_SSE2")
2261                 (symbol_ref "true")
2262                 (symbol_ref "false"))
2263            ]
2264            (const_string "*")))])
2266 (define_split
2267   [(set (match_operand:<DWI> 0 "general_reg_operand")
2268         (match_operand:<DWI> 1 "sse_reg_operand"))]
2269   "TARGET_SSE4_1
2270    && reload_completed"
2271   [(set (match_dup 2)
2272         (vec_select:DWIH
2273           (match_dup 3)
2274           (parallel [(const_int 1)])))]
2276   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2277   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2279   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2280                   gen_lowpart (<MODE>mode, operands[1]));
2283 (define_split
2284   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2285         (match_operand:DWI 1 "general_gr_operand"))]
2286   "reload_completed"
2287   [(const_int 0)]
2288   "ix86_split_long_move (operands); DONE;")
2290 (define_split
2291   [(set (match_operand:DI 0 "sse_reg_operand")
2292         (match_operand:DI 1 "general_reg_operand"))]
2293   "!TARGET_64BIT && TARGET_SSE4_1
2294    && reload_completed"
2295   [(set (match_dup 2)
2296         (vec_merge:V4SI
2297           (vec_duplicate:V4SI (match_dup 3))
2298           (match_dup 2)
2299           (const_int 2)))]
2301   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2302   operands[3] = gen_highpart (SImode, operands[1]);
2304   emit_move_insn (gen_lowpart (SImode, operands[0]),
2305                   gen_lowpart (SImode, operands[1]));
2308 ;; movabsq $0x0012345678000000, %rax is longer
2309 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2310 (define_peephole2
2311   [(set (match_operand:DI 0 "register_operand")
2312         (match_operand:DI 1 "const_int_operand"))]
2313   "TARGET_64BIT
2314    && optimize_insn_for_size_p ()
2315    && LEGACY_INT_REG_P (operands[0])
2316    && !x86_64_immediate_operand (operands[1], DImode)
2317    && !x86_64_zext_immediate_operand (operands[1], DImode)
2318    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2319         & ~(HOST_WIDE_INT) 0xffffffff)
2320    && peep2_regno_dead_p (0, FLAGS_REG)"
2321   [(set (match_dup 0) (match_dup 1))
2322    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2323               (clobber (reg:CC FLAGS_REG))])]
2325   int shift = ctz_hwi (UINTVAL (operands[1]));
2326   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2327   operands[2] = gen_int_mode (shift, QImode);
2330 (define_insn "*movsi_internal"
2331   [(set (match_operand:SI 0 "nonimmediate_operand"
2332     "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2333         (match_operand:SI 1 "general_operand"
2334     "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k ,CBC"))]
2335   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2337   switch (get_attr_type (insn))
2338     {
2339     case TYPE_SSELOG1:
2340       return standard_sse_constant_opcode (insn, operands);
2342     case TYPE_MSKMOV:
2343       return "kmovd\t{%1, %0|%0, %1}";
2345     case TYPE_MSKLOG:
2346       if (operands[1] == const0_rtx)
2347         return "kxord\t%0, %0, %0";
2348       else if (operands[1] == constm1_rtx)
2349         return "kxnord\t%0, %0, %0";
2350       gcc_unreachable ();
2352     case TYPE_SSEMOV:
2353       switch (get_attr_mode (insn))
2354         {
2355         case MODE_SI:
2356           return "%vmovd\t{%1, %0|%0, %1}";
2357         case MODE_TI:
2358           return "%vmovdqa\t{%1, %0|%0, %1}";
2359         case MODE_XI:
2360           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2362         case MODE_V4SF:
2363           return "%vmovaps\t{%1, %0|%0, %1}";
2365         case MODE_SF:
2366           gcc_assert (!TARGET_AVX);
2367           return "movss\t{%1, %0|%0, %1}";
2369         default:
2370           gcc_unreachable ();
2371         }
2373     case TYPE_MMX:
2374       return "pxor\t%0, %0";
2376     case TYPE_MMXMOV:
2377       switch (get_attr_mode (insn))
2378         {
2379         case MODE_DI:
2380           return "movq\t{%1, %0|%0, %1}";
2381         case MODE_SI:
2382           return "movd\t{%1, %0|%0, %1}";
2384         default:
2385           gcc_unreachable ();
2386         }
2388     case TYPE_LEA:
2389       return "lea{l}\t{%E1, %0|%0, %E1}";
2391     case TYPE_IMOV:
2392       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2393       if (ix86_use_lea_for_mov (insn, operands))
2394         return "lea{l}\t{%E1, %0|%0, %E1}";
2395       else
2396         return "mov{l}\t{%1, %0|%0, %1}";
2398     default:
2399       gcc_unreachable ();
2400     }
2402   [(set (attr "isa")
2403      (cond [(eq_attr "alternative" "12,13")
2404               (const_string "sse2")
2405            ]
2406            (const_string "*")))
2407    (set (attr "type")
2408      (cond [(eq_attr "alternative" "2")
2409               (const_string "mmx")
2410             (eq_attr "alternative" "3,4,5,6,7")
2411               (const_string "mmxmov")
2412             (eq_attr "alternative" "8")
2413               (const_string "sselog1")
2414             (eq_attr "alternative" "9,10,11,12,13")
2415               (const_string "ssemov")
2416             (eq_attr "alternative" "14,15,16")
2417               (const_string "mskmov")
2418             (eq_attr "alternative" "17")
2419               (const_string "msklog")
2420             (and (match_operand 0 "register_operand")
2421                  (match_operand 1 "pic_32bit_operand"))
2422               (const_string "lea")
2423            ]
2424            (const_string "imov")))
2425    (set (attr "prefix")
2426      (if_then_else (eq_attr "type" "sselog1,ssemov")
2427        (const_string "maybe_vex")
2428        (const_string "orig")))
2429    (set (attr "prefix_data16")
2430      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2431        (const_string "1")
2432        (const_string "*")))
2433    (set (attr "mode")
2434      (cond [(eq_attr "alternative" "2,3")
2435               (const_string "DI")
2436             (eq_attr "alternative" "8,9")
2437               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2438                           (match_operand 1 "ext_sse_reg_operand"))
2439                        (const_string "XI")
2440                      (ior (not (match_test "TARGET_SSE2"))
2441                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2442                        (const_string "V4SF")
2443                      (match_test "TARGET_AVX")
2444                        (const_string "TI")
2445                      (match_test "optimize_function_for_size_p (cfun)")
2446                        (const_string "V4SF")
2447                     ]
2448                     (const_string "TI"))
2450             (and (eq_attr "alternative" "10,11")
2451                  (not (match_test "TARGET_SSE2")))
2452               (const_string "SF")
2453            ]
2454            (const_string "SI")))
2455    (set (attr "preferred_for_speed")
2456      (cond [(eq_attr "alternative" "6,12")
2457               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2458             (eq_attr "alternative" "7,13")
2459               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2460            ]
2461            (symbol_ref "true")))])
2463 (define_insn "*movhi_internal"
2464   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2465         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k,CBC"))]
2466   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2468   switch (get_attr_type (insn))
2469     {
2470     case TYPE_IMOVX:
2471       /* movzwl is faster than movw on p2 due to partial word stalls,
2472          though not as fast as an aligned movl.  */
2473       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2475     case TYPE_MSKMOV:
2476       switch (which_alternative)
2477         {
2478         case 4:
2479           return "kmovw\t{%k1, %0|%0, %k1}";
2480         case 6:
2481           return "kmovw\t{%1, %k0|%k0, %1}";
2482         case 5:
2483         case 7:
2484           return "kmovw\t{%1, %0|%0, %1}";
2485         default:
2486           gcc_unreachable ();
2487         }
2489     case TYPE_MSKLOG:
2490       if (operands[1] == const0_rtx)
2491         return "kxorw\t%0, %0, %0";
2492       else if (operands[1] == constm1_rtx)
2493         return "kxnorw\t%0, %0, %0";
2494       gcc_unreachable ();
2496     default:
2497       if (get_attr_mode (insn) == MODE_SI)
2498         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2499       else
2500         return "mov{w}\t{%1, %0|%0, %1}";
2501     }
2503   [(set (attr "type")
2504      (cond [(eq_attr "alternative" "4,5,6,7")
2505               (const_string "mskmov")
2506             (eq_attr "alternative" "8")
2507               (const_string "msklog")
2508             (match_test "optimize_function_for_size_p (cfun)")
2509               (const_string "imov")
2510             (and (eq_attr "alternative" "0")
2511                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2512                       (not (match_test "TARGET_HIMODE_MATH"))))
2513               (const_string "imov")
2514             (and (eq_attr "alternative" "1,2")
2515                  (match_operand:HI 1 "aligned_operand"))
2516               (const_string "imov")
2517             (and (match_test "TARGET_MOVX")
2518                  (eq_attr "alternative" "0,2"))
2519               (const_string "imovx")
2520            ]
2521            (const_string "imov")))
2522     (set (attr "prefix")
2523       (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2524         (const_string "vex")
2525         (const_string "orig")))
2526     (set (attr "mode")
2527       (cond [(eq_attr "type" "imovx")
2528                (const_string "SI")
2529              (and (eq_attr "alternative" "1,2")
2530                   (match_operand:HI 1 "aligned_operand"))
2531                (const_string "SI")
2532              (and (eq_attr "alternative" "0")
2533                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2534                        (not (match_test "TARGET_HIMODE_MATH"))))
2535                (const_string "SI")
2536             ]
2537             (const_string "HI")))])
2539 ;; Situation is quite tricky about when to choose full sized (SImode) move
2540 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2541 ;; partial register dependency machines (such as AMD Athlon), where QImode
2542 ;; moves issue extra dependency and for partial register stalls machines
2543 ;; that don't use QImode patterns (and QImode move cause stall on the next
2544 ;; instruction).
2546 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2547 ;; register stall machines with, where we use QImode instructions, since
2548 ;; partial register stall can be caused there.  Then we use movzx.
2550 (define_insn "*movqi_internal"
2551   [(set (match_operand:QI 0 "nonimmediate_operand"
2552                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2553         (match_operand:QI 1 "general_operand"
2554                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2555   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2557   char buf[128];
2558   const char *ops;
2559   const char *suffix;
2561   switch (get_attr_type (insn))
2562     {
2563     case TYPE_IMOVX:
2564       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2565       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2567     case TYPE_MSKMOV:
2568       switch (which_alternative)
2569         {
2570         case 9:
2571           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2572           break;
2573         case 11:
2574           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2575           break;
2576         case 12:
2577         case 13:
2578           gcc_assert (TARGET_AVX512DQ);
2579           /* FALLTHRU */
2580         case 10:
2581           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2582           break;
2583         default:
2584           gcc_unreachable ();
2585         }
2587       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2589       snprintf (buf, sizeof (buf), ops, suffix);
2590       output_asm_insn (buf, operands);
2591       return "";
2593     case TYPE_MSKLOG:
2594       if (operands[1] == const0_rtx)
2595         {
2596           if (get_attr_mode (insn) == MODE_HI)
2597             return "kxorw\t%0, %0, %0";
2598           else
2599             return "kxorb\t%0, %0, %0";
2600         }
2601       else if (operands[1] == constm1_rtx)
2602         {
2603           gcc_assert (TARGET_AVX512DQ);
2604           return "kxnorb\t%0, %0, %0";
2605         }
2606       gcc_unreachable ();
2608     default:
2609       if (get_attr_mode (insn) == MODE_SI)
2610         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2611       else
2612         return "mov{b}\t{%1, %0|%0, %1}";
2613     }
2615   [(set (attr "isa")
2616      (cond [(eq_attr "alternative" "1,2")
2617               (const_string "x64")
2618             (eq_attr "alternative" "12,13,15")
2619               (const_string "avx512dq")
2620            ]
2621            (const_string "*")))
2622    (set (attr "type")
2623      (cond [(eq_attr "alternative" "9,10,11,12,13")
2624               (const_string "mskmov")
2625             (eq_attr "alternative" "14,15")
2626               (const_string "msklog")
2627             (and (eq_attr "alternative" "7")
2628                  (not (match_operand:QI 1 "aligned_operand")))
2629               (const_string "imovx")
2630             (match_test "optimize_function_for_size_p (cfun)")
2631               (const_string "imov")
2632             (and (eq_attr "alternative" "5")
2633                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2634                       (not (match_test "TARGET_QIMODE_MATH"))))
2635               (const_string "imov")
2636             (eq_attr "alternative" "5,7")
2637               (const_string "imovx")
2638             (and (match_test "TARGET_MOVX")
2639                  (eq_attr "alternative" "4"))
2640               (const_string "imovx")
2641            ]
2642            (const_string "imov")))
2643    (set (attr "prefix")
2644      (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2645        (const_string "vex")
2646        (const_string "orig")))
2647    (set (attr "mode")
2648       (cond [(eq_attr "alternative" "5,6,7")
2649                (const_string "SI")
2650              (eq_attr "alternative" "8")
2651                (const_string "QI")
2652              (and (eq_attr "alternative" "9,10,11,14")
2653                   (not (match_test "TARGET_AVX512DQ")))
2654                (const_string "HI")
2655              (eq_attr "type" "imovx")
2656                (const_string "SI")
2657              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2658              ;; ones.
2659              (and (eq_attr "type" "imov")
2660                   (and (eq_attr "alternative" "3")
2661                        (match_test "optimize_function_for_size_p (cfun)")))
2662                (const_string "QI")
2663              ;; For -Os, movl where one or both operands are NON_Q_REGS
2664              ;; and both are LEGACY_REGS is shorter than movb.
2665              ;; Otherwise movb and movl sizes are the same, so decide purely
2666              ;; based on speed factors.
2667              (and (eq_attr "type" "imov")
2668                   (and (eq_attr "alternative" "1")
2669                        (match_test "optimize_function_for_size_p (cfun)")))
2670                (const_string "SI")
2671              (and (eq_attr "type" "imov")
2672                   (and (eq_attr "alternative" "0,1,2,3")
2673                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2674                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2675                (const_string "SI")
2676              ;; Avoid partial register stalls when not using QImode arithmetic
2677              (and (eq_attr "type" "imov")
2678                   (and (eq_attr "alternative" "0,1,2,3")
2679                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2680                             (not (match_test "TARGET_QIMODE_MATH")))))
2681                (const_string "SI")
2682            ]
2683            (const_string "QI")))])
2685 ;; Stores and loads of ax to arbitrary constant address.
2686 ;; We fake an second form of instruction to force reload to load address
2687 ;; into register when rax is not available
2688 (define_insn "*movabs<mode>_1"
2689   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2690         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2691   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2693   /* Recover the full memory rtx.  */
2694   operands[0] = SET_DEST (PATTERN (insn));
2695   switch (which_alternative)
2696     {
2697     case 0:
2698       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2699     case 1:
2700       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2701     default:
2702       gcc_unreachable ();
2703     }
2705   [(set_attr "type" "imov")
2706    (set_attr "modrm" "0,*")
2707    (set_attr "length_address" "8,0")
2708    (set_attr "length_immediate" "0,*")
2709    (set_attr "memory" "store")
2710    (set_attr "mode" "<MODE>")])
2712 (define_insn "*movabs<mode>_2"
2713   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2714         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2715   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2717   /* Recover the full memory rtx.  */
2718   operands[1] = SET_SRC (PATTERN (insn));
2719   switch (which_alternative)
2720     {
2721     case 0:
2722       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2723     case 1:
2724       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2725     default:
2726       gcc_unreachable ();
2727     }
2729   [(set_attr "type" "imov")
2730    (set_attr "modrm" "0,*")
2731    (set_attr "length_address" "8,0")
2732    (set_attr "length_immediate" "0")
2733    (set_attr "memory" "load")
2734    (set_attr "mode" "<MODE>")])
2736 (define_insn "*swap<mode>"
2737   [(set (match_operand:SWI48 0 "register_operand" "+r")
2738         (match_operand:SWI48 1 "register_operand" "+r"))
2739    (set (match_dup 1)
2740         (match_dup 0))]
2741   ""
2742   "xchg{<imodesuffix>}\t%1, %0"
2743   [(set_attr "type" "imov")
2744    (set_attr "mode" "<MODE>")
2745    (set_attr "pent_pair" "np")
2746    (set_attr "athlon_decode" "vector")
2747    (set_attr "amdfam10_decode" "double")
2748    (set_attr "bdver1_decode" "double")])
2750 (define_insn "*swap<mode>"
2751   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2752         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2753    (set (match_dup 1)
2754         (match_dup 0))]
2755   ""
2756   "@
2757    xchg{<imodesuffix>}\t%1, %0
2758    xchg{l}\t%k1, %k0"
2759   [(set_attr "type" "imov")
2760    (set_attr "mode" "<MODE>,SI")
2761    (set (attr "preferred_for_size")
2762      (cond [(eq_attr "alternative" "0")
2763               (symbol_ref "false")]
2764            (symbol_ref "true")))
2765    ;; Potential partial reg stall on alternative 1.
2766    (set (attr "preferred_for_speed")
2767      (cond [(eq_attr "alternative" "1")
2768               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2769            (symbol_ref "true")))
2770    (set_attr "pent_pair" "np")
2771    (set_attr "athlon_decode" "vector")
2772    (set_attr "amdfam10_decode" "double")
2773    (set_attr "bdver1_decode" "double")])
2775 (define_expand "movstrict<mode>"
2776   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2777         (match_operand:SWI12 1 "general_operand"))]
2778   ""
2780   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2781     FAIL;
2782   if (SUBREG_P (operands[0])
2783       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2784     FAIL;
2785   /* Don't generate memory->memory moves, go through a register */
2786   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2787     operands[1] = force_reg (<MODE>mode, operands[1]);
2790 (define_insn "*movstrict<mode>_1"
2791   [(set (strict_low_part
2792           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2793         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2794   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2796   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2797   [(set_attr "type" "imov")
2798    (set_attr "mode" "<MODE>")])
2800 (define_insn "*movstrict<mode>_xor"
2801   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2802         (match_operand:SWI12 1 "const0_operand"))
2803    (clobber (reg:CC FLAGS_REG))]
2804   "reload_completed"
2805   "xor{<imodesuffix>}\t%0, %0"
2806   [(set_attr "type" "alu1")
2807    (set_attr "mode" "<MODE>")
2808    (set_attr "length_immediate" "0")])
2810 (define_expand "extv<mode>"
2811   [(set (match_operand:SWI24 0 "register_operand")
2812         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2813                             (match_operand:SI 2 "const_int_operand")
2814                             (match_operand:SI 3 "const_int_operand")))]
2815   ""
2817   /* Handle extractions from %ah et al.  */
2818   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2819     FAIL;
2821   unsigned int regno = reg_or_subregno (operands[1]);
2823   /* Be careful to expand only with registers having upper parts.  */
2824   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2825     operands[1] = copy_to_reg (operands[1]);
2828 (define_insn "*extv<mode>"
2829   [(set (match_operand:SWI24 0 "register_operand" "=R")
2830         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2831                             (const_int 8)
2832                             (const_int 8)))]
2833   ""
2834   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2835   [(set_attr "type" "imovx")
2836    (set_attr "mode" "SI")])
2838 (define_expand "extzv<mode>"
2839   [(set (match_operand:SWI248 0 "register_operand")
2840         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2841                              (match_operand:SI 2 "const_int_operand")
2842                              (match_operand:SI 3 "const_int_operand")))]
2843   ""
2845   if (ix86_expand_pextr (operands))
2846     DONE;
2848   /* Handle extractions from %ah et al.  */
2849   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2850     FAIL;
2852   unsigned int regno = reg_or_subregno (operands[1]);
2854   /* Be careful to expand only with registers having upper parts.  */
2855   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2856     operands[1] = copy_to_reg (operands[1]);
2859 (define_insn "*extzvqi_mem_rex64"
2860   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2861         (subreg:QI
2862           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2863                            (const_int 8)
2864                            (const_int 8)) 0))]
2865   "TARGET_64BIT && reload_completed"
2866   "mov{b}\t{%h1, %0|%0, %h1}"
2867   [(set_attr "type" "imov")
2868    (set_attr "mode" "QI")])
2870 (define_insn "*extzv<mode>"
2871   [(set (match_operand:SWI248 0 "register_operand" "=R")
2872         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2873                              (const_int 8)
2874                              (const_int 8)))]
2875   ""
2876   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2877   [(set_attr "type" "imovx")
2878    (set_attr "mode" "SI")])
2880 (define_insn "*extzvqi"
2881   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2882         (subreg:QI
2883           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2884                            (const_int 8)
2885                            (const_int 8)) 0))]
2886   ""
2888   switch (get_attr_type (insn))
2889     {
2890     case TYPE_IMOVX:
2891       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2892     default:
2893       return "mov{b}\t{%h1, %0|%0, %h1}";
2894     }
2896   [(set_attr "isa" "*,*,nox64")
2897    (set (attr "type")
2898      (if_then_else (and (match_operand:QI 0 "register_operand")
2899                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2900                              (match_test "TARGET_MOVX")))
2901         (const_string "imovx")
2902         (const_string "imov")))
2903    (set (attr "mode")
2904      (if_then_else (eq_attr "type" "imovx")
2905         (const_string "SI")
2906         (const_string "QI")))])
2908 (define_peephole2
2909   [(set (match_operand:QI 0 "register_operand")
2910         (subreg:QI
2911           (zero_extract:SI (match_operand 1 "ext_register_operand")
2912                            (const_int 8)
2913                            (const_int 8)) 0))
2914    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2915   "TARGET_64BIT
2916    && peep2_reg_dead_p (2, operands[0])"
2917   [(set (match_dup 2)
2918         (subreg:QI
2919           (zero_extract:SI (match_dup 1)
2920                            (const_int 8)
2921                            (const_int 8)) 0))])
2923 (define_expand "insv<mode>"
2924   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2925                              (match_operand:SI 1 "const_int_operand")
2926                              (match_operand:SI 2 "const_int_operand"))
2927         (match_operand:SWI248 3 "register_operand"))]
2928   ""
2930   rtx dst;
2932   if (ix86_expand_pinsr (operands))
2933     DONE;
2935   /* Handle insertions to %ah et al.  */
2936   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2937     FAIL;
2939   unsigned int regno = reg_or_subregno (operands[0]);
2941   /* Be careful to expand only with registers having upper parts.  */
2942   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2943     dst = copy_to_reg (operands[0]);
2944   else
2945     dst = operands[0];
2947   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2949   /* Fix up the destination if needed.  */
2950   if (dst != operands[0])
2951     emit_move_insn (operands[0], dst);
2953   DONE;
2956 (define_insn "*insvqi_1_mem_rex64"
2957   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2958                          (const_int 8)
2959                          (const_int 8))
2960         (subreg:SI
2961           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2962   "TARGET_64BIT && reload_completed"
2963   "mov{b}\t{%1, %h0|%h0, %1}"
2964   [(set_attr "type" "imov")
2965    (set_attr "mode" "QI")])
2967 (define_insn "insv<mode>_1"
2968   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2969                              (const_int 8)
2970                              (const_int 8))
2971         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2972   ""
2974   if (CONST_INT_P (operands[1]))
2975     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2976   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2978   [(set_attr "isa" "*,nox64")
2979    (set_attr "type" "imov")
2980    (set_attr "mode" "QI")])
2982 (define_insn "*insvqi_1"
2983   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2984                          (const_int 8)
2985                          (const_int 8))
2986         (subreg:SI
2987           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2988   ""
2989   "mov{b}\t{%1, %h0|%h0, %1}"
2990   [(set_attr "isa" "*,nox64")
2991    (set_attr "type" "imov")
2992    (set_attr "mode" "QI")])
2994 (define_peephole2
2995   [(set (match_operand:QI 0 "register_operand")
2996         (match_operand:QI 1 "norex_memory_operand"))
2997    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2998                          (const_int 8)
2999                          (const_int 8))
3000         (subreg:SI (match_dup 0) 0))]
3001   "TARGET_64BIT
3002    && peep2_reg_dead_p (2, operands[0])"
3003   [(set (zero_extract:SI (match_dup 2)
3004                          (const_int 8)
3005                          (const_int 8))
3006            (subreg:SI (match_dup 1) 0))])
3008 (define_code_iterator any_extract [sign_extract zero_extract])
3010 (define_insn "*insvqi_2"
3011   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3012                          (const_int 8)
3013                          (const_int 8))
3014         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3015                         (const_int 8)
3016                         (const_int 8)))]
3017   ""
3018   "mov{b}\t{%h1, %h0|%h0, %h1}"
3019   [(set_attr "type" "imov")
3020    (set_attr "mode" "QI")])
3022 (define_insn "*insvqi_3"
3023   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3024                          (const_int 8)
3025                          (const_int 8))
3026         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3027                         (const_int 8)))]
3028   ""
3029   "mov{b}\t{%h1, %h0|%h0, %h1}"
3030   [(set_attr "type" "imov")
3031    (set_attr "mode" "QI")])
3033 ;; Floating point push instructions.
3035 (define_insn "*pushtf"
3036   [(set (match_operand:TF 0 "push_operand" "=<,<")
3037         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3038   "TARGET_64BIT || TARGET_SSE"
3040   /* This insn should be already split before reg-stack.  */
3041   gcc_unreachable ();
3043   [(set_attr "isa" "*,x64")
3044    (set_attr "type" "multi")
3045    (set_attr "unit" "sse,*")
3046    (set_attr "mode" "TF,DI")])
3048 ;; %%% Kill this when call knows how to work this out.
3049 (define_split
3050   [(set (match_operand:TF 0 "push_operand")
3051         (match_operand:TF 1 "sse_reg_operand"))]
3052   "TARGET_SSE && reload_completed"
3053   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3054    (set (match_dup 0) (match_dup 1))]
3056   /* Preserve memory attributes. */
3057   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3060 (define_insn_and_split "*pushxf_rounded"
3061   [(set (mem:XF
3062           (pre_modify:P
3063             (reg:P SP_REG)
3064             (plus:P (reg:P SP_REG) (const_int -16))))
3065         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3066   "TARGET_64BIT"
3067   "#"
3068   "&& 1"
3069   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3070    (set (match_dup 1) (match_dup 0))]
3072   rtx pat = PATTERN (curr_insn);
3073   operands[1] = SET_DEST (pat);
3075   /* Preserve memory attributes. */
3076   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3078   [(set_attr "type" "multi")
3079    (set_attr "unit" "i387,*,*,*")
3080    (set (attr "mode")
3081         (cond [(eq_attr "alternative" "1,2,3")
3082                  (const_string "DI")
3083               ]
3084               (const_string "XF")))
3085    (set (attr "preferred_for_size")
3086      (cond [(eq_attr "alternative" "1")
3087               (symbol_ref "false")]
3088            (symbol_ref "true")))])
3090 (define_insn "*pushxf"
3091   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3092         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3093   ""
3095   /* This insn should be already split before reg-stack.  */
3096   gcc_unreachable ();
3098   [(set_attr "isa" "*,*,*,nox64,x64")
3099    (set_attr "type" "multi")
3100    (set_attr "unit" "i387,*,*,*,*")
3101    (set (attr "mode")
3102         (cond [(eq_attr "alternative" "1,2,3,4")
3103                  (if_then_else (match_test "TARGET_64BIT")
3104                    (const_string "DI")
3105                    (const_string "SI"))
3106               ]
3107               (const_string "XF")))
3108    (set (attr "preferred_for_size")
3109      (cond [(eq_attr "alternative" "1")
3110               (symbol_ref "false")]
3111            (symbol_ref "true")))])
3113 ;; %%% Kill this when call knows how to work this out.
3114 (define_split
3115   [(set (match_operand:XF 0 "push_operand")
3116         (match_operand:XF 1 "fp_register_operand"))]
3117   "reload_completed"
3118   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3119    (set (match_dup 0) (match_dup 1))]
3121   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3122   /* Preserve memory attributes. */
3123   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3126 (define_insn "*pushdf"
3127   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3128         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3129   ""
3131   /* This insn should be already split before reg-stack.  */
3132   gcc_unreachable ();
3134   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3135    (set_attr "type" "multi")
3136    (set_attr "unit" "i387,*,*,*,*,sse")
3137    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3138    (set (attr "preferred_for_size")
3139      (cond [(eq_attr "alternative" "1")
3140               (symbol_ref "false")]
3141            (symbol_ref "true")))
3142    (set (attr "preferred_for_speed")
3143      (cond [(eq_attr "alternative" "1")
3144               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3145            (symbol_ref "true")))])
3146    
3147 ;; %%% Kill this when call knows how to work this out.
3148 (define_split
3149   [(set (match_operand:DF 0 "push_operand")
3150         (match_operand:DF 1 "any_fp_register_operand"))]
3151   "reload_completed"
3152   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3153    (set (match_dup 0) (match_dup 1))]
3155   /* Preserve memory attributes. */
3156   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3159 (define_insn "*pushsf_rex64"
3160   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3161         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3162   "TARGET_64BIT"
3164   /* Anything else should be already split before reg-stack.  */
3165   gcc_assert (which_alternative == 1);
3166   return "push{q}\t%q1";
3168   [(set_attr "type" "multi,push,multi")
3169    (set_attr "unit" "i387,*,*")
3170    (set_attr "mode" "SF,DI,SF")])
3172 (define_insn "*pushsf"
3173   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3174         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3175   "!TARGET_64BIT"
3177   /* Anything else should be already split before reg-stack.  */
3178   gcc_assert (which_alternative == 1);
3179   return "push{l}\t%1";
3181   [(set_attr "type" "multi,push,multi")
3182    (set_attr "unit" "i387,*,*")
3183    (set_attr "mode" "SF,SI,SF")])
3185 ;; %%% Kill this when call knows how to work this out.
3186 (define_split
3187   [(set (match_operand:SF 0 "push_operand")
3188         (match_operand:SF 1 "any_fp_register_operand"))]
3189   "reload_completed"
3190   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3191    (set (match_dup 0) (match_dup 1))]
3193   rtx op = XEXP (operands[0], 0);
3194   if (GET_CODE (op) == PRE_DEC)
3195     {
3196       gcc_assert (!TARGET_64BIT);
3197       op = GEN_INT (-4);
3198     }
3199   else
3200     {
3201       op = XEXP (XEXP (op, 1), 1);
3202       gcc_assert (CONST_INT_P (op));
3203     }
3204   operands[2] = op;
3205   /* Preserve memory attributes. */
3206   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3209 (define_split
3210   [(set (match_operand:SF 0 "push_operand")
3211         (match_operand:SF 1 "memory_operand"))]
3212   "reload_completed
3213    && find_constant_src (insn)"
3214   [(set (match_dup 0) (match_dup 2))]
3215   "operands[2] = find_constant_src (curr_insn);")
3217 (define_split
3218   [(set (match_operand 0 "push_operand")
3219         (match_operand 1 "general_gr_operand"))]
3220   "reload_completed
3221    && (GET_MODE (operands[0]) == TFmode
3222        || GET_MODE (operands[0]) == XFmode
3223        || GET_MODE (operands[0]) == DFmode)"
3224   [(const_int 0)]
3225   "ix86_split_long_move (operands); DONE;")
3227 ;; Floating point move instructions.
3229 (define_expand "movtf"
3230   [(set (match_operand:TF 0 "nonimmediate_operand")
3231         (match_operand:TF 1 "nonimmediate_operand"))]
3232   "TARGET_64BIT || TARGET_SSE"
3233   "ix86_expand_move (TFmode, operands); DONE;")
3235 (define_expand "mov<mode>"
3236   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3237         (match_operand:X87MODEF 1 "general_operand"))]
3238   ""
3239   "ix86_expand_move (<MODE>mode, operands); DONE;")
3241 (define_insn "*movtf_internal"
3242   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3243         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3244   "(TARGET_64BIT || TARGET_SSE)
3245    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3246    && (lra_in_progress || reload_completed
3247        || !CONST_DOUBLE_P (operands[1])
3248        || ((optimize_function_for_size_p (cfun)
3249             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3250            && standard_sse_constant_p (operands[1], TFmode) == 1
3251            && !memory_operand (operands[0], TFmode))
3252        || (!TARGET_MEMORY_MISMATCH_STALL
3253            && memory_operand (operands[0], TFmode)))"
3255   switch (get_attr_type (insn))
3256     {
3257     case TYPE_SSELOG1:
3258       return standard_sse_constant_opcode (insn, operands);
3260     case TYPE_SSEMOV:
3261       /* Handle misaligned load/store since we
3262          don't have movmisaligntf pattern. */
3263       if (misaligned_operand (operands[0], TFmode)
3264           || misaligned_operand (operands[1], TFmode))
3265         {
3266           if (get_attr_mode (insn) == MODE_V4SF)
3267             return "%vmovups\t{%1, %0|%0, %1}";
3268           else if (TARGET_AVX512VL
3269                    && (EXT_REX_SSE_REG_P (operands[0])
3270                        || EXT_REX_SSE_REG_P (operands[1])))
3271             return "vmovdqu64\t{%1, %0|%0, %1}";
3272           else
3273             return "%vmovdqu\t{%1, %0|%0, %1}";
3274         }
3275       else
3276         {
3277           if (get_attr_mode (insn) == MODE_V4SF)
3278             return "%vmovaps\t{%1, %0|%0, %1}";
3279           else if (TARGET_AVX512VL
3280                    && (EXT_REX_SSE_REG_P (operands[0])
3281                        || EXT_REX_SSE_REG_P (operands[1])))
3282             return "vmovdqa64\t{%1, %0|%0, %1}";
3283           else
3284             return "%vmovdqa\t{%1, %0|%0, %1}";
3285         }
3287     case TYPE_MULTI:
3288         return "#";
3290     default:
3291       gcc_unreachable ();
3292     }
3294   [(set_attr "isa" "*,*,*,x64,x64")
3295    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3296    (set (attr "prefix")
3297      (if_then_else (eq_attr "type" "sselog1,ssemov")
3298        (const_string "maybe_vex")
3299        (const_string "orig")))
3300    (set (attr "mode")
3301         (cond [(eq_attr "alternative" "3,4")
3302                  (const_string "DI")
3303                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3304                  (const_string "V4SF")
3305                (and (eq_attr "alternative" "2")
3306                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3307                  (const_string "V4SF")
3308                (match_test "TARGET_AVX")
3309                  (const_string "TI")
3310                (ior (not (match_test "TARGET_SSE2"))
3311                     (match_test "optimize_function_for_size_p (cfun)"))
3312                  (const_string "V4SF")
3313                ]
3314                (const_string "TI")))])
3316 (define_split
3317   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3318         (match_operand:TF 1 "general_gr_operand"))]
3319   "reload_completed"
3320   [(const_int 0)]
3321   "ix86_split_long_move (operands); DONE;")
3323 ;; Possible store forwarding (partial memory) stall
3324 ;; in alternatives 4, 6, 7 and 8.
3325 (define_insn "*movxf_internal"
3326   [(set (match_operand:XF 0 "nonimmediate_operand"
3327          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3328         (match_operand:XF 1 "general_operand"
3329          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3331    && (lra_in_progress || reload_completed
3332        || !CONST_DOUBLE_P (operands[1])
3333        || ((optimize_function_for_size_p (cfun)
3334             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3335            && standard_80387_constant_p (operands[1]) > 0
3336            && !memory_operand (operands[0], XFmode))
3337        || (!TARGET_MEMORY_MISMATCH_STALL
3338            && memory_operand (operands[0], XFmode))
3339        || !TARGET_HARD_XF_REGS)"
3341   switch (get_attr_type (insn))
3342     {
3343     case TYPE_FMOV:
3344       if (which_alternative == 2)
3345         return standard_80387_constant_opcode (operands[1]);
3346       return output_387_reg_move (insn, operands);
3348     case TYPE_MULTI:
3349       return "#";
3351     default:
3352       gcc_unreachable ();
3353     }
3355   [(set (attr "isa")
3356         (cond [(eq_attr "alternative" "7,10")
3357                  (const_string "nox64")
3358                (eq_attr "alternative" "8,11")
3359                  (const_string "x64")
3360               ]
3361               (const_string "*")))
3362    (set (attr "type")
3363         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3364                  (const_string "multi")
3365               ]
3366               (const_string "fmov")))
3367    (set (attr "mode")
3368         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3369                  (if_then_else (match_test "TARGET_64BIT")
3370                    (const_string "DI")
3371                    (const_string "SI"))
3372               ]
3373               (const_string "XF")))
3374    (set (attr "preferred_for_size")
3375      (cond [(eq_attr "alternative" "3,4")
3376               (symbol_ref "false")]
3377            (symbol_ref "true")))
3378    (set (attr "enabled")
3379      (cond [(eq_attr "alternative" "9,10,11")
3380               (if_then_else
3381                 (match_test "TARGET_HARD_XF_REGS")
3382                 (symbol_ref "false")
3383                 (const_string "*"))
3384             (not (match_test "TARGET_HARD_XF_REGS"))
3385               (symbol_ref "false")
3386            ]
3387            (const_string "*")))])
3388    
3389 (define_split
3390   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3391         (match_operand:XF 1 "general_gr_operand"))]
3392   "reload_completed"
3393   [(const_int 0)]
3394   "ix86_split_long_move (operands); DONE;")
3396 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3397 (define_insn "*movdf_internal"
3398   [(set (match_operand:DF 0 "nonimmediate_operand"
3399     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r  ,o ,r  ,m")
3400         (match_operand:DF 1 "general_operand"
3401     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3402   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403    && (lra_in_progress || reload_completed
3404        || !CONST_DOUBLE_P (operands[1])
3405        || ((optimize_function_for_size_p (cfun)
3406             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3407            && ((IS_STACK_MODE (DFmode)
3408                 && standard_80387_constant_p (operands[1]) > 0)
3409                || (TARGET_SSE2 && TARGET_SSE_MATH
3410                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3411            && !memory_operand (operands[0], DFmode))
3412        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3413            && memory_operand (operands[0], DFmode))
3414        || !TARGET_HARD_DF_REGS)"
3416   switch (get_attr_type (insn))
3417     {
3418     case TYPE_FMOV:
3419       if (which_alternative == 2)
3420         return standard_80387_constant_opcode (operands[1]);
3421       return output_387_reg_move (insn, operands);
3423     case TYPE_MULTI:
3424       return "#";
3426     case TYPE_IMOV:
3427       if (get_attr_mode (insn) == MODE_SI)
3428         return "mov{l}\t{%1, %k0|%k0, %1}";
3429       else if (which_alternative == 11)
3430         return "movabs{q}\t{%1, %0|%0, %1}";
3431       else
3432         return "mov{q}\t{%1, %0|%0, %1}";
3434     case TYPE_SSELOG1:
3435       return standard_sse_constant_opcode (insn, operands);
3437     case TYPE_SSEMOV:
3438       switch (get_attr_mode (insn))
3439         {
3440         case MODE_DF:
3441           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3442             return "vmovsd\t{%d1, %0|%0, %d1}";
3443           return "%vmovsd\t{%1, %0|%0, %1}";
3445         case MODE_V4SF:
3446           return "%vmovaps\t{%1, %0|%0, %1}";
3447         case MODE_V8DF:
3448           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3449         case MODE_V2DF:
3450           return "%vmovapd\t{%1, %0|%0, %1}";
3452         case MODE_V2SF:
3453           gcc_assert (!TARGET_AVX);
3454           return "movlps\t{%1, %0|%0, %1}";
3455         case MODE_V1DF:
3456           gcc_assert (!TARGET_AVX);
3457           return "movlpd\t{%1, %0|%0, %1}";
3459         case MODE_DI:
3460           /* Handle broken assemblers that require movd instead of movq.  */
3461           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3462               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3463             return "%vmovd\t{%1, %0|%0, %1}";
3464           return "%vmovq\t{%1, %0|%0, %1}";
3466         default:
3467           gcc_unreachable ();
3468         }
3470     default:
3471       gcc_unreachable ();
3472     }
3474   [(set (attr "isa")
3475         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3476                  (const_string "nox64")
3477                (eq_attr "alternative" "8,9,10,11,24,25")
3478                  (const_string "x64")
3479                (eq_attr "alternative" "12,13,14,15")
3480                  (const_string "sse2")
3481                (eq_attr "alternative" "20,21")
3482                  (const_string "x64_sse2")
3483               ]
3484               (const_string "*")))
3485    (set (attr "type")
3486         (cond [(eq_attr "alternative" "0,1,2")
3487                  (const_string "fmov")
3488                (eq_attr "alternative" "3,4,5,6,7,22,23")
3489                  (const_string "multi")
3490                (eq_attr "alternative" "8,9,10,11,24,25")
3491                  (const_string "imov")
3492                (eq_attr "alternative" "12,16")
3493                  (const_string "sselog1")
3494               ]
3495               (const_string "ssemov")))
3496    (set (attr "modrm")
3497      (if_then_else (eq_attr "alternative" "11")
3498        (const_string "0")
3499        (const_string "*")))
3500    (set (attr "length_immediate")
3501      (if_then_else (eq_attr "alternative" "11")
3502        (const_string "8")
3503        (const_string "*")))
3504    (set (attr "prefix")
3505      (if_then_else (eq_attr "type" "sselog1,ssemov")
3506        (const_string "maybe_vex")
3507        (const_string "orig")))
3508    (set (attr "prefix_data16")
3509      (if_then_else
3510        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3511             (eq_attr "mode" "V1DF"))
3512        (const_string "1")
3513        (const_string "*")))
3514    (set (attr "mode")
3515         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3516                  (const_string "SI")
3517                (eq_attr "alternative" "8,9,11,20,21,24,25")
3518                  (const_string "DI")
3520                /* xorps is one byte shorter for non-AVX targets.  */
3521                (eq_attr "alternative" "12,16")
3522                  (cond [(not (match_test "TARGET_SSE2"))
3523                           (const_string "V4SF")
3524                         (and (match_test "TARGET_AVX512F")
3525                           (not (match_test "TARGET_PREFER_AVX256")))
3526                           (const_string "XI")
3527                         (match_test "TARGET_AVX")
3528                           (const_string "V2DF")
3529                         (match_test "optimize_function_for_size_p (cfun)")
3530                           (const_string "V4SF")
3531                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3532                           (const_string "TI")
3533                        ]
3534                        (const_string "V2DF"))
3536                /* For architectures resolving dependencies on
3537                   whole SSE registers use movapd to break dependency
3538                   chains, otherwise use short move to avoid extra work.  */
3540                /* movaps is one byte shorter for non-AVX targets.  */
3541                (eq_attr "alternative" "13,17")
3542                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3543                                   (not (match_test "TARGET_AVX512VL")))
3544                              (ior (match_operand 0 "ext_sse_reg_operand")
3545                                   (match_operand 1 "ext_sse_reg_operand")))
3546                           (const_string "V8DF")
3547                         (ior (not (match_test "TARGET_SSE2"))
3548                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3549                           (const_string "V4SF")
3550                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3551                           (const_string "V2DF")
3552                         (match_test "TARGET_AVX")
3553                           (const_string "DF")
3554                         (match_test "optimize_function_for_size_p (cfun)")
3555                           (const_string "V4SF")
3556                        ]
3557                        (const_string "DF"))
3559                /* For architectures resolving dependencies on register
3560                   parts we may avoid extra work to zero out upper part
3561                   of register.  */
3562                (eq_attr "alternative" "14,18")
3563                  (cond [(not (match_test "TARGET_SSE2"))
3564                           (const_string "V2SF")
3565                         (match_test "TARGET_AVX")
3566                           (const_string "DF")
3567                         (match_test "TARGET_SSE_SPLIT_REGS")
3568                           (const_string "V1DF")
3569                        ]
3570                        (const_string "DF"))
3572                (and (eq_attr "alternative" "15,19")
3573                     (not (match_test "TARGET_SSE2")))
3574                  (const_string "V2SF")
3575               ]
3576               (const_string "DF")))
3577    (set (attr "preferred_for_size")
3578      (cond [(eq_attr "alternative" "3,4")
3579               (symbol_ref "false")]
3580            (symbol_ref "true")))
3581    (set (attr "preferred_for_speed")
3582      (cond [(eq_attr "alternative" "3,4")
3583               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3584             (eq_attr "alternative" "20")
3585               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3586             (eq_attr "alternative" "21")
3587               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3588            ]
3589            (symbol_ref "true")))
3590    (set (attr "enabled")
3591      (cond [(eq_attr "alternative" "22,23,24,25")
3592               (if_then_else
3593                 (match_test "TARGET_HARD_DF_REGS")
3594                 (symbol_ref "false")
3595                 (const_string "*"))
3596             (not (match_test "TARGET_HARD_DF_REGS"))
3597               (symbol_ref "false")
3598            ]
3599            (const_string "*")))])
3601 (define_split
3602   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3603         (match_operand:DF 1 "general_gr_operand"))]
3604   "!TARGET_64BIT && reload_completed"
3605   [(const_int 0)]
3606   "ix86_split_long_move (operands); DONE;")
3608 (define_insn "*movsf_internal"
3609   [(set (match_operand:SF 0 "nonimmediate_operand"
3610           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
3611         (match_operand:SF 1 "general_operand"
3612           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
3613   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3614    && (lra_in_progress || reload_completed
3615        || !CONST_DOUBLE_P (operands[1])
3616        || ((optimize_function_for_size_p (cfun)
3617             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3618            && ((IS_STACK_MODE (SFmode)
3619                 && standard_80387_constant_p (operands[1]) > 0)
3620                || (TARGET_SSE && TARGET_SSE_MATH
3621                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3622        || memory_operand (operands[0], SFmode)
3623        || !TARGET_HARD_SF_REGS)"
3625   switch (get_attr_type (insn))
3626     {
3627     case TYPE_FMOV:
3628       if (which_alternative == 2)
3629         return standard_80387_constant_opcode (operands[1]);
3630       return output_387_reg_move (insn, operands);
3632     case TYPE_IMOV:
3633       return "mov{l}\t{%1, %0|%0, %1}";
3635     case TYPE_SSELOG1:
3636       return standard_sse_constant_opcode (insn, operands);
3638     case TYPE_SSEMOV:
3639       switch (get_attr_mode (insn))
3640         {
3641         case MODE_SF:
3642           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3643             return "vmovss\t{%d1, %0|%0, %d1}";
3644           return "%vmovss\t{%1, %0|%0, %1}";
3646         case MODE_V16SF:
3647           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3648         case MODE_V4SF:
3649           return "%vmovaps\t{%1, %0|%0, %1}";
3651         case MODE_SI:
3652           return "%vmovd\t{%1, %0|%0, %1}";
3654         default:
3655           gcc_unreachable ();
3656         }
3658     case TYPE_MMXMOV:
3659       switch (get_attr_mode (insn))
3660         {
3661         case MODE_DI:
3662           return "movq\t{%1, %0|%0, %1}";
3663         case MODE_SI:
3664           return "movd\t{%1, %0|%0, %1}";
3666         default:
3667           gcc_unreachable ();
3668         }
3670     default:
3671       gcc_unreachable ();
3672     }
3674   [(set (attr "isa")
3675      (cond [(eq_attr "alternative" "14,15")
3676               (const_string "sse2")
3677            ]
3678            (const_string "*")))
3679    (set (attr "type")
3680         (cond [(eq_attr "alternative" "0,1,2")
3681                  (const_string "fmov")
3682                (eq_attr "alternative" "3,4,16,17")
3683                  (const_string "imov")
3684                (eq_attr "alternative" "5")
3685                  (const_string "sselog1")
3686                (eq_attr "alternative" "11,12,13,14,15")
3687                  (const_string "mmxmov")
3688               ]
3689               (const_string "ssemov")))
3690    (set (attr "prefix")
3691      (if_then_else (eq_attr "type" "sselog1,ssemov")
3692        (const_string "maybe_vex")
3693        (const_string "orig")))
3694    (set (attr "prefix_data16")
3695      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3696        (const_string "1")
3697        (const_string "*")))
3698    (set (attr "mode")
3699         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3700                  (const_string "SI")
3701                (eq_attr "alternative" "11")
3702                  (const_string "DI")
3703                (eq_attr "alternative" "5")
3704                  (cond [(not (match_test "TARGET_SSE2"))
3705                           (const_string "V4SF")
3706                         (and (match_test "TARGET_AVX512F")
3707                           (not (match_test "TARGET_PREFER_AVX256")))
3708                           (const_string "V16SF")
3709                         (match_test "TARGET_AVX")
3710                           (const_string "V4SF")
3711                         (match_test "optimize_function_for_size_p (cfun)")
3712                           (const_string "V4SF")
3713                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3714                           (const_string "TI")
3715                        ]
3716                        (const_string "V4SF"))
3718                /* For architectures resolving dependencies on
3719                   whole SSE registers use APS move to break dependency
3720                   chains, otherwise use short move to avoid extra work.
3722                   Do the same for architectures resolving dependencies on
3723                   the parts.  While in DF mode it is better to always handle
3724                   just register parts, the SF mode is different due to lack
3725                   of instructions to load just part of the register.  It is
3726                   better to maintain the whole registers in single format
3727                   to avoid problems on using packed logical operations.  */
3728                (eq_attr "alternative" "6")
3729                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3730                                   (not (match_test "TARGET_AVX512VL")))
3731                              (ior (match_operand 0 "ext_sse_reg_operand")
3732                                   (match_operand 1 "ext_sse_reg_operand")))
3733                           (const_string "V16SF")
3734                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3735                              (match_test "TARGET_SSE_SPLIT_REGS"))
3736                           (const_string "V4SF")
3737                        ]
3738                        (const_string "SF"))
3739               ]
3740               (const_string "SF")))
3741    (set (attr "preferred_for_speed")
3742      (cond [(eq_attr "alternative" "9,14")
3743               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3744             (eq_attr "alternative" "10,15")
3745               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3746            ]
3747            (symbol_ref "true")))
3748    (set (attr "enabled")
3749      (cond [(eq_attr "alternative" "16,17")
3750               (if_then_else
3751                 (match_test "TARGET_HARD_SF_REGS")
3752                 (symbol_ref "false")
3753                 (const_string "*"))
3754             (not (match_test "TARGET_HARD_SF_REGS"))
3755               (symbol_ref "false")
3756            ]
3757            (const_string "*")))])
3759 (define_split
3760   [(set (match_operand 0 "any_fp_register_operand")
3761         (match_operand 1 "memory_operand"))]
3762   "reload_completed
3763    && (GET_MODE (operands[0]) == TFmode
3764        || GET_MODE (operands[0]) == XFmode
3765        || GET_MODE (operands[0]) == DFmode
3766        || GET_MODE (operands[0]) == SFmode)
3767    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3768   [(set (match_dup 0) (match_dup 2))]
3769   "operands[2] = find_constant_src (curr_insn);")
3771 (define_split
3772   [(set (match_operand 0 "any_fp_register_operand")
3773         (float_extend (match_operand 1 "memory_operand")))]
3774   "reload_completed
3775    && (GET_MODE (operands[0]) == TFmode
3776        || GET_MODE (operands[0]) == XFmode
3777        || GET_MODE (operands[0]) == DFmode)
3778    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3779   [(set (match_dup 0) (match_dup 2))]
3780   "operands[2] = find_constant_src (curr_insn);")
3782 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3783 (define_split
3784   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3785         (match_operand:X87MODEF 1 "immediate_operand"))]
3786   "reload_completed
3787    && (standard_80387_constant_p (operands[1]) == 8
3788        || standard_80387_constant_p (operands[1]) == 9)"
3789   [(set (match_dup 0)(match_dup 1))
3790    (set (match_dup 0)
3791         (neg:X87MODEF (match_dup 0)))]
3793   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3794     operands[1] = CONST0_RTX (<MODE>mode);
3795   else
3796     operands[1] = CONST1_RTX (<MODE>mode);
3799 (define_insn "*swapxf"
3800   [(set (match_operand:XF 0 "register_operand" "+f")
3801         (match_operand:XF 1 "register_operand" "+f"))
3802    (set (match_dup 1)
3803         (match_dup 0))]
3804   "TARGET_80387"
3806   if (STACK_TOP_P (operands[0]))
3807     return "fxch\t%1";
3808   else
3809     return "fxch\t%0";
3811   [(set_attr "type" "fxch")
3812    (set_attr "mode" "XF")])
3815 ;; Zero extension instructions
3817 (define_expand "zero_extendsidi2"
3818   [(set (match_operand:DI 0 "nonimmediate_operand")
3819         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3821 (define_insn "*zero_extendsidi2"
3822   [(set (match_operand:DI 0 "nonimmediate_operand"
3823                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3824         (zero_extend:DI
3825          (match_operand:SI 1 "x86_64_zext_operand"
3826                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k,*km")))]
3827   ""
3829   switch (get_attr_type (insn))
3830     {
3831     case TYPE_IMOVX:
3832       if (ix86_use_lea_for_mov (insn, operands))
3833         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3834       else
3835         return "mov{l}\t{%1, %k0|%k0, %1}";
3837     case TYPE_MULTI:
3838       return "#";
3840     case TYPE_MMXMOV:
3841       return "movd\t{%1, %0|%0, %1}";
3843     case TYPE_SSEMOV:
3844       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3845         {
3846           if (EXT_REX_SSE_REG_P (operands[0])
3847               || EXT_REX_SSE_REG_P (operands[1]))
3848             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3849           else
3850             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3851         }
3853       if (GENERAL_REG_P (operands[0]))
3854         return "%vmovd\t{%1, %k0|%k0, %1}";
3856       return "%vmovd\t{%1, %0|%0, %1}";
3858     case TYPE_MSKMOV:
3859       return "kmovd\t{%1, %k0|%k0, %1}";
3861     default:
3862       gcc_unreachable ();
3863     }
3865   [(set (attr "isa")
3866      (cond [(eq_attr "alternative" "0,1,2")
3867               (const_string "nox64")
3868             (eq_attr "alternative" "3")
3869               (const_string "x64")
3870             (eq_attr "alternative" "7,8,9")
3871               (const_string "sse2")
3872             (eq_attr "alternative" "10")
3873               (const_string "sse4")
3874             (eq_attr "alternative" "11")
3875               (const_string "avx512f")
3876             (eq_attr "alternative" "12")
3877               (const_string "x64_avx512bw")
3878             (eq_attr "alternative" "13")
3879               (const_string "avx512bw")
3880            ]
3881            (const_string "*")))
3882    (set (attr "mmx_isa")
3883      (if_then_else (eq_attr "alternative" "5,6")
3884                    (const_string "native")
3885                    (const_string "*")))
3886    (set (attr "type")
3887      (cond [(eq_attr "alternative" "0,1,2,4")
3888               (const_string "multi")
3889             (eq_attr "alternative" "5,6")
3890               (const_string "mmxmov")
3891             (eq_attr "alternative" "7")
3892               (if_then_else (match_test "TARGET_64BIT")
3893                 (const_string "ssemov")
3894                 (const_string "multi"))
3895             (eq_attr "alternative" "8,9,10,11")
3896               (const_string "ssemov")
3897             (eq_attr "alternative" "12,13")
3898               (const_string "mskmov")
3899            ]
3900            (const_string "imovx")))
3901    (set (attr "prefix_extra")
3902      (if_then_else (eq_attr "alternative" "10,11")
3903        (const_string "1")
3904        (const_string "*")))
3905    (set (attr "prefix")
3906      (if_then_else (eq_attr "type" "ssemov")
3907        (const_string "maybe_vex")
3908        (const_string "orig")))
3909    (set (attr "prefix_0f")
3910      (if_then_else (eq_attr "type" "imovx")
3911        (const_string "0")
3912        (const_string "*")))
3913    (set (attr "mode")
3914      (cond [(eq_attr "alternative" "5,6")
3915               (const_string "DI")
3916             (and (eq_attr "alternative" "7")
3917                  (match_test "TARGET_64BIT"))
3918               (const_string "TI")
3919             (eq_attr "alternative" "8,10,11")
3920               (const_string "TI")
3921            ]
3922            (const_string "SI")))
3923    (set (attr "preferred_for_speed")
3924      (cond [(eq_attr "alternative" "7")
3925               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3926             (eq_attr "alternative" "5,8")
3927               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3928            ]
3929            (symbol_ref "true")))])
3931 (define_split
3932   [(set (match_operand:DI 0 "memory_operand")
3933         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3934   "reload_completed"
3935   [(set (match_dup 4) (const_int 0))]
3936   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3938 (define_split
3939   [(set (match_operand:DI 0 "general_reg_operand")
3940         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3941   "!TARGET_64BIT && reload_completed
3942    && REGNO (operands[0]) == REGNO (operands[1])"
3943   [(set (match_dup 4) (const_int 0))]
3944   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3946 (define_split
3947   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3948         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3949   "!TARGET_64BIT && reload_completed
3950    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3951   [(set (match_dup 3) (match_dup 1))
3952    (set (match_dup 4) (const_int 0))]
3953   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3955 (define_mode_attr kmov_isa
3956   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3958 (define_insn "zero_extend<mode>di2"
3959   [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3960         (zero_extend:DI
3961          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3962   "TARGET_64BIT"
3963   "@
3964    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3965    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3966    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3967   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3968    (set_attr "type" "imovx,mskmov,mskmov")
3969    (set_attr "mode" "SI,<MODE>,<MODE>")])
3971 (define_expand "zero_extend<mode>si2"
3972   [(set (match_operand:SI 0 "register_operand")
3973         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3974   ""
3976   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3977     {
3978       operands[1] = force_reg (<MODE>mode, operands[1]);
3979       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3980       DONE;
3981     }
3984 (define_insn_and_split "zero_extend<mode>si2_and"
3985   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3986         (zero_extend:SI
3987           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3988    (clobber (reg:CC FLAGS_REG))]
3989   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3990   "#"
3991   "&& reload_completed"
3992   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3993               (clobber (reg:CC FLAGS_REG))])]
3995   if (!REG_P (operands[1])
3996       || REGNO (operands[0]) != REGNO (operands[1]))
3997     {
3998       ix86_expand_clear (operands[0]);
4000       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4001       emit_insn (gen_movstrict<mode>
4002                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4003       DONE;
4004     }
4006   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4008   [(set_attr "type" "alu1")
4009    (set_attr "mode" "SI")])
4011 (define_insn "*zero_extend<mode>si2"
4012   [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4013         (zero_extend:SI
4014           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4015   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4016   "@
4017    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4018    kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4019    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4020   [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4021    (set_attr "type" "imovx,mskmov,mskmov")
4022    (set_attr "mode" "SI,<MODE>,<MODE>")])
4024 (define_expand "zero_extendqihi2"
4025   [(set (match_operand:HI 0 "register_operand")
4026         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4027   ""
4029   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4030     {
4031       operands[1] = force_reg (QImode, operands[1]);
4032       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4033       DONE;
4034     }
4037 (define_insn_and_split "zero_extendqihi2_and"
4038   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4039         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4040    (clobber (reg:CC FLAGS_REG))]
4041   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4042   "#"
4043   "&& reload_completed"
4044   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4045               (clobber (reg:CC FLAGS_REG))])]
4047   if (!REG_P (operands[1])
4048       || REGNO (operands[0]) != REGNO (operands[1]))
4049     {
4050       ix86_expand_clear (operands[0]);
4052       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4053       emit_insn (gen_movstrictqi
4054                   (gen_lowpart (QImode, operands[0]), operands[1]));
4055       DONE;
4056     }
4058   operands[0] = gen_lowpart (SImode, operands[0]);
4060   [(set_attr "type" "alu1")
4061    (set_attr "mode" "SI")])
4063 ; zero extend to SImode to avoid partial register stalls
4064 (define_insn "*zero_extendqihi2"
4065   [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4066         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4067   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4068   "@
4069    movz{bl|x}\t{%1, %k0|%k0, %1}
4070    kmovb\t{%1, %k0|%k0, %1}
4071    kmovb\t{%1, %0|%0, %1}"
4072   [(set_attr "isa" "*,avx512dq,avx512dq")
4073    (set_attr "type" "imovx,mskmov,mskmov")
4074    (set_attr "mode" "SI,QI,QI")])
4076 (define_insn_and_split "*zext<mode>_doubleword_and"
4077   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4078         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4079   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4080    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4081   "#"
4082   "&& reload_completed && GENERAL_REG_P (operands[0])"
4083   [(set (match_dup 2) (const_int 0))]
4085   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4087   emit_move_insn (operands[0], const0_rtx);
4089   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4090   emit_insn (gen_movstrict<mode>
4091              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4094 (define_insn_and_split "*zext<mode>_doubleword"
4095   [(set (match_operand:DI 0 "register_operand" "=r")
4096         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4097   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4098    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4099   "#"
4100   "&& reload_completed && GENERAL_REG_P (operands[0])"
4101   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4102    (set (match_dup 2) (const_int 0))]
4103   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4105 (define_insn_and_split "*zextsi_doubleword"
4106   [(set (match_operand:DI 0 "register_operand" "=r")
4107         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4108   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4109   "#"
4110   "&& reload_completed && GENERAL_REG_P (operands[0])"
4111   [(set (match_dup 0) (match_dup 1))
4112    (set (match_dup 2) (const_int 0))]
4113   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4115 ;; Sign extension instructions
4117 (define_expand "extendsidi2"
4118   [(set (match_operand:DI 0 "register_operand")
4119         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4120   ""
4122   if (!TARGET_64BIT)
4123     {
4124       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4125       DONE;
4126     }
4129 (define_insn "*extendsidi2_rex64"
4130   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4131         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4132   "TARGET_64BIT"
4133   "@
4134    {cltq|cdqe}
4135    movs{lq|x}\t{%1, %0|%0, %1}"
4136   [(set_attr "type" "imovx")
4137    (set_attr "mode" "DI")
4138    (set_attr "prefix_0f" "0")
4139    (set_attr "modrm" "0,1")])
4141 (define_insn "extendsidi2_1"
4142   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4143         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4144    (clobber (reg:CC FLAGS_REG))
4145    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4146   "!TARGET_64BIT"
4147   "#")
4149 ;; Split the memory case.  If the source register doesn't die, it will stay
4150 ;; this way, if it does die, following peephole2s take care of it.
4151 (define_split
4152   [(set (match_operand:DI 0 "memory_operand")
4153         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4154    (clobber (reg:CC FLAGS_REG))
4155    (clobber (match_operand:SI 2 "register_operand"))]
4156   "reload_completed"
4157   [(const_int 0)]
4159   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4161   emit_move_insn (operands[3], operands[1]);
4163   /* Generate a cltd if possible and doing so it profitable.  */
4164   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4165       && REGNO (operands[1]) == AX_REG
4166       && REGNO (operands[2]) == DX_REG)
4167     {
4168       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4169     }
4170   else
4171     {
4172       emit_move_insn (operands[2], operands[1]);
4173       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4174     }
4175   emit_move_insn (operands[4], operands[2]);
4176   DONE;
4179 ;; Peepholes for the case where the source register does die, after
4180 ;; being split with the above splitter.
4181 (define_peephole2
4182   [(set (match_operand:SI 0 "memory_operand")
4183         (match_operand:SI 1 "general_reg_operand"))
4184    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4185    (parallel [(set (match_dup 2)
4186                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4187                (clobber (reg:CC FLAGS_REG))])
4188    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4189   "REGNO (operands[1]) != REGNO (operands[2])
4190    && peep2_reg_dead_p (2, operands[1])
4191    && peep2_reg_dead_p (4, operands[2])
4192    && !reg_mentioned_p (operands[2], operands[3])"
4193   [(set (match_dup 0) (match_dup 1))
4194    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4195               (clobber (reg:CC FLAGS_REG))])
4196    (set (match_dup 3) (match_dup 1))])
4198 (define_peephole2
4199   [(set (match_operand:SI 0 "memory_operand")
4200         (match_operand:SI 1 "general_reg_operand"))
4201    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4202                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4203                (clobber (reg:CC FLAGS_REG))])
4204    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4205   "/* cltd is shorter than sarl $31, %eax */
4206    !optimize_function_for_size_p (cfun)
4207    && REGNO (operands[1]) == AX_REG
4208    && REGNO (operands[2]) == DX_REG
4209    && peep2_reg_dead_p (2, operands[1])
4210    && peep2_reg_dead_p (3, operands[2])
4211    && !reg_mentioned_p (operands[2], operands[3])"
4212   [(set (match_dup 0) (match_dup 1))
4213    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4214               (clobber (reg:CC FLAGS_REG))])
4215    (set (match_dup 3) (match_dup 1))])
4217 ;; Extend to register case.  Optimize case where source and destination
4218 ;; registers match and cases where we can use cltd.
4219 (define_split
4220   [(set (match_operand:DI 0 "register_operand")
4221         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4222    (clobber (reg:CC FLAGS_REG))
4223    (clobber (match_scratch:SI 2))]
4224   "reload_completed"
4225   [(const_int 0)]
4227   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4229   if (REGNO (operands[3]) != REGNO (operands[1]))
4230     emit_move_insn (operands[3], operands[1]);
4232   /* Generate a cltd if possible and doing so it profitable.  */
4233   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4234       && REGNO (operands[3]) == AX_REG
4235       && REGNO (operands[4]) == DX_REG)
4236     {
4237       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4238       DONE;
4239     }
4241   if (REGNO (operands[4]) != REGNO (operands[1]))
4242     emit_move_insn (operands[4], operands[1]);
4244   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4245   DONE;
4248 (define_insn "extend<mode>di2"
4249   [(set (match_operand:DI 0 "register_operand" "=r")
4250         (sign_extend:DI
4251          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4252   "TARGET_64BIT"
4253   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4254   [(set_attr "type" "imovx")
4255    (set_attr "mode" "DI")])
4257 (define_insn "extendhisi2"
4258   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4259         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4260   ""
4262   switch (get_attr_prefix_0f (insn))
4263     {
4264     case 0:
4265       return "{cwtl|cwde}";
4266     default:
4267       return "movs{wl|x}\t{%1, %0|%0, %1}";
4268     }
4270   [(set_attr "type" "imovx")
4271    (set_attr "mode" "SI")
4272    (set (attr "prefix_0f")
4273      ;; movsx is short decodable while cwtl is vector decoded.
4274      (if_then_else (and (eq_attr "cpu" "!k6")
4275                         (eq_attr "alternative" "0"))
4276         (const_string "0")
4277         (const_string "1")))
4278    (set (attr "znver1_decode")
4279      (if_then_else (eq_attr "prefix_0f" "0")
4280         (const_string "double")
4281         (const_string "direct")))
4282    (set (attr "modrm")
4283      (if_then_else (eq_attr "prefix_0f" "0")
4284         (const_string "0")
4285         (const_string "1")))])
4287 (define_insn "*extendhisi2_zext"
4288   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4289         (zero_extend:DI
4290          (sign_extend:SI
4291           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4292   "TARGET_64BIT"
4294   switch (get_attr_prefix_0f (insn))
4295     {
4296     case 0:
4297       return "{cwtl|cwde}";
4298     default:
4299       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4300     }
4302   [(set_attr "type" "imovx")
4303    (set_attr "mode" "SI")
4304    (set (attr "prefix_0f")
4305      ;; movsx is short decodable while cwtl is vector decoded.
4306      (if_then_else (and (eq_attr "cpu" "!k6")
4307                         (eq_attr "alternative" "0"))
4308         (const_string "0")
4309         (const_string "1")))
4310    (set (attr "modrm")
4311      (if_then_else (eq_attr "prefix_0f" "0")
4312         (const_string "0")
4313         (const_string "1")))])
4315 (define_insn "extendqisi2"
4316   [(set (match_operand:SI 0 "register_operand" "=r")
4317         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4318   ""
4319   "movs{bl|x}\t{%1, %0|%0, %1}"
4320    [(set_attr "type" "imovx")
4321     (set_attr "mode" "SI")])
4323 (define_insn "*extendqisi2_zext"
4324   [(set (match_operand:DI 0 "register_operand" "=r")
4325         (zero_extend:DI
4326           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4327   "TARGET_64BIT"
4328   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4329    [(set_attr "type" "imovx")
4330     (set_attr "mode" "SI")])
4332 (define_insn "extendqihi2"
4333   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4334         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4335   ""
4337   switch (get_attr_prefix_0f (insn))
4338     {
4339     case 0:
4340       return "{cbtw|cbw}";
4341     default:
4342       return "movs{bw|x}\t{%1, %0|%0, %1}";
4343     }
4345   [(set_attr "type" "imovx")
4346    (set_attr "mode" "HI")
4347    (set (attr "prefix_0f")
4348      ;; movsx is short decodable while cwtl is vector decoded.
4349      (if_then_else (and (eq_attr "cpu" "!k6")
4350                         (eq_attr "alternative" "0"))
4351         (const_string "0")
4352         (const_string "1")))
4353    (set (attr "modrm")
4354      (if_then_else (eq_attr "prefix_0f" "0")
4355         (const_string "0")
4356         (const_string "1")))])
4358 ;; Conversions between float and double.
4360 ;; These are all no-ops in the model used for the 80387.
4361 ;; So just emit moves.
4363 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4364 (define_split
4365   [(set (match_operand:DF 0 "push_operand")
4366         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4367   "reload_completed"
4368   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4369    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4371 (define_split
4372   [(set (match_operand:XF 0 "push_operand")
4373         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4374   "reload_completed"
4375   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4376    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4377   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4379 (define_expand "extendsfdf2"
4380   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4381         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4382   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4384   /* ??? Needed for compress_float_constant since all fp constants
4385      are TARGET_LEGITIMATE_CONSTANT_P.  */
4386   if (CONST_DOUBLE_P (operands[1]))
4387     {
4388       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4389           && standard_80387_constant_p (operands[1]) > 0)
4390         {
4391           operands[1] = simplify_const_unary_operation
4392             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4393           emit_move_insn_1 (operands[0], operands[1]);
4394           DONE;
4395         }
4396       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4397     }
4400 (define_insn "*extendsfdf2"
4401   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4402         (float_extend:DF
4403           (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4404   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4406   switch (which_alternative)
4407     {
4408     case 0:
4409     case 1:
4410       return output_387_reg_move (insn, operands);
4412     case 2:
4413       return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4414     case 3:
4415       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4417     default:
4418       gcc_unreachable ();
4419     }
4421   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4422    (set_attr "avx_partial_xmm_update" "false,false,false,true")
4423    (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4424    (set_attr "mode" "SF,XF,DF,DF")
4425    (set (attr "enabled")
4426      (if_then_else
4427        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4428        (if_then_else
4429          (eq_attr "alternative" "0,1")
4430          (symbol_ref "TARGET_MIX_SSE_I387")
4431          (symbol_ref "true"))
4432        (if_then_else
4433          (eq_attr "alternative" "0,1")
4434          (symbol_ref "true")
4435          (symbol_ref "false"))))])
4437 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4438    cvtss2sd:
4439       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4440       cvtps2pd xmm2,xmm1
4441    We do the conversion post reload to avoid producing of 128bit spills
4442    that might lead to ICE on 32bit target.  The sequence unlikely combine
4443    anyway.  */
4444 (define_split
4445   [(set (match_operand:DF 0 "sse_reg_operand")
4446         (float_extend:DF
4447           (match_operand:SF 1 "nonimmediate_operand")))]
4448   "TARGET_USE_VECTOR_FP_CONVERTS
4449    && optimize_insn_for_speed_p ()
4450    && reload_completed
4451    && (!EXT_REX_SSE_REG_P (operands[0])
4452        || TARGET_AVX512VL)"
4453    [(set (match_dup 2)
4454          (float_extend:V2DF
4455            (vec_select:V2SF
4456              (match_dup 3)
4457              (parallel [(const_int 0) (const_int 1)]))))]
4459   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4460   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4461   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4462      Try to avoid move when unpacking can be done in source.  */
4463   if (REG_P (operands[1]))
4464     {
4465       /* If it is unsafe to overwrite upper half of source, we need
4466          to move to destination and unpack there.  */
4467       if (REGNO (operands[0]) != REGNO (operands[1])
4468           || (EXT_REX_SSE_REG_P (operands[1])
4469               && !TARGET_AVX512VL))
4470         {
4471           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4472           emit_move_insn (tmp, operands[1]);
4473         }
4474       else
4475         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4476       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4477          =v, v, then vbroadcastss will be only needed for AVX512F without
4478          AVX512VL.  */
4479       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4480         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4481                                                operands[3]));
4482       else
4483         {
4484           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4485           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4486         }
4487     }
4488   else
4489     emit_insn (gen_vec_setv4sf_0 (operands[3],
4490                                   CONST0_RTX (V4SFmode), operands[1]));
4493 ;; It's more profitable to split and then extend in the same register.
4494 (define_peephole2
4495   [(set (match_operand:DF 0 "sse_reg_operand")
4496         (float_extend:DF
4497           (match_operand:SF 1 "memory_operand")))]
4498   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4499    && optimize_insn_for_speed_p ()"
4500   [(set (match_dup 2) (match_dup 1))
4501    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4502   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4504 ;; Break partial SSE register dependency stall.  This splitter should split
4505 ;; late in the pass sequence (after register rename pass), so allocated
4506 ;; registers won't change anymore
4508 (define_split
4509   [(set (match_operand:DF 0 "sse_reg_operand")
4510         (float_extend:DF
4511           (match_operand:SF 1 "nonimmediate_operand")))]
4512   "!TARGET_AVX
4513    && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4514    && optimize_function_for_speed_p (cfun)
4515    && (!REG_P (operands[1])
4516        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4517    && (!EXT_REX_SSE_REG_P (operands[0])
4518        || TARGET_AVX512VL)"
4519   [(set (match_dup 0)
4520         (vec_merge:V2DF
4521           (vec_duplicate:V2DF
4522             (float_extend:DF
4523               (match_dup 1)))
4524           (match_dup 0)
4525           (const_int 1)))]
4527   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4528   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4531 (define_expand "extend<mode>xf2"
4532   [(set (match_operand:XF 0 "nonimmediate_operand")
4533         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4534   "TARGET_80387"
4536   /* ??? Needed for compress_float_constant since all fp constants
4537      are TARGET_LEGITIMATE_CONSTANT_P.  */
4538   if (CONST_DOUBLE_P (operands[1]))
4539     {
4540       if (standard_80387_constant_p (operands[1]) > 0)
4541         {
4542           operands[1] = simplify_const_unary_operation
4543             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4544           emit_move_insn_1 (operands[0], operands[1]);
4545           DONE;
4546         }
4547       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4548     }
4551 (define_insn "*extend<mode>xf2_i387"
4552   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4553         (float_extend:XF
4554           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4555   "TARGET_80387"
4556   "* return output_387_reg_move (insn, operands);"
4557   [(set_attr "type" "fmov")
4558    (set_attr "mode" "<MODE>,XF")])
4560 ;; %%% This seems like bad news.
4561 ;; This cannot output into an f-reg because there is no way to be sure
4562 ;; of truncating in that case.  Otherwise this is just like a simple move
4563 ;; insn.  So we pretend we can output to a reg in order to get better
4564 ;; register preferencing, but we really use a stack slot.
4566 ;; Conversion from DFmode to SFmode.
4568 (define_insn "truncdfsf2"
4569   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4570         (float_truncate:SF
4571           (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4572   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4574   switch (which_alternative)
4575     {
4576     case 0:
4577     case 1:
4578       return output_387_reg_move (insn, operands);
4580     case 2:
4581       return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4582     case 3:
4583       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4585     default:
4586       gcc_unreachable ();
4587     }
4589   [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4590    (set_attr "avx_partial_xmm_update" "false,false,false,true")
4591    (set_attr "mode" "SF")
4592    (set (attr "enabled")
4593      (if_then_else
4594        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4595        (cond [(eq_attr "alternative" "0")
4596                 (symbol_ref "TARGET_MIX_SSE_I387")
4597               (eq_attr "alternative" "1")
4598                 (symbol_ref "TARGET_MIX_SSE_I387
4599                              && flag_unsafe_math_optimizations")
4600            ]
4601            (symbol_ref "true"))
4602        (cond [(eq_attr "alternative" "0")
4603                 (symbol_ref "true")
4604               (eq_attr "alternative" "1")
4605                 (symbol_ref "flag_unsafe_math_optimizations")
4606            ]
4607            (symbol_ref "false"))))])
4609 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4610    cvtsd2ss:
4611       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4612       cvtpd2ps xmm2,xmm1
4613    We do the conversion post reload to avoid producing of 128bit spills
4614    that might lead to ICE on 32bit target.  The sequence unlikely combine
4615    anyway.  */
4616 (define_split
4617   [(set (match_operand:SF 0 "sse_reg_operand")
4618         (float_truncate:SF
4619           (match_operand:DF 1 "nonimmediate_operand")))]
4620   "TARGET_USE_VECTOR_FP_CONVERTS
4621    && optimize_insn_for_speed_p ()
4622    && reload_completed
4623    && (!EXT_REX_SSE_REG_P (operands[0])
4624        || TARGET_AVX512VL)"
4625    [(set (match_dup 2)
4626          (vec_concat:V4SF
4627            (float_truncate:V2SF
4628              (match_dup 4))
4629            (match_dup 3)))]
4631   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4632   operands[3] = CONST0_RTX (V2SFmode);
4633   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4634   /* Use movsd for loading from memory, unpcklpd for registers.
4635      Try to avoid move when unpacking can be done in source, or SSE3
4636      movddup is available.  */
4637   if (REG_P (operands[1]))
4638     {
4639       if (!TARGET_SSE3
4640           && REGNO (operands[0]) != REGNO (operands[1]))
4641         {
4642           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4643           emit_move_insn (tmp, operands[1]);
4644           operands[1] = tmp;
4645         }
4646       else if (!TARGET_SSE3)
4647         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4648       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4649     }
4650   else
4651     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4652                                    CONST0_RTX (DFmode)));
4655 ;; It's more profitable to split and then truncate in the same register.
4656 (define_peephole2
4657   [(set (match_operand:SF 0 "sse_reg_operand")
4658         (float_truncate:SF
4659           (match_operand:DF 1 "memory_operand")))]
4660   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4661    && optimize_insn_for_speed_p ()"
4662   [(set (match_dup 2) (match_dup 1))
4663    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4664   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4666 ;; Break partial SSE register dependency stall.  This splitter should split
4667 ;; late in the pass sequence (after register rename pass), so allocated
4668 ;; registers won't change anymore
4670 (define_split
4671   [(set (match_operand:SF 0 "sse_reg_operand")
4672         (float_truncate:SF
4673           (match_operand:DF 1 "nonimmediate_operand")))]
4674   "!TARGET_AVX
4675    && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4676    && optimize_function_for_speed_p (cfun)
4677    && (!REG_P (operands[1])
4678        || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4679    && (!EXT_REX_SSE_REG_P (operands[0])
4680        || TARGET_AVX512VL)"
4681   [(set (match_dup 0)
4682         (vec_merge:V4SF
4683           (vec_duplicate:V4SF
4684             (float_truncate:SF
4685               (match_dup 1)))
4686           (match_dup 0)
4687           (const_int 1)))]
4689   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4690   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4693 ;; Conversion from XFmode to {SF,DF}mode
4695 (define_insn "truncxf<mode>2"
4696   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4697         (float_truncate:MODEF
4698           (match_operand:XF 1 "register_operand" "f,f")))]
4699   "TARGET_80387"
4700   "* return output_387_reg_move (insn, operands);"
4701   [(set_attr "type" "fmov")
4702    (set_attr "mode" "<MODE>")
4703    (set (attr "enabled")
4704      (cond [(eq_attr "alternative" "1")
4705               (symbol_ref "flag_unsafe_math_optimizations")
4706            ]
4707            (symbol_ref "true")))])
4709 ;; Signed conversion to DImode.
4711 (define_expand "fix_truncxfdi2"
4712   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4713                    (fix:DI (match_operand:XF 1 "register_operand")))
4714               (clobber (reg:CC FLAGS_REG))])]
4715   "TARGET_80387"
4717   if (TARGET_FISTTP)
4718    {
4719      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4720      DONE;
4721    }
4724 (define_expand "fix_trunc<mode>di2"
4725   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4726                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4727               (clobber (reg:CC FLAGS_REG))])]
4728   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4730   if (TARGET_FISTTP
4731       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4732    {
4733      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4734      DONE;
4735    }
4736   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4737    {
4738      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4739      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4740      if (out != operands[0])
4741         emit_move_insn (operands[0], out);
4742      DONE;
4743    }
4746 ;; Signed conversion to SImode.
4748 (define_expand "fix_truncxfsi2"
4749   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4750                    (fix:SI (match_operand:XF 1 "register_operand")))
4751               (clobber (reg:CC FLAGS_REG))])]
4752   "TARGET_80387"
4754   if (TARGET_FISTTP)
4755    {
4756      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4757      DONE;
4758    }
4761 (define_expand "fix_trunc<mode>si2"
4762   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4763                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4764               (clobber (reg:CC FLAGS_REG))])]
4765   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4767   if (TARGET_FISTTP
4768       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4769    {
4770      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4771      DONE;
4772    }
4773   if (SSE_FLOAT_MODE_P (<MODE>mode))
4774    {
4775      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4776      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4777      if (out != operands[0])
4778         emit_move_insn (operands[0], out);
4779      DONE;
4780    }
4783 ;; Signed conversion to HImode.
4785 (define_expand "fix_trunc<mode>hi2"
4786   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4787                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4788               (clobber (reg:CC FLAGS_REG))])]
4789   "TARGET_80387
4790    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4792   if (TARGET_FISTTP)
4793    {
4794      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4795      DONE;
4796    }
4799 ;; Unsigned conversion to DImode
4801 (define_insn "fixuns_trunc<mode>di2"
4802   [(set (match_operand:DI 0 "register_operand" "=r")
4803         (unsigned_fix:DI
4804           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4805   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4806   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4807   [(set_attr "type" "sseicvt")
4808    (set_attr "prefix" "evex")
4809    (set_attr "mode" "DI")])
4811 ;; Unsigned conversion to SImode.
4813 (define_expand "fixuns_trunc<mode>si2"
4814   [(parallel
4815     [(set (match_operand:SI 0 "register_operand")
4816           (unsigned_fix:SI
4817             (match_operand:MODEF 1 "nonimmediate_operand")))
4818      (use (match_dup 2))
4819      (clobber (match_scratch:<ssevecmode> 3))
4820      (clobber (match_scratch:<ssevecmode> 4))])]
4821   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4823   machine_mode mode = <MODE>mode;
4824   machine_mode vecmode = <ssevecmode>mode;
4825   REAL_VALUE_TYPE TWO31r;
4826   rtx two31;
4828   if (TARGET_AVX512F)
4829     {
4830       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4831       DONE;
4832     }
4834   if (optimize_insn_for_size_p ())
4835     FAIL;
4837   real_ldexp (&TWO31r, &dconst1, 31);
4838   two31 = const_double_from_real_value (TWO31r, mode);
4839   two31 = ix86_build_const_vector (vecmode, true, two31);
4840   operands[2] = force_reg (vecmode, two31);
4843 (define_insn "fixuns_trunc<mode>si2_avx512f"
4844   [(set (match_operand:SI 0 "register_operand" "=r")
4845         (unsigned_fix:SI
4846           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4847   "TARGET_AVX512F && TARGET_SSE_MATH"
4848   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4849   [(set_attr "type" "sseicvt")
4850    (set_attr "prefix" "evex")
4851    (set_attr "mode" "SI")])
4853 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4854   [(set (match_operand:DI 0 "register_operand" "=r")
4855         (zero_extend:DI
4856           (unsigned_fix:SI
4857             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4858   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4859   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4860   [(set_attr "type" "sseicvt")
4861    (set_attr "prefix" "evex")
4862    (set_attr "mode" "SI")])
4864 (define_insn_and_split "*fixuns_trunc<mode>_1"
4865   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4866         (unsigned_fix:SI
4867           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4868    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4869    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4870    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4871   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4872    && optimize_function_for_speed_p (cfun)"
4873   "#"
4874   "&& reload_completed"
4875   [(const_int 0)]
4877   ix86_split_convert_uns_si_sse (operands);
4878   DONE;
4881 ;; Unsigned conversion to HImode.
4882 ;; Without these patterns, we'll try the unsigned SI conversion which
4883 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4885 (define_expand "fixuns_trunc<mode>hi2"
4886   [(set (match_dup 2)
4887         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4888    (set (match_operand:HI 0 "nonimmediate_operand")
4889         (subreg:HI (match_dup 2) 0))]
4890   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4891   "operands[2] = gen_reg_rtx (SImode);")
4893 ;; When SSE is available, it is always faster to use it!
4894 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4895   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4896         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4897   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4898    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4899   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4900   [(set_attr "type" "sseicvt")
4901    (set_attr "prefix" "maybe_vex")
4902    (set (attr "prefix_rex")
4903         (if_then_else
4904           (match_test "<SWI48:MODE>mode == DImode")
4905           (const_string "1")
4906           (const_string "*")))
4907    (set_attr "mode" "<MODEF:MODE>")
4908    (set_attr "athlon_decode" "double,vector")
4909    (set_attr "amdfam10_decode" "double,double")
4910    (set_attr "bdver1_decode" "double,double")])
4912 ;; Avoid vector decoded forms of the instruction.
4913 (define_peephole2
4914   [(match_scratch:MODEF 2 "x")
4915    (set (match_operand:SWI48 0 "register_operand")
4916         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4917   "TARGET_AVOID_VECTOR_DECODE
4918    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4919    && optimize_insn_for_speed_p ()"
4920   [(set (match_dup 2) (match_dup 1))
4921    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4923 (define_insn "fix_trunc<mode>_i387_fisttp"
4924   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4925         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4926    (clobber (match_scratch:XF 2 "=&f"))]
4927   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4928    && TARGET_FISTTP
4929    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4930          && (TARGET_64BIT || <MODE>mode != DImode))
4931         && TARGET_SSE_MATH)"
4932   "* return output_fix_trunc (insn, operands, true);"
4933   [(set_attr "type" "fisttp")
4934    (set_attr "mode" "<MODE>")])
4936 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4937 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4938 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4939 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4940 ;; function in i386.c.
4941 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4942   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4943         (fix:SWI248x (match_operand 1 "register_operand")))
4944    (clobber (reg:CC FLAGS_REG))]
4945   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4946    && !TARGET_FISTTP
4947    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4948          && (TARGET_64BIT || <MODE>mode != DImode))
4949    && can_create_pseudo_p ()"
4950   "#"
4951   "&& 1"
4952   [(const_int 0)]
4954   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4956   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4957   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4959   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4960                                        operands[2], operands[3]));
4961   DONE;
4963   [(set_attr "type" "fistp")
4964    (set_attr "i387_cw" "trunc")
4965    (set_attr "mode" "<MODE>")])
4967 (define_insn "fix_truncdi_i387"
4968   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4969         (fix:DI (match_operand 1 "register_operand" "f")))
4970    (use (match_operand:HI 2 "memory_operand" "m"))
4971    (use (match_operand:HI 3 "memory_operand" "m"))
4972    (clobber (match_scratch:XF 4 "=&f"))]
4973   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4974    && !TARGET_FISTTP
4975    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4976   "* return output_fix_trunc (insn, operands, false);"
4977   [(set_attr "type" "fistp")
4978    (set_attr "i387_cw" "trunc")
4979    (set_attr "mode" "DI")])
4981 (define_insn "fix_trunc<mode>_i387"
4982   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4983         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4984    (use (match_operand:HI 2 "memory_operand" "m"))
4985    (use (match_operand:HI 3 "memory_operand" "m"))]
4986   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4987    && !TARGET_FISTTP
4988    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4989   "* return output_fix_trunc (insn, operands, false);"
4990   [(set_attr "type" "fistp")
4991    (set_attr "i387_cw" "trunc")
4992    (set_attr "mode" "<MODE>")])
4994 (define_insn "x86_fnstcw_1"
4995   [(set (match_operand:HI 0 "memory_operand" "=m")
4996         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4997   "TARGET_80387"
4998   "fnstcw\t%0"
4999   [(set (attr "length")
5000         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5001    (set_attr "mode" "HI")
5002    (set_attr "unit" "i387")
5003    (set_attr "bdver1_decode" "vector")])
5005 ;; Conversion between fixed point and floating point.
5007 ;; Even though we only accept memory inputs, the backend _really_
5008 ;; wants to be able to do this between registers.  Thankfully, LRA
5009 ;; will fix this up for us during register allocation.
5011 (define_insn "floathi<mode>2"
5012   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5013         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5014   "TARGET_80387
5015    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5016        || TARGET_MIX_SSE_I387)"
5017   "fild%Z1\t%1"
5018   [(set_attr "type" "fmov")
5019    (set_attr "mode" "<MODE>")
5020    (set_attr "znver1_decode" "double")
5021    (set_attr "fp_int_src" "true")])
5023 (define_insn "float<SWI48x:mode>xf2"
5024   [(set (match_operand:XF 0 "register_operand" "=f")
5025         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5026   "TARGET_80387"
5027   "fild%Z1\t%1"
5028   [(set_attr "type" "fmov")
5029    (set_attr "mode" "XF")
5030    (set_attr "znver1_decode" "double")
5031    (set_attr "fp_int_src" "true")])
5033 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5034   [(set (match_operand:MODEF 0 "register_operand")
5035         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5036   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5037    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5038        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5040 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5041   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5042         (float:MODEF
5043           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5044   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5045    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5046   "@
5047    fild%Z1\t%1
5048    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5049    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5050   [(set_attr "type" "fmov,sseicvt,sseicvt")
5051    (set_attr "avx_partial_xmm_update" "false,true,true")
5052    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5053    (set_attr "mode" "<MODEF:MODE>")
5054    (set (attr "prefix_rex")
5055      (if_then_else
5056        (and (eq_attr "prefix" "maybe_vex")
5057             (match_test "<SWI48:MODE>mode == DImode"))
5058        (const_string "1")
5059        (const_string "*")))
5060    (set_attr "unit" "i387,*,*")
5061    (set_attr "athlon_decode" "*,double,direct")
5062    (set_attr "amdfam10_decode" "*,vector,double")
5063    (set_attr "bdver1_decode" "*,double,direct")
5064    (set_attr "znver1_decode" "double,*,*")
5065    (set_attr "fp_int_src" "true")
5066    (set (attr "enabled")
5067      (if_then_else
5068        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5069        (if_then_else
5070          (eq_attr "alternative" "0")
5071          (symbol_ref "TARGET_MIX_SSE_I387
5072                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5073                                            <SWI48:MODE>mode)")
5074          (symbol_ref "true"))
5075        (if_then_else
5076          (eq_attr "alternative" "0")
5077          (symbol_ref "true")
5078          (symbol_ref "false"))))
5079    (set (attr "preferred_for_speed")
5080      (cond [(eq_attr "alternative" "1")
5081               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5082            (symbol_ref "true")))])
5084 (define_insn "*floatdi<MODEF:mode>2_i387"
5085   [(set (match_operand:MODEF 0 "register_operand" "=f")
5086         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5087   "!TARGET_64BIT
5088    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5089   "fild%Z1\t%1"
5090   [(set_attr "type" "fmov")
5091    (set_attr "mode" "<MODEF:MODE>")
5092    (set_attr "znver1_decode" "double")
5093    (set_attr "fp_int_src" "true")])
5095 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5096 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5097 ;; alternative in sse2_loadld.
5098 (define_split
5099   [(set (match_operand:MODEF 0 "sse_reg_operand")
5100         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5101   "TARGET_SSE2
5102    && TARGET_USE_VECTOR_CONVERTS
5103    && optimize_function_for_speed_p (cfun)
5104    && reload_completed
5105    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5106    && (!EXT_REX_SSE_REG_P (operands[0])
5107        || TARGET_AVX512VL)"
5108   [(const_int 0)]
5110   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5111   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5113   emit_insn (gen_sse2_loadld (operands[4],
5114                               CONST0_RTX (V4SImode), operands[1]));
5116   if (<ssevecmode>mode == V4SFmode)
5117     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5118   else
5119     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5120   DONE;
5123 ;; Avoid store forwarding (partial memory) stall penalty
5124 ;; by passing DImode value through XMM registers.  */
5126 (define_split
5127   [(set (match_operand:X87MODEF 0 "register_operand")
5128         (float:X87MODEF
5129           (match_operand:DI 1 "register_operand")))]
5130   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5131    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5132    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5133    && can_create_pseudo_p ()"
5134   [(const_int 0)]
5136   emit_insn (gen_floatdi<mode>2_i387_with_xmm
5137              (operands[0], operands[1],
5138               assign_386_stack_local (DImode, SLOT_TEMP)));
5139   DONE;
5142 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5143   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5144         (float:X87MODEF
5145           (match_operand:DI 1 "register_operand" "r,r")))
5146    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5147    (clobber (match_scratch:V4SI 3 "=x,x"))
5148    (clobber (match_scratch:V4SI 4 "=X,x"))]
5149   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5150    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5151    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5152   "#"
5153   "&& reload_completed"
5154   [(set (match_dup 2) (match_dup 3))
5155    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5157   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5158      Assemble the 64-bit DImode value in an xmm register.  */
5159   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5160                               gen_lowpart (SImode, operands[1])));
5161   if (TARGET_SSE4_1)
5162     emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5163                                   gen_highpart (SImode, operands[1]),
5164                                   GEN_INT (2)));
5165   else
5166     {
5167       emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5168                                   gen_highpart (SImode, operands[1])));
5169       emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5170                                              operands[4]));
5171     }
5172   operands[3] = gen_lowpart (DImode, operands[3]);
5174   [(set_attr "isa" "sse4,*")
5175    (set_attr "type" "multi")
5176    (set_attr "mode" "<X87MODEF:MODE>")
5177    (set_attr "unit" "i387")
5178    (set_attr "fp_int_src" "true")])
5180 ;; Break partial SSE register dependency stall.  This splitter should split
5181 ;; late in the pass sequence (after register rename pass), so allocated
5182 ;; registers won't change anymore
5184 (define_split
5185   [(set (match_operand:MODEF 0 "sse_reg_operand")
5186         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5187   "!TARGET_AVX
5188    && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5189    && optimize_function_for_speed_p (cfun)
5190    && (!EXT_REX_SSE_REG_P (operands[0])
5191        || TARGET_AVX512VL)"
5192   [(set (match_dup 0)
5193         (vec_merge:<MODEF:ssevecmode>
5194           (vec_duplicate:<MODEF:ssevecmode>
5195             (float:MODEF
5196               (match_dup 1)))
5197           (match_dup 0)
5198           (const_int 1)))]
5200   const machine_mode vmode = <MODEF:ssevecmode>mode;
5202   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5203   emit_move_insn (operands[0], CONST0_RTX (vmode));
5206 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5207   [(set (match_operand:MODEF 0 "register_operand")
5208         (unsigned_float:MODEF
5209           (match_operand:SWI12 1 "nonimmediate_operand")))]
5210   "!TARGET_64BIT
5211    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5213   operands[1] = convert_to_mode (SImode, operands[1], 1);
5214   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5215   DONE;
5218 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5219   [(set (match_operand:MODEF 0 "register_operand" "=v")
5220         (unsigned_float:MODEF
5221           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5222   "TARGET_AVX512F && TARGET_SSE_MATH"
5223   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5224   [(set_attr "type" "sseicvt")
5225    (set_attr "prefix" "evex")
5226    (set_attr "mode" "<MODEF:MODE>")])
5228 ;; Avoid store forwarding (partial memory) stall penalty by extending
5229 ;; SImode value to DImode through XMM register instead of pushing two
5230 ;; SImode values to stack. Also note that fild loads from memory only.
5232 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5233   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5234         (unsigned_float:X87MODEF
5235           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5236    (clobber (match_operand:DI 2 "memory_operand" "=m"))
5237    (clobber (match_scratch:DI 3 "=x"))]
5238   "!TARGET_64BIT
5239    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5241   "#"
5242   "&& reload_completed"
5243   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5244    (set (match_dup 2) (match_dup 3))
5245    (set (match_dup 0)
5246         (float:X87MODEF (match_dup 2)))]
5247   ""
5248   [(set_attr "type" "multi")
5249    (set_attr "mode" "<MODE>")])
5251 (define_expand "floatunssi<mode>2"
5252   [(set (match_operand:X87MODEF 0 "register_operand")
5253         (unsigned_float:X87MODEF
5254           (match_operand:SI 1 "nonimmediate_operand")))]
5255   "(!TARGET_64BIT
5256     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5258    || ((!TARGET_64BIT || TARGET_AVX512F)
5259        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5261   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5262     {
5263       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5264                   (operands[0], operands[1],
5265                    assign_386_stack_local (DImode, SLOT_TEMP)));
5266       DONE;
5267     }
5268   if (!TARGET_AVX512F)
5269     {
5270       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5271       DONE;
5272     }
5275 (define_expand "floatunsdisf2"
5276   [(set (match_operand:SF 0 "register_operand")
5277         (unsigned_float:SF
5278           (match_operand:DI 1 "nonimmediate_operand")))]
5279   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5281   if (!TARGET_AVX512F)
5282     {
5283       x86_emit_floatuns (operands);
5284       DONE;
5285     }
5288 (define_expand "floatunsdidf2"
5289   [(set (match_operand:DF 0 "register_operand")
5290         (unsigned_float:DF
5291           (match_operand:DI 1 "nonimmediate_operand")))]
5292   "((TARGET_64BIT && TARGET_AVX512F)
5293     || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5294    && TARGET_SSE2 && TARGET_SSE_MATH"
5296   if (!TARGET_64BIT)
5297     {
5298       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5299       DONE;
5300     }
5301   if (!TARGET_AVX512F)
5302     {
5303       x86_emit_floatuns (operands);
5304       DONE;
5305     }
5308 ;; Load effective address instructions
5310 (define_insn_and_split "*lea<mode>"
5311   [(set (match_operand:SWI48 0 "register_operand" "=r")
5312         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5313   ""
5315   if (SImode_address_operand (operands[1], VOIDmode))
5316     {
5317       gcc_assert (TARGET_64BIT);
5318       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5319     }
5320   else 
5321     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5323   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5324   [(const_int 0)]
5326   machine_mode mode = <MODE>mode;
5327   rtx pat;
5329   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5330      change operands[] array behind our back.  */
5331   pat = PATTERN (curr_insn);
5333   operands[0] = SET_DEST (pat);
5334   operands[1] = SET_SRC (pat);
5336   /* Emit all operations in SImode for zero-extended addresses.  */
5337   if (SImode_address_operand (operands[1], VOIDmode))
5338     mode = SImode;
5340   ix86_split_lea_for_addr (curr_insn, operands, mode);
5342   /* Zero-extend return register to DImode for zero-extended addresses.  */
5343   if (mode != <MODE>mode)
5344     emit_insn (gen_zero_extendsidi2
5345                (operands[0], gen_lowpart (mode, operands[0])));
5347   DONE;
5349   [(set_attr "type" "lea")
5350    (set (attr "mode")
5351      (if_then_else
5352        (match_operand 1 "SImode_address_operand")
5353        (const_string "SI")
5354        (const_string "<MODE>")))])
5356 ;; Add instructions
5358 (define_expand "add<mode>3"
5359   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5360         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5361                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5362   ""
5363   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5365 (define_insn_and_split "*add<dwi>3_doubleword"
5366   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5367         (plus:<DWI>
5368           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5369           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5370                                                         "ro<di>,r<di>")))
5371    (clobber (reg:CC FLAGS_REG))]
5372   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5373   "#"
5374   "reload_completed"
5375   [(parallel [(set (reg:CCC FLAGS_REG)
5376                    (compare:CCC
5377                      (plus:DWIH (match_dup 1) (match_dup 2))
5378                      (match_dup 1)))
5379               (set (match_dup 0)
5380                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5381    (parallel [(set (match_dup 3)
5382                    (plus:DWIH
5383                      (plus:DWIH
5384                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5385                        (match_dup 4))
5386                      (match_dup 5)))
5387               (clobber (reg:CC FLAGS_REG))])]
5389   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5390   if (operands[2] == const0_rtx)
5391     {
5392       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5393       DONE;
5394     }
5397 (define_insn "*add<mode>_1"
5398   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5399         (plus:SWI48
5400           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5401           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5402    (clobber (reg:CC FLAGS_REG))]
5403   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5405   switch (get_attr_type (insn))
5406     {
5407     case TYPE_LEA:
5408       return "#";
5410     case TYPE_INCDEC:
5411       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5412       if (operands[2] == const1_rtx)
5413         return "inc{<imodesuffix>}\t%0";
5414       else
5415         {
5416           gcc_assert (operands[2] == constm1_rtx);
5417           return "dec{<imodesuffix>}\t%0";
5418         }
5420     default:
5421       /* For most processors, ADD is faster than LEA.  This alternative
5422          was added to use ADD as much as possible.  */
5423       if (which_alternative == 2)
5424         std::swap (operands[1], operands[2]);
5425         
5426       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5428         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5430       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5431     }
5433   [(set (attr "type")
5434      (cond [(eq_attr "alternative" "3")
5435               (const_string "lea")
5436             (match_operand:SWI48 2 "incdec_operand")
5437               (const_string "incdec")
5438            ]
5439            (const_string "alu")))
5440    (set (attr "length_immediate")
5441       (if_then_else
5442         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5443         (const_string "1")
5444         (const_string "*")))
5445    (set_attr "mode" "<MODE>")])
5447 ;; It may seem that nonimmediate operand is proper one for operand 1.
5448 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5449 ;; we take care in ix86_binary_operator_ok to not allow two memory
5450 ;; operands so proper swapping will be done in reload.  This allow
5451 ;; patterns constructed from addsi_1 to match.
5453 (define_insn "addsi_1_zext"
5454   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5455         (zero_extend:DI
5456           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5457                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5458    (clobber (reg:CC FLAGS_REG))]
5459   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5461   switch (get_attr_type (insn))
5462     {
5463     case TYPE_LEA:
5464       return "#";
5466     case TYPE_INCDEC:
5467       if (operands[2] == const1_rtx)
5468         return "inc{l}\t%k0";
5469       else
5470         {
5471           gcc_assert (operands[2] == constm1_rtx);
5472           return "dec{l}\t%k0";
5473         }
5475     default:
5476       /* For most processors, ADD is faster than LEA.  This alternative
5477          was added to use ADD as much as possible.  */
5478       if (which_alternative == 1)
5479         std::swap (operands[1], operands[2]);
5481       if (x86_maybe_negate_const_int (&operands[2], SImode))
5482         return "sub{l}\t{%2, %k0|%k0, %2}";
5484       return "add{l}\t{%2, %k0|%k0, %2}";
5485     }
5487   [(set (attr "type")
5488      (cond [(eq_attr "alternative" "2")
5489               (const_string "lea")
5490             (match_operand:SI 2 "incdec_operand")
5491               (const_string "incdec")
5492            ]
5493            (const_string "alu")))
5494    (set (attr "length_immediate")
5495       (if_then_else
5496         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5497         (const_string "1")
5498         (const_string "*")))
5499    (set_attr "mode" "SI")])
5501 (define_insn "*addhi_1"
5502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5503         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5504                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5505    (clobber (reg:CC FLAGS_REG))]
5506   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5508   switch (get_attr_type (insn))
5509     {
5510     case TYPE_LEA:
5511       return "#";
5513     case TYPE_INCDEC:
5514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515       if (operands[2] == const1_rtx)
5516         return "inc{w}\t%0";
5517       else
5518         {
5519           gcc_assert (operands[2] == constm1_rtx);
5520           return "dec{w}\t%0";
5521         }
5523     default:
5524       /* For most processors, ADD is faster than LEA.  This alternative
5525          was added to use ADD as much as possible.  */
5526       if (which_alternative == 2)
5527         std::swap (operands[1], operands[2]);
5529       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530       if (x86_maybe_negate_const_int (&operands[2], HImode))
5531         return "sub{w}\t{%2, %0|%0, %2}";
5533       return "add{w}\t{%2, %0|%0, %2}";
5534     }
5536   [(set (attr "type")
5537      (cond [(eq_attr "alternative" "3")
5538               (const_string "lea")
5539             (match_operand:HI 2 "incdec_operand")
5540               (const_string "incdec")
5541            ]
5542            (const_string "alu")))
5543    (set (attr "length_immediate")
5544       (if_then_else
5545         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5546         (const_string "1")
5547         (const_string "*")))
5548    (set_attr "mode" "HI,HI,HI,SI")])
5550 (define_insn "*addqi_1"
5551   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5552         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5553                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5554    (clobber (reg:CC FLAGS_REG))]
5555   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5557   bool widen = (get_attr_mode (insn) != MODE_QI);
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_LEA:
5562       return "#";
5564     case TYPE_INCDEC:
5565       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566       if (operands[2] == const1_rtx)
5567         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5568       else
5569         {
5570           gcc_assert (operands[2] == constm1_rtx);
5571           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5572         }
5574     default:
5575       /* For most processors, ADD is faster than LEA.  These alternatives
5576          were added to use ADD as much as possible.  */
5577       if (which_alternative == 2 || which_alternative == 4)
5578         std::swap (operands[1], operands[2]);
5580       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581       if (x86_maybe_negate_const_int (&operands[2], QImode))
5582         {
5583           if (widen)
5584             return "sub{l}\t{%2, %k0|%k0, %2}";
5585           else
5586             return "sub{b}\t{%2, %0|%0, %2}";
5587         }
5588       if (widen)
5589         return "add{l}\t{%k2, %k0|%k0, %k2}";
5590       else
5591         return "add{b}\t{%2, %0|%0, %2}";
5592     }
5594   [(set (attr "type")
5595      (cond [(eq_attr "alternative" "5")
5596               (const_string "lea")
5597             (match_operand:QI 2 "incdec_operand")
5598               (const_string "incdec")
5599            ]
5600            (const_string "alu")))
5601    (set (attr "length_immediate")
5602       (if_then_else
5603         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604         (const_string "1")
5605         (const_string "*")))
5606    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5607    ;; Potential partial reg stall on alternatives 3 and 4.
5608    (set (attr "preferred_for_speed")
5609      (cond [(eq_attr "alternative" "3,4")
5610               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5611            (symbol_ref "true")))])
5613 (define_insn "*addqi_1_slp"
5614   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5615         (plus:QI (match_dup 0)
5616                  (match_operand:QI 1 "general_operand" "qn,qm")))
5617    (clobber (reg:CC FLAGS_REG))]
5618   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5619    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5621   switch (get_attr_type (insn))
5622     {
5623     case TYPE_INCDEC:
5624       if (operands[1] == const1_rtx)
5625         return "inc{b}\t%0";
5626       else
5627         {
5628           gcc_assert (operands[1] == constm1_rtx);
5629           return "dec{b}\t%0";
5630         }
5632     default:
5633       if (x86_maybe_negate_const_int (&operands[1], QImode))
5634         return "sub{b}\t{%1, %0|%0, %1}";
5636       return "add{b}\t{%1, %0|%0, %1}";
5637     }
5639   [(set (attr "type")
5640      (if_then_else (match_operand:QI 1 "incdec_operand")
5641         (const_string "incdec")
5642         (const_string "alu1")))
5643    (set (attr "memory")
5644      (if_then_else (match_operand 1 "memory_operand")
5645         (const_string "load")
5646         (const_string "none")))
5647    (set_attr "mode" "QI")])
5649 ;; Split non destructive adds if we cannot use lea.
5650 (define_split
5651   [(set (match_operand:SWI48 0 "register_operand")
5652         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5653                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5654    (clobber (reg:CC FLAGS_REG))]
5655   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5656   [(set (match_dup 0) (match_dup 1))
5657    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5658               (clobber (reg:CC FLAGS_REG))])])
5660 ;; Split non destructive adds if we cannot use lea.
5661 (define_split
5662   [(set (match_operand:DI 0 "register_operand")
5663         (zero_extend:DI
5664           (plus:SI (match_operand:SI 1 "register_operand")
5665                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5666    (clobber (reg:CC FLAGS_REG))]
5667   "TARGET_64BIT
5668    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5669   [(set (match_dup 3) (match_dup 1))
5670    (parallel [(set (match_dup 0)
5671                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5672               (clobber (reg:CC FLAGS_REG))])]
5673   "operands[3] = gen_lowpart (SImode, operands[0]);")
5675 ;; Convert add to the lea pattern to avoid flags dependency.
5676 (define_split
5677   [(set (match_operand:SWI 0 "register_operand")
5678         (plus:SWI (match_operand:SWI 1 "register_operand")
5679                   (match_operand:SWI 2 "<nonmemory_operand>")))
5680    (clobber (reg:CC FLAGS_REG))]
5681   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5682   [(set (match_dup 0)
5683         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5685   if (<MODE>mode != <LEAMODE>mode)
5686     {
5687       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5688       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5689       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5690     }
5693 ;; Convert add to the lea pattern to avoid flags dependency.
5694 (define_split
5695   [(set (match_operand:DI 0 "register_operand")
5696         (zero_extend:DI
5697           (plus:SI (match_operand:SI 1 "register_operand")
5698                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5699    (clobber (reg:CC FLAGS_REG))]
5700   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5701   [(set (match_dup 0)
5702         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5704 (define_insn "*add<mode>_2"
5705   [(set (reg FLAGS_REG)
5706         (compare
5707           (plus:SWI
5708             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5709             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5710           (const_int 0)))
5711    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5712         (plus:SWI (match_dup 1) (match_dup 2)))]
5713   "ix86_match_ccmode (insn, CCGOCmode)
5714    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5716   switch (get_attr_type (insn))
5717     {
5718     case TYPE_INCDEC:
5719       if (operands[2] == const1_rtx)
5720         return "inc{<imodesuffix>}\t%0";
5721       else
5722         {
5723           gcc_assert (operands[2] == constm1_rtx);
5724           return "dec{<imodesuffix>}\t%0";
5725         }
5727     default:
5728       if (which_alternative == 2)
5729         std::swap (operands[1], operands[2]);
5730         
5731       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5732       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5733         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5735       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5736     }
5738   [(set (attr "type")
5739      (if_then_else (match_operand:SWI 2 "incdec_operand")
5740         (const_string "incdec")
5741         (const_string "alu")))
5742    (set (attr "length_immediate")
5743       (if_then_else
5744         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5745         (const_string "1")
5746         (const_string "*")))
5747    (set_attr "mode" "<MODE>")])
5749 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5750 (define_insn "*addsi_2_zext"
5751   [(set (reg FLAGS_REG)
5752         (compare
5753           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5754                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5755           (const_int 0)))
5756    (set (match_operand:DI 0 "register_operand" "=r,r")
5757         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5758   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5759    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5761   switch (get_attr_type (insn))
5762     {
5763     case TYPE_INCDEC:
5764       if (operands[2] == const1_rtx)
5765         return "inc{l}\t%k0";
5766       else
5767         {
5768           gcc_assert (operands[2] == constm1_rtx);
5769           return "dec{l}\t%k0";
5770         }
5772     default:
5773       if (which_alternative == 1)
5774         std::swap (operands[1], operands[2]);
5776       if (x86_maybe_negate_const_int (&operands[2], SImode))
5777         return "sub{l}\t{%2, %k0|%k0, %2}";
5779       return "add{l}\t{%2, %k0|%k0, %2}";
5780     }
5782   [(set (attr "type")
5783      (if_then_else (match_operand:SI 2 "incdec_operand")
5784         (const_string "incdec")
5785         (const_string "alu")))
5786    (set (attr "length_immediate")
5787       (if_then_else
5788         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5789         (const_string "1")
5790         (const_string "*")))
5791    (set_attr "mode" "SI")])
5793 (define_insn "*add<mode>_3"
5794   [(set (reg FLAGS_REG)
5795         (compare
5796           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5797           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5798    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5799   "ix86_match_ccmode (insn, CCZmode)
5800    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5802   switch (get_attr_type (insn))
5803     {
5804     case TYPE_INCDEC:
5805       if (operands[2] == const1_rtx)
5806         return "inc{<imodesuffix>}\t%0";
5807       else
5808         {
5809           gcc_assert (operands[2] == constm1_rtx);
5810           return "dec{<imodesuffix>}\t%0";
5811         }
5813     default:
5814       if (which_alternative == 1)
5815         std::swap (operands[1], operands[2]);
5817       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5819         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5821       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5822     }
5824   [(set (attr "type")
5825      (if_then_else (match_operand:SWI 2 "incdec_operand")
5826         (const_string "incdec")
5827         (const_string "alu")))
5828    (set (attr "length_immediate")
5829       (if_then_else
5830         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5831         (const_string "1")
5832         (const_string "*")))
5833    (set_attr "mode" "<MODE>")])
5835 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5836 (define_insn "*addsi_3_zext"
5837   [(set (reg FLAGS_REG)
5838         (compare
5839           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5840           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5841    (set (match_operand:DI 0 "register_operand" "=r,r")
5842         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5843   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5844    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5846   switch (get_attr_type (insn))
5847     {
5848     case TYPE_INCDEC:
5849       if (operands[2] == const1_rtx)
5850         return "inc{l}\t%k0";
5851       else
5852         {
5853           gcc_assert (operands[2] == constm1_rtx);
5854           return "dec{l}\t%k0";
5855         }
5857     default:
5858       if (which_alternative == 1)
5859         std::swap (operands[1], operands[2]);
5861       if (x86_maybe_negate_const_int (&operands[2], SImode))
5862         return "sub{l}\t{%2, %k0|%k0, %2}";
5864       return "add{l}\t{%2, %k0|%k0, %2}";
5865     }
5867   [(set (attr "type")
5868      (if_then_else (match_operand:SI 2 "incdec_operand")
5869         (const_string "incdec")
5870         (const_string "alu")))
5871    (set (attr "length_immediate")
5872       (if_then_else
5873         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5874         (const_string "1")
5875         (const_string "*")))
5876    (set_attr "mode" "SI")])
5878 ; For comparisons against 1, -1 and 128, we may generate better code
5879 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5880 ; is matched then.  We can't accept general immediate, because for
5881 ; case of overflows,  the result is messed up.
5882 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5883 ; only for comparisons not depending on it.
5885 (define_insn "*adddi_4"
5886   [(set (reg FLAGS_REG)
5887         (compare
5888           (match_operand:DI 1 "nonimmediate_operand" "0")
5889           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5890    (clobber (match_scratch:DI 0 "=rm"))]
5891   "TARGET_64BIT
5892    && ix86_match_ccmode (insn, CCGCmode)"
5894   switch (get_attr_type (insn))
5895     {
5896     case TYPE_INCDEC:
5897       if (operands[2] == constm1_rtx)
5898         return "inc{q}\t%0";
5899       else
5900         {
5901           gcc_assert (operands[2] == const1_rtx);
5902           return "dec{q}\t%0";
5903         }
5905     default:
5906       if (x86_maybe_negate_const_int (&operands[2], DImode))
5907         return "add{q}\t{%2, %0|%0, %2}";
5909       return "sub{q}\t{%2, %0|%0, %2}";
5910     }
5912   [(set (attr "type")
5913      (if_then_else (match_operand:DI 2 "incdec_operand")
5914         (const_string "incdec")
5915         (const_string "alu")))
5916    (set (attr "length_immediate")
5917       (if_then_else
5918         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5919         (const_string "1")
5920         (const_string "*")))
5921    (set_attr "mode" "DI")])
5923 ; For comparisons against 1, -1 and 128, we may generate better code
5924 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5925 ; is matched then.  We can't accept general immediate, because for
5926 ; case of overflows,  the result is messed up.
5927 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5928 ; only for comparisons not depending on it.
5930 (define_insn "*add<mode>_4"
5931   [(set (reg FLAGS_REG)
5932         (compare
5933           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5934           (match_operand:SWI124 2 "const_int_operand" "n")))
5935    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5936   "ix86_match_ccmode (insn, CCGCmode)"
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == constm1_rtx)
5942         return "inc{<imodesuffix>}\t%0";
5943       else
5944         {
5945           gcc_assert (operands[2] == const1_rtx);
5946           return "dec{<imodesuffix>}\t%0";
5947         }
5949     default:
5950       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5951         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5953       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5954     }
5956   [(set (attr "type")
5957      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5958         (const_string "incdec")
5959         (const_string "alu")))
5960    (set (attr "length_immediate")
5961       (if_then_else
5962         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5963         (const_string "1")
5964         (const_string "*")))
5965    (set_attr "mode" "<MODE>")])
5967 (define_insn "*add<mode>_5"
5968   [(set (reg FLAGS_REG)
5969         (compare
5970           (plus:SWI
5971             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5972             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5973           (const_int 0)))
5974    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5975   "ix86_match_ccmode (insn, CCGOCmode)
5976    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978   switch (get_attr_type (insn))
5979     {
5980     case TYPE_INCDEC:
5981       if (operands[2] == const1_rtx)
5982         return "inc{<imodesuffix>}\t%0";
5983       else
5984         {
5985           gcc_assert (operands[2] == constm1_rtx);
5986           return "dec{<imodesuffix>}\t%0";
5987         }
5989     default:
5990       if (which_alternative == 1)
5991         std::swap (operands[1], operands[2]);
5993       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5995         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5997       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5998     }
6000   [(set (attr "type")
6001      (if_then_else (match_operand:SWI 2 "incdec_operand")
6002         (const_string "incdec")
6003         (const_string "alu")))
6004    (set (attr "length_immediate")
6005       (if_then_else
6006         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6007         (const_string "1")
6008         (const_string "*")))
6009    (set_attr "mode" "<MODE>")])
6011 (define_insn "addqi_ext_1"
6012   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6013                          (const_int 8)
6014                          (const_int 8))
6015         (subreg:SI
6016           (plus:QI
6017             (subreg:QI
6018               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6019                                (const_int 8)
6020                                (const_int 8)) 0)
6021             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6022    (clobber (reg:CC FLAGS_REG))]
6023   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6024    rtx_equal_p (operands[0], operands[1])"
6026   switch (get_attr_type (insn))
6027     {
6028     case TYPE_INCDEC:
6029       if (operands[2] == const1_rtx)
6030         return "inc{b}\t%h0";
6031       else
6032         {
6033           gcc_assert (operands[2] == constm1_rtx);
6034           return "dec{b}\t%h0";
6035         }
6037     default:
6038       return "add{b}\t{%2, %h0|%h0, %2}";
6039     }
6041   [(set_attr "isa" "*,nox64")
6042    (set (attr "type")
6043      (if_then_else (match_operand:QI 2 "incdec_operand")
6044         (const_string "incdec")
6045         (const_string "alu")))
6046    (set_attr "mode" "QI")])
6048 (define_insn "*addqi_ext_2"
6049   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6050                          (const_int 8)
6051                          (const_int 8))
6052         (subreg:SI
6053           (plus:QI
6054             (subreg:QI
6055               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6056                                (const_int 8)
6057                                (const_int 8)) 0)
6058             (subreg:QI
6059               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6060                                (const_int 8)
6061                                (const_int 8)) 0)) 0))
6062   (clobber (reg:CC FLAGS_REG))]
6063   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6064    rtx_equal_p (operands[0], operands[1])
6065    || rtx_equal_p (operands[0], operands[2])"
6066   "add{b}\t{%h2, %h0|%h0, %h2}"
6067   [(set_attr "type" "alu")
6068    (set_attr "mode" "QI")])
6070 ;; Add with jump on overflow.
6071 (define_expand "addv<mode>4"
6072   [(parallel [(set (reg:CCO FLAGS_REG)
6073                    (eq:CCO (plus:<DWI>
6074                               (sign_extend:<DWI>
6075                                  (match_operand:SWI 1 "nonimmediate_operand"))
6076                               (match_dup 4))
6077                            (sign_extend:<DWI>
6078                               (plus:SWI (match_dup 1)
6079                                         (match_operand:SWI 2
6080                                            "<general_operand>")))))
6081               (set (match_operand:SWI 0 "register_operand")
6082                    (plus:SWI (match_dup 1) (match_dup 2)))])
6083    (set (pc) (if_then_else
6084                (eq (reg:CCO FLAGS_REG) (const_int 0))
6085                (label_ref (match_operand 3))
6086                (pc)))]
6087   ""
6089   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6090   if (CONST_INT_P (operands[2]))
6091     operands[4] = operands[2];
6092   else
6093     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6096 (define_insn "*addv<mode>4"
6097   [(set (reg:CCO FLAGS_REG)
6098         (eq:CCO (plus:<DWI>
6099                    (sign_extend:<DWI>
6100                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6101                    (sign_extend:<DWI>
6102                       (match_operand:SWI 2 "<general_sext_operand>"
6103                                            "<r>mWe,<r>We")))
6104                 (sign_extend:<DWI>
6105                    (plus:SWI (match_dup 1) (match_dup 2)))))
6106    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6107         (plus:SWI (match_dup 1) (match_dup 2)))]
6108   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6109   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6110   [(set_attr "type" "alu")
6111    (set_attr "mode" "<MODE>")])
6113 (define_insn "*addv<mode>4_1"
6114   [(set (reg:CCO FLAGS_REG)
6115         (eq:CCO (plus:<DWI>
6116                    (sign_extend:<DWI>
6117                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6118                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6119                 (sign_extend:<DWI>
6120                    (plus:SWI (match_dup 1)
6121                              (match_operand:SWI 2 "x86_64_immediate_operand"
6122                                                   "<i>")))))
6123    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6124         (plus:SWI (match_dup 1) (match_dup 2)))]
6125   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6126    && CONST_INT_P (operands[2])
6127    && INTVAL (operands[2]) == INTVAL (operands[3])"
6128   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6129   [(set_attr "type" "alu")
6130    (set_attr "mode" "<MODE>")
6131    (set (attr "length_immediate")
6132         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6133                   (const_string "1")
6134                (match_test "<MODE_SIZE> == 8")
6135                   (const_string "4")]
6136               (const_string "<MODE_SIZE>")))])
6138 (define_expand "uaddv<mode>4"
6139   [(parallel [(set (reg:CCC FLAGS_REG)
6140                    (compare:CCC
6141                      (plus:SWI
6142                        (match_operand:SWI 1 "nonimmediate_operand")
6143                        (match_operand:SWI 2 "<general_operand>"))
6144                      (match_dup 1)))
6145               (set (match_operand:SWI 0 "register_operand")
6146                    (plus:SWI (match_dup 1) (match_dup 2)))])
6147    (set (pc) (if_then_else
6148                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6149                (label_ref (match_operand 3))
6150                (pc)))]
6151   ""
6152   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6154 ;; The lea patterns for modes less than 32 bits need to be matched by
6155 ;; several insns converted to real lea by splitters.
6157 (define_insn_and_split "*lea<mode>_general_1"
6158   [(set (match_operand:SWI12 0 "register_operand" "=r")
6159         (plus:SWI12
6160           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6161                       (match_operand:SWI12 2 "register_operand" "r"))
6162           (match_operand:SWI12 3 "immediate_operand" "i")))]
6163   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6164   "#"
6165   "&& reload_completed"
6166   [(set (match_dup 0)
6167         (plus:SI
6168           (plus:SI (match_dup 1) (match_dup 2))
6169           (match_dup 3)))]
6171   operands[0] = gen_lowpart (SImode, operands[0]);
6172   operands[1] = gen_lowpart (SImode, operands[1]);
6173   operands[2] = gen_lowpart (SImode, operands[2]);
6174   operands[3] = gen_lowpart (SImode, operands[3]);
6176   [(set_attr "type" "lea")
6177    (set_attr "mode" "SI")])
6179 (define_insn_and_split "*lea<mode>_general_2"
6180   [(set (match_operand:SWI12 0 "register_operand" "=r")
6181         (plus:SWI12
6182           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6183                       (match_operand 2 "const248_operand" "n"))
6184           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6185   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6186   "#"
6187   "&& reload_completed"
6188   [(set (match_dup 0)
6189         (plus:SI
6190           (mult:SI (match_dup 1) (match_dup 2))
6191           (match_dup 3)))]
6193   operands[0] = gen_lowpart (SImode, operands[0]);
6194   operands[1] = gen_lowpart (SImode, operands[1]);
6195   operands[3] = gen_lowpart (SImode, operands[3]);
6197   [(set_attr "type" "lea")
6198    (set_attr "mode" "SI")])
6200 (define_insn_and_split "*lea<mode>_general_2b"
6201   [(set (match_operand:SWI12 0 "register_operand" "=r")
6202         (plus:SWI12
6203           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6204                         (match_operand 2 "const123_operand" "n"))
6205           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6206   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6207   "#"
6208   "&& reload_completed"
6209   [(set (match_dup 0)
6210         (plus:SI
6211           (ashift:SI (match_dup 1) (match_dup 2))
6212           (match_dup 3)))]
6214   operands[0] = gen_lowpart (SImode, operands[0]);
6215   operands[1] = gen_lowpart (SImode, operands[1]);
6216   operands[3] = gen_lowpart (SImode, operands[3]);
6218   [(set_attr "type" "lea")
6219    (set_attr "mode" "SI")])
6221 (define_insn_and_split "*lea<mode>_general_3"
6222   [(set (match_operand:SWI12 0 "register_operand" "=r")
6223         (plus:SWI12
6224           (plus:SWI12
6225             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6226                         (match_operand 2 "const248_operand" "n"))
6227             (match_operand:SWI12 3 "register_operand" "r"))
6228           (match_operand:SWI12 4 "immediate_operand" "i")))]
6229   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6230   "#"
6231   "&& reload_completed"
6232   [(set (match_dup 0)
6233         (plus:SI
6234           (plus:SI
6235             (mult:SI (match_dup 1) (match_dup 2))
6236             (match_dup 3))
6237           (match_dup 4)))]
6239   operands[0] = gen_lowpart (SImode, operands[0]);
6240   operands[1] = gen_lowpart (SImode, operands[1]);
6241   operands[3] = gen_lowpart (SImode, operands[3]);
6242   operands[4] = gen_lowpart (SImode, operands[4]);
6244   [(set_attr "type" "lea")
6245    (set_attr "mode" "SI")])
6247 (define_insn_and_split "*lea<mode>_general_3b"
6248   [(set (match_operand:SWI12 0 "register_operand" "=r")
6249         (plus:SWI12
6250           (plus:SWI12
6251             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6252                           (match_operand 2 "const123_operand" "n"))
6253             (match_operand:SWI12 3 "register_operand" "r"))
6254           (match_operand:SWI12 4 "immediate_operand" "i")))]
6255   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6256   "#"
6257   "&& reload_completed"
6258   [(set (match_dup 0)
6259         (plus:SI
6260           (plus:SI
6261             (ashift:SI (match_dup 1) (match_dup 2))
6262             (match_dup 3))
6263           (match_dup 4)))]
6265   operands[0] = gen_lowpart (SImode, operands[0]);
6266   operands[1] = gen_lowpart (SImode, operands[1]);
6267   operands[3] = gen_lowpart (SImode, operands[3]);
6268   operands[4] = gen_lowpart (SImode, operands[4]);
6270   [(set_attr "type" "lea")
6271    (set_attr "mode" "SI")])
6273 (define_insn_and_split "*lea<mode>_general_4"
6274   [(set (match_operand:SWI12 0 "register_operand" "=r")
6275         (any_or:SWI12
6276           (ashift:SWI12
6277             (match_operand:SWI12 1 "index_register_operand" "l")
6278             (match_operand 2 "const_0_to_3_operand" "n"))
6279           (match_operand 3 "const_int_operand" "n")))]
6280   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6281    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6282        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6283   "#"
6284   "&& reload_completed"
6285   [(set (match_dup 0)
6286         (plus:SI
6287           (mult:SI (match_dup 1) (match_dup 2))
6288           (match_dup 3)))]
6290   operands[0] = gen_lowpart (SImode, operands[0]);
6291   operands[1] = gen_lowpart (SImode, operands[1]);
6292   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6294   [(set_attr "type" "lea")
6295    (set_attr "mode" "SI")])
6297 (define_insn_and_split "*lea<mode>_general_4"
6298   [(set (match_operand:SWI48 0 "register_operand" "=r")
6299         (any_or:SWI48
6300           (ashift:SWI48
6301             (match_operand:SWI48 1 "index_register_operand" "l")
6302             (match_operand 2 "const_0_to_3_operand" "n"))
6303           (match_operand 3 "const_int_operand" "n")))]
6304   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6306   "#"
6307   "&& reload_completed"
6308   [(set (match_dup 0)
6309         (plus:SWI48
6310           (mult:SWI48 (match_dup 1) (match_dup 2))
6311           (match_dup 3)))]
6312   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6313   [(set_attr "type" "lea")
6314    (set_attr "mode" "<MODE>")])
6316 ;; Subtract instructions
6318 (define_expand "sub<mode>3"
6319   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6320         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6321                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6322   ""
6323   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6325 (define_insn_and_split "*sub<dwi>3_doubleword"
6326   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6327         (minus:<DWI>
6328           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6329           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6330                                                         "ro<di>,r<di>")))
6331    (clobber (reg:CC FLAGS_REG))]
6332   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6333   "#"
6334   "reload_completed"
6335   [(parallel [(set (reg:CC FLAGS_REG)
6336                    (compare:CC (match_dup 1) (match_dup 2)))
6337               (set (match_dup 0)
6338                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6339    (parallel [(set (match_dup 3)
6340                    (minus:DWIH
6341                      (minus:DWIH
6342                        (match_dup 4)
6343                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6344                      (match_dup 5)))
6345               (clobber (reg:CC FLAGS_REG))])]
6347   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6348   if (operands[2] == const0_rtx)
6349     {
6350       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6351       DONE;
6352     }
6355 (define_insn "*sub<mode>_1"
6356   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6357         (minus:SWI
6358           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6359           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6360    (clobber (reg:CC FLAGS_REG))]
6361   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6362   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6363   [(set_attr "type" "alu")
6364    (set_attr "mode" "<MODE>")])
6366 (define_insn "*subsi_1_zext"
6367   [(set (match_operand:DI 0 "register_operand" "=r")
6368         (zero_extend:DI
6369           (minus:SI (match_operand:SI 1 "register_operand" "0")
6370                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6371    (clobber (reg:CC FLAGS_REG))]
6372   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6373   "sub{l}\t{%2, %k0|%k0, %2}"
6374   [(set_attr "type" "alu")
6375    (set_attr "mode" "SI")])
6377 (define_insn "*subqi_1_slp"
6378   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6379         (minus:QI (match_dup 0)
6380                   (match_operand:QI 1 "general_operand" "qn,qm")))
6381    (clobber (reg:CC FLAGS_REG))]
6382   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6383    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6384   "sub{b}\t{%1, %0|%0, %1}"
6385   [(set_attr "type" "alu1")
6386    (set_attr "mode" "QI")])
6388 (define_insn "*sub<mode>_2"
6389   [(set (reg FLAGS_REG)
6390         (compare
6391           (minus:SWI
6392             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6393             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6394           (const_int 0)))
6395    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6396         (minus:SWI (match_dup 1) (match_dup 2)))]
6397   "ix86_match_ccmode (insn, CCGOCmode)
6398    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6399   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6400   [(set_attr "type" "alu")
6401    (set_attr "mode" "<MODE>")])
6403 (define_insn "*subsi_2_zext"
6404   [(set (reg FLAGS_REG)
6405         (compare
6406           (minus:SI (match_operand:SI 1 "register_operand" "0")
6407                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6408           (const_int 0)))
6409    (set (match_operand:DI 0 "register_operand" "=r")
6410         (zero_extend:DI
6411           (minus:SI (match_dup 1)
6412                     (match_dup 2))))]
6413   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6414    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6415   "sub{l}\t{%2, %k0|%k0, %2}"
6416   [(set_attr "type" "alu")
6417    (set_attr "mode" "SI")])
6419 ;; Subtract with jump on overflow.
6420 (define_expand "subv<mode>4"
6421   [(parallel [(set (reg:CCO FLAGS_REG)
6422                    (eq:CCO (minus:<DWI>
6423                               (sign_extend:<DWI>
6424                                  (match_operand:SWI 1 "nonimmediate_operand"))
6425                               (match_dup 4))
6426                            (sign_extend:<DWI>
6427                               (minus:SWI (match_dup 1)
6428                                          (match_operand:SWI 2
6429                                             "<general_operand>")))))
6430               (set (match_operand:SWI 0 "register_operand")
6431                    (minus:SWI (match_dup 1) (match_dup 2)))])
6432    (set (pc) (if_then_else
6433                (eq (reg:CCO FLAGS_REG) (const_int 0))
6434                (label_ref (match_operand 3))
6435                (pc)))]
6436   ""
6438   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6439   if (CONST_INT_P (operands[2]))
6440     operands[4] = operands[2];
6441   else
6442     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6445 (define_insn "*subv<mode>4"
6446   [(set (reg:CCO FLAGS_REG)
6447         (eq:CCO (minus:<DWI>
6448                    (sign_extend:<DWI>
6449                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6450                    (sign_extend:<DWI>
6451                       (match_operand:SWI 2 "<general_sext_operand>"
6452                                            "<r>We,<r>m")))
6453                 (sign_extend:<DWI>
6454                    (minus:SWI (match_dup 1) (match_dup 2)))))
6455    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6456         (minus:SWI (match_dup 1) (match_dup 2)))]
6457   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6458   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6459   [(set_attr "type" "alu")
6460    (set_attr "mode" "<MODE>")])
6462 (define_insn "*subv<mode>4_1"
6463   [(set (reg:CCO FLAGS_REG)
6464         (eq:CCO (minus:<DWI>
6465                    (sign_extend:<DWI>
6466                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6467                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6468                 (sign_extend:<DWI>
6469                    (minus:SWI (match_dup 1)
6470                               (match_operand:SWI 2 "x86_64_immediate_operand"
6471                                                    "<i>")))))
6472    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6473         (minus:SWI (match_dup 1) (match_dup 2)))]
6474   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6475    && CONST_INT_P (operands[2])
6476    && INTVAL (operands[2]) == INTVAL (operands[3])"
6477   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6478   [(set_attr "type" "alu")
6479    (set_attr "mode" "<MODE>")
6480    (set (attr "length_immediate")
6481         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6482                   (const_string "1")
6483                (match_test "<MODE_SIZE> == 8")
6484                   (const_string "4")]
6485               (const_string "<MODE_SIZE>")))])
6487 (define_expand "usubv<mode>4"
6488   [(parallel [(set (reg:CC FLAGS_REG)
6489                    (compare:CC
6490                      (match_operand:SWI 1 "nonimmediate_operand")
6491                      (match_operand:SWI 2 "<general_operand>")))
6492               (set (match_operand:SWI 0 "register_operand")
6493                    (minus:SWI (match_dup 1) (match_dup 2)))])
6494    (set (pc) (if_then_else
6495                (ltu (reg:CC FLAGS_REG) (const_int 0))
6496                (label_ref (match_operand 3))
6497                (pc)))]
6498   ""
6499   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6501 (define_insn "*sub<mode>_3"
6502   [(set (reg FLAGS_REG)
6503         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6504                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6506         (minus:SWI (match_dup 1) (match_dup 2)))]
6507   "ix86_match_ccmode (insn, CCmode)
6508    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510   [(set_attr "type" "alu")
6511    (set_attr "mode" "<MODE>")])
6513 (define_peephole2
6514   [(parallel
6515      [(set (reg:CC FLAGS_REG)
6516            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6517                        (match_operand:SWI 1 "general_gr_operand")))
6518       (set (match_dup 0)
6519            (minus:SWI (match_dup 0) (match_dup 1)))])]
6520   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6521   [(set (reg:CC FLAGS_REG)
6522         (compare:CC (match_dup 0) (match_dup 1)))])
6524 (define_insn "*subsi_3_zext"
6525   [(set (reg FLAGS_REG)
6526         (compare (match_operand:SI 1 "register_operand" "0")
6527                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6528    (set (match_operand:DI 0 "register_operand" "=r")
6529         (zero_extend:DI
6530           (minus:SI (match_dup 1)
6531                     (match_dup 2))))]
6532   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6533    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6534   "sub{l}\t{%2, %1|%1, %2}"
6535   [(set_attr "type" "alu")
6536    (set_attr "mode" "SI")])
6538 ;; Add with carry and subtract with borrow
6540 (define_insn "add<mode>3_carry"
6541   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6542         (plus:SWI
6543           (plus:SWI
6544             (match_operator:SWI 4 "ix86_carry_flag_operator"
6545              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6546             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6547           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6550   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "use_carry" "1")
6553    (set_attr "pent_pair" "pu")
6554    (set_attr "mode" "<MODE>")])
6556 (define_insn "*add<mode>3_carry_0"
6557   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6558         (plus:SWI
6559           (match_operator:SWI 3 "ix86_carry_flag_operator"
6560             [(match_operand 2 "flags_reg_operand") (const_int 0)])
6561           (match_operand:SWI 1 "nonimmediate_operand" "0")))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6564   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6565   [(set_attr "type" "alu")
6566    (set_attr "use_carry" "1")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "<MODE>")])
6570 (define_insn "*addsi3_carry_zext"
6571   [(set (match_operand:DI 0 "register_operand" "=r")
6572         (zero_extend:DI
6573           (plus:SI
6574             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6575                       [(reg FLAGS_REG) (const_int 0)])
6576                      (match_operand:SI 1 "register_operand" "%0"))
6577             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6578    (clobber (reg:CC FLAGS_REG))]
6579   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6580   "adc{l}\t{%2, %k0|%k0, %2}"
6581   [(set_attr "type" "alu")
6582    (set_attr "use_carry" "1")
6583    (set_attr "pent_pair" "pu")
6584    (set_attr "mode" "SI")])
6586 (define_insn "*addsi3_carry_zext_0"
6587   [(set (match_operand:DI 0 "register_operand" "=r")
6588         (zero_extend:DI
6589           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6590                     [(reg FLAGS_REG) (const_int 0)])
6591                    (match_operand:SI 1 "register_operand" "0"))))
6592    (clobber (reg:CC FLAGS_REG))]
6593   "TARGET_64BIT"
6594   "adc{l}\t{$0, %k0|%k0, 0}"
6595   [(set_attr "type" "alu")
6596    (set_attr "use_carry" "1")
6597    (set_attr "pent_pair" "pu")
6598    (set_attr "mode" "SI")])
6600 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6602 (define_insn "addcarry<mode>"
6603   [(set (reg:CCC FLAGS_REG)
6604         (compare:CCC
6605           (zero_extend:<DWI>
6606             (plus:SWI48
6607               (plus:SWI48
6608                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6609                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
6610                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6611               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6612           (plus:<DWI>
6613             (zero_extend:<DWI> (match_dup 2))
6614             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6615               [(match_dup 3) (const_int 0)]))))
6616    (set (match_operand:SWI48 0 "register_operand" "=r")
6617         (plus:SWI48 (plus:SWI48 (match_op_dup 5
6618                                  [(match_dup 3) (const_int 0)])
6619                                 (match_dup 1))
6620                     (match_dup 2)))]
6621   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6622   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "use_carry" "1")
6625    (set_attr "pent_pair" "pu")
6626    (set_attr "mode" "<MODE>")])
6628 (define_expand "addcarry<mode>_0"
6629   [(parallel
6630      [(set (reg:CCC FLAGS_REG)
6631            (compare:CCC
6632              (plus:SWI48
6633                (match_operand:SWI48 1 "nonimmediate_operand")
6634                (match_operand:SWI48 2 "x86_64_general_operand"))
6635              (match_dup 1)))
6636       (set (match_operand:SWI48 0 "register_operand")
6637            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6638   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6640 (define_insn "@sub<mode>3_carry"
6641   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6642         (minus:SWI
6643           (minus:SWI
6644             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6645             (match_operator:SWI 4 "ix86_carry_flag_operator"
6646              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6647           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "use_carry" "1")
6653    (set_attr "pent_pair" "pu")
6654    (set_attr "mode" "<MODE>")])
6656 (define_insn "*sub<mode>3_carry_0"
6657   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6658         (minus:SWI
6659           (match_operand:SWI 1 "nonimmediate_operand" "0")
6660           (match_operator:SWI 3 "ix86_carry_flag_operator"
6661             [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6664   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6665   [(set_attr "type" "alu")
6666    (set_attr "use_carry" "1")
6667    (set_attr "pent_pair" "pu")
6668    (set_attr "mode" "<MODE>")])
6670 (define_insn "*subsi3_carry_zext"
6671   [(set (match_operand:DI 0 "register_operand" "=r")
6672         (zero_extend:DI
6673           (minus:SI
6674             (minus:SI
6675               (match_operand:SI 1 "register_operand" "0")
6676               (match_operator:SI 3 "ix86_carry_flag_operator"
6677                [(reg FLAGS_REG) (const_int 0)]))
6678             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6679    (clobber (reg:CC FLAGS_REG))]
6680   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681   "sbb{l}\t{%2, %k0|%k0, %2}"
6682   [(set_attr "type" "alu")
6683    (set_attr "use_carry" "1")
6684    (set_attr "pent_pair" "pu")
6685    (set_attr "mode" "SI")])
6687 (define_insn "*subsi3_carry_zext_0"
6688   [(set (match_operand:DI 0 "register_operand" "=r")
6689         (zero_extend:DI
6690           (minus:SI
6691             (match_operand:SI 1 "register_operand" "0")
6692             (match_operator:SI 2 "ix86_carry_flag_operator"
6693               [(reg FLAGS_REG) (const_int 0)]))))
6694    (clobber (reg:CC FLAGS_REG))]
6695   "TARGET_64BIT"
6696   "sbb{l}\t{$0, %k0|%k0, 0}"
6697   [(set_attr "type" "alu")
6698    (set_attr "use_carry" "1")
6699    (set_attr "pent_pair" "pu")
6700    (set_attr "mode" "SI")])
6702 (define_insn "sub<mode>3_carry_ccc"
6703   [(set (reg:CCC FLAGS_REG)
6704         (compare:CCC
6705           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6706           (plus:<DWI>
6707             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6708             (zero_extend:<DWI>
6709               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6710    (clobber (match_scratch:DWIH 0 "=r"))]
6711   ""
6712   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "mode" "<MODE>")])
6716 (define_insn "*sub<mode>3_carry_ccc_1"
6717   [(set (reg:CCC FLAGS_REG)
6718         (compare:CCC
6719           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6720           (plus:<DWI>
6721             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6722             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6723    (clobber (match_scratch:DWIH 0 "=r"))]
6724   ""
6726   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6727   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6729   [(set_attr "type" "alu")
6730    (set_attr "mode" "<MODE>")])
6732 ;; The sign flag is set from the
6733 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6734 ;; result, the overflow flag likewise, but the overflow flag is also
6735 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6736 (define_insn "sub<mode>3_carry_ccgz"
6737   [(set (reg:CCGZ FLAGS_REG)
6738         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6739                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6740                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6741                      UNSPEC_SBB))
6742    (clobber (match_scratch:DWIH 0 "=r"))]
6743   ""
6744   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6745   [(set_attr "type" "alu")
6746    (set_attr "mode" "<MODE>")])
6748 (define_insn "subborrow<mode>"
6749   [(set (reg:CCC FLAGS_REG)
6750         (compare:CCC
6751           (zero_extend:<DWI>
6752             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6753           (plus:<DWI>
6754             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6755               [(match_operand 3 "flags_reg_operand") (const_int 0)])
6756             (zero_extend:<DWI>
6757               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6758    (set (match_operand:SWI48 0 "register_operand" "=r")
6759         (minus:SWI48 (minus:SWI48
6760                        (match_dup 1)
6761                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
6762                          [(match_dup 3) (const_int 0)]))
6763                      (match_dup 2)))]
6764   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6765   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "use_carry" "1")
6768    (set_attr "pent_pair" "pu")
6769    (set_attr "mode" "<MODE>")])
6771 (define_expand "subborrow<mode>_0"
6772   [(parallel
6773      [(set (reg:CC FLAGS_REG)
6774            (compare:CC
6775              (match_operand:SWI48 1 "nonimmediate_operand")
6776              (match_operand:SWI48 2 "<general_operand>")))
6777       (set (match_operand:SWI48 0 "register_operand")
6778            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6779   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6781 ;; Overflow setting add instructions
6783 (define_expand "addqi3_cconly_overflow"
6784   [(parallel
6785      [(set (reg:CCC FLAGS_REG)
6786            (compare:CCC
6787              (plus:QI
6788                (match_operand:QI 0 "nonimmediate_operand")
6789                (match_operand:QI 1 "general_operand"))
6790              (match_dup 0)))
6791       (clobber (match_scratch:QI 2))])]
6792   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6794 (define_insn "*add<mode>3_cconly_overflow_1"
6795   [(set (reg:CCC FLAGS_REG)
6796         (compare:CCC
6797           (plus:SWI
6798             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6799             (match_operand:SWI 2 "<general_operand>" "<g>"))
6800           (match_dup 1)))
6801    (clobber (match_scratch:SWI 0 "=<r>"))]
6802   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6804   [(set_attr "type" "alu")
6805    (set_attr "mode" "<MODE>")])
6807 (define_insn "*add<mode>3_cc_overflow_1"
6808   [(set (reg:CCC FLAGS_REG)
6809         (compare:CCC
6810             (plus:SWI
6811                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6812                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6813             (match_dup 1)))
6814    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6815         (plus:SWI (match_dup 1) (match_dup 2)))]
6816   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6817   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6818   [(set_attr "type" "alu")
6819    (set_attr "mode" "<MODE>")])
6821 (define_insn "*addsi3_zext_cc_overflow_1"
6822   [(set (reg:CCC FLAGS_REG)
6823         (compare:CCC
6824           (plus:SI
6825             (match_operand:SI 1 "nonimmediate_operand" "%0")
6826             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6827           (match_dup 1)))
6828    (set (match_operand:DI 0 "register_operand" "=r")
6829         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6830   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6831   "add{l}\t{%2, %k0|%k0, %2}"
6832   [(set_attr "type" "alu")
6833    (set_attr "mode" "SI")])
6835 (define_insn "*add<mode>3_cconly_overflow_2"
6836   [(set (reg:CCC FLAGS_REG)
6837         (compare:CCC
6838           (plus:SWI
6839             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6840             (match_operand:SWI 2 "<general_operand>" "<g>"))
6841           (match_dup 2)))
6842    (clobber (match_scratch:SWI 0 "=<r>"))]
6843   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6844   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6845   [(set_attr "type" "alu")
6846    (set_attr "mode" "<MODE>")])
6848 (define_insn "*add<mode>3_cc_overflow_2"
6849   [(set (reg:CCC FLAGS_REG)
6850         (compare:CCC
6851             (plus:SWI
6852                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6853                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6854             (match_dup 2)))
6855    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6856         (plus:SWI (match_dup 1) (match_dup 2)))]
6857   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6858   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6859   [(set_attr "type" "alu")
6860    (set_attr "mode" "<MODE>")])
6862 (define_insn "*addsi3_zext_cc_overflow_2"
6863   [(set (reg:CCC FLAGS_REG)
6864         (compare:CCC
6865           (plus:SI
6866             (match_operand:SI 1 "nonimmediate_operand" "%0")
6867             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6868           (match_dup 2)))
6869    (set (match_operand:DI 0 "register_operand" "=r")
6870         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6871   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6872   "add{l}\t{%2, %k0|%k0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "SI")])
6876 ;; The patterns that match these are at the end of this file.
6878 (define_expand "<plusminus_insn>xf3"
6879   [(set (match_operand:XF 0 "register_operand")
6880         (plusminus:XF
6881           (match_operand:XF 1 "register_operand")
6882           (match_operand:XF 2 "register_operand")))]
6883   "TARGET_80387")
6885 (define_expand "<plusminus_insn><mode>3"
6886   [(set (match_operand:MODEF 0 "register_operand")
6887         (plusminus:MODEF
6888           (match_operand:MODEF 1 "register_operand")
6889           (match_operand:MODEF 2 "nonimmediate_operand")))]
6890   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6891     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6893 ;; Multiply instructions
6895 (define_expand "mul<mode>3"
6896   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6897                    (mult:SWIM248
6898                      (match_operand:SWIM248 1 "register_operand")
6899                      (match_operand:SWIM248 2 "<general_operand>")))
6900               (clobber (reg:CC FLAGS_REG))])])
6902 (define_expand "mulqi3"
6903   [(parallel [(set (match_operand:QI 0 "register_operand")
6904                    (mult:QI
6905                      (match_operand:QI 1 "register_operand")
6906                      (match_operand:QI 2 "nonimmediate_operand")))
6907               (clobber (reg:CC FLAGS_REG))])]
6908   "TARGET_QIMODE_MATH")
6910 ;; On AMDFAM10
6911 ;; IMUL reg32/64, reg32/64, imm8        Direct
6912 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6913 ;; IMUL reg32/64, reg32/64, imm32       Direct
6914 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6915 ;; IMUL reg32/64, reg32/64              Direct
6916 ;; IMUL reg32/64, mem32/64              Direct
6918 ;; On BDVER1, all above IMULs use DirectPath
6920 ;; On AMDFAM10
6921 ;; IMUL reg16, reg16, imm8      VectorPath
6922 ;; IMUL reg16, mem16, imm8      VectorPath
6923 ;; IMUL reg16, reg16, imm16     VectorPath
6924 ;; IMUL reg16, mem16, imm16     VectorPath
6925 ;; IMUL reg16, reg16            Direct
6926 ;; IMUL reg16, mem16            Direct
6928 ;; On BDVER1, all HI MULs use DoublePath
6930 (define_insn "*mul<mode>3_1"
6931   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6932         (mult:SWIM248
6933           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6934           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6935    (clobber (reg:CC FLAGS_REG))]
6936   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937   "@
6938    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6939    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6940    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6941   [(set_attr "type" "imul")
6942    (set_attr "prefix_0f" "0,0,1")
6943    (set (attr "athlon_decode")
6944         (cond [(eq_attr "cpu" "athlon")
6945                   (const_string "vector")
6946                (eq_attr "alternative" "1")
6947                   (const_string "vector")
6948                (and (eq_attr "alternative" "2")
6949                     (ior (match_test "<MODE>mode == HImode")
6950                          (match_operand 1 "memory_operand")))
6951                   (const_string "vector")]
6952               (const_string "direct")))
6953    (set (attr "amdfam10_decode")
6954         (cond [(and (eq_attr "alternative" "0,1")
6955                     (ior (match_test "<MODE>mode == HImode")
6956                          (match_operand 1 "memory_operand")))
6957                   (const_string "vector")]
6958               (const_string "direct")))
6959    (set (attr "bdver1_decode")
6960         (if_then_else
6961           (match_test "<MODE>mode == HImode")
6962             (const_string "double")
6963             (const_string "direct")))
6964    (set_attr "mode" "<MODE>")])
6966 (define_insn "*mulsi3_1_zext"
6967   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6968         (zero_extend:DI
6969           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6970                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6971    (clobber (reg:CC FLAGS_REG))]
6972   "TARGET_64BIT
6973    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974   "@
6975    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977    imul{l}\t{%2, %k0|%k0, %2}"
6978   [(set_attr "type" "imul")
6979    (set_attr "prefix_0f" "0,0,1")
6980    (set (attr "athlon_decode")
6981         (cond [(eq_attr "cpu" "athlon")
6982                   (const_string "vector")
6983                (eq_attr "alternative" "1")
6984                   (const_string "vector")
6985                (and (eq_attr "alternative" "2")
6986                     (match_operand 1 "memory_operand"))
6987                   (const_string "vector")]
6988               (const_string "direct")))
6989    (set (attr "amdfam10_decode")
6990         (cond [(and (eq_attr "alternative" "0,1")
6991                     (match_operand 1 "memory_operand"))
6992                   (const_string "vector")]
6993               (const_string "direct")))
6994    (set_attr "bdver1_decode" "direct")
6995    (set_attr "mode" "SI")])
6997 ;;On AMDFAM10 and BDVER1
6998 ;; MUL reg8     Direct
6999 ;; MUL mem8     Direct
7001 (define_insn "*mulqi3_1"
7002   [(set (match_operand:QI 0 "register_operand" "=a")
7003         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7004                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7005    (clobber (reg:CC FLAGS_REG))]
7006   "TARGET_QIMODE_MATH
7007    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008   "mul{b}\t%2"
7009   [(set_attr "type" "imul")
7010    (set_attr "length_immediate" "0")
7011    (set (attr "athlon_decode")
7012      (if_then_else (eq_attr "cpu" "athlon")
7013         (const_string "vector")
7014         (const_string "direct")))
7015    (set_attr "amdfam10_decode" "direct")
7016    (set_attr "bdver1_decode" "direct")
7017    (set_attr "mode" "QI")])
7019 ;; Multiply with jump on overflow.
7020 (define_expand "mulv<mode>4"
7021   [(parallel [(set (reg:CCO FLAGS_REG)
7022                    (eq:CCO (mult:<DWI>
7023                               (sign_extend:<DWI>
7024                                  (match_operand:SWI248 1 "register_operand"))
7025                               (match_dup 4))
7026                            (sign_extend:<DWI>
7027                               (mult:SWI248 (match_dup 1)
7028                                            (match_operand:SWI248 2
7029                                               "<general_operand>")))))
7030               (set (match_operand:SWI248 0 "register_operand")
7031                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7032    (set (pc) (if_then_else
7033                (eq (reg:CCO FLAGS_REG) (const_int 0))
7034                (label_ref (match_operand 3))
7035                (pc)))]
7036   ""
7038   if (CONST_INT_P (operands[2]))
7039     operands[4] = operands[2];
7040   else
7041     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7044 (define_insn "*mulv<mode>4"
7045   [(set (reg:CCO FLAGS_REG)
7046         (eq:CCO (mult:<DWI>
7047                    (sign_extend:<DWI>
7048                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7049                    (sign_extend:<DWI>
7050                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7051                 (sign_extend:<DWI>
7052                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7053    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7054         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7055   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056   "@
7057    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7058    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7059   [(set_attr "type" "imul")
7060    (set_attr "prefix_0f" "0,1")
7061    (set (attr "athlon_decode")
7062         (cond [(eq_attr "cpu" "athlon")
7063                   (const_string "vector")
7064                (eq_attr "alternative" "0")
7065                   (const_string "vector")
7066                (and (eq_attr "alternative" "1")
7067                     (match_operand 1 "memory_operand"))
7068                   (const_string "vector")]
7069               (const_string "direct")))
7070    (set (attr "amdfam10_decode")
7071         (cond [(and (eq_attr "alternative" "1")
7072                     (match_operand 1 "memory_operand"))
7073                   (const_string "vector")]
7074               (const_string "direct")))
7075    (set_attr "bdver1_decode" "direct")
7076    (set_attr "mode" "<MODE>")])
7078 (define_insn "*mulvhi4"
7079   [(set (reg:CCO FLAGS_REG)
7080         (eq:CCO (mult:SI
7081                    (sign_extend:SI
7082                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7083                    (sign_extend:SI
7084                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7085                 (sign_extend:SI
7086                    (mult:HI (match_dup 1) (match_dup 2)))))
7087    (set (match_operand:HI 0 "register_operand" "=r")
7088         (mult:HI (match_dup 1) (match_dup 2)))]
7089   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7090   "imul{w}\t{%2, %0|%0, %2}"
7091   [(set_attr "type" "imul")
7092    (set_attr "prefix_0f" "1")
7093    (set_attr "athlon_decode" "vector")
7094    (set_attr "amdfam10_decode" "direct")
7095    (set_attr "bdver1_decode" "double")
7096    (set_attr "mode" "HI")])
7098 (define_insn "*mulv<mode>4_1"
7099   [(set (reg:CCO FLAGS_REG)
7100         (eq:CCO (mult:<DWI>
7101                    (sign_extend:<DWI>
7102                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7103                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7104                 (sign_extend:<DWI>
7105                    (mult:SWI248 (match_dup 1)
7106                                 (match_operand:SWI248 2
7107                                    "<immediate_operand>" "K,<i>")))))
7108    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7109         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7110   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7111    && CONST_INT_P (operands[2])
7112    && INTVAL (operands[2]) == INTVAL (operands[3])"
7113   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7114   [(set_attr "type" "imul")
7115    (set (attr "prefix_0f")
7116         (if_then_else
7117           (match_test "<MODE>mode == HImode")
7118             (const_string "0")
7119             (const_string "*")))
7120    (set (attr "athlon_decode")
7121         (cond [(eq_attr "cpu" "athlon")
7122                   (const_string "vector")
7123                (eq_attr "alternative" "1")
7124                   (const_string "vector")]
7125               (const_string "direct")))
7126    (set (attr "amdfam10_decode")
7127         (cond [(ior (match_test "<MODE>mode == HImode")
7128                     (match_operand 1 "memory_operand"))
7129                   (const_string "vector")]
7130               (const_string "direct")))
7131    (set (attr "bdver1_decode")
7132         (if_then_else
7133           (match_test "<MODE>mode == HImode")
7134             (const_string "double")
7135             (const_string "direct")))
7136    (set_attr "mode" "<MODE>")
7137    (set (attr "length_immediate")
7138         (cond [(eq_attr "alternative" "0")
7139                   (const_string "1")
7140                (match_test "<MODE_SIZE> == 8")
7141                   (const_string "4")]
7142               (const_string "<MODE_SIZE>")))])
7144 (define_expand "umulv<mode>4"
7145   [(parallel [(set (reg:CCO FLAGS_REG)
7146                    (eq:CCO (mult:<DWI>
7147                               (zero_extend:<DWI>
7148                                  (match_operand:SWI248 1
7149                                                       "nonimmediate_operand"))
7150                               (zero_extend:<DWI>
7151                                  (match_operand:SWI248 2
7152                                                       "nonimmediate_operand")))
7153                            (zero_extend:<DWI>
7154                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7155               (set (match_operand:SWI248 0 "register_operand")
7156                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7157               (clobber (match_scratch:SWI248 4))])
7158    (set (pc) (if_then_else
7159                (eq (reg:CCO FLAGS_REG) (const_int 0))
7160                (label_ref (match_operand 3))
7161                (pc)))]
7162   ""
7164   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7165     operands[1] = force_reg (<MODE>mode, operands[1]);
7168 (define_insn "*umulv<mode>4"
7169   [(set (reg:CCO FLAGS_REG)
7170         (eq:CCO (mult:<DWI>
7171                    (zero_extend:<DWI>
7172                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7173                    (zero_extend:<DWI>
7174                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7175                 (zero_extend:<DWI>
7176                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7177    (set (match_operand:SWI248 0 "register_operand" "=a")
7178         (mult:SWI248 (match_dup 1) (match_dup 2)))
7179    (clobber (match_scratch:SWI248 3 "=d"))]
7180   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7181   "mul{<imodesuffix>}\t%2"
7182   [(set_attr "type" "imul")
7183    (set_attr "length_immediate" "0")
7184    (set (attr "athlon_decode")
7185      (if_then_else (eq_attr "cpu" "athlon")
7186        (const_string "vector")
7187        (const_string "double")))
7188    (set_attr "amdfam10_decode" "double")
7189    (set_attr "bdver1_decode" "direct")
7190    (set_attr "mode" "<MODE>")])
7192 (define_expand "<u>mulvqi4"
7193   [(parallel [(set (reg:CCO FLAGS_REG)
7194                    (eq:CCO (mult:HI
7195                               (any_extend:HI
7196                                  (match_operand:QI 1 "nonimmediate_operand"))
7197                               (any_extend:HI
7198                                  (match_operand:QI 2 "nonimmediate_operand")))
7199                            (any_extend:HI
7200                               (mult:QI (match_dup 1) (match_dup 2)))))
7201               (set (match_operand:QI 0 "register_operand")
7202                    (mult:QI (match_dup 1) (match_dup 2)))])
7203    (set (pc) (if_then_else
7204                (eq (reg:CCO FLAGS_REG) (const_int 0))
7205                (label_ref (match_operand 3))
7206                (pc)))]
7207   "TARGET_QIMODE_MATH"
7209   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7210     operands[1] = force_reg (QImode, operands[1]);
7213 (define_insn "*<u>mulvqi4"
7214   [(set (reg:CCO FLAGS_REG)
7215         (eq:CCO (mult:HI
7216                    (any_extend:HI
7217                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7218                    (any_extend:HI
7219                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7220                 (any_extend:HI
7221                    (mult:QI (match_dup 1) (match_dup 2)))))
7222    (set (match_operand:QI 0 "register_operand" "=a")
7223         (mult:QI (match_dup 1) (match_dup 2)))]
7224   "TARGET_QIMODE_MATH
7225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7226   "<sgnprefix>mul{b}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "direct")))
7233    (set_attr "amdfam10_decode" "direct")
7234    (set_attr "bdver1_decode" "direct")
7235    (set_attr "mode" "QI")])
7237 (define_expand "<u>mul<mode><dwi>3"
7238   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7239                    (mult:<DWI>
7240                      (any_extend:<DWI>
7241                        (match_operand:DWIH 1 "nonimmediate_operand"))
7242                      (any_extend:<DWI>
7243                        (match_operand:DWIH 2 "register_operand"))))
7244               (clobber (reg:CC FLAGS_REG))])])
7246 (define_expand "<u>mulqihi3"
7247   [(parallel [(set (match_operand:HI 0 "register_operand")
7248                    (mult:HI
7249                      (any_extend:HI
7250                        (match_operand:QI 1 "nonimmediate_operand"))
7251                      (any_extend:HI
7252                        (match_operand:QI 2 "register_operand"))))
7253               (clobber (reg:CC FLAGS_REG))])]
7254   "TARGET_QIMODE_MATH")
7256 (define_insn "*bmi2_umul<mode><dwi>3_1"
7257   [(set (match_operand:DWIH 0 "register_operand" "=r")
7258         (mult:DWIH
7259           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7260           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7261    (set (match_operand:DWIH 1 "register_operand" "=r")
7262         (truncate:DWIH
7263           (lshiftrt:<DWI>
7264             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7265                         (zero_extend:<DWI> (match_dup 3)))
7266             (match_operand:QI 4 "const_int_operand" "n"))))]
7267   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7268    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269   "mulx\t{%3, %0, %1|%1, %0, %3}"
7270   [(set_attr "type" "imulx")
7271    (set_attr "prefix" "vex")
7272    (set_attr "mode" "<MODE>")])
7274 (define_insn "*umul<mode><dwi>3_1"
7275   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7276         (mult:<DWI>
7277           (zero_extend:<DWI>
7278             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7279           (zero_extend:<DWI>
7280             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7281    (clobber (reg:CC FLAGS_REG))]
7282   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283   "@
7284    #
7285    mul{<imodesuffix>}\t%2"
7286   [(set_attr "isa" "bmi2,*")
7287    (set_attr "type" "imulx,imul")
7288    (set_attr "length_immediate" "*,0")
7289    (set (attr "athlon_decode")
7290         (cond [(eq_attr "alternative" "1")
7291                  (if_then_else (eq_attr "cpu" "athlon")
7292                    (const_string "vector")
7293                    (const_string "double"))]
7294               (const_string "*")))
7295    (set_attr "amdfam10_decode" "*,double")
7296    (set_attr "bdver1_decode" "*,direct")
7297    (set_attr "prefix" "vex,orig")
7298    (set_attr "mode" "<MODE>")])
7300 ;; Convert mul to the mulx pattern to avoid flags dependency.
7301 (define_split
7302  [(set (match_operand:<DWI> 0 "register_operand")
7303        (mult:<DWI>
7304          (zero_extend:<DWI>
7305            (match_operand:DWIH 1 "register_operand"))
7306          (zero_extend:<DWI>
7307            (match_operand:DWIH 2 "nonimmediate_operand"))))
7308   (clobber (reg:CC FLAGS_REG))]
7309  "TARGET_BMI2 && reload_completed
7310   && REGNO (operands[1]) == DX_REG"
7311   [(parallel [(set (match_dup 3)
7312                    (mult:DWIH (match_dup 1) (match_dup 2)))
7313               (set (match_dup 4)
7314                    (truncate:DWIH
7315                      (lshiftrt:<DWI>
7316                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7317                                    (zero_extend:<DWI> (match_dup 2)))
7318                        (match_dup 5))))])]
7320   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7322   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7325 (define_insn "*mul<mode><dwi>3_1"
7326   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7327         (mult:<DWI>
7328           (sign_extend:<DWI>
7329             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7330           (sign_extend:<DWI>
7331             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7334   "imul{<imodesuffix>}\t%2"
7335   [(set_attr "type" "imul")
7336    (set_attr "length_immediate" "0")
7337    (set (attr "athlon_decode")
7338      (if_then_else (eq_attr "cpu" "athlon")
7339         (const_string "vector")
7340         (const_string "double")))
7341    (set_attr "amdfam10_decode" "double")
7342    (set_attr "bdver1_decode" "direct")
7343    (set_attr "mode" "<MODE>")])
7345 (define_insn "*<u>mulqihi3_1"
7346   [(set (match_operand:HI 0 "register_operand" "=a")
7347         (mult:HI
7348           (any_extend:HI
7349             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7350           (any_extend:HI
7351             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "TARGET_QIMODE_MATH
7354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355   "<sgnprefix>mul{b}\t%2"
7356   [(set_attr "type" "imul")
7357    (set_attr "length_immediate" "0")
7358    (set (attr "athlon_decode")
7359      (if_then_else (eq_attr "cpu" "athlon")
7360         (const_string "vector")
7361         (const_string "direct")))
7362    (set_attr "amdfam10_decode" "direct")
7363    (set_attr "bdver1_decode" "direct")
7364    (set_attr "mode" "QI")])
7366 (define_expand "<s>mul<mode>3_highpart"
7367   [(parallel [(set (match_operand:DWIH 0 "register_operand")
7368                    (truncate:DWIH
7369                      (lshiftrt:<DWI>
7370                        (mult:<DWI>
7371                          (any_extend:<DWI>
7372                            (match_operand:DWIH 1 "nonimmediate_operand"))
7373                          (any_extend:<DWI>
7374                            (match_operand:DWIH 2 "register_operand")))
7375                        (match_dup 3))))
7376               (clobber (match_scratch:DWIH 4))
7377               (clobber (reg:CC FLAGS_REG))])]
7378   ""
7379   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7381 (define_insn "*<s>muldi3_highpart_1"
7382   [(set (match_operand:DI 0 "register_operand" "=d")
7383         (truncate:DI
7384           (lshiftrt:TI
7385             (mult:TI
7386               (any_extend:TI
7387                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7388               (any_extend:TI
7389                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7390             (const_int 64))))
7391    (clobber (match_scratch:DI 3 "=1"))
7392    (clobber (reg:CC FLAGS_REG))]
7393   "TARGET_64BIT
7394    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7395   "<sgnprefix>mul{q}\t%2"
7396   [(set_attr "type" "imul")
7397    (set_attr "length_immediate" "0")
7398    (set (attr "athlon_decode")
7399      (if_then_else (eq_attr "cpu" "athlon")
7400         (const_string "vector")
7401         (const_string "double")))
7402    (set_attr "amdfam10_decode" "double")
7403    (set_attr "bdver1_decode" "direct")
7404    (set_attr "mode" "DI")])
7406 (define_insn "*<s>mulsi3_highpart_zext"
7407   [(set (match_operand:DI 0 "register_operand" "=d")
7408         (zero_extend:DI (truncate:SI
7409           (lshiftrt:DI
7410             (mult:DI (any_extend:DI
7411                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7412                      (any_extend:DI
7413                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7414             (const_int 32)))))
7415    (clobber (match_scratch:SI 3 "=1"))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT
7418    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419   "<sgnprefix>mul{l}\t%2"
7420   [(set_attr "type" "imul")
7421    (set_attr "length_immediate" "0")
7422    (set (attr "athlon_decode")
7423      (if_then_else (eq_attr "cpu" "athlon")
7424         (const_string "vector")
7425         (const_string "double")))
7426    (set_attr "amdfam10_decode" "double")
7427    (set_attr "bdver1_decode" "direct")
7428    (set_attr "mode" "SI")])
7430 (define_insn "*<s>mulsi3_highpart_1"
7431   [(set (match_operand:SI 0 "register_operand" "=d")
7432         (truncate:SI
7433           (lshiftrt:DI
7434             (mult:DI
7435               (any_extend:DI
7436                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7437               (any_extend:DI
7438                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7439             (const_int 32))))
7440    (clobber (match_scratch:SI 3 "=1"))
7441    (clobber (reg:CC FLAGS_REG))]
7442   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7443   "<sgnprefix>mul{l}\t%2"
7444   [(set_attr "type" "imul")
7445    (set_attr "length_immediate" "0")
7446    (set (attr "athlon_decode")
7447      (if_then_else (eq_attr "cpu" "athlon")
7448         (const_string "vector")
7449         (const_string "double")))
7450    (set_attr "amdfam10_decode" "double")
7451    (set_attr "bdver1_decode" "direct")
7452    (set_attr "mode" "SI")])
7454 ;; The patterns that match these are at the end of this file.
7456 (define_expand "mulxf3"
7457   [(set (match_operand:XF 0 "register_operand")
7458         (mult:XF (match_operand:XF 1 "register_operand")
7459                  (match_operand:XF 2 "register_operand")))]
7460   "TARGET_80387")
7462 (define_expand "mul<mode>3"
7463   [(set (match_operand:MODEF 0 "register_operand")
7464         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7465                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7466   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7467     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7469 ;; Divide instructions
7471 ;; The patterns that match these are at the end of this file.
7473 (define_expand "divxf3"
7474   [(set (match_operand:XF 0 "register_operand")
7475         (div:XF (match_operand:XF 1 "register_operand")
7476                 (match_operand:XF 2 "register_operand")))]
7477   "TARGET_80387")
7479 (define_expand "div<mode>3"
7480   [(set (match_operand:MODEF 0 "register_operand")
7481         (div:MODEF (match_operand:MODEF 1 "register_operand")
7482                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7483   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7484     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7486   if (<MODE>mode == SFmode
7487       && TARGET_SSE && TARGET_SSE_MATH
7488       && TARGET_RECIP_DIV
7489       && optimize_insn_for_speed_p ()
7490       && flag_finite_math_only && !flag_trapping_math
7491       && flag_unsafe_math_optimizations)
7492     {
7493       ix86_emit_swdivsf (operands[0], operands[1],
7494                          operands[2], SFmode);
7495       DONE;
7496     }
7499 ;; Divmod instructions.
7501 (define_code_iterator any_div [div udiv])
7502 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7504 (define_expand "<u>divmod<mode>4"
7505   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7506                    (any_div:SWIM248
7507                      (match_operand:SWIM248 1 "register_operand")
7508                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7509               (set (match_operand:SWIM248 3 "register_operand")
7510                    (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7511               (clobber (reg:CC FLAGS_REG))])])
7513 ;; Split with 8bit unsigned divide:
7514 ;;      if (dividend an divisor are in [0-255])
7515 ;;         use 8bit unsigned integer divide
7516 ;;       else
7517 ;;         use original integer divide
7518 (define_split
7519   [(set (match_operand:SWI48 0 "register_operand")
7520         (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7521                        (match_operand:SWI48 3 "nonimmediate_operand")))
7522    (set (match_operand:SWI48 1 "register_operand")
7523         (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7524    (clobber (reg:CC FLAGS_REG))]
7525   "TARGET_USE_8BIT_IDIV
7526    && TARGET_QIMODE_MATH
7527    && can_create_pseudo_p ()
7528    && !optimize_insn_for_size_p ()"
7529   [(const_int 0)]
7530   "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7532 (define_split
7533   [(set (match_operand:DI 0 "register_operand")
7534         (zero_extend:DI
7535           (any_div:SI (match_operand:SI 2 "register_operand")
7536                       (match_operand:SI 3 "nonimmediate_operand"))))
7537    (set (match_operand:SI 1 "register_operand")
7538         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7539    (clobber (reg:CC FLAGS_REG))]
7540   "TARGET_64BIT
7541    && TARGET_USE_8BIT_IDIV
7542    && TARGET_QIMODE_MATH
7543    && can_create_pseudo_p ()
7544    && !optimize_insn_for_size_p ()"
7545   [(const_int 0)]
7546   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7548 (define_split
7549   [(set (match_operand:DI 1 "register_operand")
7550         (zero_extend:DI
7551           (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7552                            (match_operand:SI 3 "nonimmediate_operand"))))
7553    (set (match_operand:SI 0 "register_operand")
7554         (any_div:SI  (match_dup 2) (match_dup 3)))
7555    (clobber (reg:CC FLAGS_REG))]
7556   "TARGET_64BIT
7557    && TARGET_USE_8BIT_IDIV
7558    && TARGET_QIMODE_MATH
7559    && can_create_pseudo_p ()
7560    && !optimize_insn_for_size_p ()"
7561   [(const_int 0)]
7562   "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7564 (define_insn_and_split "divmod<mode>4_1"
7565   [(set (match_operand:SWI48 0 "register_operand" "=a")
7566         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7567                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7568    (set (match_operand:SWI48 1 "register_operand" "=&d")
7569         (mod:SWI48 (match_dup 2) (match_dup 3)))
7570    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7571    (clobber (reg:CC FLAGS_REG))]
7572   ""
7573   "#"
7574   "reload_completed"
7575   [(parallel [(set (match_dup 1)
7576                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7577               (clobber (reg:CC FLAGS_REG))])
7578    (parallel [(set (match_dup 0)
7579                    (div:SWI48 (match_dup 2) (match_dup 3)))
7580               (set (match_dup 1)
7581                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7582               (use (match_dup 1))
7583               (clobber (reg:CC FLAGS_REG))])]
7585   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7587   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7588     operands[4] = operands[2];
7589   else
7590     {
7591       /* Avoid use of cltd in favor of a mov+shift.  */
7592       emit_move_insn (operands[1], operands[2]);
7593       operands[4] = operands[1];
7594     }
7596   [(set_attr "type" "multi")
7597    (set_attr "mode" "<MODE>")])
7599 (define_insn_and_split "udivmod<mode>4_1"
7600   [(set (match_operand:SWI48 0 "register_operand" "=a")
7601         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7602                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7603    (set (match_operand:SWI48 1 "register_operand" "=&d")
7604         (umod:SWI48 (match_dup 2) (match_dup 3)))
7605    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7606    (clobber (reg:CC FLAGS_REG))]
7607   ""
7608   "#"
7609   "reload_completed"
7610   [(set (match_dup 1) (const_int 0))
7611    (parallel [(set (match_dup 0)
7612                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7613               (set (match_dup 1)
7614                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7615               (use (match_dup 1))
7616               (clobber (reg:CC FLAGS_REG))])]
7617   ""
7618   [(set_attr "type" "multi")
7619    (set_attr "mode" "<MODE>")])
7621 (define_insn_and_split "divmodsi4_zext_1"
7622   [(set (match_operand:DI 0 "register_operand" "=a")
7623         (zero_extend:DI
7624           (div:SI (match_operand:SI 2 "register_operand" "0")
7625                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7626    (set (match_operand:SI 1 "register_operand" "=&d")
7627         (mod:SI (match_dup 2) (match_dup 3)))
7628    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7629    (clobber (reg:CC FLAGS_REG))]
7630   "TARGET_64BIT"
7631   "#"
7632   "&& reload_completed"
7633   [(parallel [(set (match_dup 1)
7634                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7635               (clobber (reg:CC FLAGS_REG))])
7636    (parallel [(set (match_dup 0)
7637                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7638               (set (match_dup 1)
7639                    (mod:SI (match_dup 2) (match_dup 3)))
7640               (use (match_dup 1))
7641               (clobber (reg:CC FLAGS_REG))])]
7643   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7645   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7646     operands[4] = operands[2];
7647   else
7648     {
7649       /* Avoid use of cltd in favor of a mov+shift.  */
7650       emit_move_insn (operands[1], operands[2]);
7651       operands[4] = operands[1];
7652     }
7654   [(set_attr "type" "multi")
7655    (set_attr "mode" "SI")])
7657 (define_insn_and_split "udivmodsi4_zext_1"
7658   [(set (match_operand:DI 0 "register_operand" "=a")
7659         (zero_extend:DI
7660           (udiv:SI (match_operand:SI 2 "register_operand" "0")
7661                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7662    (set (match_operand:SI 1 "register_operand" "=&d")
7663         (umod:SI (match_dup 2) (match_dup 3)))
7664    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7665    (clobber (reg:CC FLAGS_REG))]
7666   "TARGET_64BIT"
7667   "#"
7668   "&& reload_completed"
7669   [(set (match_dup 1) (const_int 0))
7670    (parallel [(set (match_dup 0)
7671                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7672               (set (match_dup 1)
7673                    (umod:SI (match_dup 2) (match_dup 3)))
7674               (use (match_dup 1))
7675               (clobber (reg:CC FLAGS_REG))])]
7676   ""
7677   [(set_attr "type" "multi")
7678    (set_attr "mode" "SI")])
7680 (define_insn_and_split "divmodsi4_zext_2"
7681   [(set (match_operand:DI 1 "register_operand" "=&d")
7682         (zero_extend:DI
7683           (mod:SI (match_operand:SI 2 "register_operand" "0")
7684                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7685    (set (match_operand:SI 0 "register_operand" "=a")
7686         (div:SI (match_dup 2) (match_dup 3)))
7687    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7688    (clobber (reg:CC FLAGS_REG))]
7689   "TARGET_64BIT"
7690   "#"
7691   "&& reload_completed"
7692   [(parallel [(set (match_dup 6)
7693                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7694               (clobber (reg:CC FLAGS_REG))])
7695    (parallel [(set (match_dup 1)
7696                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7697               (set (match_dup 0)
7698                    (div:SI (match_dup 2) (match_dup 3)))
7699               (use (match_dup 6))
7700               (clobber (reg:CC FLAGS_REG))])]
7702   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7703   operands[6] = gen_lowpart (SImode, operands[1]);
7705   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7706     operands[4] = operands[2];
7707   else
7708     {
7709       /* Avoid use of cltd in favor of a mov+shift.  */
7710       emit_move_insn (operands[6], operands[2]);
7711       operands[4] = operands[6];
7712     }
7714   [(set_attr "type" "multi")
7715    (set_attr "mode" "SI")])
7717 (define_insn_and_split "udivmodsi4_zext_2"
7718   [(set (match_operand:DI 1 "register_operand" "=&d")
7719         (zero_extend:DI
7720           (umod:SI (match_operand:SI 2 "register_operand" "0")
7721                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7722    (set (match_operand:SI 0 "register_operand" "=a")
7723         (udiv:SI (match_dup 2) (match_dup 3)))
7724    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7725    (clobber (reg:CC FLAGS_REG))]
7726   "TARGET_64BIT"
7727   "#"
7728   "&& reload_completed"
7729   [(set (match_dup 4) (const_int 0))
7730    (parallel [(set (match_dup 1)
7731                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7732               (set (match_dup 0)
7733                    (udiv:SI (match_dup 2) (match_dup 3)))
7734               (use (match_dup 4))
7735               (clobber (reg:CC FLAGS_REG))])]
7736   "operands[4] = gen_lowpart (SImode, operands[1]);"
7737   [(set_attr "type" "multi")
7738    (set_attr "mode" "SI")])
7740 (define_insn_and_split "*divmod<mode>4"
7741   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7742         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7743                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7744    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7745         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7746    (clobber (reg:CC FLAGS_REG))]
7747   ""
7748   "#"
7749   "reload_completed"
7750   [(parallel [(set (match_dup 1)
7751                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7752               (clobber (reg:CC FLAGS_REG))])
7753    (parallel [(set (match_dup 0)
7754                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7755               (set (match_dup 1)
7756                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7757               (use (match_dup 1))
7758               (clobber (reg:CC FLAGS_REG))])]
7760   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7762   if (<MODE>mode != HImode
7763       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7764     operands[4] = operands[2];
7765   else
7766     {
7767       /* Avoid use of cltd in favor of a mov+shift.  */
7768       emit_move_insn (operands[1], operands[2]);
7769       operands[4] = operands[1];
7770     }
7772   [(set_attr "type" "multi")
7773    (set_attr "mode" "<MODE>")])
7775 (define_insn_and_split "*udivmod<mode>4"
7776   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7777         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7778                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7779    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7780         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7781    (clobber (reg:CC FLAGS_REG))]
7782   ""
7783   "#"
7784   "reload_completed"
7785   [(set (match_dup 1) (const_int 0))
7786    (parallel [(set (match_dup 0)
7787                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7788               (set (match_dup 1)
7789                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7790               (use (match_dup 1))
7791               (clobber (reg:CC FLAGS_REG))])]
7792   ""
7793   [(set_attr "type" "multi")
7794    (set_attr "mode" "<MODE>")])
7796 ;; Optimize division or modulo by constant power of 2, if the constant
7797 ;; materializes only after expansion.
7798 (define_insn_and_split "*udivmod<mode>4_pow2"
7799   [(set (match_operand:SWI48 0 "register_operand" "=r")
7800         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7801                     (match_operand:SWI48 3 "const_int_operand" "n")))
7802    (set (match_operand:SWI48 1 "register_operand" "=r")
7803         (umod:SWI48 (match_dup 2) (match_dup 3)))
7804    (clobber (reg:CC FLAGS_REG))]
7805   "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
7806   "#"
7807   "&& reload_completed"
7808   [(set (match_dup 1) (match_dup 2))
7809    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7810               (clobber (reg:CC FLAGS_REG))])
7811    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7812               (clobber (reg:CC FLAGS_REG))])]
7814   int v = exact_log2 (UINTVAL (operands[3]));
7815   operands[4] = GEN_INT (v);
7816   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7818   [(set_attr "type" "multi")
7819    (set_attr "mode" "<MODE>")])
7821 (define_insn_and_split "*divmodsi4_zext_1"
7822   [(set (match_operand:DI 0 "register_operand" "=a")
7823         (zero_extend:DI
7824           (div:SI (match_operand:SI 2 "register_operand" "0")
7825                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7826    (set (match_operand:SI 1 "register_operand" "=&d")
7827         (mod:SI (match_dup 2) (match_dup 3)))
7828    (clobber (reg:CC FLAGS_REG))]
7829   "TARGET_64BIT"
7830   "#"
7831   "&& reload_completed"
7832   [(parallel [(set (match_dup 1)
7833                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7834               (clobber (reg:CC FLAGS_REG))])
7835    (parallel [(set (match_dup 0)
7836                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7837               (set (match_dup 1)
7838                    (mod:SI (match_dup 2) (match_dup 3)))
7839               (use (match_dup 1))
7840               (clobber (reg:CC FLAGS_REG))])]
7842   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7844   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7845     operands[4] = operands[2];
7846   else
7847     {
7848       /* Avoid use of cltd in favor of a mov+shift.  */
7849       emit_move_insn (operands[1], operands[2]);
7850       operands[4] = operands[1];
7851     }
7853   [(set_attr "type" "multi")
7854    (set_attr "mode" "SI")])
7856 (define_insn_and_split "*udivmodsi4_zext_1"
7857   [(set (match_operand:DI 0 "register_operand" "=a")
7858         (zero_extend:DI
7859           (udiv:SI (match_operand:SI 2 "register_operand" "0")
7860                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7861    (set (match_operand:SI 1 "register_operand" "=&d")
7862         (umod:SI (match_dup 2) (match_dup 3)))
7863    (clobber (reg:CC FLAGS_REG))]
7864   "TARGET_64BIT"
7865   "#"
7866   "&& reload_completed"
7867   [(set (match_dup 1) (const_int 0))
7868    (parallel [(set (match_dup 0)
7869                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7870               (set (match_dup 1)
7871                    (umod:SI (match_dup 2) (match_dup 3)))
7872               (use (match_dup 1))
7873               (clobber (reg:CC FLAGS_REG))])]
7874   ""
7875   [(set_attr "type" "multi")
7876    (set_attr "mode" "SI")])
7878 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7879   [(set (match_operand:DI 0 "register_operand" "=r")
7880         (zero_extend:DI
7881           (udiv:SI (match_operand:SI 2 "register_operand" "0")
7882                    (match_operand:SI 3 "const_int_operand" "n"))))
7883    (set (match_operand:SI 1 "register_operand" "=r")
7884         (umod:SI (match_dup 2) (match_dup 3)))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "TARGET_64BIT
7887    && exact_log2 (UINTVAL (operands[3])) > 0"
7888   "#"
7889   "&& reload_completed"
7890   [(set (match_dup 1) (match_dup 2))
7891    (parallel [(set (match_dup 0)
7892                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
7893               (clobber (reg:CC FLAGS_REG))])
7894    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
7895               (clobber (reg:CC FLAGS_REG))])]
7897   int v = exact_log2 (UINTVAL (operands[3]));
7898   operands[4] = GEN_INT (v);
7899   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7901   [(set_attr "type" "multi")
7902    (set_attr "mode" "SI")])
7904 (define_insn_and_split "*divmodsi4_zext_2"
7905   [(set (match_operand:DI 1 "register_operand" "=&d")
7906         (zero_extend:DI
7907           (mod:SI (match_operand:SI 2 "register_operand" "0")
7908                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7909    (set (match_operand:SI 0 "register_operand" "=a")
7910         (div:SI (match_dup 2) (match_dup 3)))
7911    (clobber (reg:CC FLAGS_REG))]
7912   "TARGET_64BIT"
7913   "#"
7914   "&& reload_completed"
7915   [(parallel [(set (match_dup 6)
7916                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7917               (clobber (reg:CC FLAGS_REG))])
7918    (parallel [(set (match_dup 1)
7919                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7920               (set (match_dup 0)
7921                    (div:SI (match_dup 2) (match_dup 3)))
7922               (use (match_dup 6))
7923               (clobber (reg:CC FLAGS_REG))])]
7925   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7926   operands[6] = gen_lowpart (SImode, operands[1]);
7928   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7929     operands[4] = operands[2];
7930   else
7931     {
7932       /* Avoid use of cltd in favor of a mov+shift.  */
7933       emit_move_insn (operands[6], operands[2]);
7934       operands[4] = operands[6];
7935     }
7937   [(set_attr "type" "multi")
7938    (set_attr "mode" "SI")])
7940 (define_insn_and_split "*udivmodsi4_zext_2"
7941   [(set (match_operand:DI 1 "register_operand" "=&d")
7942         (zero_extend:DI
7943           (umod:SI (match_operand:SI 2 "register_operand" "0")
7944                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7945    (set (match_operand:SI 0 "register_operand" "=a")
7946         (udiv:SI (match_dup 2) (match_dup 3)))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "TARGET_64BIT"
7949   "#"
7950   "&& reload_completed"
7951   [(set (match_dup 4) (const_int 0))
7952    (parallel [(set (match_dup 1)
7953                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7954               (set (match_dup 0)
7955                    (udiv:SI (match_dup 2) (match_dup 3)))
7956               (use (match_dup 4))
7957               (clobber (reg:CC FLAGS_REG))])]
7958   "operands[4] = gen_lowpart (SImode, operands[1]);"
7959   [(set_attr "type" "multi")
7960    (set_attr "mode" "SI")])
7962 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
7963   [(set (match_operand:DI 1 "register_operand" "=r")
7964         (zero_extend:DI
7965           (umod:SI (match_operand:SI 2 "register_operand" "0")
7966                    (match_operand:SI 3 "const_int_operand" "n"))))
7967    (set (match_operand:SI 0 "register_operand" "=r")
7968         (umod:SI (match_dup 2) (match_dup 3)))
7969    (clobber (reg:CC FLAGS_REG))]
7970   "TARGET_64BIT
7971    && exact_log2 (UINTVAL (operands[3])) > 0"
7972   "#"
7973   "&& reload_completed"
7974   [(set (match_dup 1) (match_dup 2))
7975    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
7976               (clobber (reg:CC FLAGS_REG))])
7977    (parallel [(set (match_dup 1)
7978                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
7979               (clobber (reg:CC FLAGS_REG))])]
7981   int v = exact_log2 (UINTVAL (operands[3]));
7982   operands[4] = GEN_INT (v);
7983   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7985   [(set_attr "type" "multi")
7986    (set_attr "mode" "SI")])
7988 (define_insn "*<u>divmod<mode>4_noext"
7989   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7990         (any_div:SWIM248
7991           (match_operand:SWIM248 2 "register_operand" "0")
7992           (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993    (set (match_operand:SWIM248 1 "register_operand" "=d")
7994         (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
7995    (use (match_operand:SWIM248 4 "register_operand" "1"))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "<sgnprefix>div{<imodesuffix>}\t%3"
7999   [(set_attr "type" "idiv")
8000    (set_attr "mode" "<MODE>")])
8002 (define_insn "*<u>divmodsi4_noext_zext_1"
8003   [(set (match_operand:DI 0 "register_operand" "=a")
8004         (zero_extend:DI
8005           (any_div:SI (match_operand:SI 2 "register_operand" "0")
8006                       (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8007    (set (match_operand:SI 1 "register_operand" "=d")
8008         (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8009    (use (match_operand:SI 4 "register_operand" "1"))
8010    (clobber (reg:CC FLAGS_REG))]
8011   "TARGET_64BIT"
8012   "<sgnprefix>div{l}\t%3"
8013   [(set_attr "type" "idiv")
8014    (set_attr "mode" "SI")])
8016 (define_insn "*<u>divmodsi4_noext_zext_2"
8017   [(set (match_operand:DI 1 "register_operand" "=d")
8018         (zero_extend:DI
8019           (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8020                            (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8021    (set (match_operand:SI 0 "register_operand" "=a")
8022         (any_div:SI (match_dup 2) (match_dup 3)))
8023    (use (match_operand:SI 4 "register_operand" "1"))
8024    (clobber (reg:CC FLAGS_REG))]
8025   "TARGET_64BIT"
8026   "<sgnprefix>div{l}\t%3"
8027   [(set_attr "type" "idiv")
8028    (set_attr "mode" "SI")])
8030 (define_expand "divmodqi4"
8031   [(parallel [(set (match_operand:QI 0 "register_operand")
8032                    (div:QI
8033                      (match_operand:QI 1 "register_operand")
8034                      (match_operand:QI 2 "nonimmediate_operand")))
8035               (set (match_operand:QI 3 "register_operand")
8036                    (mod:QI (match_dup 1) (match_dup 2)))
8037               (clobber (reg:CC FLAGS_REG))])]
8038   "TARGET_QIMODE_MATH"
8040   rtx div, mod;
8041   rtx tmp0, tmp1;
8043   tmp0 = gen_reg_rtx (HImode);
8044   tmp1 = gen_reg_rtx (HImode);
8046   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8047   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8048   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8050   /* Extract remainder from AH.  */
8051   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8052   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8053   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8055   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8056   set_unique_reg_note (insn, REG_EQUAL, mod);
8058   /* Extract quotient from AL.  */
8059   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8061   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8062   set_unique_reg_note (insn, REG_EQUAL, div);
8064   DONE;
8067 (define_expand "udivmodqi4"
8068   [(parallel [(set (match_operand:QI 0 "register_operand")
8069                    (udiv:QI
8070                      (match_operand:QI 1 "register_operand")
8071                      (match_operand:QI 2 "nonimmediate_operand")))
8072               (set (match_operand:QI 3 "register_operand")
8073                    (umod:QI (match_dup 1) (match_dup 2)))
8074               (clobber (reg:CC FLAGS_REG))])]
8075   "TARGET_QIMODE_MATH"
8077   rtx div, mod;
8078   rtx tmp0, tmp1;
8080   tmp0 = gen_reg_rtx (HImode);
8081   tmp1 = gen_reg_rtx (HImode);
8083   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8084   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8085   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8087   /* Extract remainder from AH.  */
8088   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8089   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8090   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8092   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8093   set_unique_reg_note (insn, REG_EQUAL, mod);
8095   /* Extract quotient from AL.  */
8096   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8098   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8099   set_unique_reg_note (insn, REG_EQUAL, div);
8101   DONE;
8104 ;; Divide AX by r/m8, with result stored in
8105 ;; AL <- Quotient
8106 ;; AH <- Remainder
8107 ;; Change div/mod to HImode and extend the second argument to HImode
8108 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8109 ;; combine may fail.
8110 (define_insn "<u>divmodhiqi3"
8111   [(set (match_operand:HI 0 "register_operand" "=a")
8112         (ior:HI
8113           (ashift:HI
8114             (zero_extend:HI
8115               (truncate:QI
8116                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8117                         (any_extend:HI
8118                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8119             (const_int 8))
8120           (zero_extend:HI
8121             (truncate:QI
8122               (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "TARGET_QIMODE_MATH"
8125   "<sgnprefix>div{b}\t%2"
8126   [(set_attr "type" "idiv")
8127    (set_attr "mode" "QI")])
8129 ;; We cannot use div/idiv for double division, because it causes
8130 ;; "division by zero" on the overflow and that's not what we expect
8131 ;; from truncate.  Because true (non truncating) double division is
8132 ;; never generated, we can't create this insn anyway.
8134 ;(define_insn ""
8135 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8136 ;       (truncate:SI
8137 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8138 ;                  (zero_extend:DI
8139 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8140 ;   (set (match_operand:SI 3 "register_operand" "=d")
8141 ;       (truncate:SI
8142 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8143 ;   (clobber (reg:CC FLAGS_REG))]
8144 ;  ""
8145 ;  "div{l}\t{%2, %0|%0, %2}"
8146 ;  [(set_attr "type" "idiv")])
8148 ;;- Logical AND instructions
8150 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8151 ;; Note that this excludes ah.
8153 (define_expand "testsi_ccno_1"
8154   [(set (reg:CCNO FLAGS_REG)
8155         (compare:CCNO
8156           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8157                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8158           (const_int 0)))])
8160 (define_expand "testqi_ccz_1"
8161   [(set (reg:CCZ FLAGS_REG)
8162         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8163                              (match_operand:QI 1 "nonmemory_operand"))
8164                  (const_int 0)))])
8166 (define_expand "testdi_ccno_1"
8167   [(set (reg:CCNO FLAGS_REG)
8168         (compare:CCNO
8169           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8170                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8171           (const_int 0)))]
8172   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8174 (define_insn "*testdi_1"
8175   [(set (reg FLAGS_REG)
8176         (compare
8177          (and:DI
8178           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8179           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8180          (const_int 0)))]
8181   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8182    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8183   "@
8184    test{l}\t{%k1, %k0|%k0, %k1}
8185    test{l}\t{%k1, %k0|%k0, %k1}
8186    test{q}\t{%1, %0|%0, %1}
8187    test{q}\t{%1, %0|%0, %1}
8188    test{q}\t{%1, %0|%0, %1}"
8189   [(set_attr "type" "test")
8190    (set_attr "modrm" "0,1,0,1,1")
8191    (set_attr "mode" "SI,SI,DI,DI,DI")])
8193 (define_insn "*testqi_1_maybe_si"
8194   [(set (reg FLAGS_REG)
8195         (compare
8196           (and:QI
8197             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8198             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8199           (const_int 0)))]
8200    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8201     && ix86_match_ccmode (insn,
8202                          CONST_INT_P (operands[1])
8203                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8205   if (which_alternative == 3)
8206     {
8207       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8208         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8209       return "test{l}\t{%1, %k0|%k0, %1}";
8210     }
8211   return "test{b}\t{%1, %0|%0, %1}";
8213   [(set_attr "type" "test")
8214    (set_attr "modrm" "0,1,1,1")
8215    (set_attr "mode" "QI,QI,QI,SI")
8216    (set_attr "pent_pair" "uv,np,uv,np")])
8218 (define_insn "*test<mode>_1"
8219   [(set (reg FLAGS_REG)
8220         (compare
8221          (and:SWI124
8222           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8223           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8224          (const_int 0)))]
8225   "ix86_match_ccmode (insn, CCNOmode)
8226    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8227   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8228   [(set_attr "type" "test")
8229    (set_attr "modrm" "0,1,1")
8230    (set_attr "mode" "<MODE>")
8231    (set_attr "pent_pair" "uv,np,uv")])
8233 (define_expand "testqi_ext_1_ccno"
8234   [(set (reg:CCNO FLAGS_REG)
8235         (compare:CCNO
8236           (and:QI
8237             (subreg:QI
8238               (zero_extract:SI (match_operand 0 "ext_register_operand")
8239                                (const_int 8)
8240                                (const_int 8)) 0)
8241               (match_operand 1 "const_int_operand"))
8242           (const_int 0)))])
8244 (define_insn "*testqi_ext_1"
8245   [(set (reg FLAGS_REG)
8246         (compare
8247           (and:QI
8248             (subreg:QI
8249               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8250                                (const_int 8)
8251                                (const_int 8)) 0)
8252             (match_operand:QI 1 "general_operand" "QnBc,m"))
8253           (const_int 0)))]
8254   "ix86_match_ccmode (insn, CCNOmode)"
8255   "test{b}\t{%1, %h0|%h0, %1}"
8256   [(set_attr "isa" "*,nox64")
8257    (set_attr "type" "test")
8258    (set_attr "mode" "QI")])
8260 (define_insn "*testqi_ext_2"
8261   [(set (reg FLAGS_REG)
8262         (compare
8263           (and:QI
8264             (subreg:QI
8265               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8266                                (const_int 8)
8267                                (const_int 8)) 0)
8268             (subreg:QI
8269               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8270                                (const_int 8)
8271                                (const_int 8)) 0))
8272           (const_int 0)))]
8273   "ix86_match_ccmode (insn, CCNOmode)"
8274   "test{b}\t{%h1, %h0|%h0, %h1}"
8275   [(set_attr "type" "test")
8276    (set_attr "mode" "QI")])
8278 ;; Combine likes to form bit extractions for some tests.  Humor it.
8279 (define_insn_and_split "*testqi_ext_3"
8280   [(set (match_operand 0 "flags_reg_operand")
8281         (match_operator 1 "compare_operator"
8282           [(zero_extract:SWI248
8283              (match_operand 2 "nonimmediate_operand" "rm")
8284              (match_operand 3 "const_int_operand" "n")
8285              (match_operand 4 "const_int_operand" "n"))
8286            (const_int 0)]))]
8287   "ix86_match_ccmode (insn, CCNOmode)
8288    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8289        || GET_MODE (operands[2]) == SImode
8290        || GET_MODE (operands[2]) == HImode
8291        || GET_MODE (operands[2]) == QImode)
8292    /* Ensure that resulting mask is zero or sign extended operand.  */
8293    && INTVAL (operands[4]) >= 0
8294    && ((INTVAL (operands[3]) > 0
8295         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8296        || (<MODE>mode == DImode
8297            && INTVAL (operands[3]) > 32
8298            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8299   "#"
8300   "&& 1"
8301   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8303   rtx val = operands[2];
8304   HOST_WIDE_INT len = INTVAL (operands[3]);
8305   HOST_WIDE_INT pos = INTVAL (operands[4]);
8306   machine_mode mode = GET_MODE (val);
8308   if (SUBREG_P (val))
8309     {
8310       machine_mode submode = GET_MODE (SUBREG_REG (val));
8312       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8313       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8314           && GET_MODE_CLASS (submode) == MODE_INT)
8315         {
8316           val = SUBREG_REG (val);
8317           mode = submode;
8318         }
8319     }
8321   /* Small HImode tests can be converted to QImode.  */
8322   if (register_operand (val, HImode) && pos + len <= 8)
8323     {
8324       val = gen_lowpart (QImode, val);
8325       mode = QImode;
8326     }
8328   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8330   wide_int mask
8331     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8333   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8336 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8337 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8338 ;; this is relatively important trick.
8339 ;; Do the conversion only post-reload to avoid limiting of the register class
8340 ;; to QI regs.
8341 (define_split
8342   [(set (match_operand 0 "flags_reg_operand")
8343         (match_operator 1 "compare_operator"
8344           [(and (match_operand 2 "QIreg_operand")
8345                 (match_operand 3 "const_int_operand"))
8346            (const_int 0)]))]
8347    "reload_completed
8348     && GET_MODE (operands[2]) != QImode
8349     && ((ix86_match_ccmode (insn, CCZmode)
8350          && !(INTVAL (operands[3]) & ~(255 << 8)))
8351         || (ix86_match_ccmode (insn, CCNOmode)
8352             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8353   [(set (match_dup 0)
8354         (match_op_dup 1
8355           [(and:QI
8356              (subreg:QI
8357                (zero_extract:SI (match_dup 2)
8358                                 (const_int 8)
8359                                 (const_int 8)) 0)
8360              (match_dup 3))
8361            (const_int 0)]))]
8363   operands[2] = gen_lowpart (SImode, operands[2]);
8364   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8367 (define_split
8368   [(set (match_operand 0 "flags_reg_operand")
8369         (match_operator 1 "compare_operator"
8370           [(and (match_operand 2 "nonimmediate_operand")
8371                 (match_operand 3 "const_int_operand"))
8372            (const_int 0)]))]
8373    "reload_completed
8374     && GET_MODE (operands[2]) != QImode
8375     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8376     && ((ix86_match_ccmode (insn, CCZmode)
8377          && !(INTVAL (operands[3]) & ~255))
8378         || (ix86_match_ccmode (insn, CCNOmode)
8379             && !(INTVAL (operands[3]) & ~127)))"
8380   [(set (match_dup 0)
8381         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8382                          (const_int 0)]))]
8384   operands[2] = gen_lowpart (QImode, operands[2]);
8385   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8388 ;; %%% This used to optimize known byte-wide and operations to memory,
8389 ;; and sometimes to QImode registers.  If this is considered useful,
8390 ;; it should be done with splitters.
8392 (define_expand "and<mode>3"
8393   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8394         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8395                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8396   ""
8398   machine_mode mode = <MODE>mode;
8399   rtx (*insn) (rtx, rtx);
8401   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8402     {
8403       HOST_WIDE_INT ival = INTVAL (operands[2]);
8405       if (ival == (HOST_WIDE_INT) 0xffffffff)
8406         mode = SImode;
8407       else if (ival == 0xffff)
8408         mode = HImode;
8409       else if (ival == 0xff)
8410         mode = QImode;
8411       }
8413   if (mode == <MODE>mode)
8414     {
8415       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8416       DONE;
8417     }
8419   if (<MODE>mode == DImode)
8420     insn = (mode == SImode)
8421            ? gen_zero_extendsidi2
8422            : (mode == HImode)
8423            ? gen_zero_extendhidi2
8424            : gen_zero_extendqidi2;
8425   else if (<MODE>mode == SImode)
8426     insn = (mode == HImode)
8427            ? gen_zero_extendhisi2
8428            : gen_zero_extendqisi2;
8429   else if (<MODE>mode == HImode)
8430     insn = gen_zero_extendqihi2;
8431   else
8432     gcc_unreachable ();
8434   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8435   DONE;
8438 (define_insn_and_split "*anddi3_doubleword"
8439   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8440         (and:DI
8441          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8442          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8445    && ix86_binary_operator_ok (AND, DImode, operands)"
8446   "#"
8447   "&& reload_completed"
8448   [(const_int 0)]
8450   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8451   if (operands[2] == const0_rtx)
8452     {
8453       operands[1] = const0_rtx;
8454       ix86_expand_move (SImode, &operands[0]);
8455     }
8456   else if (operands[2] != constm1_rtx)
8457     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8458   else if (operands[5] == constm1_rtx)
8459     emit_note (NOTE_INSN_DELETED);
8460   if (operands[5] == const0_rtx)
8461     {
8462       operands[4] = const0_rtx;
8463       ix86_expand_move (SImode, &operands[3]);
8464     }
8465   else if (operands[5] != constm1_rtx)
8466     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8467   DONE;
8470 (define_insn "*anddi_1"
8471   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8472         (and:DI
8473          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8474          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8475    (clobber (reg:CC FLAGS_REG))]
8476   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8477   "@
8478    and{l}\t{%k2, %k0|%k0, %k2}
8479    and{q}\t{%2, %0|%0, %2}
8480    and{q}\t{%2, %0|%0, %2}
8481    #"
8482   [(set_attr "type" "alu,alu,alu,imovx")
8483    (set_attr "length_immediate" "*,*,*,0")
8484    (set (attr "prefix_rex")
8485      (if_then_else
8486        (and (eq_attr "type" "imovx")
8487             (and (match_test "INTVAL (operands[2]) == 0xff")
8488                  (match_operand 1 "ext_QIreg_operand")))
8489        (const_string "1")
8490        (const_string "*")))
8491    (set_attr "mode" "SI,DI,DI,SI")])
8493 (define_insn_and_split "*anddi_1_btr"
8494   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8495         (and:DI
8496          (match_operand:DI 1 "nonimmediate_operand" "%0")
8497          (match_operand:DI 2 "const_int_operand" "n")))
8498    (clobber (reg:CC FLAGS_REG))]
8499   "TARGET_64BIT && TARGET_USE_BT
8500    && ix86_binary_operator_ok (AND, DImode, operands)
8501    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8502   "#"
8503   "&& reload_completed"
8504   [(parallel [(set (zero_extract:DI (match_dup 0)
8505                                     (const_int 1)
8506                                     (match_dup 3))
8507                    (const_int 0))
8508               (clobber (reg:CC FLAGS_REG))])]
8509   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8510   [(set_attr "type" "alu1")
8511    (set_attr "prefix_0f" "1")
8512    (set_attr "znver1_decode" "double")
8513    (set_attr "mode" "DI")])
8515 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8516 (define_split
8517   [(set (match_operand:DI 0 "register_operand")
8518         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8519                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8520    (clobber (reg:CC FLAGS_REG))]
8521   "TARGET_64BIT"
8522   [(parallel [(set (match_dup 0)
8523                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8524               (clobber (reg:CC FLAGS_REG))])]
8526   if (GET_CODE (operands[2]) == SYMBOL_REF
8527       || GET_CODE (operands[2]) == LABEL_REF)
8528     {
8529       operands[2] = shallow_copy_rtx (operands[2]);
8530       PUT_MODE (operands[2], SImode);
8531     }
8532   else if (GET_CODE (operands[2]) == CONST)
8533     {
8534       /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8535       operands[2] = copy_rtx (operands[2]);
8536       PUT_MODE (operands[2], SImode);
8537       PUT_MODE (XEXP (operands[2], 0), SImode);
8538       PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8539     }    
8540   else
8541     operands[2] = gen_lowpart (SImode, operands[2]);
8544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8545 (define_insn "*andsi_1_zext"
8546   [(set (match_operand:DI 0 "register_operand" "=r")
8547         (zero_extend:DI
8548           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8549                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8550    (clobber (reg:CC FLAGS_REG))]
8551   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8552   "and{l}\t{%2, %k0|%k0, %2}"
8553   [(set_attr "type" "alu")
8554    (set_attr "mode" "SI")])
8556 (define_insn "*and<mode>_1"
8557   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8558         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8559                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8560    (clobber (reg:CC FLAGS_REG))]
8561   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8562   "@
8563    and{<imodesuffix>}\t{%2, %0|%0, %2}
8564    and{<imodesuffix>}\t{%2, %0|%0, %2}
8565    #"
8566   [(set_attr "type" "alu,alu,imovx")
8567    (set_attr "length_immediate" "*,*,0")
8568    (set (attr "prefix_rex")
8569      (if_then_else
8570        (and (eq_attr "type" "imovx")
8571             (and (match_test "INTVAL (operands[2]) == 0xff")
8572                  (match_operand 1 "ext_QIreg_operand")))
8573        (const_string "1")
8574        (const_string "*")))
8575    (set_attr "mode" "<MODE>,<MODE>,SI")])
8577 (define_insn "*andqi_1"
8578   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8579         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8580                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "ix86_binary_operator_ok (AND, QImode, operands)"
8583   "@
8584    and{b}\t{%2, %0|%0, %2}
8585    and{b}\t{%2, %0|%0, %2}
8586    and{l}\t{%k2, %k0|%k0, %k2}"
8587   [(set_attr "type" "alu")
8588    (set_attr "mode" "QI,QI,SI")
8589    ;; Potential partial reg stall on alternative 2.
8590    (set (attr "preferred_for_speed")
8591      (cond [(eq_attr "alternative" "2")
8592               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8593            (symbol_ref "true")))])
8595 (define_insn "*andqi_1_slp"
8596   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8597         (and:QI (match_dup 0)
8598                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8601    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8602   "and{b}\t{%1, %0|%0, %1}"
8603   [(set_attr "type" "alu1")
8604    (set_attr "mode" "QI")])
8606 (define_split
8607   [(set (match_operand:SWI248 0 "register_operand")
8608         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8609                     (match_operand:SWI248 2 "const_int_operand")))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "reload_completed
8612    && (!REG_P (operands[1])
8613        || REGNO (operands[0]) != REGNO (operands[1]))"
8614   [(const_int 0)]
8616   HOST_WIDE_INT ival = INTVAL (operands[2]);
8617   machine_mode mode;
8618   rtx (*insn) (rtx, rtx);
8620   if (ival == (HOST_WIDE_INT) 0xffffffff)
8621     mode = SImode;
8622   else if (ival == 0xffff)
8623     mode = HImode;
8624   else
8625     {
8626       gcc_assert (ival == 0xff);
8627       mode = QImode;
8628     }
8630   if (<MODE>mode == DImode)
8631     insn = (mode == SImode)
8632            ? gen_zero_extendsidi2
8633            : (mode == HImode)
8634            ? gen_zero_extendhidi2
8635            : gen_zero_extendqidi2;
8636   else
8637     {
8638       if (<MODE>mode != SImode)
8639         /* Zero extend to SImode to avoid partial register stalls.  */
8640         operands[0] = gen_lowpart (SImode, operands[0]);
8642       insn = (mode == HImode)
8643              ? gen_zero_extendhisi2
8644              : gen_zero_extendqisi2;
8645     }
8646   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8647   DONE;
8650 (define_split
8651   [(set (match_operand:SWI48 0 "register_operand")
8652         (and:SWI48 (match_dup 0)
8653                    (const_int -65536)))
8654    (clobber (reg:CC FLAGS_REG))]
8655   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8656     || optimize_function_for_size_p (cfun)"
8657   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8658   "operands[1] = gen_lowpart (HImode, operands[0]);")
8660 (define_split
8661   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8662         (and:SWI248 (match_dup 0)
8663                     (const_int -256)))
8664    (clobber (reg:CC FLAGS_REG))]
8665   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8666    && reload_completed"
8667   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8668   "operands[1] = gen_lowpart (QImode, operands[0]);")
8670 (define_split
8671   [(set (match_operand:SWI248 0 "QIreg_operand")
8672         (and:SWI248 (match_dup 0)
8673                     (const_int -65281)))
8674    (clobber (reg:CC FLAGS_REG))]
8675   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8676    && reload_completed"
8677   [(parallel
8678      [(set (zero_extract:SI (match_dup 0)
8679                             (const_int 8)
8680                             (const_int 8))
8681            (subreg:SI
8682              (xor:QI
8683                (subreg:QI
8684                  (zero_extract:SI (match_dup 0)
8685                                   (const_int 8)
8686                                   (const_int 8)) 0)
8687                (subreg:QI
8688                  (zero_extract:SI (match_dup 0)
8689                                   (const_int 8)
8690                                   (const_int 8)) 0)) 0))
8691       (clobber (reg:CC FLAGS_REG))])]
8692   "operands[0] = gen_lowpart (SImode, operands[0]);")
8694 (define_insn "*anddi_2"
8695   [(set (reg FLAGS_REG)
8696         (compare
8697          (and:DI
8698           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8699           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8700          (const_int 0)))
8701    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8702         (and:DI (match_dup 1) (match_dup 2)))]
8703   "TARGET_64BIT
8704    && ix86_match_ccmode
8705         (insn,
8706          /* If we are going to emit andl instead of andq, and the operands[2]
8707             constant might have the SImode sign bit set, make sure the sign
8708             flag isn't tested, because the instruction will set the sign flag
8709             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8710             conservatively assume it might have bit 31 set.  */
8711          (satisfies_constraint_Z (operands[2])
8712           && (!CONST_INT_P (operands[2])
8713               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8714          ? CCZmode : CCNOmode)
8715    && ix86_binary_operator_ok (AND, DImode, operands)"
8716   "@
8717    and{l}\t{%k2, %k0|%k0, %k2}
8718    and{q}\t{%2, %0|%0, %2}
8719    and{q}\t{%2, %0|%0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "SI,DI,DI")])
8723 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8724 (define_insn "*andsi_2_zext"
8725   [(set (reg FLAGS_REG)
8726         (compare (and:SI
8727                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8728                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8729                  (const_int 0)))
8730    (set (match_operand:DI 0 "register_operand" "=r")
8731         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8732   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8733    && ix86_binary_operator_ok (AND, SImode, operands)"
8734   "and{l}\t{%2, %k0|%k0, %2}"
8735   [(set_attr "type" "alu")
8736    (set_attr "mode" "SI")])
8738 (define_insn "*andqi_2_maybe_si"
8739   [(set (reg FLAGS_REG)
8740         (compare (and:QI
8741                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8742                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8743                  (const_int 0)))
8744    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8745         (and:QI (match_dup 1) (match_dup 2)))]
8746   "ix86_binary_operator_ok (AND, QImode, operands)
8747    && ix86_match_ccmode (insn,
8748                          CONST_INT_P (operands[2])
8749                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8751   if (which_alternative == 2)
8752     {
8753       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8754         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8755       return "and{l}\t{%2, %k0|%k0, %2}";
8756     }
8757   return "and{b}\t{%2, %0|%0, %2}";
8759   [(set_attr "type" "alu")
8760    (set_attr "mode" "QI,QI,SI")])
8762 (define_insn "*and<mode>_2"
8763   [(set (reg FLAGS_REG)
8764         (compare (and:SWI124
8765                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8766                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8767                  (const_int 0)))
8768    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8769         (and:SWI124 (match_dup 1) (match_dup 2)))]
8770   "ix86_match_ccmode (insn, CCNOmode)
8771    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8772   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8773   [(set_attr "type" "alu")
8774    (set_attr "mode" "<MODE>")])
8776 (define_insn "*andqi_2_slp"
8777   [(set (reg FLAGS_REG)
8778         (compare (and:QI
8779                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8780                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8781                  (const_int 0)))
8782    (set (strict_low_part (match_dup 0))
8783         (and:QI (match_dup 0) (match_dup 1)))]
8784   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8785    && ix86_match_ccmode (insn, CCNOmode)
8786    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8787   "and{b}\t{%1, %0|%0, %1}"
8788   [(set_attr "type" "alu1")
8789    (set_attr "mode" "QI")])
8791 (define_insn "andqi_ext_1"
8792   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8793                          (const_int 8)
8794                          (const_int 8))
8795         (subreg:SI
8796           (and:QI
8797             (subreg:QI
8798               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8799                                (const_int 8)
8800                                (const_int 8)) 0)
8801             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8802    (clobber (reg:CC FLAGS_REG))]
8803   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8804    rtx_equal_p (operands[0], operands[1])"
8805   "and{b}\t{%2, %h0|%h0, %2}"
8806   [(set_attr "isa" "*,nox64")
8807    (set_attr "type" "alu")
8808    (set_attr "mode" "QI")])
8810 ;; Generated by peephole translating test to and.  This shows up
8811 ;; often in fp comparisons.
8812 (define_insn "*andqi_ext_1_cc"
8813   [(set (reg FLAGS_REG)
8814         (compare
8815           (and:QI
8816             (subreg:QI
8817               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8818                                (const_int 8)
8819                                (const_int 8)) 0)
8820             (match_operand:QI 2 "general_operand" "QnBc,m"))
8821           (const_int 0)))
8822    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8823                          (const_int 8)
8824                          (const_int 8))
8825         (subreg:SI
8826           (and:QI
8827             (subreg:QI
8828               (zero_extract:SI (match_dup 1)
8829                                (const_int 8)
8830                                (const_int 8)) 0)
8831             (match_dup 2)) 0))]
8832   "ix86_match_ccmode (insn, CCNOmode)
8833    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8834    && rtx_equal_p (operands[0], operands[1])"
8835   "and{b}\t{%2, %h0|%h0, %2}"
8836   [(set_attr "isa" "*,nox64")
8837    (set_attr "type" "alu")
8838    (set_attr "mode" "QI")])
8840 (define_insn "*andqi_ext_2"
8841   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8842                          (const_int 8)
8843                          (const_int 8))
8844         (subreg:SI
8845           (and:QI
8846             (subreg:QI
8847               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8848                                (const_int 8)
8849                                (const_int 8)) 0)
8850             (subreg:QI
8851               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8852                                (const_int 8)
8853                                (const_int 8)) 0)) 0))
8854    (clobber (reg:CC FLAGS_REG))]
8855   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8856    rtx_equal_p (operands[0], operands[1])
8857    || rtx_equal_p (operands[0], operands[2])"
8858   "and{b}\t{%h2, %h0|%h0, %h2}"
8859   [(set_attr "type" "alu")
8860    (set_attr "mode" "QI")])
8862 ;; Convert wide AND instructions with immediate operand to shorter QImode
8863 ;; equivalents when possible.
8864 ;; Don't do the splitting with memory operands, since it introduces risk
8865 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8866 ;; for size, but that can (should?) be handled by generic code instead.
8867 (define_split
8868   [(set (match_operand:SWI248 0 "QIreg_operand")
8869         (and:SWI248 (match_operand:SWI248 1 "register_operand")
8870                     (match_operand:SWI248 2 "const_int_operand")))
8871    (clobber (reg:CC FLAGS_REG))]
8872    "reload_completed
8873     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8874     && !(~INTVAL (operands[2]) & ~(255 << 8))"
8875   [(parallel
8876      [(set (zero_extract:SI (match_dup 0)
8877                             (const_int 8)
8878                             (const_int 8))
8879            (subreg:SI
8880              (and:QI
8881                (subreg:QI
8882                  (zero_extract:SI (match_dup 1)
8883                                   (const_int 8)
8884                                   (const_int 8)) 0)
8885                (match_dup 2)) 0))
8886       (clobber (reg:CC FLAGS_REG))])]
8888   operands[0] = gen_lowpart (SImode, operands[0]);
8889   operands[1] = gen_lowpart (SImode, operands[1]);
8890   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8893 ;; Since AND can be encoded with sign extended immediate, this is only
8894 ;; profitable when 7th bit is not set.
8895 (define_split
8896   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8897         (and:SWI248 (match_operand:SWI248 1 "general_operand")
8898                     (match_operand:SWI248 2 "const_int_operand")))
8899    (clobber (reg:CC FLAGS_REG))]
8900    "reload_completed
8901     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8902     && !(~INTVAL (operands[2]) & ~255)
8903     && !(INTVAL (operands[2]) & 128)"
8904   [(parallel [(set (strict_low_part (match_dup 0))
8905                    (and:QI (match_dup 1)
8906                            (match_dup 2)))
8907               (clobber (reg:CC FLAGS_REG))])]
8909   operands[0] = gen_lowpart (QImode, operands[0]);
8910   operands[1] = gen_lowpart (QImode, operands[1]);
8911   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8914 (define_insn "*andndi3_doubleword"
8915   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
8916         (and:DI
8917           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
8918           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8921   "#"
8922   [(set_attr "isa" "bmi,bmi,bmi,*")])
8924 (define_split
8925   [(set (match_operand:DI 0 "register_operand")
8926         (and:DI
8927           (not:DI (match_operand:DI 1 "register_operand"))
8928           (match_operand:DI 2 "nonimmediate_operand")))
8929    (clobber (reg:CC FLAGS_REG))]
8930   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8931    && reload_completed"
8932   [(parallel [(set (match_dup 0)
8933                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8934               (clobber (reg:CC FLAGS_REG))])
8935    (parallel [(set (match_dup 3)
8936                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8937               (clobber (reg:CC FLAGS_REG))])]
8938   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8940 (define_split
8941   [(set (match_operand:DI 0 "register_operand")
8942         (and:DI
8943           (not:DI (match_dup 0))
8944           (match_operand:DI 1 "nonimmediate_operand")))
8945    (clobber (reg:CC FLAGS_REG))]
8946   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8947    && reload_completed"
8948   [(set (match_dup 0) (not:SI (match_dup 0)))
8949    (parallel [(set (match_dup 0)
8950                    (and:SI (match_dup 0) (match_dup 1)))
8951               (clobber (reg:CC FLAGS_REG))])
8952    (set (match_dup 2) (not:SI (match_dup 2)))
8953    (parallel [(set (match_dup 2)
8954                    (and:SI (match_dup 2) (match_dup 3)))
8955               (clobber (reg:CC FLAGS_REG))])]
8956   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8958 (define_insn "*andn<mode>_1"
8959   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8960         (and:SWI48
8961           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8962           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8963    (clobber (reg:CC FLAGS_REG))]
8964   "TARGET_BMI"
8965   "andn\t{%2, %1, %0|%0, %1, %2}"
8966   [(set_attr "type" "bitmanip")
8967    (set_attr "btver2_decode" "direct, double")
8968    (set_attr "mode" "<MODE>")])
8970 (define_insn "*andn<mode>_1"
8971   [(set (match_operand:SWI12 0 "register_operand" "=r")
8972         (and:SWI12
8973           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8974           (match_operand:SWI12 2 "register_operand" "r")))
8975    (clobber (reg:CC FLAGS_REG))]
8976   "TARGET_BMI"
8977   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8978   [(set_attr "type" "bitmanip")
8979    (set_attr "btver2_decode" "direct")
8980    (set_attr "mode" "SI")])
8982 (define_insn "*andn_<mode>_ccno"
8983   [(set (reg FLAGS_REG)
8984         (compare
8985           (and:SWI48
8986             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8987             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8988           (const_int 0)))
8989    (clobber (match_scratch:SWI48 0 "=r,r"))]
8990   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8991   "andn\t{%2, %1, %0|%0, %1, %2}"
8992   [(set_attr "type" "bitmanip")
8993    (set_attr "btver2_decode" "direct, double")
8994    (set_attr "mode" "<MODE>")])
8996 ;; Logical inclusive and exclusive OR instructions
8998 ;; %%% This used to optimize known byte-wide and operations to memory.
8999 ;; If this is considered useful, it should be done with splitters.
9001 (define_expand "<code><mode>3"
9002   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9003         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9004                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9005   ""
9006   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9008 (define_insn_and_split "*<code>di3_doubleword"
9009   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9010         (any_or:DI
9011          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9012          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9013    (clobber (reg:CC FLAGS_REG))]
9014   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9015    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9016   "#"
9017   "&& reload_completed"
9018   [(const_int 0)]
9020   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9021   if (operands[2] == constm1_rtx)
9022     {
9023       if (<CODE> == IOR)
9024         {
9025           operands[1] = constm1_rtx;
9026           ix86_expand_move (SImode, &operands[0]);
9027         }
9028       else
9029         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9030     }
9031   else if (operands[2] != const0_rtx)
9032     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9033   else if (operands[5] == const0_rtx)
9034     emit_note (NOTE_INSN_DELETED);
9035   if (operands[5] == constm1_rtx)
9036     {
9037       if (<CODE> == IOR)
9038         {
9039           operands[4] = constm1_rtx;
9040           ix86_expand_move (SImode, &operands[3]);
9041         }
9042       else
9043         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9044     }
9045   else if (operands[5] != const0_rtx)
9046     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9047   DONE;
9050 (define_insn "*<code><mode>_1"
9051   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9052         (any_or:SWI248
9053          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9054          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9055    (clobber (reg:CC FLAGS_REG))]
9056   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9057   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9058   [(set_attr "type" "alu")
9059    (set_attr "mode" "<MODE>")])
9061 (define_insn_and_split "*iordi_1_bts"
9062   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9063         (ior:DI
9064          (match_operand:DI 1 "nonimmediate_operand" "%0")
9065          (match_operand:DI 2 "const_int_operand" "n")))
9066    (clobber (reg:CC FLAGS_REG))]
9067   "TARGET_64BIT && TARGET_USE_BT
9068    && ix86_binary_operator_ok (IOR, DImode, operands)
9069    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9070   "#"
9071   "&& reload_completed"
9072   [(parallel [(set (zero_extract:DI (match_dup 0)
9073                                     (const_int 1)
9074                                     (match_dup 3))
9075                    (const_int 1))
9076               (clobber (reg:CC FLAGS_REG))])]
9077   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9078   [(set_attr "type" "alu1")
9079    (set_attr "prefix_0f" "1")
9080    (set_attr "znver1_decode" "double")
9081    (set_attr "mode" "DI")])
9083 (define_insn_and_split "*xordi_1_btc"
9084   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9085         (xor:DI
9086          (match_operand:DI 1 "nonimmediate_operand" "%0")
9087          (match_operand:DI 2 "const_int_operand" "n")))
9088    (clobber (reg:CC FLAGS_REG))]
9089   "TARGET_64BIT && TARGET_USE_BT
9090    && ix86_binary_operator_ok (XOR, DImode, operands)
9091    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9092   "#"
9093   "&& reload_completed"
9094   [(parallel [(set (zero_extract:DI (match_dup 0)
9095                                     (const_int 1)
9096                                     (match_dup 3))
9097                    (not:DI (zero_extract:DI (match_dup 0)
9098                                             (const_int 1)
9099                                             (match_dup 3))))
9100               (clobber (reg:CC FLAGS_REG))])]
9101   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9102   [(set_attr "type" "alu1")
9103    (set_attr "prefix_0f" "1")
9104    (set_attr "znver1_decode" "double")
9105    (set_attr "mode" "DI")])
9107 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9108 (define_insn "*<code>si_1_zext"
9109   [(set (match_operand:DI 0 "register_operand" "=r")
9110         (zero_extend:DI
9111          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9112                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9113    (clobber (reg:CC FLAGS_REG))]
9114   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9115   "<logic>{l}\t{%2, %k0|%k0, %2}"
9116   [(set_attr "type" "alu")
9117    (set_attr "mode" "SI")])
9119 (define_insn "*<code>si_1_zext_imm"
9120   [(set (match_operand:DI 0 "register_operand" "=r")
9121         (any_or:DI
9122          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9123          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9126   "<logic>{l}\t{%2, %k0|%k0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "mode" "SI")])
9130 (define_insn "*<code>qi_1"
9131   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9132         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9133                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9134    (clobber (reg:CC FLAGS_REG))]
9135   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9136   "@
9137    <logic>{b}\t{%2, %0|%0, %2}
9138    <logic>{b}\t{%2, %0|%0, %2}
9139    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "QI,QI,SI")
9142    ;; Potential partial reg stall on alternative 2.
9143    (set (attr "preferred_for_speed")
9144      (cond [(eq_attr "alternative" "2")
9145               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9146            (symbol_ref "true")))])
9148 (define_insn "*<code>qi_1_slp"
9149   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9150         (any_or:QI (match_dup 0)
9151                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9152    (clobber (reg:CC FLAGS_REG))]
9153   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9154    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9155   "<logic>{b}\t{%1, %0|%0, %1}"
9156   [(set_attr "type" "alu1")
9157    (set_attr "mode" "QI")])
9159 (define_insn "*<code><mode>_2"
9160   [(set (reg FLAGS_REG)
9161         (compare (any_or:SWI
9162                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9163                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9164                  (const_int 0)))
9165    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9166         (any_or:SWI (match_dup 1) (match_dup 2)))]
9167   "ix86_match_ccmode (insn, CCNOmode)
9168    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9169   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "mode" "<MODE>")])
9173 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9174 ;; ??? Special case for immediate operand is missing - it is tricky.
9175 (define_insn "*<code>si_2_zext"
9176   [(set (reg FLAGS_REG)
9177         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9178                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9179                  (const_int 0)))
9180    (set (match_operand:DI 0 "register_operand" "=r")
9181         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9182   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9183    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9184   "<logic>{l}\t{%2, %k0|%k0, %2}"
9185   [(set_attr "type" "alu")
9186    (set_attr "mode" "SI")])
9188 (define_insn "*<code>si_2_zext_imm"
9189   [(set (reg FLAGS_REG)
9190         (compare (any_or:SI
9191                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9192                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9193                  (const_int 0)))
9194    (set (match_operand:DI 0 "register_operand" "=r")
9195         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9196   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9197    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9198   "<logic>{l}\t{%2, %k0|%k0, %2}"
9199   [(set_attr "type" "alu")
9200    (set_attr "mode" "SI")])
9202 (define_insn "*<code>qi_2_slp"
9203   [(set (reg FLAGS_REG)
9204         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9205                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9206                  (const_int 0)))
9207    (set (strict_low_part (match_dup 0))
9208         (any_or:QI (match_dup 0) (match_dup 1)))]
9209   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9210    && ix86_match_ccmode (insn, CCNOmode)
9211    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9212   "<logic>{b}\t{%1, %0|%0, %1}"
9213   [(set_attr "type" "alu1")
9214    (set_attr "mode" "QI")])
9216 (define_insn "*<code><mode>_3"
9217   [(set (reg FLAGS_REG)
9218         (compare (any_or:SWI
9219                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9220                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9221                  (const_int 0)))
9222    (clobber (match_scratch:SWI 0 "=<r>"))]
9223   "ix86_match_ccmode (insn, CCNOmode)
9224    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9225   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "mode" "<MODE>")])
9229 (define_insn "*<code>qi_ext_1"
9230   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9231                          (const_int 8)
9232                          (const_int 8))
9233         (subreg:SI
9234           (any_or:QI
9235             (subreg:QI
9236               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9237                                (const_int 8)
9238                                (const_int 8)) 0)
9239             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9240    (clobber (reg:CC FLAGS_REG))]
9241   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9242    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9243    && rtx_equal_p (operands[0], operands[1])"
9244   "<logic>{b}\t{%2, %h0|%h0, %2}"
9245   [(set_attr "isa" "*,nox64")
9246    (set_attr "type" "alu")
9247    (set_attr "mode" "QI")])
9249 (define_insn "*<code>qi_ext_2"
9250   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9251                          (const_int 8)
9252                          (const_int 8))
9253         (subreg:SI
9254           (any_or:QI
9255             (subreg:QI
9256               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9257                                (const_int 8)
9258                                (const_int 8)) 0)
9259             (subreg:QI
9260               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9261                                (const_int 8)
9262                                (const_int 8)) 0)) 0))
9263    (clobber (reg:CC FLAGS_REG))]
9264   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9265    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9266    && (rtx_equal_p (operands[0], operands[1])
9267        || rtx_equal_p (operands[0], operands[2]))"
9268   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9269   [(set_attr "type" "alu")
9270    (set_attr "mode" "QI")])
9272 ;; Convert wide OR instructions with immediate operand to shorter QImode
9273 ;; equivalents when possible.
9274 ;; Don't do the splitting with memory operands, since it introduces risk
9275 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9276 ;; for size, but that can (should?) be handled by generic code instead.
9277 (define_split
9278   [(set (match_operand:SWI248 0 "QIreg_operand")
9279         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9280                        (match_operand:SWI248 2 "const_int_operand")))
9281    (clobber (reg:CC FLAGS_REG))]
9282    "reload_completed
9283     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9284     && !(INTVAL (operands[2]) & ~(255 << 8))"
9285   [(parallel
9286      [(set (zero_extract:SI (match_dup 0)
9287                             (const_int 8)
9288                             (const_int 8))
9289            (subreg:SI
9290              (any_or:QI
9291                (subreg:QI
9292                  (zero_extract:SI (match_dup 1)
9293                                   (const_int 8)
9294                                   (const_int 8)) 0)
9295                (match_dup 2)) 0))
9296       (clobber (reg:CC FLAGS_REG))])]
9298   operands[0] = gen_lowpart (SImode, operands[0]);
9299   operands[1] = gen_lowpart (SImode, operands[1]);
9300   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9303 ;; Since OR can be encoded with sign extended immediate, this is only
9304 ;; profitable when 7th bit is set.
9305 (define_split
9306   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9307         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9308                        (match_operand:SWI248 2 "const_int_operand")))
9309    (clobber (reg:CC FLAGS_REG))]
9310    "reload_completed
9311     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9312     && !(INTVAL (operands[2]) & ~255)
9313     && (INTVAL (operands[2]) & 128)"
9314   [(parallel [(set (strict_low_part (match_dup 0))
9315                    (any_or:QI (match_dup 1)
9316                               (match_dup 2)))
9317               (clobber (reg:CC FLAGS_REG))])]
9319   operands[0] = gen_lowpart (QImode, operands[0]);
9320   operands[1] = gen_lowpart (QImode, operands[1]);
9321   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9324 (define_expand "xorqi_ext_1_cc"
9325   [(parallel [
9326      (set (reg:CCNO FLAGS_REG)
9327           (compare:CCNO
9328             (xor:QI
9329               (subreg:QI
9330                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9331                                  (const_int 8)
9332                                  (const_int 8)) 0)
9333               (match_operand 2 "const_int_operand"))
9334             (const_int 0)))
9335      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9336                            (const_int 8)
9337                            (const_int 8))
9338           (subreg:SI
9339             (xor:QI
9340               (subreg:QI
9341                 (zero_extract:SI (match_dup 1)
9342                                  (const_int 8)
9343                                  (const_int 8)) 0)
9344             (match_dup 2)) 0))])])
9346 (define_insn "*xorqi_ext_1_cc"
9347   [(set (reg FLAGS_REG)
9348         (compare
9349           (xor:QI
9350             (subreg:QI
9351               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9352                                (const_int 8)
9353                                (const_int 8)) 0)
9354             (match_operand:QI 2 "general_operand" "QnBc,m"))
9355           (const_int 0)))
9356    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9357                          (const_int 8)
9358                          (const_int 8))
9359         (subreg:SI
9360           (xor:QI
9361             (subreg:QI
9362               (zero_extract:SI (match_dup 1)
9363                                (const_int 8)
9364                                (const_int 8)) 0)
9365           (match_dup 2)) 0))]
9366   "ix86_match_ccmode (insn, CCNOmode)
9367    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9368    && rtx_equal_p (operands[0], operands[1])"
9369   "xor{b}\t{%2, %h0|%h0, %2}"
9370   [(set_attr "isa" "*,nox64")
9371    (set_attr "type" "alu")
9372    (set_attr "mode" "QI")])
9374 ;; Negation instructions
9376 (define_expand "neg<mode>2"
9377   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9378         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9379   ""
9380   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9382 (define_insn_and_split "*neg<dwi>2_doubleword"
9383   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9384         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9387   "#"
9388   "reload_completed"
9389   [(parallel
9390     [(set (reg:CCZ FLAGS_REG)
9391           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9392      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9393    (parallel
9394     [(set (match_dup 2)
9395           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9396                                 (match_dup 3))
9397                      (const_int 0)))
9398      (clobber (reg:CC FLAGS_REG))])
9399    (parallel
9400     [(set (match_dup 2)
9401           (neg:DWIH (match_dup 2)))
9402      (clobber (reg:CC FLAGS_REG))])]
9403   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9405 (define_insn "*neg<mode>2_1"
9406   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9407         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9408    (clobber (reg:CC FLAGS_REG))]
9409   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9410   "neg{<imodesuffix>}\t%0"
9411   [(set_attr "type" "negnot")
9412    (set_attr "mode" "<MODE>")])
9414 ;; Combine is quite creative about this pattern.
9415 (define_insn "*negsi2_1_zext"
9416   [(set (match_operand:DI 0 "register_operand" "=r")
9417         (lshiftrt:DI
9418           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9419                              (const_int 32)))
9420         (const_int 32)))
9421    (clobber (reg:CC FLAGS_REG))]
9422   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9423   "neg{l}\t%k0"
9424   [(set_attr "type" "negnot")
9425    (set_attr "mode" "SI")])
9427 ;; The problem with neg is that it does not perform (compare x 0),
9428 ;; it really performs (compare 0 x), which leaves us with the zero
9429 ;; flag being the only useful item.
9431 (define_insn "*neg<mode>2_cmpz"
9432   [(set (reg:CCZ FLAGS_REG)
9433         (compare:CCZ
9434           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9435                    (const_int 0)))
9436    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9437         (neg:SWI (match_dup 1)))]
9438   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9439   "neg{<imodesuffix>}\t%0"
9440   [(set_attr "type" "negnot")
9441    (set_attr "mode" "<MODE>")])
9443 (define_insn "*negsi2_cmpz_zext"
9444   [(set (reg:CCZ FLAGS_REG)
9445         (compare:CCZ
9446           (lshiftrt:DI
9447             (neg:DI (ashift:DI
9448                       (match_operand:DI 1 "register_operand" "0")
9449                       (const_int 32)))
9450             (const_int 32))
9451           (const_int 0)))
9452    (set (match_operand:DI 0 "register_operand" "=r")
9453         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9454                                         (const_int 32)))
9455                      (const_int 32)))]
9456   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9457   "neg{l}\t%k0"
9458   [(set_attr "type" "negnot")
9459    (set_attr "mode" "SI")])
9461 ;; Negate with jump on overflow.
9462 (define_expand "negv<mode>3"
9463   [(parallel [(set (reg:CCO FLAGS_REG)
9464                    (ne:CCO (match_operand:SWI 1 "register_operand")
9465                            (match_dup 3)))
9466               (set (match_operand:SWI 0 "register_operand")
9467                    (neg:SWI (match_dup 1)))])
9468    (set (pc) (if_then_else
9469                (eq (reg:CCO FLAGS_REG) (const_int 0))
9470                (label_ref (match_operand 2))
9471                (pc)))]
9472   ""
9474   operands[3]
9475     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9476                     <MODE>mode);
9479 (define_insn "*negv<mode>3"
9480   [(set (reg:CCO FLAGS_REG)
9481         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9482                 (match_operand:SWI 2 "const_int_operand")))
9483    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9484         (neg:SWI (match_dup 1)))]
9485   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9486    && mode_signbit_p (<MODE>mode, operands[2])"
9487   "neg{<imodesuffix>}\t%0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "<MODE>")])
9491 ;; Changing of sign for FP values is doable using integer unit too.
9493 (define_expand "<code><mode>2"
9494   [(set (match_operand:X87MODEF 0 "register_operand")
9495         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9496   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9497   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9499 (define_insn "*absneg<mode>2"
9500   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9501         (match_operator:MODEF 3 "absneg_operator"
9502           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9503    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9504    (clobber (reg:CC FLAGS_REG))]
9505   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9506   "#"
9507   [(set (attr "enabled")
9508      (if_then_else
9509        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9510        (if_then_else
9511          (eq_attr "alternative" "2")
9512          (symbol_ref "TARGET_MIX_SSE_I387")
9513          (symbol_ref "true"))
9514        (if_then_else
9515          (eq_attr "alternative" "2,3")
9516          (symbol_ref "true")
9517          (symbol_ref "false"))))])
9519 (define_insn "*absnegxf2_i387"
9520   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9521         (match_operator:XF 3 "absneg_operator"
9522           [(match_operand:XF 1 "register_operand" "0,0")]))
9523    (use (match_operand 2))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "TARGET_80387"
9526   "#")
9528 (define_expand "<code>tf2"
9529   [(set (match_operand:TF 0 "register_operand")
9530         (absneg:TF (match_operand:TF 1 "register_operand")))]
9531   "TARGET_SSE"
9532   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9534 (define_insn "*absnegtf2_sse"
9535   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9536         (match_operator:TF 3 "absneg_operator"
9537           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9538    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9539    (clobber (reg:CC FLAGS_REG))]
9540   "TARGET_SSE"
9541   "#")
9543 ;; Splitters for fp abs and neg.
9545 (define_split
9546   [(set (match_operand 0 "fp_register_operand")
9547         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9548    (use (match_operand 2))
9549    (clobber (reg:CC FLAGS_REG))]
9550   "reload_completed"
9551   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9553 (define_split
9554   [(set (match_operand 0 "sse_reg_operand")
9555         (match_operator 3 "absneg_operator"
9556           [(match_operand 1 "register_operand")]))
9557    (use (match_operand 2 "nonimmediate_operand"))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "reload_completed"
9560   [(set (match_dup 0) (match_dup 3))]
9562   machine_mode mode = GET_MODE (operands[0]);
9563   machine_mode vmode = GET_MODE (operands[2]);
9564   rtx tmp;
9566   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9567   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9568   if (operands_match_p (operands[0], operands[2]))
9569     std::swap (operands[1], operands[2]);
9570   if (GET_CODE (operands[3]) == ABS)
9571     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9572   else
9573     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9574   operands[3] = tmp;
9577 (define_split
9578   [(set (match_operand:SF 0 "general_reg_operand")
9579         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9580    (use (match_operand:V4SF 2))
9581    (clobber (reg:CC FLAGS_REG))]
9582   "reload_completed"
9583   [(parallel [(set (match_dup 0) (match_dup 1))
9584               (clobber (reg:CC FLAGS_REG))])]
9586   rtx tmp;
9587   operands[0] = gen_lowpart (SImode, operands[0]);
9588   if (GET_CODE (operands[1]) == ABS)
9589     {
9590       tmp = gen_int_mode (0x7fffffff, SImode);
9591       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9592     }
9593   else
9594     {
9595       tmp = gen_int_mode (0x80000000, SImode);
9596       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9597     }
9598   operands[1] = tmp;
9601 (define_split
9602   [(set (match_operand:DF 0 "general_reg_operand")
9603         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9604    (use (match_operand 2))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "reload_completed"
9607   [(parallel [(set (match_dup 0) (match_dup 1))
9608               (clobber (reg:CC FLAGS_REG))])]
9610   rtx tmp;
9611   if (TARGET_64BIT)
9612     {
9613       tmp = gen_lowpart (DImode, operands[0]);
9614       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9615       operands[0] = tmp;
9617       if (GET_CODE (operands[1]) == ABS)
9618         tmp = const0_rtx;
9619       else
9620         tmp = gen_rtx_NOT (DImode, tmp);
9621     }
9622   else
9623     {
9624       operands[0] = gen_highpart (SImode, operands[0]);
9625       if (GET_CODE (operands[1]) == ABS)
9626         {
9627           tmp = gen_int_mode (0x7fffffff, SImode);
9628           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9629         }
9630       else
9631         {
9632           tmp = gen_int_mode (0x80000000, SImode);
9633           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9634         }
9635     }
9636   operands[1] = tmp;
9639 (define_split
9640   [(set (match_operand:XF 0 "general_reg_operand")
9641         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9642    (use (match_operand 2))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "reload_completed"
9645   [(parallel [(set (match_dup 0) (match_dup 1))
9646               (clobber (reg:CC FLAGS_REG))])]
9648   rtx tmp;
9649   operands[0] = gen_rtx_REG (SImode,
9650                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9651   if (GET_CODE (operands[1]) == ABS)
9652     {
9653       tmp = GEN_INT (0x7fff);
9654       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9655     }
9656   else
9657     {
9658       tmp = GEN_INT (0x8000);
9659       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9660     }
9661   operands[1] = tmp;
9664 ;; Conditionalize these after reload. If they match before reload, we
9665 ;; lose the clobber and ability to use integer instructions.
9667 (define_insn "*<code><mode>2_1"
9668   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9669         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9670   "TARGET_80387
9671    && (reload_completed
9672        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9673   "<absneg_mnemonic>"
9674   [(set_attr "type" "fsgn")
9675    (set_attr "mode" "<MODE>")])
9677 ;; Copysign instructions
9679 (define_mode_iterator CSGNMODE [SF DF TF])
9680 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9682 (define_expand "copysign<mode>3"
9683   [(match_operand:CSGNMODE 0 "register_operand")
9684    (match_operand:CSGNMODE 1 "nonmemory_operand")
9685    (match_operand:CSGNMODE 2 "register_operand")]
9686   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9687    || (TARGET_SSE && (<MODE>mode == TFmode))"
9688   "ix86_expand_copysign (operands); DONE;")
9690 (define_insn_and_split "copysign<mode>3_const"
9691   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9692         (unspec:CSGNMODE
9693           [(match_operand:<CSGNVMODE> 1 "nonimm_or_0_operand" "YvmC")
9694            (match_operand:CSGNMODE 2 "register_operand" "0")
9695            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9696           UNSPEC_COPYSIGN))]
9697   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9698    || (TARGET_SSE && (<MODE>mode == TFmode))"
9699   "#"
9700   "&& reload_completed"
9701   [(const_int 0)]
9702   "ix86_split_copysign_const (operands); DONE;")
9704 (define_insn "copysign<mode>3_var"
9705   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9706         (unspec:CSGNMODE
9707           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9708            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9709            (match_operand:<CSGNVMODE> 4
9710              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9711            (match_operand:<CSGNVMODE> 5
9712              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9713           UNSPEC_COPYSIGN))
9714    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9715   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9716    || (TARGET_SSE && (<MODE>mode == TFmode))"
9717   "#")
9719 (define_split
9720   [(set (match_operand:CSGNMODE 0 "register_operand")
9721         (unspec:CSGNMODE
9722           [(match_operand:CSGNMODE 2 "register_operand")
9723            (match_operand:CSGNMODE 3 "register_operand")
9724            (match_operand:<CSGNVMODE> 4)
9725            (match_operand:<CSGNVMODE> 5)]
9726           UNSPEC_COPYSIGN))
9727    (clobber (match_scratch:<CSGNVMODE> 1))]
9728   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9729     || (TARGET_SSE && (<MODE>mode == TFmode)))
9730    && reload_completed"
9731   [(const_int 0)]
9732   "ix86_split_copysign_var (operands); DONE;")
9734 (define_expand "xorsign<mode>3"
9735   [(match_operand:MODEF 0 "register_operand")
9736    (match_operand:MODEF 1 "register_operand")
9737    (match_operand:MODEF 2 "register_operand")]
9738   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9739   "ix86_expand_xorsign (operands); DONE;")
9741 (define_insn_and_split "xorsign<mode>3_1"
9742   [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9743         (unspec:MODEF
9744           [(match_operand:MODEF 1 "register_operand" "Yv")
9745            (match_operand:MODEF 2 "register_operand" "0")
9746            (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9747           UNSPEC_XORSIGN))]
9748   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9749   "#"
9750   "&& reload_completed"
9751   [(const_int 0)]
9752   "ix86_split_xorsign (operands); DONE;")
9754 ;; One complement instructions
9756 (define_expand "one_cmpl<mode>2"
9757   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9758         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9759   ""
9760   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9762 (define_insn_and_split "*one_cmpldi2_doubleword"
9763   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9764         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9765   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9766    && ix86_unary_operator_ok (NOT, DImode, operands)"
9767   "#"
9768   "&& reload_completed"
9769   [(set (match_dup 0)
9770         (not:SI (match_dup 1)))
9771    (set (match_dup 2)
9772         (not:SI (match_dup 3)))]
9773   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9775 (define_insn "*one_cmpl<mode>2_1"
9776   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9777         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9778   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9779   "not{<imodesuffix>}\t%0"
9780   [(set_attr "type" "negnot")
9781    (set_attr "mode" "<MODE>")])
9783 ;; ??? Currently never generated - xor is used instead.
9784 (define_insn "*one_cmplsi2_1_zext"
9785   [(set (match_operand:DI 0 "register_operand" "=r")
9786         (zero_extend:DI
9787           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9788   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9789   "not{l}\t%k0"
9790   [(set_attr "type" "negnot")
9791    (set_attr "mode" "SI")])
9793 (define_insn "*one_cmplqi2_1"
9794   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9795         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9796   "ix86_unary_operator_ok (NOT, QImode, operands)"
9797   "@
9798    not{b}\t%0
9799    not{l}\t%k0"
9800   [(set_attr "type" "negnot")
9801    (set_attr "mode" "QI,SI")
9802    ;; Potential partial reg stall on alternative 1.
9803    (set (attr "preferred_for_speed")
9804      (cond [(eq_attr "alternative" "1")
9805               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9806            (symbol_ref "true")))])
9808 (define_insn "*one_cmpl<mode>2_2"
9809   [(set (reg FLAGS_REG)
9810         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9811                  (const_int 0)))
9812    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9813         (not:SWI (match_dup 1)))]
9814   "ix86_match_ccmode (insn, CCNOmode)
9815    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9816   "#"
9817   [(set_attr "type" "alu1")
9818    (set_attr "mode" "<MODE>")])
9820 (define_split
9821   [(set (match_operand 0 "flags_reg_operand")
9822         (match_operator 2 "compare_operator"
9823           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9824            (const_int 0)]))
9825    (set (match_operand:SWI 1 "nonimmediate_operand")
9826         (not:SWI (match_dup 3)))]
9827   "ix86_match_ccmode (insn, CCNOmode)"
9828   [(parallel [(set (match_dup 0)
9829                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9830                                     (const_int 0)]))
9831               (set (match_dup 1)
9832                    (xor:SWI (match_dup 3) (const_int -1)))])])
9834 ;; ??? Currently never generated - xor is used instead.
9835 (define_insn "*one_cmplsi2_2_zext"
9836   [(set (reg FLAGS_REG)
9837         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9838                  (const_int 0)))
9839    (set (match_operand:DI 0 "register_operand" "=r")
9840         (zero_extend:DI (not:SI (match_dup 1))))]
9841   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9842    && ix86_unary_operator_ok (NOT, SImode, operands)"
9843   "#"
9844   [(set_attr "type" "alu1")
9845    (set_attr "mode" "SI")])
9847 (define_split
9848   [(set (match_operand 0 "flags_reg_operand")
9849         (match_operator 2 "compare_operator"
9850           [(not:SI (match_operand:SI 3 "register_operand"))
9851            (const_int 0)]))
9852    (set (match_operand:DI 1 "register_operand")
9853         (zero_extend:DI (not:SI (match_dup 3))))]
9854   "ix86_match_ccmode (insn, CCNOmode)"
9855   [(parallel [(set (match_dup 0)
9856                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9857                                     (const_int 0)]))
9858               (set (match_dup 1)
9859                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9861 ;; Shift instructions
9863 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9864 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9865 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9866 ;; from the assembler input.
9868 ;; This instruction shifts the target reg/mem as usual, but instead of
9869 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9870 ;; is a left shift double, bits are taken from the high order bits of
9871 ;; reg, else if the insn is a shift right double, bits are taken from the
9872 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9873 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9875 ;; Since sh[lr]d does not change the `reg' operand, that is done
9876 ;; separately, making all shifts emit pairs of shift double and normal
9877 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9878 ;; support a 63 bit shift, each shift where the count is in a reg expands
9879 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9881 ;; If the shift count is a constant, we need never emit more than one
9882 ;; shift pair, instead using moves and sign extension for counts greater
9883 ;; than 31.
9885 (define_expand "ashl<mode>3"
9886   [(set (match_operand:SDWIM 0 "<shift_operand>")
9887         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9888                       (match_operand:QI 2 "nonmemory_operand")))]
9889   ""
9890   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9892 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9893   [(set (match_operand:<DWI> 0 "register_operand")
9894         (ashift:<DWI>
9895           (match_operand:<DWI> 1 "register_operand")
9896           (subreg:QI
9897             (and:SI
9898               (match_operand:SI 2 "register_operand" "c")
9899               (match_operand:SI 3 "const_int_operand")) 0)))
9900    (clobber (reg:CC FLAGS_REG))]
9901   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9902    && can_create_pseudo_p ()"
9903   "#"
9904   "&& 1"
9905   [(parallel
9906      [(set (match_dup 6)
9907            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9908                      (lshiftrt:DWIH (match_dup 5)
9909                        (minus:QI (match_dup 8) (match_dup 2)))))
9910       (clobber (reg:CC FLAGS_REG))])
9911    (parallel
9912      [(set (match_dup 4)
9913            (ashift:DWIH (match_dup 5) (match_dup 2)))
9914       (clobber (reg:CC FLAGS_REG))])]
9916   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9918   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9920   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9921       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9922     {
9923       rtx tem = gen_reg_rtx (SImode);
9924       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9925       operands[2] = tem;
9926     }
9928   operands[2] = gen_lowpart (QImode, operands[2]);
9930   if (!rtx_equal_p (operands[6], operands[7]))
9931     emit_move_insn (operands[6], operands[7]);
9934 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9935   [(set (match_operand:<DWI> 0 "register_operand")
9936         (ashift:<DWI>
9937           (match_operand:<DWI> 1 "register_operand")
9938           (and:QI
9939             (match_operand:QI 2 "register_operand" "c")
9940             (match_operand:QI 3 "const_int_operand"))))
9941    (clobber (reg:CC FLAGS_REG))]
9942   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9943    && can_create_pseudo_p ()"
9944   "#"
9945   "&& 1"
9946   [(parallel
9947      [(set (match_dup 6)
9948            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9949                      (lshiftrt:DWIH (match_dup 5)
9950                        (minus:QI (match_dup 8) (match_dup 2)))))
9951       (clobber (reg:CC FLAGS_REG))])
9952    (parallel
9953      [(set (match_dup 4)
9954            (ashift:DWIH (match_dup 5) (match_dup 2)))
9955       (clobber (reg:CC FLAGS_REG))])]
9957   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9959   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9961   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9962       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9963     {
9964       rtx tem = gen_reg_rtx (QImode);
9965       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9966       operands[2] = tem;
9967     }
9969   if (!rtx_equal_p (operands[6], operands[7]))
9970     emit_move_insn (operands[6], operands[7]);
9973 (define_insn "*ashl<mode>3_doubleword"
9974   [(set (match_operand:DWI 0 "register_operand" "=&r")
9975         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9976                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9977    (clobber (reg:CC FLAGS_REG))]
9978   ""
9979   "#"
9980   [(set_attr "type" "multi")])
9982 (define_split
9983   [(set (match_operand:DWI 0 "register_operand")
9984         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9985                     (match_operand:QI 2 "nonmemory_operand")))
9986    (clobber (reg:CC FLAGS_REG))]
9987   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9988   [(const_int 0)]
9989   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9991 ;; By default we don't ask for a scratch register, because when DWImode
9992 ;; values are manipulated, registers are already at a premium.  But if
9993 ;; we have one handy, we won't turn it away.
9995 (define_peephole2
9996   [(match_scratch:DWIH 3 "r")
9997    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9998                    (ashift:<DWI>
9999                      (match_operand:<DWI> 1 "nonmemory_operand")
10000                      (match_operand:QI 2 "nonmemory_operand")))
10001               (clobber (reg:CC FLAGS_REG))])
10002    (match_dup 3)]
10003   "TARGET_CMOVE"
10004   [(const_int 0)]
10005   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10007 (define_insn "x86_64_shld"
10008   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10009         (ior:DI (ashift:DI (match_dup 0)
10010                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10011                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10012                   (minus:QI (const_int 64) (match_dup 2)))))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "TARGET_64BIT"
10015   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10016   [(set_attr "type" "ishift")
10017    (set_attr "prefix_0f" "1")
10018    (set_attr "mode" "DI")
10019    (set_attr "athlon_decode" "vector")
10020    (set_attr "amdfam10_decode" "vector")
10021    (set_attr "bdver1_decode" "vector")])
10023 (define_insn "x86_shld"
10024   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10025         (ior:SI (ashift:SI (match_dup 0)
10026                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10027                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10028                   (minus:QI (const_int 32) (match_dup 2)))))
10029    (clobber (reg:CC FLAGS_REG))]
10030   ""
10031   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10032   [(set_attr "type" "ishift")
10033    (set_attr "prefix_0f" "1")
10034    (set_attr "mode" "SI")
10035    (set_attr "pent_pair" "np")
10036    (set_attr "athlon_decode" "vector")
10037    (set_attr "amdfam10_decode" "vector")
10038    (set_attr "bdver1_decode" "vector")])
10040 (define_expand "x86_shift<mode>_adj_1"
10041   [(set (reg:CCZ FLAGS_REG)
10042         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10043                              (match_dup 4))
10044                      (const_int 0)))
10045    (set (match_operand:SWI48 0 "register_operand")
10046         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10047                             (match_operand:SWI48 1 "register_operand")
10048                             (match_dup 0)))
10049    (set (match_dup 1)
10050         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10051                             (match_operand:SWI48 3 "register_operand")
10052                             (match_dup 1)))]
10053   "TARGET_CMOVE"
10054   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10056 (define_expand "x86_shift<mode>_adj_2"
10057   [(use (match_operand:SWI48 0 "register_operand"))
10058    (use (match_operand:SWI48 1 "register_operand"))
10059    (use (match_operand:QI 2 "register_operand"))]
10060   ""
10062   rtx_code_label *label = gen_label_rtx ();
10063   rtx tmp;
10065   emit_insn (gen_testqi_ccz_1 (operands[2],
10066                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10068   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10069   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10070   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10071                               gen_rtx_LABEL_REF (VOIDmode, label),
10072                               pc_rtx);
10073   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10074   JUMP_LABEL (tmp) = label;
10076   emit_move_insn (operands[0], operands[1]);
10077   ix86_expand_clear (operands[1]);
10079   emit_label (label);
10080   LABEL_NUSES (label) = 1;
10082   DONE;
10085 ;; Avoid useless masking of count operand.
10086 (define_insn_and_split "*ashl<mode>3_mask"
10087   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10088         (ashift:SWI48
10089           (match_operand:SWI48 1 "nonimmediate_operand")
10090           (subreg:QI
10091             (and:SI
10092               (match_operand:SI 2 "register_operand" "c,r")
10093               (match_operand:SI 3 "const_int_operand")) 0)))
10094    (clobber (reg:CC FLAGS_REG))]
10095   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10096    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10097       == GET_MODE_BITSIZE (<MODE>mode)-1
10098    && can_create_pseudo_p ()"
10099   "#"
10100   "&& 1"
10101   [(parallel
10102      [(set (match_dup 0)
10103            (ashift:SWI48 (match_dup 1)
10104                          (match_dup 2)))
10105       (clobber (reg:CC FLAGS_REG))])]
10106   "operands[2] = gen_lowpart (QImode, operands[2]);"
10107   [(set_attr "isa" "*,bmi2")])
10109 (define_insn_and_split "*ashl<mode>3_mask_1"
10110   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10111         (ashift:SWI48
10112           (match_operand:SWI48 1 "nonimmediate_operand")
10113           (and:QI
10114             (match_operand:QI 2 "register_operand" "c,r")
10115             (match_operand:QI 3 "const_int_operand"))))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10118    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10119       == GET_MODE_BITSIZE (<MODE>mode)-1
10120    && can_create_pseudo_p ()"
10121   "#"
10122   "&& 1"
10123   [(parallel
10124      [(set (match_dup 0)
10125            (ashift:SWI48 (match_dup 1)
10126                          (match_dup 2)))
10127       (clobber (reg:CC FLAGS_REG))])]
10128   ""
10129   [(set_attr "isa" "*,bmi2")])
10131 (define_insn "*bmi2_ashl<mode>3_1"
10132   [(set (match_operand:SWI48 0 "register_operand" "=r")
10133         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10134                       (match_operand:SWI48 2 "register_operand" "r")))]
10135   "TARGET_BMI2"
10136   "shlx\t{%2, %1, %0|%0, %1, %2}"
10137   [(set_attr "type" "ishiftx")
10138    (set_attr "mode" "<MODE>")])
10140 (define_insn "*ashl<mode>3_1"
10141   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10142         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10143                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10144    (clobber (reg:CC FLAGS_REG))]
10145   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10147   switch (get_attr_type (insn))
10148     {
10149     case TYPE_LEA:
10150     case TYPE_ISHIFTX:
10151       return "#";
10153     case TYPE_ALU:
10154       gcc_assert (operands[2] == const1_rtx);
10155       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10156       return "add{<imodesuffix>}\t%0, %0";
10158     default:
10159       if (operands[2] == const1_rtx
10160           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10161         return "sal{<imodesuffix>}\t%0";
10162       else
10163         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10164     }
10166   [(set_attr "isa" "*,*,bmi2")
10167    (set (attr "type")
10168      (cond [(eq_attr "alternative" "1")
10169               (const_string "lea")
10170             (eq_attr "alternative" "2")
10171               (const_string "ishiftx")
10172             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10173                       (match_operand 0 "register_operand"))
10174                  (match_operand 2 "const1_operand"))
10175               (const_string "alu")
10176            ]
10177            (const_string "ishift")))
10178    (set (attr "length_immediate")
10179      (if_then_else
10180        (ior (eq_attr "type" "alu")
10181             (and (eq_attr "type" "ishift")
10182                  (and (match_operand 2 "const1_operand")
10183                       (ior (match_test "TARGET_SHIFT1")
10184                            (match_test "optimize_function_for_size_p (cfun)")))))
10185        (const_string "0")
10186        (const_string "*")))
10187    (set_attr "mode" "<MODE>")])
10189 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10190 (define_split
10191   [(set (match_operand:SWI48 0 "register_operand")
10192         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10193                       (match_operand:QI 2 "register_operand")))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "TARGET_BMI2 && reload_completed"
10196   [(set (match_dup 0)
10197         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10198   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10200 (define_insn "*bmi2_ashlsi3_1_zext"
10201   [(set (match_operand:DI 0 "register_operand" "=r")
10202         (zero_extend:DI
10203           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10204                      (match_operand:SI 2 "register_operand" "r"))))]
10205   "TARGET_64BIT && TARGET_BMI2"
10206   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10207   [(set_attr "type" "ishiftx")
10208    (set_attr "mode" "SI")])
10210 (define_insn "*ashlsi3_1_zext"
10211   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10212         (zero_extend:DI
10213           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10214                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10215    (clobber (reg:CC FLAGS_REG))]
10216   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10218   switch (get_attr_type (insn))
10219     {
10220     case TYPE_LEA:
10221     case TYPE_ISHIFTX:
10222       return "#";
10224     case TYPE_ALU:
10225       gcc_assert (operands[2] == const1_rtx);
10226       return "add{l}\t%k0, %k0";
10228     default:
10229       if (operands[2] == const1_rtx
10230           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10231         return "sal{l}\t%k0";
10232       else
10233         return "sal{l}\t{%2, %k0|%k0, %2}";
10234     }
10236   [(set_attr "isa" "*,*,bmi2")
10237    (set (attr "type")
10238      (cond [(eq_attr "alternative" "1")
10239               (const_string "lea")
10240             (eq_attr "alternative" "2")
10241               (const_string "ishiftx")
10242             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10243                  (match_operand 2 "const1_operand"))
10244               (const_string "alu")
10245            ]
10246            (const_string "ishift")))
10247    (set (attr "length_immediate")
10248      (if_then_else
10249        (ior (eq_attr "type" "alu")
10250             (and (eq_attr "type" "ishift")
10251                  (and (match_operand 2 "const1_operand")
10252                       (ior (match_test "TARGET_SHIFT1")
10253                            (match_test "optimize_function_for_size_p (cfun)")))))
10254        (const_string "0")
10255        (const_string "*")))
10256    (set_attr "mode" "SI")])
10258 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10259 (define_split
10260   [(set (match_operand:DI 0 "register_operand")
10261         (zero_extend:DI
10262           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10263                      (match_operand:QI 2 "register_operand"))))
10264    (clobber (reg:CC FLAGS_REG))]
10265   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10266   [(set (match_dup 0)
10267         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10268   "operands[2] = gen_lowpart (SImode, operands[2]);")
10270 (define_insn "*ashlhi3_1"
10271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10272         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10273                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10274    (clobber (reg:CC FLAGS_REG))]
10275   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10277   switch (get_attr_type (insn))
10278     {
10279     case TYPE_LEA:
10280       return "#";
10282     case TYPE_ALU:
10283       gcc_assert (operands[2] == const1_rtx);
10284       return "add{w}\t%0, %0";
10286     default:
10287       if (operands[2] == const1_rtx
10288           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10289         return "sal{w}\t%0";
10290       else
10291         return "sal{w}\t{%2, %0|%0, %2}";
10292     }
10294   [(set (attr "type")
10295      (cond [(eq_attr "alternative" "1")
10296               (const_string "lea")
10297             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10298                       (match_operand 0 "register_operand"))
10299                  (match_operand 2 "const1_operand"))
10300               (const_string "alu")
10301            ]
10302            (const_string "ishift")))
10303    (set (attr "length_immediate")
10304      (if_then_else
10305        (ior (eq_attr "type" "alu")
10306             (and (eq_attr "type" "ishift")
10307                  (and (match_operand 2 "const1_operand")
10308                       (ior (match_test "TARGET_SHIFT1")
10309                            (match_test "optimize_function_for_size_p (cfun)")))))
10310        (const_string "0")
10311        (const_string "*")))
10312    (set_attr "mode" "HI,SI")])
10314 (define_insn "*ashlqi3_1"
10315   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10316         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10317                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10318    (clobber (reg:CC FLAGS_REG))]
10319   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10321   switch (get_attr_type (insn))
10322     {
10323     case TYPE_LEA:
10324       return "#";
10326     case TYPE_ALU:
10327       gcc_assert (operands[2] == const1_rtx);
10328       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10329         return "add{l}\t%k0, %k0";
10330       else
10331         return "add{b}\t%0, %0";
10333     default:
10334       if (operands[2] == const1_rtx
10335           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10336         {
10337           if (get_attr_mode (insn) == MODE_SI)
10338             return "sal{l}\t%k0";
10339           else
10340             return "sal{b}\t%0";
10341         }
10342       else
10343         {
10344           if (get_attr_mode (insn) == MODE_SI)
10345             return "sal{l}\t{%2, %k0|%k0, %2}";
10346           else
10347             return "sal{b}\t{%2, %0|%0, %2}";
10348         }
10349     }
10351   [(set (attr "type")
10352      (cond [(eq_attr "alternative" "2")
10353               (const_string "lea")
10354             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10355                       (match_operand 0 "register_operand"))
10356                  (match_operand 2 "const1_operand"))
10357               (const_string "alu")
10358            ]
10359            (const_string "ishift")))
10360    (set (attr "length_immediate")
10361      (if_then_else
10362        (ior (eq_attr "type" "alu")
10363             (and (eq_attr "type" "ishift")
10364                  (and (match_operand 2 "const1_operand")
10365                       (ior (match_test "TARGET_SHIFT1")
10366                            (match_test "optimize_function_for_size_p (cfun)")))))
10367        (const_string "0")
10368        (const_string "*")))
10369    (set_attr "mode" "QI,SI,SI")
10370    ;; Potential partial reg stall on alternative 1.
10371    (set (attr "preferred_for_speed")
10372      (cond [(eq_attr "alternative" "1")
10373               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10374            (symbol_ref "true")))])
10376 (define_insn "*ashlqi3_1_slp"
10377   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10378         (ashift:QI (match_dup 0)
10379                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10380    (clobber (reg:CC FLAGS_REG))]
10381   "(optimize_function_for_size_p (cfun)
10382     || !TARGET_PARTIAL_FLAG_REG_STALL
10383     || (operands[1] == const1_rtx
10384         && (TARGET_SHIFT1
10385             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10387   switch (get_attr_type (insn))
10388     {
10389     case TYPE_ALU1:
10390       gcc_assert (operands[1] == const1_rtx);
10391       return "add{b}\t%0, %0";
10393     default:
10394       if (operands[1] == const1_rtx
10395           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10396         return "sal{b}\t%0";
10397       else
10398         return "sal{b}\t{%1, %0|%0, %1}";
10399     }
10401   [(set (attr "type")
10402      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10403                       (match_operand 0 "register_operand"))
10404                  (match_operand 1 "const1_operand"))
10405               (const_string "alu1")
10406            ]
10407            (const_string "ishift1")))
10408    (set (attr "length_immediate")
10409      (if_then_else
10410        (ior (eq_attr "type" "alu1")
10411             (and (eq_attr "type" "ishift1")
10412                  (and (match_operand 1 "const1_operand")
10413                       (ior (match_test "TARGET_SHIFT1")
10414                            (match_test "optimize_function_for_size_p (cfun)")))))
10415        (const_string "0")
10416        (const_string "*")))
10417    (set_attr "mode" "QI")])
10419 ;; Convert ashift to the lea pattern to avoid flags dependency.
10420 (define_split
10421   [(set (match_operand:SWI 0 "register_operand")
10422         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10423                     (match_operand 2 "const_0_to_3_operand")))
10424    (clobber (reg:CC FLAGS_REG))]
10425   "reload_completed
10426    && REGNO (operands[0]) != REGNO (operands[1])"
10427   [(set (match_dup 0)
10428         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10430   if (<MODE>mode != <LEAMODE>mode)
10431     {
10432       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10433       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10434     }
10435   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10438 ;; Convert ashift to the lea pattern to avoid flags dependency.
10439 (define_split
10440   [(set (match_operand:DI 0 "register_operand")
10441         (zero_extend:DI
10442           (ashift:SI (match_operand:SI 1 "index_register_operand")
10443                      (match_operand 2 "const_0_to_3_operand"))))
10444    (clobber (reg:CC FLAGS_REG))]
10445   "TARGET_64BIT && reload_completed
10446    && REGNO (operands[0]) != REGNO (operands[1])"
10447   [(set (match_dup 0)
10448         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10450   operands[1] = gen_lowpart (SImode, operands[1]);
10451   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10454 ;; This pattern can't accept a variable shift count, since shifts by
10455 ;; zero don't affect the flags.  We assume that shifts by constant
10456 ;; zero are optimized away.
10457 (define_insn "*ashl<mode>3_cmp"
10458   [(set (reg FLAGS_REG)
10459         (compare
10460           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10461                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10462           (const_int 0)))
10463    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10464         (ashift:SWI (match_dup 1) (match_dup 2)))]
10465   "(optimize_function_for_size_p (cfun)
10466     || !TARGET_PARTIAL_FLAG_REG_STALL
10467     || (operands[2] == const1_rtx
10468         && (TARGET_SHIFT1
10469             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10470    && ix86_match_ccmode (insn, CCGOCmode)
10471    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10473   switch (get_attr_type (insn))
10474     {
10475     case TYPE_ALU:
10476       gcc_assert (operands[2] == const1_rtx);
10477       return "add{<imodesuffix>}\t%0, %0";
10479     default:
10480       if (operands[2] == const1_rtx
10481           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10482         return "sal{<imodesuffix>}\t%0";
10483       else
10484         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10485     }
10487   [(set (attr "type")
10488      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10489                       (match_operand 0 "register_operand"))
10490                  (match_operand 2 "const1_operand"))
10491               (const_string "alu")
10492            ]
10493            (const_string "ishift")))
10494    (set (attr "length_immediate")
10495      (if_then_else
10496        (ior (eq_attr "type" "alu")
10497             (and (eq_attr "type" "ishift")
10498                  (and (match_operand 2 "const1_operand")
10499                       (ior (match_test "TARGET_SHIFT1")
10500                            (match_test "optimize_function_for_size_p (cfun)")))))
10501        (const_string "0")
10502        (const_string "*")))
10503    (set_attr "mode" "<MODE>")])
10505 (define_insn "*ashlsi3_cmp_zext"
10506   [(set (reg FLAGS_REG)
10507         (compare
10508           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10509                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10510           (const_int 0)))
10511    (set (match_operand:DI 0 "register_operand" "=r")
10512         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10513   "TARGET_64BIT
10514    && (optimize_function_for_size_p (cfun)
10515        || !TARGET_PARTIAL_FLAG_REG_STALL
10516        || (operands[2] == const1_rtx
10517            && (TARGET_SHIFT1
10518                || TARGET_DOUBLE_WITH_ADD)))
10519    && ix86_match_ccmode (insn, CCGOCmode)
10520    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10522   switch (get_attr_type (insn))
10523     {
10524     case TYPE_ALU:
10525       gcc_assert (operands[2] == const1_rtx);
10526       return "add{l}\t%k0, %k0";
10528     default:
10529       if (operands[2] == const1_rtx
10530           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10531         return "sal{l}\t%k0";
10532       else
10533         return "sal{l}\t{%2, %k0|%k0, %2}";
10534     }
10536   [(set (attr "type")
10537      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10538                  (match_operand 2 "const1_operand"))
10539               (const_string "alu")
10540            ]
10541            (const_string "ishift")))
10542    (set (attr "length_immediate")
10543      (if_then_else
10544        (ior (eq_attr "type" "alu")
10545             (and (eq_attr "type" "ishift")
10546                  (and (match_operand 2 "const1_operand")
10547                       (ior (match_test "TARGET_SHIFT1")
10548                            (match_test "optimize_function_for_size_p (cfun)")))))
10549        (const_string "0")
10550        (const_string "*")))
10551    (set_attr "mode" "SI")])
10553 (define_insn "*ashl<mode>3_cconly"
10554   [(set (reg FLAGS_REG)
10555         (compare
10556           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10557                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10558           (const_int 0)))
10559    (clobber (match_scratch:SWI 0 "=<r>"))]
10560   "(optimize_function_for_size_p (cfun)
10561     || !TARGET_PARTIAL_FLAG_REG_STALL
10562     || (operands[2] == const1_rtx
10563         && (TARGET_SHIFT1
10564             || TARGET_DOUBLE_WITH_ADD)))
10565    && ix86_match_ccmode (insn, CCGOCmode)"
10567   switch (get_attr_type (insn))
10568     {
10569     case TYPE_ALU:
10570       gcc_assert (operands[2] == const1_rtx);
10571       return "add{<imodesuffix>}\t%0, %0";
10573     default:
10574       if (operands[2] == const1_rtx
10575           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10576         return "sal{<imodesuffix>}\t%0";
10577       else
10578         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10579     }
10581   [(set (attr "type")
10582      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10583                       (match_operand 0 "register_operand"))
10584                  (match_operand 2 "const1_operand"))
10585               (const_string "alu")
10586            ]
10587            (const_string "ishift")))
10588    (set (attr "length_immediate")
10589      (if_then_else
10590        (ior (eq_attr "type" "alu")
10591             (and (eq_attr "type" "ishift")
10592                  (and (match_operand 2 "const1_operand")
10593                       (ior (match_test "TARGET_SHIFT1")
10594                            (match_test "optimize_function_for_size_p (cfun)")))))
10595        (const_string "0")
10596        (const_string "*")))
10597    (set_attr "mode" "<MODE>")])
10599 ;; See comment above `ashl<mode>3' about how this works.
10601 (define_expand "<shift_insn><mode>3"
10602   [(set (match_operand:SDWIM 0 "<shift_operand>")
10603         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10604                            (match_operand:QI 2 "nonmemory_operand")))]
10605   ""
10606   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10608 ;; Avoid useless masking of count operand.
10609 (define_insn_and_split "*<shift_insn><mode>3_mask"
10610   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10611         (any_shiftrt:SWI48
10612           (match_operand:SWI48 1 "nonimmediate_operand")
10613           (subreg:QI
10614             (and:SI
10615               (match_operand:SI 2 "register_operand" "c,r")
10616               (match_operand:SI 3 "const_int_operand")) 0)))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10619    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10620       == GET_MODE_BITSIZE (<MODE>mode)-1
10621    && can_create_pseudo_p ()"
10622   "#"
10623   "&& 1"
10624   [(parallel
10625      [(set (match_dup 0)
10626            (any_shiftrt:SWI48 (match_dup 1)
10627                               (match_dup 2)))
10628       (clobber (reg:CC FLAGS_REG))])]
10629   "operands[2] = gen_lowpart (QImode, operands[2]);"
10630   [(set_attr "isa" "*,bmi2")])
10632 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10633   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10634         (any_shiftrt:SWI48
10635           (match_operand:SWI48 1 "nonimmediate_operand")
10636           (and:QI
10637             (match_operand:QI 2 "register_operand" "c,r")
10638             (match_operand:QI 3 "const_int_operand"))))
10639    (clobber (reg:CC FLAGS_REG))]
10640   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10641    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10642       == GET_MODE_BITSIZE (<MODE>mode)-1
10643    && can_create_pseudo_p ()"
10644   "#"
10645   "&& 1"
10646   [(parallel
10647      [(set (match_dup 0)
10648            (any_shiftrt:SWI48 (match_dup 1)
10649                               (match_dup 2)))
10650       (clobber (reg:CC FLAGS_REG))])]
10651   ""
10652   [(set_attr "isa" "*,bmi2")])
10654 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10655   [(set (match_operand:<DWI> 0 "register_operand")
10656         (any_shiftrt:<DWI>
10657           (match_operand:<DWI> 1 "register_operand")
10658           (subreg:QI
10659             (and:SI
10660               (match_operand:SI 2 "register_operand" "c")
10661               (match_operand:SI 3 "const_int_operand")) 0)))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10664    && can_create_pseudo_p ()"
10665   "#"
10666   "&& 1"
10667   [(parallel
10668      [(set (match_dup 4)
10669            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10670                      (ashift:DWIH (match_dup 7)
10671                        (minus:QI (match_dup 8) (match_dup 2)))))
10672       (clobber (reg:CC FLAGS_REG))])
10673    (parallel
10674      [(set (match_dup 6)
10675            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10676       (clobber (reg:CC FLAGS_REG))])]
10678   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10680   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10682   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10683       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10684     {
10685       rtx tem = gen_reg_rtx (SImode);
10686       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10687       operands[2] = tem;
10688     }
10690   operands[2] = gen_lowpart (QImode, operands[2]);
10692   if (!rtx_equal_p (operands[4], operands[5]))
10693     emit_move_insn (operands[4], operands[5]);
10696 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10697   [(set (match_operand:<DWI> 0 "register_operand")
10698         (any_shiftrt:<DWI>
10699           (match_operand:<DWI> 1 "register_operand")
10700           (and:QI
10701             (match_operand:QI 2 "register_operand" "c")
10702             (match_operand:QI 3 "const_int_operand"))))
10703    (clobber (reg:CC FLAGS_REG))]
10704   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10705    && can_create_pseudo_p ()"
10706   "#"
10707   "&& 1"
10708   [(parallel
10709      [(set (match_dup 4)
10710            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10711                      (ashift:DWIH (match_dup 7)
10712                        (minus:QI (match_dup 8) (match_dup 2)))))
10713       (clobber (reg:CC FLAGS_REG))])
10714    (parallel
10715      [(set (match_dup 6)
10716            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10717       (clobber (reg:CC FLAGS_REG))])]
10719   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10721   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10723   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10724       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10725     {
10726       rtx tem = gen_reg_rtx (QImode);
10727       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10728       operands[2] = tem;
10729     }
10731   if (!rtx_equal_p (operands[4], operands[5]))
10732     emit_move_insn (operands[4], operands[5]);
10735 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10736   [(set (match_operand:DWI 0 "register_operand" "=&r")
10737         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10738                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10739    (clobber (reg:CC FLAGS_REG))]
10740   ""
10741   "#"
10742   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10743   [(const_int 0)]
10744   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10745   [(set_attr "type" "multi")])
10747 ;; By default we don't ask for a scratch register, because when DWImode
10748 ;; values are manipulated, registers are already at a premium.  But if
10749 ;; we have one handy, we won't turn it away.
10751 (define_peephole2
10752   [(match_scratch:DWIH 3 "r")
10753    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10754                    (any_shiftrt:<DWI>
10755                      (match_operand:<DWI> 1 "register_operand")
10756                      (match_operand:QI 2 "nonmemory_operand")))
10757               (clobber (reg:CC FLAGS_REG))])
10758    (match_dup 3)]
10759   "TARGET_CMOVE"
10760   [(const_int 0)]
10761   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10763 (define_insn "x86_64_shrd"
10764   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10765         (ior:DI (lshiftrt:DI (match_dup 0)
10766                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10767                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10768                   (minus:QI (const_int 64) (match_dup 2)))))
10769    (clobber (reg:CC FLAGS_REG))]
10770   "TARGET_64BIT"
10771   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10772   [(set_attr "type" "ishift")
10773    (set_attr "prefix_0f" "1")
10774    (set_attr "mode" "DI")
10775    (set_attr "athlon_decode" "vector")
10776    (set_attr "amdfam10_decode" "vector")
10777    (set_attr "bdver1_decode" "vector")])
10779 (define_insn "x86_shrd"
10780   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10781         (ior:SI (lshiftrt:SI (match_dup 0)
10782                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10783                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10784                   (minus:QI (const_int 32) (match_dup 2)))))
10785    (clobber (reg:CC FLAGS_REG))]
10786   ""
10787   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10788   [(set_attr "type" "ishift")
10789    (set_attr "prefix_0f" "1")
10790    (set_attr "mode" "SI")
10791    (set_attr "pent_pair" "np")
10792    (set_attr "athlon_decode" "vector")
10793    (set_attr "amdfam10_decode" "vector")
10794    (set_attr "bdver1_decode" "vector")])
10796 ;; Base name for insn mnemonic.
10797 (define_mode_attr cvt_mnemonic
10798   [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
10800 (define_insn "ashr<mode>3_cvt"
10801   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
10802         (ashiftrt:SWI48
10803           (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
10804           (match_operand:QI 2 "const_int_operand")))
10805    (clobber (reg:CC FLAGS_REG))]
10806   "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
10807    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10808    && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
10809   "@
10810    <cvt_mnemonic>
10811    sar{<imodesuffix>}\t{%2, %0|%0, %2}"
10812   [(set_attr "type" "imovx,ishift")
10813    (set_attr "prefix_0f" "0,*")
10814    (set_attr "length_immediate" "0,*")
10815    (set_attr "modrm" "0,1")
10816    (set_attr "mode" "<MODE>")])
10818 (define_insn "*ashrsi3_cvt_zext"
10819   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10820         (zero_extend:DI
10821           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10822                        (match_operand:QI 2 "const_int_operand"))))
10823    (clobber (reg:CC FLAGS_REG))]
10824   "TARGET_64BIT && INTVAL (operands[2]) == 31
10825    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10826    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10827   "@
10828    {cltd|cdq}
10829    sar{l}\t{%2, %k0|%k0, %2}"
10830   [(set_attr "type" "imovx,ishift")
10831    (set_attr "prefix_0f" "0,*")
10832    (set_attr "length_immediate" "0,*")
10833    (set_attr "modrm" "0,1")
10834    (set_attr "mode" "SI")])
10836 (define_expand "x86_shift<mode>_adj_3"
10837   [(use (match_operand:SWI48 0 "register_operand"))
10838    (use (match_operand:SWI48 1 "register_operand"))
10839    (use (match_operand:QI 2 "register_operand"))]
10840   ""
10842   rtx_code_label *label = gen_label_rtx ();
10843   rtx tmp;
10845   emit_insn (gen_testqi_ccz_1 (operands[2],
10846                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10848   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10849   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10850   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10851                               gen_rtx_LABEL_REF (VOIDmode, label),
10852                               pc_rtx);
10853   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10854   JUMP_LABEL (tmp) = label;
10856   emit_move_insn (operands[0], operands[1]);
10857   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10858                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10859   emit_label (label);
10860   LABEL_NUSES (label) = 1;
10862   DONE;
10865 (define_insn "*bmi2_<shift_insn><mode>3_1"
10866   [(set (match_operand:SWI48 0 "register_operand" "=r")
10867         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10868                            (match_operand:SWI48 2 "register_operand" "r")))]
10869   "TARGET_BMI2"
10870   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10871   [(set_attr "type" "ishiftx")
10872    (set_attr "mode" "<MODE>")])
10874 (define_insn "*<shift_insn><mode>3_1"
10875   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10876         (any_shiftrt:SWI48
10877           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10878           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10879    (clobber (reg:CC FLAGS_REG))]
10880   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10882   switch (get_attr_type (insn))
10883     {
10884     case TYPE_ISHIFTX:
10885       return "#";
10887     default:
10888       if (operands[2] == const1_rtx
10889           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10890         return "<shift>{<imodesuffix>}\t%0";
10891       else
10892         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10893     }
10895   [(set_attr "isa" "*,bmi2")
10896    (set_attr "type" "ishift,ishiftx")
10897    (set (attr "length_immediate")
10898      (if_then_else
10899        (and (match_operand 2 "const1_operand")
10900             (ior (match_test "TARGET_SHIFT1")
10901                  (match_test "optimize_function_for_size_p (cfun)")))
10902        (const_string "0")
10903        (const_string "*")))
10904    (set_attr "mode" "<MODE>")])
10906 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10907 (define_split
10908   [(set (match_operand:SWI48 0 "register_operand")
10909         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10910                            (match_operand:QI 2 "register_operand")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_BMI2 && reload_completed"
10913   [(set (match_dup 0)
10914         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10915   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10917 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10918   [(set (match_operand:DI 0 "register_operand" "=r")
10919         (zero_extend:DI
10920           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10921                           (match_operand:SI 2 "register_operand" "r"))))]
10922   "TARGET_64BIT && TARGET_BMI2"
10923   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10924   [(set_attr "type" "ishiftx")
10925    (set_attr "mode" "SI")])
10927 (define_insn "*<shift_insn>si3_1_zext"
10928   [(set (match_operand:DI 0 "register_operand" "=r,r")
10929         (zero_extend:DI
10930           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10931                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10932    (clobber (reg:CC FLAGS_REG))]
10933   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10935   switch (get_attr_type (insn))
10936     {
10937     case TYPE_ISHIFTX:
10938       return "#";
10940     default:
10941       if (operands[2] == const1_rtx
10942           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10943         return "<shift>{l}\t%k0";
10944       else
10945         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10946     }
10948   [(set_attr "isa" "*,bmi2")
10949    (set_attr "type" "ishift,ishiftx")
10950    (set (attr "length_immediate")
10951      (if_then_else
10952        (and (match_operand 2 "const1_operand")
10953             (ior (match_test "TARGET_SHIFT1")
10954                  (match_test "optimize_function_for_size_p (cfun)")))
10955        (const_string "0")
10956        (const_string "*")))
10957    (set_attr "mode" "SI")])
10959 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10960 (define_split
10961   [(set (match_operand:DI 0 "register_operand")
10962         (zero_extend:DI
10963           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10964                           (match_operand:QI 2 "register_operand"))))
10965    (clobber (reg:CC FLAGS_REG))]
10966   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10967   [(set (match_dup 0)
10968         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10969   "operands[2] = gen_lowpart (SImode, operands[2]);")
10971 (define_insn "*<shift_insn><mode>3_1"
10972   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10973         (any_shiftrt:SWI12
10974           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10975           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10976    (clobber (reg:CC FLAGS_REG))]
10977   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10979   if (operands[2] == const1_rtx
10980       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10981     return "<shift>{<imodesuffix>}\t%0";
10982   else
10983     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10985   [(set_attr "type" "ishift")
10986    (set (attr "length_immediate")
10987      (if_then_else
10988        (and (match_operand 2 "const1_operand")
10989             (ior (match_test "TARGET_SHIFT1")
10990                  (match_test "optimize_function_for_size_p (cfun)")))
10991        (const_string "0")
10992        (const_string "*")))
10993    (set_attr "mode" "<MODE>")])
10995 (define_insn "*<shift_insn>qi3_1_slp"
10996   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10997         (any_shiftrt:QI (match_dup 0)
10998                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10999    (clobber (reg:CC FLAGS_REG))]
11000   "(optimize_function_for_size_p (cfun)
11001     || !TARGET_PARTIAL_REG_STALL
11002     || (operands[1] == const1_rtx
11003         && TARGET_SHIFT1))"
11005   if (operands[1] == const1_rtx
11006       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11007     return "<shift>{b}\t%0";
11008   else
11009     return "<shift>{b}\t{%1, %0|%0, %1}";
11011   [(set_attr "type" "ishift1")
11012    (set (attr "length_immediate")
11013      (if_then_else
11014        (and (match_operand 1 "const1_operand")
11015             (ior (match_test "TARGET_SHIFT1")
11016                  (match_test "optimize_function_for_size_p (cfun)")))
11017        (const_string "0")
11018        (const_string "*")))
11019    (set_attr "mode" "QI")])
11021 ;; This pattern can't accept a variable shift count, since shifts by
11022 ;; zero don't affect the flags.  We assume that shifts by constant
11023 ;; zero are optimized away.
11024 (define_insn "*<shift_insn><mode>3_cmp"
11025   [(set (reg FLAGS_REG)
11026         (compare
11027           (any_shiftrt:SWI
11028             (match_operand:SWI 1 "nonimmediate_operand" "0")
11029             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11030           (const_int 0)))
11031    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11032         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11033   "(optimize_function_for_size_p (cfun)
11034     || !TARGET_PARTIAL_FLAG_REG_STALL
11035     || (operands[2] == const1_rtx
11036         && TARGET_SHIFT1))
11037    && ix86_match_ccmode (insn, CCGOCmode)
11038    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11040   if (operands[2] == const1_rtx
11041       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11042     return "<shift>{<imodesuffix>}\t%0";
11043   else
11044     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11046   [(set_attr "type" "ishift")
11047    (set (attr "length_immediate")
11048      (if_then_else
11049        (and (match_operand 2 "const1_operand")
11050             (ior (match_test "TARGET_SHIFT1")
11051                  (match_test "optimize_function_for_size_p (cfun)")))
11052        (const_string "0")
11053        (const_string "*")))
11054    (set_attr "mode" "<MODE>")])
11056 (define_insn "*<shift_insn>si3_cmp_zext"
11057   [(set (reg FLAGS_REG)
11058         (compare
11059           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11060                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11061           (const_int 0)))
11062    (set (match_operand:DI 0 "register_operand" "=r")
11063         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11064   "TARGET_64BIT
11065    && (optimize_function_for_size_p (cfun)
11066        || !TARGET_PARTIAL_FLAG_REG_STALL
11067        || (operands[2] == const1_rtx
11068            && TARGET_SHIFT1))
11069    && ix86_match_ccmode (insn, CCGOCmode)
11070    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11072   if (operands[2] == const1_rtx
11073       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11074     return "<shift>{l}\t%k0";
11075   else
11076     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11078   [(set_attr "type" "ishift")
11079    (set (attr "length_immediate")
11080      (if_then_else
11081        (and (match_operand 2 "const1_operand")
11082             (ior (match_test "TARGET_SHIFT1")
11083                  (match_test "optimize_function_for_size_p (cfun)")))
11084        (const_string "0")
11085        (const_string "*")))
11086    (set_attr "mode" "SI")])
11088 (define_insn "*<shift_insn><mode>3_cconly"
11089   [(set (reg FLAGS_REG)
11090         (compare
11091           (any_shiftrt:SWI
11092             (match_operand:SWI 1 "register_operand" "0")
11093             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11094           (const_int 0)))
11095    (clobber (match_scratch:SWI 0 "=<r>"))]
11096   "(optimize_function_for_size_p (cfun)
11097     || !TARGET_PARTIAL_FLAG_REG_STALL
11098     || (operands[2] == const1_rtx
11099         && TARGET_SHIFT1))
11100    && ix86_match_ccmode (insn, CCGOCmode)"
11102   if (operands[2] == const1_rtx
11103       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11104     return "<shift>{<imodesuffix>}\t%0";
11105   else
11106     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11108   [(set_attr "type" "ishift")
11109    (set (attr "length_immediate")
11110      (if_then_else
11111        (and (match_operand 2 "const1_operand")
11112             (ior (match_test "TARGET_SHIFT1")
11113                  (match_test "optimize_function_for_size_p (cfun)")))
11114        (const_string "0")
11115        (const_string "*")))
11116    (set_attr "mode" "<MODE>")])
11118 ;; Rotate instructions
11120 (define_expand "<rotate_insn>ti3"
11121   [(set (match_operand:TI 0 "register_operand")
11122         (any_rotate:TI (match_operand:TI 1 "register_operand")
11123                        (match_operand:QI 2 "nonmemory_operand")))]
11124   "TARGET_64BIT"
11126   if (const_1_to_63_operand (operands[2], VOIDmode))
11127     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11128                 (operands[0], operands[1], operands[2]));
11129   else
11130     FAIL;
11132   DONE;
11135 (define_expand "<rotate_insn>di3"
11136   [(set (match_operand:DI 0 "shiftdi_operand")
11137         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11138                        (match_operand:QI 2 "nonmemory_operand")))]
11139  ""
11141   if (TARGET_64BIT)
11142     ix86_expand_binary_operator (<CODE>, DImode, operands);
11143   else if (const_1_to_31_operand (operands[2], VOIDmode))
11144     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11145                 (operands[0], operands[1], operands[2]));
11146   else
11147     FAIL;
11149   DONE;
11152 (define_expand "<rotate_insn><mode>3"
11153   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11154         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11155                             (match_operand:QI 2 "nonmemory_operand")))]
11156   ""
11157   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11159 ;; Avoid useless masking of count operand.
11160 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11161   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11162         (any_rotate:SWI48
11163           (match_operand:SWI48 1 "nonimmediate_operand")
11164           (subreg:QI
11165             (and:SI
11166               (match_operand:SI 2 "register_operand" "c")
11167               (match_operand:SI 3 "const_int_operand")) 0)))
11168    (clobber (reg:CC FLAGS_REG))]
11169   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11170    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11171       == GET_MODE_BITSIZE (<MODE>mode)-1
11172    && can_create_pseudo_p ()"
11173   "#"
11174   "&& 1"
11175   [(parallel
11176      [(set (match_dup 0)
11177            (any_rotate:SWI48 (match_dup 1)
11178                              (match_dup 2)))
11179       (clobber (reg:CC FLAGS_REG))])]
11180   "operands[2] = gen_lowpart (QImode, operands[2]);")
11182 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11183   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11184         (any_rotate:SWI48
11185           (match_operand:SWI48 1 "nonimmediate_operand")
11186           (and:QI
11187             (match_operand:QI 2 "register_operand" "c")
11188             (match_operand:QI 3 "const_int_operand"))))
11189    (clobber (reg:CC FLAGS_REG))]
11190   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11191    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11192       == GET_MODE_BITSIZE (<MODE>mode)-1
11193    && can_create_pseudo_p ()"
11194   "#"
11195   "&& 1"
11196   [(parallel
11197      [(set (match_dup 0)
11198            (any_rotate:SWI48 (match_dup 1)
11199                              (match_dup 2)))
11200       (clobber (reg:CC FLAGS_REG))])])
11202 ;; Implement rotation using two double-precision
11203 ;; shift instructions and a scratch register.
11205 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11206  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11207        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11208                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11209   (clobber (reg:CC FLAGS_REG))
11210   (clobber (match_scratch:DWIH 3 "=&r"))]
11211  ""
11212  "#"
11213  "reload_completed"
11214  [(set (match_dup 3) (match_dup 4))
11215   (parallel
11216    [(set (match_dup 4)
11217          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11218                    (lshiftrt:DWIH (match_dup 5)
11219                                   (minus:QI (match_dup 6) (match_dup 2)))))
11220     (clobber (reg:CC FLAGS_REG))])
11221   (parallel
11222    [(set (match_dup 5)
11223          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11224                    (lshiftrt:DWIH (match_dup 3)
11225                                   (minus:QI (match_dup 6) (match_dup 2)))))
11226     (clobber (reg:CC FLAGS_REG))])]
11228   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11230   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11233 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11234  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11235        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11236                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11237   (clobber (reg:CC FLAGS_REG))
11238   (clobber (match_scratch:DWIH 3 "=&r"))]
11239  ""
11240  "#"
11241  "reload_completed"
11242  [(set (match_dup 3) (match_dup 4))
11243   (parallel
11244    [(set (match_dup 4)
11245          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11246                    (ashift:DWIH (match_dup 5)
11247                                 (minus:QI (match_dup 6) (match_dup 2)))))
11248     (clobber (reg:CC FLAGS_REG))])
11249   (parallel
11250    [(set (match_dup 5)
11251          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11252                    (ashift:DWIH (match_dup 3)
11253                                 (minus:QI (match_dup 6) (match_dup 2)))))
11254     (clobber (reg:CC FLAGS_REG))])]
11256   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11258   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11261 (define_mode_attr rorx_immediate_operand
11262         [(SI "const_0_to_31_operand")
11263          (DI "const_0_to_63_operand")])
11265 (define_insn "*bmi2_rorx<mode>3_1"
11266   [(set (match_operand:SWI48 0 "register_operand" "=r")
11267         (rotatert:SWI48
11268           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11269           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11270   "TARGET_BMI2"
11271   "rorx\t{%2, %1, %0|%0, %1, %2}"
11272   [(set_attr "type" "rotatex")
11273    (set_attr "mode" "<MODE>")])
11275 (define_insn "*<rotate_insn><mode>3_1"
11276   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11277         (any_rotate:SWI48
11278           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11279           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11283   switch (get_attr_type (insn))
11284     {
11285     case TYPE_ROTATEX:
11286       return "#";
11288     default:
11289       if (operands[2] == const1_rtx
11290           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11291         return "<rotate>{<imodesuffix>}\t%0";
11292       else
11293         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11294     }
11296   [(set_attr "isa" "*,bmi2")
11297    (set_attr "type" "rotate,rotatex")
11298    (set (attr "length_immediate")
11299      (if_then_else
11300        (and (eq_attr "type" "rotate")
11301             (and (match_operand 2 "const1_operand")
11302                  (ior (match_test "TARGET_SHIFT1")
11303                       (match_test "optimize_function_for_size_p (cfun)"))))
11304        (const_string "0")
11305        (const_string "*")))
11306    (set_attr "mode" "<MODE>")])
11308 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11309 (define_split
11310   [(set (match_operand:SWI48 0 "register_operand")
11311         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11312                       (match_operand:QI 2 "const_int_operand")))
11313    (clobber (reg:CC FLAGS_REG))]
11314   "TARGET_BMI2 && reload_completed"
11315   [(set (match_dup 0)
11316         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11318   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11320   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11323 (define_split
11324   [(set (match_operand:SWI48 0 "register_operand")
11325         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11326                         (match_operand:QI 2 "const_int_operand")))
11327    (clobber (reg:CC FLAGS_REG))]
11328   "TARGET_BMI2 && reload_completed"
11329   [(set (match_dup 0)
11330         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11332 (define_insn "*bmi2_rorxsi3_1_zext"
11333   [(set (match_operand:DI 0 "register_operand" "=r")
11334         (zero_extend:DI
11335           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11336                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11337   "TARGET_64BIT && TARGET_BMI2"
11338   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11339   [(set_attr "type" "rotatex")
11340    (set_attr "mode" "SI")])
11342 (define_insn "*<rotate_insn>si3_1_zext"
11343   [(set (match_operand:DI 0 "register_operand" "=r,r")
11344         (zero_extend:DI
11345           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11346                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11347    (clobber (reg:CC FLAGS_REG))]
11348   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11350   switch (get_attr_type (insn))
11351     {
11352     case TYPE_ROTATEX:
11353       return "#";
11355     default:
11356       if (operands[2] == const1_rtx
11357           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11358         return "<rotate>{l}\t%k0";
11359       else
11360         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11361     }
11363   [(set_attr "isa" "*,bmi2")
11364    (set_attr "type" "rotate,rotatex")
11365    (set (attr "length_immediate")
11366      (if_then_else
11367        (and (eq_attr "type" "rotate")
11368             (and (match_operand 2 "const1_operand")
11369                  (ior (match_test "TARGET_SHIFT1")
11370                       (match_test "optimize_function_for_size_p (cfun)"))))
11371        (const_string "0")
11372        (const_string "*")))
11373    (set_attr "mode" "SI")])
11375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11376 (define_split
11377   [(set (match_operand:DI 0 "register_operand")
11378         (zero_extend:DI
11379           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11380                      (match_operand:QI 2 "const_int_operand"))))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11383   [(set (match_dup 0)
11384         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11386   int bitsize = GET_MODE_BITSIZE (SImode);
11388   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11391 (define_split
11392   [(set (match_operand:DI 0 "register_operand")
11393         (zero_extend:DI
11394           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11395                        (match_operand:QI 2 "const_int_operand"))))
11396    (clobber (reg:CC FLAGS_REG))]
11397   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11398   [(set (match_dup 0)
11399         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11401 (define_insn "*<rotate_insn><mode>3_1"
11402   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11403         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11404                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11405    (clobber (reg:CC FLAGS_REG))]
11406   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11408   if (operands[2] == const1_rtx
11409       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11410     return "<rotate>{<imodesuffix>}\t%0";
11411   else
11412     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11414   [(set_attr "type" "rotate")
11415    (set (attr "length_immediate")
11416      (if_then_else
11417        (and (match_operand 2 "const1_operand")
11418             (ior (match_test "TARGET_SHIFT1")
11419                  (match_test "optimize_function_for_size_p (cfun)")))
11420        (const_string "0")
11421        (const_string "*")))
11422    (set_attr "mode" "<MODE>")])
11424 (define_insn "*<rotate_insn>qi3_1_slp"
11425   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11426         (any_rotate:QI (match_dup 0)
11427                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "(optimize_function_for_size_p (cfun)
11430     || !TARGET_PARTIAL_REG_STALL
11431     || (operands[1] == const1_rtx
11432         && TARGET_SHIFT1))"
11434   if (operands[1] == const1_rtx
11435       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11436     return "<rotate>{b}\t%0";
11437   else
11438     return "<rotate>{b}\t{%1, %0|%0, %1}";
11440   [(set_attr "type" "rotate1")
11441    (set (attr "length_immediate")
11442      (if_then_else
11443        (and (match_operand 1 "const1_operand")
11444             (ior (match_test "TARGET_SHIFT1")
11445                  (match_test "optimize_function_for_size_p (cfun)")))
11446        (const_string "0")
11447        (const_string "*")))
11448    (set_attr "mode" "QI")])
11450 (define_split
11451  [(set (match_operand:HI 0 "QIreg_operand")
11452        (any_rotate:HI (match_dup 0) (const_int 8)))
11453   (clobber (reg:CC FLAGS_REG))]
11454  "reload_completed
11455   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11456  [(parallel [(set (strict_low_part (match_dup 0))
11457                   (bswap:HI (match_dup 0)))
11458              (clobber (reg:CC FLAGS_REG))])])
11460 ;; Bit set / bit test instructions
11462 ;; %%% bts, btr, btc
11464 ;; These instructions are *slow* when applied to memory.
11466 (define_code_attr btsc [(ior "bts") (xor "btc")])
11468 (define_insn "*<btsc><mode>"
11469   [(set (match_operand:SWI48 0 "register_operand" "=r")
11470         (any_or:SWI48
11471           (ashift:SWI48 (const_int 1)
11472                         (match_operand:QI 2 "register_operand" "r"))
11473           (match_operand:SWI48 1 "register_operand" "0")))
11474    (clobber (reg:CC FLAGS_REG))]
11475   "TARGET_USE_BT"
11476   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11477   [(set_attr "type" "alu1")
11478    (set_attr "prefix_0f" "1")
11479    (set_attr "znver1_decode" "double")
11480    (set_attr "mode" "<MODE>")])
11482 ;; Avoid useless masking of count operand.
11483 (define_insn_and_split "*<btsc><mode>_mask"
11484   [(set (match_operand:SWI48 0 "register_operand")
11485         (any_or:SWI48
11486           (ashift:SWI48
11487             (const_int 1)
11488             (subreg:QI
11489               (and:SI
11490                 (match_operand:SI 1 "register_operand")
11491                 (match_operand:SI 2 "const_int_operand")) 0))
11492           (match_operand:SWI48 3 "register_operand")))
11493    (clobber (reg:CC FLAGS_REG))]
11494   "TARGET_USE_BT
11495    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11496       == GET_MODE_BITSIZE (<MODE>mode)-1
11497    && can_create_pseudo_p ()"
11498   "#"
11499   "&& 1"
11500   [(parallel
11501      [(set (match_dup 0)
11502            (any_or:SWI48
11503              (ashift:SWI48 (const_int 1)
11504                            (match_dup 1))
11505              (match_dup 3)))
11506       (clobber (reg:CC FLAGS_REG))])]
11507   "operands[1] = gen_lowpart (QImode, operands[1]);")
11509 (define_insn_and_split "*<btsc><mode>_mask_1"
11510   [(set (match_operand:SWI48 0 "register_operand")
11511         (any_or:SWI48
11512           (ashift:SWI48
11513             (const_int 1)
11514             (and:QI
11515               (match_operand:QI 1 "register_operand")
11516               (match_operand:QI 2 "const_int_operand")))
11517           (match_operand:SWI48 3 "register_operand")))
11518    (clobber (reg:CC FLAGS_REG))]
11519   "TARGET_USE_BT
11520    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11521       == GET_MODE_BITSIZE (<MODE>mode)-1
11522    && can_create_pseudo_p ()"
11523   "#"
11524   "&& 1"
11525   [(parallel
11526      [(set (match_dup 0)
11527            (any_or:SWI48
11528              (ashift:SWI48 (const_int 1)
11529                            (match_dup 1))
11530              (match_dup 3)))
11531       (clobber (reg:CC FLAGS_REG))])])
11533 (define_insn "*btr<mode>"
11534   [(set (match_operand:SWI48 0 "register_operand" "=r")
11535         (and:SWI48
11536           (rotate:SWI48 (const_int -2)
11537                         (match_operand:QI 2 "register_operand" "r"))
11538         (match_operand:SWI48 1 "register_operand" "0")))
11539    (clobber (reg:CC FLAGS_REG))]
11540   "TARGET_USE_BT"
11541   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11542   [(set_attr "type" "alu1")
11543    (set_attr "prefix_0f" "1")
11544    (set_attr "znver1_decode" "double")
11545    (set_attr "mode" "<MODE>")])
11547 ;; Avoid useless masking of count operand.
11548 (define_insn_and_split "*btr<mode>_mask"
11549   [(set (match_operand:SWI48 0 "register_operand")
11550         (and:SWI48
11551           (rotate:SWI48
11552             (const_int -2)
11553             (subreg:QI
11554               (and:SI
11555                 (match_operand:SI 1 "register_operand")
11556                 (match_operand:SI 2 "const_int_operand")) 0))
11557           (match_operand:SWI48 3 "register_operand")))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "TARGET_USE_BT
11560    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11561       == GET_MODE_BITSIZE (<MODE>mode)-1
11562    && can_create_pseudo_p ()"
11563   "#"
11564   "&& 1"
11565   [(parallel
11566      [(set (match_dup 0)
11567            (and:SWI48
11568              (rotate:SWI48 (const_int -2)
11569                            (match_dup 1))
11570              (match_dup 3)))
11571       (clobber (reg:CC FLAGS_REG))])]
11572   "operands[1] = gen_lowpart (QImode, operands[1]);")
11574 (define_insn_and_split "*btr<mode>_mask_1"
11575   [(set (match_operand:SWI48 0 "register_operand")
11576         (and:SWI48
11577           (rotate:SWI48
11578             (const_int -2)
11579             (and:QI
11580               (match_operand:QI 1 "register_operand")
11581               (match_operand:QI 2 "const_int_operand")))
11582           (match_operand:SWI48 3 "register_operand")))
11583    (clobber (reg:CC FLAGS_REG))]
11584   "TARGET_USE_BT
11585    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11586       == GET_MODE_BITSIZE (<MODE>mode)-1
11587    && can_create_pseudo_p ()"
11588   "#"
11589   "&& 1"
11590   [(parallel
11591      [(set (match_dup 0)
11592            (and:SWI48
11593              (rotate:SWI48 (const_int -2)
11594                            (match_dup 1))
11595              (match_dup 3)))
11596       (clobber (reg:CC FLAGS_REG))])])
11598 ;; These instructions are never faster than the corresponding
11599 ;; and/ior/xor operations when using immediate operand, so with
11600 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11601 ;; relevant immediates within the instruction itself, so operating
11602 ;; on bits in the high 32-bits of a register becomes easier.
11604 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11605 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11606 ;; negdf respectively, so they can never be disabled entirely.
11608 (define_insn "*btsq_imm"
11609   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11610                          (const_int 1)
11611                          (match_operand 1 "const_0_to_63_operand" "J"))
11612         (const_int 1))
11613    (clobber (reg:CC FLAGS_REG))]
11614   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11615   "bts{q}\t{%1, %0|%0, %1}"
11616   [(set_attr "type" "alu1")
11617    (set_attr "prefix_0f" "1")
11618    (set_attr "znver1_decode" "double")
11619    (set_attr "mode" "DI")])
11621 (define_insn "*btrq_imm"
11622   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11623                          (const_int 1)
11624                          (match_operand 1 "const_0_to_63_operand" "J"))
11625         (const_int 0))
11626    (clobber (reg:CC FLAGS_REG))]
11627   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11628   "btr{q}\t{%1, %0|%0, %1}"
11629   [(set_attr "type" "alu1")
11630    (set_attr "prefix_0f" "1")
11631    (set_attr "znver1_decode" "double")
11632    (set_attr "mode" "DI")])
11634 (define_insn "*btcq_imm"
11635   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11636                          (const_int 1)
11637                          (match_operand 1 "const_0_to_63_operand" "J"))
11638         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11639    (clobber (reg:CC FLAGS_REG))]
11640   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11641   "btc{q}\t{%1, %0|%0, %1}"
11642   [(set_attr "type" "alu1")
11643    (set_attr "prefix_0f" "1")
11644    (set_attr "znver1_decode" "double")
11645    (set_attr "mode" "DI")])
11647 ;; Allow Nocona to avoid these instructions if a register is available.
11649 (define_peephole2
11650   [(match_scratch:DI 2 "r")
11651    (parallel [(set (zero_extract:DI
11652                      (match_operand:DI 0 "nonimmediate_operand")
11653                      (const_int 1)
11654                      (match_operand 1 "const_0_to_63_operand"))
11655                    (const_int 1))
11656               (clobber (reg:CC FLAGS_REG))])]
11657   "TARGET_64BIT && !TARGET_USE_BT"
11658   [(parallel [(set (match_dup 0)
11659                    (ior:DI (match_dup 0) (match_dup 3)))
11660               (clobber (reg:CC FLAGS_REG))])]
11662   int i = INTVAL (operands[1]);
11664   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11666   if (!x86_64_immediate_operand (operands[3], DImode))
11667     {
11668       emit_move_insn (operands[2], operands[3]);
11669       operands[3] = operands[2];
11670     }
11673 (define_peephole2
11674   [(match_scratch:DI 2 "r")
11675    (parallel [(set (zero_extract:DI
11676                      (match_operand:DI 0 "nonimmediate_operand")
11677                      (const_int 1)
11678                      (match_operand 1 "const_0_to_63_operand"))
11679                    (const_int 0))
11680               (clobber (reg:CC FLAGS_REG))])]
11681   "TARGET_64BIT && !TARGET_USE_BT"
11682   [(parallel [(set (match_dup 0)
11683                    (and:DI (match_dup 0) (match_dup 3)))
11684               (clobber (reg:CC FLAGS_REG))])]
11686   int i = INTVAL (operands[1]);
11688   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11690   if (!x86_64_immediate_operand (operands[3], DImode))
11691     {
11692       emit_move_insn (operands[2], operands[3]);
11693       operands[3] = operands[2];
11694     }
11697 (define_peephole2
11698   [(match_scratch:DI 2 "r")
11699    (parallel [(set (zero_extract:DI
11700                      (match_operand:DI 0 "nonimmediate_operand")
11701                      (const_int 1)
11702                      (match_operand 1 "const_0_to_63_operand"))
11703               (not:DI (zero_extract:DI
11704                         (match_dup 0) (const_int 1) (match_dup 1))))
11705               (clobber (reg:CC FLAGS_REG))])]
11706   "TARGET_64BIT && !TARGET_USE_BT"
11707   [(parallel [(set (match_dup 0)
11708                    (xor:DI (match_dup 0) (match_dup 3)))
11709               (clobber (reg:CC FLAGS_REG))])]
11711   int i = INTVAL (operands[1]);
11713   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11715   if (!x86_64_immediate_operand (operands[3], DImode))
11716     {
11717       emit_move_insn (operands[2], operands[3]);
11718       operands[3] = operands[2];
11719     }
11722 ;; %%% bt
11724 (define_insn "*bt<mode>"
11725   [(set (reg:CCC FLAGS_REG)
11726         (compare:CCC
11727           (zero_extract:SWI48
11728             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11729             (const_int 1)
11730             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11731           (const_int 0)))]
11732   ""
11734   switch (get_attr_mode (insn))
11735     {
11736     case MODE_SI:
11737       return "bt{l}\t{%1, %k0|%k0, %1}";
11739     case MODE_DI:
11740       return "bt{q}\t{%q1, %0|%0, %q1}";
11742     default:
11743       gcc_unreachable ();
11744     }
11746   [(set_attr "type" "alu1")
11747    (set_attr "prefix_0f" "1")
11748    (set (attr "mode")
11749         (if_then_else
11750           (and (match_test "CONST_INT_P (operands[1])")
11751                (match_test "INTVAL (operands[1]) < 32"))
11752           (const_string "SI")
11753           (const_string "<MODE>")))])
11755 (define_insn_and_split "*jcc_bt<mode>"
11756   [(set (pc)
11757         (if_then_else (match_operator 0 "bt_comparison_operator"
11758                         [(zero_extract:SWI48
11759                            (match_operand:SWI48 1 "nonimmediate_operand")
11760                            (const_int 1)
11761                            (match_operand:SI 2 "nonmemory_operand"))
11762                          (const_int 0)])
11763                       (label_ref (match_operand 3))
11764                       (pc)))
11765    (clobber (reg:CC FLAGS_REG))]
11766   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11767    && (CONST_INT_P (operands[2])
11768        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11769           && INTVAL (operands[2])
11770                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11771        : !memory_operand (operands[1], <MODE>mode))
11772    && can_create_pseudo_p ()"
11773   "#"
11774   "&& 1"
11775   [(set (reg:CCC FLAGS_REG)
11776         (compare:CCC
11777           (zero_extract:SWI48
11778             (match_dup 1)
11779             (const_int 1)
11780             (match_dup 2))
11781           (const_int 0)))
11782    (set (pc)
11783         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11784                       (label_ref (match_dup 3))
11785                       (pc)))]
11787   operands[0] = shallow_copy_rtx (operands[0]);
11788   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11791 (define_insn_and_split "*jcc_bt<mode>_1"
11792   [(set (pc)
11793         (if_then_else (match_operator 0 "bt_comparison_operator"
11794                         [(zero_extract:SWI48
11795                            (match_operand:SWI48 1 "register_operand")
11796                            (const_int 1)
11797                            (zero_extend:SI
11798                              (match_operand:QI 2 "register_operand")))
11799                          (const_int 0)])
11800                       (label_ref (match_operand 3))
11801                       (pc)))
11802    (clobber (reg:CC FLAGS_REG))]
11803   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11804    && can_create_pseudo_p ()"
11805   "#"
11806   "&& 1"
11807   [(set (reg:CCC FLAGS_REG)
11808         (compare:CCC
11809           (zero_extract:SWI48
11810             (match_dup 1)
11811             (const_int 1)
11812             (match_dup 2))
11813           (const_int 0)))
11814    (set (pc)
11815         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11816                       (label_ref (match_dup 3))
11817                       (pc)))]
11819   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11820   operands[0] = shallow_copy_rtx (operands[0]);
11821   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11824 ;; Avoid useless masking of bit offset operand.
11825 (define_insn_and_split "*jcc_bt<mode>_mask"
11826   [(set (pc)
11827         (if_then_else (match_operator 0 "bt_comparison_operator"
11828                         [(zero_extract:SWI48
11829                            (match_operand:SWI48 1 "register_operand")
11830                            (const_int 1)
11831                            (and:SI
11832                              (match_operand:SI 2 "register_operand")
11833                              (match_operand 3 "const_int_operand")))])
11834                       (label_ref (match_operand 4))
11835                       (pc)))
11836    (clobber (reg:CC FLAGS_REG))]
11837   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11838    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11839       == GET_MODE_BITSIZE (<MODE>mode)-1
11840    && can_create_pseudo_p ()"
11841   "#"
11842   "&& 1"
11843   [(set (reg:CCC FLAGS_REG)
11844         (compare:CCC
11845           (zero_extract:SWI48
11846             (match_dup 1)
11847             (const_int 1)
11848             (match_dup 2))
11849           (const_int 0)))
11850    (set (pc)
11851         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11852                       (label_ref (match_dup 4))
11853                       (pc)))]
11855   operands[0] = shallow_copy_rtx (operands[0]);
11856   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11859 ;; Store-flag instructions.
11861 ;; For all sCOND expanders, also expand the compare or test insn that
11862 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11864 (define_insn_and_split "*setcc_di_1"
11865   [(set (match_operand:DI 0 "register_operand" "=q")
11866         (match_operator:DI 1 "ix86_comparison_operator"
11867           [(reg FLAGS_REG) (const_int 0)]))]
11868   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11869   "#"
11870   "&& reload_completed"
11871   [(set (match_dup 2) (match_dup 1))
11872    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11874   operands[1] = shallow_copy_rtx (operands[1]);
11875   PUT_MODE (operands[1], QImode);
11876   operands[2] = gen_lowpart (QImode, operands[0]);
11879 (define_insn_and_split "*setcc_si_1_and"
11880   [(set (match_operand:SI 0 "register_operand" "=q")
11881         (match_operator:SI 1 "ix86_comparison_operator"
11882           [(reg FLAGS_REG) (const_int 0)]))
11883    (clobber (reg:CC FLAGS_REG))]
11884   "!TARGET_PARTIAL_REG_STALL
11885    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11886   "#"
11887   "&& reload_completed"
11888   [(set (match_dup 2) (match_dup 1))
11889    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11890               (clobber (reg:CC FLAGS_REG))])]
11892   operands[1] = shallow_copy_rtx (operands[1]);
11893   PUT_MODE (operands[1], QImode);
11894   operands[2] = gen_lowpart (QImode, operands[0]);
11897 (define_insn_and_split "*setcc_si_1_movzbl"
11898   [(set (match_operand:SI 0 "register_operand" "=q")
11899         (match_operator:SI 1 "ix86_comparison_operator"
11900           [(reg FLAGS_REG) (const_int 0)]))]
11901   "!TARGET_PARTIAL_REG_STALL
11902    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11903   "#"
11904   "&& reload_completed"
11905   [(set (match_dup 2) (match_dup 1))
11906    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11908   operands[1] = shallow_copy_rtx (operands[1]);
11909   PUT_MODE (operands[1], QImode);
11910   operands[2] = gen_lowpart (QImode, operands[0]);
11913 (define_insn "*setcc_qi"
11914   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11915         (match_operator:QI 1 "ix86_comparison_operator"
11916           [(reg FLAGS_REG) (const_int 0)]))]
11917   ""
11918   "set%C1\t%0"
11919   [(set_attr "type" "setcc")
11920    (set_attr "mode" "QI")])
11922 (define_insn "*setcc_qi_slp"
11923   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11924         (match_operator:QI 1 "ix86_comparison_operator"
11925           [(reg FLAGS_REG) (const_int 0)]))]
11926   ""
11927   "set%C1\t%0"
11928   [(set_attr "type" "setcc")
11929    (set_attr "mode" "QI")])
11931 ;; In general it is not safe to assume too much about CCmode registers,
11932 ;; so simplify-rtx stops when it sees a second one.  Under certain
11933 ;; conditions this is safe on x86, so help combine not create
11935 ;;      seta    %al
11936 ;;      testb   %al, %al
11937 ;;      sete    %al
11939 (define_split
11940   [(set (match_operand:QI 0 "nonimmediate_operand")
11941         (ne:QI (match_operator 1 "ix86_comparison_operator"
11942                  [(reg FLAGS_REG) (const_int 0)])
11943             (const_int 0)))]
11944   ""
11945   [(set (match_dup 0) (match_dup 1))]
11947   operands[1] = shallow_copy_rtx (operands[1]);
11948   PUT_MODE (operands[1], QImode);
11951 (define_split
11952   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11953         (ne:QI (match_operator 1 "ix86_comparison_operator"
11954                  [(reg FLAGS_REG) (const_int 0)])
11955             (const_int 0)))]
11956   ""
11957   [(set (match_dup 0) (match_dup 1))]
11959   operands[1] = shallow_copy_rtx (operands[1]);
11960   PUT_MODE (operands[1], QImode);
11963 (define_split
11964   [(set (match_operand:QI 0 "nonimmediate_operand")
11965         (eq:QI (match_operator 1 "ix86_comparison_operator"
11966                  [(reg FLAGS_REG) (const_int 0)])
11967             (const_int 0)))]
11968   ""
11969   [(set (match_dup 0) (match_dup 1))]
11971   operands[1] = shallow_copy_rtx (operands[1]);
11972   PUT_MODE (operands[1], QImode);
11973   PUT_CODE (operands[1],
11974             ix86_reverse_condition (GET_CODE (operands[1]),
11975                                     GET_MODE (XEXP (operands[1], 0))));
11977   /* Make sure that (a) the CCmode we have for the flags is strong
11978      enough for the reversed compare or (b) we have a valid FP compare.  */
11979   if (! ix86_comparison_operator (operands[1], VOIDmode))
11980     FAIL;
11983 (define_split
11984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11985         (eq:QI (match_operator 1 "ix86_comparison_operator"
11986                  [(reg FLAGS_REG) (const_int 0)])
11987             (const_int 0)))]
11988   ""
11989   [(set (match_dup 0) (match_dup 1))]
11991   operands[1] = shallow_copy_rtx (operands[1]);
11992   PUT_MODE (operands[1], QImode);
11993   PUT_CODE (operands[1],
11994             ix86_reverse_condition (GET_CODE (operands[1]),
11995                                     GET_MODE (XEXP (operands[1], 0))));
11997   /* Make sure that (a) the CCmode we have for the flags is strong
11998      enough for the reversed compare or (b) we have a valid FP compare.  */
11999   if (! ix86_comparison_operator (operands[1], VOIDmode))
12000     FAIL;
12003 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12004 ;; subsequent logical operations are used to imitate conditional moves.
12005 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12006 ;; it directly.
12008 (define_insn "setcc_<mode>_sse"
12009   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12010         (match_operator:MODEF 3 "sse_comparison_operator"
12011           [(match_operand:MODEF 1 "register_operand" "0,x")
12012            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12013   "SSE_FLOAT_MODE_P (<MODE>mode)"
12014   "@
12015    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12016    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12017   [(set_attr "isa" "noavx,avx")
12018    (set_attr "type" "ssecmp")
12019    (set_attr "length_immediate" "1")
12020    (set_attr "prefix" "orig,vex")
12021    (set_attr "mode" "<MODE>")])
12023 ;; Basic conditional jump instructions.
12024 ;; We ignore the overflow flag for signed branch instructions.
12026 (define_insn "*jcc"
12027   [(set (pc)
12028         (if_then_else (match_operator 1 "ix86_comparison_operator"
12029                                       [(reg FLAGS_REG) (const_int 0)])
12030                       (label_ref (match_operand 0))
12031                       (pc)))]
12032   ""
12033   "%!%+j%C1\t%l0"
12034   [(set_attr "type" "ibr")
12035    (set_attr "modrm" "0")
12036    (set (attr "length")
12037         (if_then_else
12038           (and (ge (minus (match_dup 0) (pc))
12039                    (const_int -126))
12040                (lt (minus (match_dup 0) (pc))
12041                    (const_int 128)))
12042           (const_int 2)
12043           (const_int 6)))])
12045 ;; In general it is not safe to assume too much about CCmode registers,
12046 ;; so simplify-rtx stops when it sees a second one.  Under certain
12047 ;; conditions this is safe on x86, so help combine not create
12049 ;;      seta    %al
12050 ;;      testb   %al, %al
12051 ;;      je      Lfoo
12053 (define_split
12054   [(set (pc)
12055         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12056                                       [(reg FLAGS_REG) (const_int 0)])
12057                           (const_int 0))
12058                       (label_ref (match_operand 1))
12059                       (pc)))]
12060   ""
12061   [(set (pc)
12062         (if_then_else (match_dup 0)
12063                       (label_ref (match_dup 1))
12064                       (pc)))]
12066   operands[0] = shallow_copy_rtx (operands[0]);
12067   PUT_MODE (operands[0], VOIDmode);
12070 (define_split
12071   [(set (pc)
12072         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12073                                       [(reg FLAGS_REG) (const_int 0)])
12074                           (const_int 0))
12075                       (label_ref (match_operand 1))
12076                       (pc)))]
12077   ""
12078   [(set (pc)
12079         (if_then_else (match_dup 0)
12080                       (label_ref (match_dup 1))
12081                       (pc)))]
12083   operands[0] = shallow_copy_rtx (operands[0]);
12084   PUT_MODE (operands[0], VOIDmode);
12085   PUT_CODE (operands[0],
12086             ix86_reverse_condition (GET_CODE (operands[0]),
12087                                     GET_MODE (XEXP (operands[0], 0))));
12089   /* Make sure that (a) the CCmode we have for the flags is strong
12090      enough for the reversed compare or (b) we have a valid FP compare.  */
12091   if (! ix86_comparison_operator (operands[0], VOIDmode))
12092     FAIL;
12095 ;; Unconditional and other jump instructions
12097 (define_insn "jump"
12098   [(set (pc)
12099         (label_ref (match_operand 0)))]
12100   ""
12101   "%!jmp\t%l0"
12102   [(set_attr "type" "ibr")
12103    (set_attr "modrm" "0")
12104    (set (attr "length")
12105         (if_then_else
12106           (and (ge (minus (match_dup 0) (pc))
12107                    (const_int -126))
12108                (lt (minus (match_dup 0) (pc))
12109                    (const_int 128)))
12110           (const_int 2)
12111           (const_int 5)))])
12113 (define_expand "indirect_jump"
12114   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12115   ""
12117   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12118     operands[0] = convert_memory_address (word_mode, operands[0]);
12119   cfun->machine->has_local_indirect_jump = true;
12122 (define_insn "*indirect_jump"
12123   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12124   ""
12125   "* return ix86_output_indirect_jmp (operands[0]);"
12126   [(set (attr "type")
12127      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12128                                  != indirect_branch_keep)")
12129         (const_string "multi")
12130         (const_string "ibr")))
12131    (set_attr "length_immediate" "0")])
12133 (define_expand "tablejump"
12134   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12135               (use (label_ref (match_operand 1)))])]
12136   ""
12138   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12139      relative.  Convert the relative address to an absolute address.  */
12140   if (flag_pic)
12141     {
12142       rtx op0, op1;
12143       enum rtx_code code;
12145       /* We can't use @GOTOFF for text labels on VxWorks;
12146          see gotoff_operand.  */
12147       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12148         {
12149           code = PLUS;
12150           op0 = operands[0];
12151           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12152         }
12153       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12154         {
12155           code = PLUS;
12156           op0 = operands[0];
12157           op1 = pic_offset_table_rtx;
12158         }
12159       else
12160         {
12161           code = MINUS;
12162           op0 = pic_offset_table_rtx;
12163           op1 = operands[0];
12164         }
12166       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12167                                          OPTAB_DIRECT);
12168     }
12170   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12171     operands[0] = convert_memory_address (word_mode, operands[0]);
12172   cfun->machine->has_local_indirect_jump = true;
12175 (define_insn "*tablejump_1"
12176   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12177    (use (label_ref (match_operand 1)))]
12178   ""
12179   "* return ix86_output_indirect_jmp (operands[0]);"
12180   [(set (attr "type")
12181      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12182                                  != indirect_branch_keep)")
12183         (const_string "multi")
12184         (const_string "ibr")))
12185    (set_attr "length_immediate" "0")])
12187 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12189 (define_peephole2
12190   [(set (reg FLAGS_REG) (match_operand 0))
12191    (set (match_operand:QI 1 "register_operand")
12192         (match_operator:QI 2 "ix86_comparison_operator"
12193           [(reg FLAGS_REG) (const_int 0)]))
12194    (set (match_operand 3 "any_QIreg_operand")
12195         (zero_extend (match_dup 1)))]
12196   "(peep2_reg_dead_p (3, operands[1])
12197     || operands_match_p (operands[1], operands[3]))
12198    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12199    && peep2_regno_dead_p (0, FLAGS_REG)"
12200   [(set (match_dup 4) (match_dup 0))
12201    (set (strict_low_part (match_dup 5))
12202         (match_dup 2))]
12204   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12205   operands[5] = gen_lowpart (QImode, operands[3]);
12206   ix86_expand_clear (operands[3]);
12209 (define_peephole2
12210   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12211               (match_operand 4)])
12212    (set (match_operand:QI 1 "register_operand")
12213         (match_operator:QI 2 "ix86_comparison_operator"
12214           [(reg FLAGS_REG) (const_int 0)]))
12215    (set (match_operand 3 "any_QIreg_operand")
12216         (zero_extend (match_dup 1)))]
12217   "(peep2_reg_dead_p (3, operands[1])
12218     || operands_match_p (operands[1], operands[3]))
12219    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12220    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12221    && ! reg_set_p (operands[3], operands[4])
12222    && peep2_regno_dead_p (0, FLAGS_REG)"
12223   [(parallel [(set (match_dup 5) (match_dup 0))
12224               (match_dup 4)])
12225    (set (strict_low_part (match_dup 6))
12226         (match_dup 2))]
12228   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12229   operands[6] = gen_lowpart (QImode, operands[3]);
12230   ix86_expand_clear (operands[3]);
12233 (define_peephole2
12234   [(set (reg FLAGS_REG) (match_operand 0))
12235    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12236               (match_operand 5)])
12237    (set (match_operand:QI 2 "register_operand")
12238         (match_operator:QI 3 "ix86_comparison_operator"
12239           [(reg FLAGS_REG) (const_int 0)]))
12240    (set (match_operand 4 "any_QIreg_operand")
12241         (zero_extend (match_dup 2)))]
12242   "(peep2_reg_dead_p (4, operands[2])
12243     || operands_match_p (operands[2], operands[4]))
12244    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12245    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12246    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12247    && ! reg_set_p (operands[4], operands[5])
12248    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12249    && peep2_regno_dead_p (0, FLAGS_REG)"
12250   [(set (match_dup 6) (match_dup 0))
12251    (parallel [(set (match_dup 7) (match_dup 1))
12252               (match_dup 5)])
12253    (set (strict_low_part (match_dup 8))
12254         (match_dup 3))]
12256   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12257   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12258   operands[8] = gen_lowpart (QImode, operands[4]);
12259   ix86_expand_clear (operands[4]);
12262 ;; Similar, but match zero extend with andsi3.
12264 (define_peephole2
12265   [(set (reg FLAGS_REG) (match_operand 0))
12266    (set (match_operand:QI 1 "register_operand")
12267         (match_operator:QI 2 "ix86_comparison_operator"
12268           [(reg FLAGS_REG) (const_int 0)]))
12269    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12270                    (and:SI (match_dup 3) (const_int 255)))
12271               (clobber (reg:CC FLAGS_REG))])]
12272   "REGNO (operands[1]) == REGNO (operands[3])
12273    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12274    && peep2_regno_dead_p (0, FLAGS_REG)"
12275   [(set (match_dup 4) (match_dup 0))
12276    (set (strict_low_part (match_dup 5))
12277         (match_dup 2))]
12279   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12280   operands[5] = gen_lowpart (QImode, operands[3]);
12281   ix86_expand_clear (operands[3]);
12284 (define_peephole2
12285   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12286               (match_operand 4)])
12287    (set (match_operand:QI 1 "register_operand")
12288         (match_operator:QI 2 "ix86_comparison_operator"
12289           [(reg FLAGS_REG) (const_int 0)]))
12290    (parallel [(set (match_operand 3 "any_QIreg_operand")
12291                    (zero_extend (match_dup 1)))
12292               (clobber (reg:CC FLAGS_REG))])]
12293   "(peep2_reg_dead_p (3, operands[1])
12294     || operands_match_p (operands[1], operands[3]))
12295    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12296    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12297    && ! reg_set_p (operands[3], operands[4])
12298    && peep2_regno_dead_p (0, FLAGS_REG)"
12299   [(parallel [(set (match_dup 5) (match_dup 0))
12300               (match_dup 4)])
12301    (set (strict_low_part (match_dup 6))
12302         (match_dup 2))]
12304   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12305   operands[6] = gen_lowpart (QImode, operands[3]);
12306   ix86_expand_clear (operands[3]);
12309 (define_peephole2
12310   [(set (reg FLAGS_REG) (match_operand 0))
12311    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12312               (match_operand 5)])
12313    (set (match_operand:QI 2 "register_operand")
12314         (match_operator:QI 3 "ix86_comparison_operator"
12315           [(reg FLAGS_REG) (const_int 0)]))
12316    (parallel [(set (match_operand 4 "any_QIreg_operand")
12317                    (zero_extend (match_dup 2)))
12318               (clobber (reg:CC FLAGS_REG))])]
12319   "(peep2_reg_dead_p (4, operands[2])
12320     || operands_match_p (operands[2], operands[4]))
12321    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12322    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12323    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12324    && ! reg_set_p (operands[4], operands[5])
12325    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12326    && peep2_regno_dead_p (0, FLAGS_REG)"
12327   [(set (match_dup 6) (match_dup 0))
12328    (parallel [(set (match_dup 7) (match_dup 1))
12329               (match_dup 5)])
12330    (set (strict_low_part (match_dup 8))
12331         (match_dup 3))]
12333   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12334   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12335   operands[8] = gen_lowpart (QImode, operands[4]);
12336   ix86_expand_clear (operands[4]);
12339 ;; Call instructions.
12341 ;; The predicates normally associated with named expanders are not properly
12342 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12343 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12345 ;; P6 processors will jump to the address after the decrement when %esp
12346 ;; is used as a call operand, so they will execute return address as a code.
12347 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12349 ;; Register constraint for call instruction.
12350 (define_mode_attr c [(SI "l") (DI "r")])
12352 ;; Call subroutine returning no value.
12354 (define_expand "call"
12355   [(call (match_operand:QI 0)
12356          (match_operand 1))
12357    (use (match_operand 2))]
12358   ""
12360   ix86_expand_call (NULL, operands[0], operands[1],
12361                     operands[2], NULL, false);
12362   DONE;
12365 (define_expand "sibcall"
12366   [(call (match_operand:QI 0)
12367          (match_operand 1))
12368    (use (match_operand 2))]
12369   ""
12371   ix86_expand_call (NULL, operands[0], operands[1],
12372                     operands[2], NULL, true);
12373   DONE;
12376 (define_insn "*call"
12377   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12378          (match_operand 1))]
12379   "!SIBLING_CALL_P (insn)"
12380   "* return ix86_output_call_insn (insn, operands[0]);"
12381   [(set_attr "type" "call")])
12383 ;; This covers both call and sibcall since only GOT slot is allowed.
12384 (define_insn "*call_got_x32"
12385   [(call (mem:QI (zero_extend:DI
12386                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12387          (match_operand 1))]
12388   "TARGET_X32"
12390   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12391   return ix86_output_call_insn (insn, fnaddr);
12393   [(set_attr "type" "call")])
12395 ;; Since sibcall never returns, we can only use call-clobbered register
12396 ;; as GOT base.
12397 (define_insn "*sibcall_GOT_32"
12398   [(call (mem:QI
12399            (mem:SI (plus:SI
12400                      (match_operand:SI 0 "register_no_elim_operand" "U")
12401                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12402          (match_operand 2))]
12403   "!TARGET_MACHO
12404   && !TARGET_64BIT
12405   && !TARGET_INDIRECT_BRANCH_REGISTER
12406   && SIBLING_CALL_P (insn)"
12408   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12409   fnaddr = gen_const_mem (SImode, fnaddr);
12410   return ix86_output_call_insn (insn, fnaddr);
12412   [(set_attr "type" "call")])
12414 (define_insn "*sibcall"
12415   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12416          (match_operand 1))]
12417   "SIBLING_CALL_P (insn)"
12418   "* return ix86_output_call_insn (insn, operands[0]);"
12419   [(set_attr "type" "call")])
12421 (define_insn "*sibcall_memory"
12422   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12423          (match_operand 1))
12424    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12425   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12426   "* return ix86_output_call_insn (insn, operands[0]);"
12427   [(set_attr "type" "call")])
12429 (define_peephole2
12430   [(set (match_operand:W 0 "register_operand")
12431         (match_operand:W 1 "memory_operand"))
12432    (call (mem:QI (match_dup 0))
12433          (match_operand 3))]
12434   "!TARGET_X32
12435    && !TARGET_INDIRECT_BRANCH_REGISTER
12436    && SIBLING_CALL_P (peep2_next_insn (1))
12437    && !reg_mentioned_p (operands[0],
12438                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12439   [(parallel [(call (mem:QI (match_dup 1))
12440                     (match_dup 3))
12441               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12443 (define_peephole2
12444   [(set (match_operand:W 0 "register_operand")
12445         (match_operand:W 1 "memory_operand"))
12446    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12447    (call (mem:QI (match_dup 0))
12448          (match_operand 3))]
12449   "!TARGET_X32
12450    && !TARGET_INDIRECT_BRANCH_REGISTER
12451    && SIBLING_CALL_P (peep2_next_insn (2))
12452    && !reg_mentioned_p (operands[0],
12453                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12454   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12455    (parallel [(call (mem:QI (match_dup 1))
12456                     (match_dup 3))
12457               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12459 (define_expand "call_pop"
12460   [(parallel [(call (match_operand:QI 0)
12461                     (match_operand:SI 1))
12462               (set (reg:SI SP_REG)
12463                    (plus:SI (reg:SI SP_REG)
12464                             (match_operand:SI 3)))])]
12465   "!TARGET_64BIT"
12467   ix86_expand_call (NULL, operands[0], operands[1],
12468                     operands[2], operands[3], false);
12469   DONE;
12472 (define_insn "*call_pop"
12473   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12474          (match_operand 1))
12475    (set (reg:SI SP_REG)
12476         (plus:SI (reg:SI SP_REG)
12477                  (match_operand:SI 2 "immediate_operand" "i")))]
12478   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12479   "* return ix86_output_call_insn (insn, operands[0]);"
12480   [(set_attr "type" "call")])
12482 (define_insn "*sibcall_pop"
12483   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12484          (match_operand 1))
12485    (set (reg:SI SP_REG)
12486         (plus:SI (reg:SI SP_REG)
12487                  (match_operand:SI 2 "immediate_operand" "i")))]
12488   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12489   "* return ix86_output_call_insn (insn, operands[0]);"
12490   [(set_attr "type" "call")])
12492 (define_insn "*sibcall_pop_memory"
12493   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12494          (match_operand 1))
12495    (set (reg:SI SP_REG)
12496         (plus:SI (reg:SI SP_REG)
12497                  (match_operand:SI 2 "immediate_operand" "i")))
12498    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12499   "!TARGET_64BIT"
12500   "* return ix86_output_call_insn (insn, operands[0]);"
12501   [(set_attr "type" "call")])
12503 (define_peephole2
12504   [(set (match_operand:SI 0 "register_operand")
12505         (match_operand:SI 1 "memory_operand"))
12506    (parallel [(call (mem:QI (match_dup 0))
12507                     (match_operand 3))
12508               (set (reg:SI SP_REG)
12509                    (plus:SI (reg:SI SP_REG)
12510                             (match_operand:SI 4 "immediate_operand")))])]
12511   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12512    && !reg_mentioned_p (operands[0],
12513                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12514   [(parallel [(call (mem:QI (match_dup 1))
12515                     (match_dup 3))
12516               (set (reg:SI SP_REG)
12517                    (plus:SI (reg:SI SP_REG)
12518                             (match_dup 4)))
12519               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12521 (define_peephole2
12522   [(set (match_operand:SI 0 "register_operand")
12523         (match_operand:SI 1 "memory_operand"))
12524    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12525    (parallel [(call (mem:QI (match_dup 0))
12526                     (match_operand 3))
12527               (set (reg:SI SP_REG)
12528                    (plus:SI (reg:SI SP_REG)
12529                             (match_operand:SI 4 "immediate_operand")))])]
12530   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12531    && !reg_mentioned_p (operands[0],
12532                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12533   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12534    (parallel [(call (mem:QI (match_dup 1))
12535                     (match_dup 3))
12536               (set (reg:SI SP_REG)
12537                    (plus:SI (reg:SI SP_REG)
12538                             (match_dup 4)))
12539               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12541 ;; Combining simple memory jump instruction
12543 (define_peephole2
12544   [(set (match_operand:W 0 "register_operand")
12545         (match_operand:W 1 "memory_operand"))
12546    (set (pc) (match_dup 0))]
12547   "!TARGET_X32
12548    && !TARGET_INDIRECT_BRANCH_REGISTER
12549    && peep2_reg_dead_p (2, operands[0])"
12550   [(set (pc) (match_dup 1))])
12552 ;; Call subroutine, returning value in operand 0
12554 (define_expand "call_value"
12555   [(set (match_operand 0)
12556         (call (match_operand:QI 1)
12557               (match_operand 2)))
12558    (use (match_operand 3))]
12559   ""
12561   ix86_expand_call (operands[0], operands[1], operands[2],
12562                     operands[3], NULL, false);
12563   DONE;
12566 (define_expand "sibcall_value"
12567   [(set (match_operand 0)
12568         (call (match_operand:QI 1)
12569               (match_operand 2)))
12570    (use (match_operand 3))]
12571   ""
12573   ix86_expand_call (operands[0], operands[1], operands[2],
12574                     operands[3], NULL, true);
12575   DONE;
12578 (define_insn "*call_value"
12579   [(set (match_operand 0)
12580         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12581               (match_operand 2)))]
12582   "!SIBLING_CALL_P (insn)"
12583   "* return ix86_output_call_insn (insn, operands[1]);"
12584   [(set_attr "type" "callv")])
12586 ;; This covers both call and sibcall since only GOT slot is allowed.
12587 (define_insn "*call_value_got_x32"
12588   [(set (match_operand 0)
12589         (call (mem:QI
12590                 (zero_extend:DI
12591                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12592               (match_operand 2)))]
12593   "TARGET_X32"
12595   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12596   return ix86_output_call_insn (insn, fnaddr);
12598   [(set_attr "type" "callv")])
12600 ;; Since sibcall never returns, we can only use call-clobbered register
12601 ;; as GOT base.
12602 (define_insn "*sibcall_value_GOT_32"
12603   [(set (match_operand 0)
12604         (call (mem:QI
12605                 (mem:SI (plus:SI
12606                           (match_operand:SI 1 "register_no_elim_operand" "U")
12607                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12608          (match_operand 3)))]
12609   "!TARGET_MACHO
12610    && !TARGET_64BIT
12611    && !TARGET_INDIRECT_BRANCH_REGISTER
12612    && SIBLING_CALL_P (insn)"
12614   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12615   fnaddr = gen_const_mem (SImode, fnaddr);
12616   return ix86_output_call_insn (insn, fnaddr);
12618   [(set_attr "type" "callv")])
12620 (define_insn "*sibcall_value"
12621   [(set (match_operand 0)
12622         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12623               (match_operand 2)))]
12624   "SIBLING_CALL_P (insn)"
12625   "* return ix86_output_call_insn (insn, operands[1]);"
12626   [(set_attr "type" "callv")])
12628 (define_insn "*sibcall_value_memory"
12629   [(set (match_operand 0)
12630         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12631               (match_operand 2)))
12632    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12633   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12634   "* return ix86_output_call_insn (insn, operands[1]);"
12635   [(set_attr "type" "callv")])
12637 (define_peephole2
12638   [(set (match_operand:W 0 "register_operand")
12639         (match_operand:W 1 "memory_operand"))
12640    (set (match_operand 2)
12641    (call (mem:QI (match_dup 0))
12642                  (match_operand 3)))]
12643   "!TARGET_X32
12644    && !TARGET_INDIRECT_BRANCH_REGISTER
12645    && SIBLING_CALL_P (peep2_next_insn (1))
12646    && !reg_mentioned_p (operands[0],
12647                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12648   [(parallel [(set (match_dup 2)
12649                    (call (mem:QI (match_dup 1))
12650                          (match_dup 3)))
12651               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12653 (define_peephole2
12654   [(set (match_operand:W 0 "register_operand")
12655         (match_operand:W 1 "memory_operand"))
12656    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12657    (set (match_operand 2)
12658         (call (mem:QI (match_dup 0))
12659               (match_operand 3)))]
12660   "!TARGET_X32
12661    && !TARGET_INDIRECT_BRANCH_REGISTER
12662    && SIBLING_CALL_P (peep2_next_insn (2))
12663    && !reg_mentioned_p (operands[0],
12664                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12665   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12666    (parallel [(set (match_dup 2)
12667                    (call (mem:QI (match_dup 1))
12668                          (match_dup 3)))
12669               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12671 (define_expand "call_value_pop"
12672   [(parallel [(set (match_operand 0)
12673                    (call (match_operand:QI 1)
12674                          (match_operand:SI 2)))
12675               (set (reg:SI SP_REG)
12676                    (plus:SI (reg:SI SP_REG)
12677                             (match_operand:SI 4)))])]
12678   "!TARGET_64BIT"
12680   ix86_expand_call (operands[0], operands[1], operands[2],
12681                     operands[3], operands[4], false);
12682   DONE;
12685 (define_insn "*call_value_pop"
12686   [(set (match_operand 0)
12687         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12688               (match_operand 2)))
12689    (set (reg:SI SP_REG)
12690         (plus:SI (reg:SI SP_REG)
12691                  (match_operand:SI 3 "immediate_operand" "i")))]
12692   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12693   "* return ix86_output_call_insn (insn, operands[1]);"
12694   [(set_attr "type" "callv")])
12696 (define_insn "*sibcall_value_pop"
12697   [(set (match_operand 0)
12698         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12699               (match_operand 2)))
12700    (set (reg:SI SP_REG)
12701         (plus:SI (reg:SI SP_REG)
12702                  (match_operand:SI 3 "immediate_operand" "i")))]
12703   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12704   "* return ix86_output_call_insn (insn, operands[1]);"
12705   [(set_attr "type" "callv")])
12707 (define_insn "*sibcall_value_pop_memory"
12708   [(set (match_operand 0)
12709         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12710               (match_operand 2)))
12711    (set (reg:SI SP_REG)
12712         (plus:SI (reg:SI SP_REG)
12713                  (match_operand:SI 3 "immediate_operand" "i")))
12714    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12715   "!TARGET_64BIT"
12716   "* return ix86_output_call_insn (insn, operands[1]);"
12717   [(set_attr "type" "callv")])
12719 (define_peephole2
12720   [(set (match_operand:SI 0 "register_operand")
12721         (match_operand:SI 1 "memory_operand"))
12722    (parallel [(set (match_operand 2)
12723                    (call (mem:QI (match_dup 0))
12724                          (match_operand 3)))
12725               (set (reg:SI SP_REG)
12726                    (plus:SI (reg:SI SP_REG)
12727                             (match_operand:SI 4 "immediate_operand")))])]
12728   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12729    && !reg_mentioned_p (operands[0],
12730                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12731   [(parallel [(set (match_dup 2)
12732                    (call (mem:QI (match_dup 1))
12733                          (match_dup 3)))
12734               (set (reg:SI SP_REG)
12735                    (plus:SI (reg:SI SP_REG)
12736                             (match_dup 4)))
12737               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12739 (define_peephole2
12740   [(set (match_operand:SI 0 "register_operand")
12741         (match_operand:SI 1 "memory_operand"))
12742    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12743    (parallel [(set (match_operand 2)
12744                    (call (mem:QI (match_dup 0))
12745                          (match_operand 3)))
12746               (set (reg:SI SP_REG)
12747                    (plus:SI (reg:SI SP_REG)
12748                             (match_operand:SI 4 "immediate_operand")))])]
12749   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12750    && !reg_mentioned_p (operands[0],
12751                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12752   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12753    (parallel [(set (match_dup 2)
12754                    (call (mem:QI (match_dup 1))
12755                          (match_dup 3)))
12756               (set (reg:SI SP_REG)
12757                    (plus:SI (reg:SI SP_REG)
12758                             (match_dup 4)))
12759               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12761 ;; Call subroutine returning any type.
12763 (define_expand "untyped_call"
12764   [(parallel [(call (match_operand 0)
12765                     (const_int 0))
12766               (match_operand 1)
12767               (match_operand 2)])]
12768   ""
12770   int i;
12772   /* In order to give reg-stack an easier job in validating two
12773      coprocessor registers as containing a possible return value,
12774      simply pretend the untyped call returns a complex long double
12775      value. 
12777      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12778      and should have the default ABI.  */
12780   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12781                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12782                     operands[0], const0_rtx,
12783                     GEN_INT ((TARGET_64BIT
12784                               ? (ix86_abi == SYSV_ABI
12785                                  ? X86_64_SSE_REGPARM_MAX
12786                                  : X86_64_MS_SSE_REGPARM_MAX)
12787                               : X86_32_SSE_REGPARM_MAX)
12788                              - 1),
12789                     NULL, false);
12791   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12792     {
12793       rtx set = XVECEXP (operands[2], 0, i);
12794       emit_move_insn (SET_DEST (set), SET_SRC (set));
12795     }
12797   /* The optimizer does not know that the call sets the function value
12798      registers we stored in the result block.  We avoid problems by
12799      claiming that all hard registers are used and clobbered at this
12800      point.  */
12801   emit_insn (gen_blockage ());
12803   DONE;
12806 ;; Prologue and epilogue instructions
12808 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12809 ;; all of memory.  This blocks insns from being moved across this point.
12811 (define_insn "blockage"
12812   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12813   ""
12814   ""
12815   [(set_attr "length" "0")])
12817 ;; Do not schedule instructions accessing memory across this point.
12819 (define_expand "memory_blockage"
12820   [(set (match_dup 0)
12821         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12822   ""
12824   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12825   MEM_VOLATILE_P (operands[0]) = 1;
12828 (define_insn "*memory_blockage"
12829   [(set (match_operand:BLK 0)
12830         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12831   ""
12832   ""
12833   [(set_attr "length" "0")])
12835 ;; As USE insns aren't meaningful after reload, this is used instead
12836 ;; to prevent deleting instructions setting registers for PIC code
12837 (define_insn "prologue_use"
12838   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12839   ""
12840   ""
12841   [(set_attr "length" "0")])
12843 ;; Insn emitted into the body of a function to return from a function.
12844 ;; This is only done if the function's epilogue is known to be simple.
12845 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12847 (define_expand "return"
12848   [(simple_return)]
12849   "ix86_can_use_return_insn_p ()"
12851   if (crtl->args.pops_args)
12852     {
12853       rtx popc = GEN_INT (crtl->args.pops_args);
12854       emit_jump_insn (gen_simple_return_pop_internal (popc));
12855       DONE;
12856     }
12859 ;; We need to disable this for TARGET_SEH, as otherwise
12860 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12861 ;; the maximum size of prologue in unwind information.
12862 ;; Also disallow shrink-wrapping if using stack slot to pass the
12863 ;; static chain pointer - the first instruction has to be pushl %esi
12864 ;; and it can't be moved around, as we use alternate entry points
12865 ;; in that case.
12867 (define_expand "simple_return"
12868   [(simple_return)]
12869   "!TARGET_SEH && !ix86_static_chain_on_stack"
12871   if (crtl->args.pops_args)
12872     {
12873       rtx popc = GEN_INT (crtl->args.pops_args);
12874       emit_jump_insn (gen_simple_return_pop_internal (popc));
12875       DONE;
12876     }
12879 (define_insn "simple_return_internal"
12880   [(simple_return)]
12881   "reload_completed"
12882   "* return ix86_output_function_return (false);"
12883   [(set_attr "length" "1")
12884    (set_attr "atom_unit" "jeu")
12885    (set_attr "length_immediate" "0")
12886    (set_attr "modrm" "0")])
12888 (define_insn "interrupt_return"
12889   [(simple_return)
12890    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12891   "reload_completed"
12893   return TARGET_64BIT ? "iretq" : "iret";
12896 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12897 ;; instruction Athlon and K8 have.
12899 (define_insn "simple_return_internal_long"
12900   [(simple_return)
12901    (unspec [(const_int 0)] UNSPEC_REP)]
12902   "reload_completed"
12903   "* return ix86_output_function_return (true);"
12904   [(set_attr "length" "2")
12905    (set_attr "atom_unit" "jeu")
12906    (set_attr "length_immediate" "0")
12907    (set_attr "prefix_rep" "1")
12908    (set_attr "modrm" "0")])
12910 (define_insn_and_split "simple_return_pop_internal"
12911   [(simple_return)
12912    (use (match_operand:SI 0 "const_int_operand"))]
12913   "reload_completed"
12914   "%!ret\t%0"
12915   "&& cfun->machine->function_return_type != indirect_branch_keep"
12916   [(const_int 0)]
12917   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12918   [(set_attr "length" "3")
12919    (set_attr "atom_unit" "jeu")
12920    (set_attr "length_immediate" "2")
12921    (set_attr "modrm" "0")])
12923 (define_expand "simple_return_indirect_internal"
12924   [(parallel
12925      [(simple_return)
12926       (use (match_operand 0 "register_operand"))])])
12928 (define_insn "*simple_return_indirect_internal<mode>"
12929   [(simple_return)
12930    (use (match_operand:W 0 "register_operand" "r"))]
12931   "reload_completed"
12932   "* return ix86_output_indirect_function_return (operands[0]);"
12933   [(set (attr "type")
12934      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12935                                  != indirect_branch_keep)")
12936         (const_string "multi")
12937         (const_string "ibr")))
12938    (set_attr "length_immediate" "0")])
12940 (define_insn "nop"
12941   [(const_int 0)]
12942   ""
12943   "nop"
12944   [(set_attr "length" "1")
12945    (set_attr "length_immediate" "0")
12946    (set_attr "modrm" "0")])
12948 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12949 (define_insn "nops"
12950   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12951                     UNSPECV_NOPS)]
12952   "reload_completed"
12954   int num = INTVAL (operands[0]);
12956   gcc_assert (IN_RANGE (num, 1, 8));
12958   while (num--)
12959     fputs ("\tnop\n", asm_out_file);
12961   return "";
12963   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12964    (set_attr "length_immediate" "0")
12965    (set_attr "modrm" "0")])
12967 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12968 ;; branch prediction penalty for the third jump in a 16-byte
12969 ;; block on K8.
12971 (define_insn "pad"
12972   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12973   ""
12975 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12976   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12977 #else
12978   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12979      The align insn is used to avoid 3 jump instructions in the row to improve
12980      branch prediction and the benefits hardly outweigh the cost of extra 8
12981      nops on the average inserted by full alignment pseudo operation.  */
12982 #endif
12983   return "";
12985   [(set_attr "length" "16")])
12987 (define_expand "prologue"
12988   [(const_int 0)]
12989   ""
12990   "ix86_expand_prologue (); DONE;")
12992 (define_expand "set_got"
12993   [(parallel
12994      [(set (match_operand:SI 0 "register_operand")
12995            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12996       (clobber (reg:CC FLAGS_REG))])]
12997   "!TARGET_64BIT"
12999   if (flag_pic && !TARGET_VXWORKS_RTP)
13000     ix86_pc_thunk_call_expanded = true;
13003 (define_insn "*set_got"
13004   [(set (match_operand:SI 0 "register_operand" "=r")
13005         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13006    (clobber (reg:CC FLAGS_REG))]
13007   "!TARGET_64BIT"
13008   "* return output_set_got (operands[0], NULL_RTX);"
13009   [(set_attr "type" "multi")
13010    (set_attr "length" "12")])
13012 (define_expand "set_got_labelled"
13013   [(parallel
13014      [(set (match_operand:SI 0 "register_operand")
13015            (unspec:SI [(label_ref (match_operand 1))]
13016                       UNSPEC_SET_GOT))
13017       (clobber (reg:CC FLAGS_REG))])]
13018   "!TARGET_64BIT"
13020   if (flag_pic && !TARGET_VXWORKS_RTP)
13021     ix86_pc_thunk_call_expanded = true;
13024 (define_insn "*set_got_labelled"
13025   [(set (match_operand:SI 0 "register_operand" "=r")
13026         (unspec:SI [(label_ref (match_operand 1))]
13027          UNSPEC_SET_GOT))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "!TARGET_64BIT"
13030   "* return output_set_got (operands[0], operands[1]);"
13031   [(set_attr "type" "multi")
13032    (set_attr "length" "12")])
13034 (define_insn "set_got_rex64"
13035   [(set (match_operand:DI 0 "register_operand" "=r")
13036         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13037   "TARGET_64BIT"
13038   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13039   [(set_attr "type" "lea")
13040    (set_attr "length_address" "4")
13041    (set_attr "mode" "DI")])
13043 (define_insn "set_rip_rex64"
13044   [(set (match_operand:DI 0 "register_operand" "=r")
13045         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13046   "TARGET_64BIT"
13047   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13048   [(set_attr "type" "lea")
13049    (set_attr "length_address" "4")
13050    (set_attr "mode" "DI")])
13052 (define_insn "set_got_offset_rex64"
13053   [(set (match_operand:DI 0 "register_operand" "=r")
13054         (unspec:DI
13055           [(label_ref (match_operand 1))]
13056           UNSPEC_SET_GOT_OFFSET))]
13057   "TARGET_LP64"
13058   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13059   [(set_attr "type" "imov")
13060    (set_attr "length_immediate" "0")
13061    (set_attr "length_address" "8")
13062    (set_attr "mode" "DI")])
13064 (define_expand "epilogue"
13065   [(const_int 0)]
13066   ""
13067   "ix86_expand_epilogue (1); DONE;")
13069 (define_expand "sibcall_epilogue"
13070   [(const_int 0)]
13071   ""
13072   "ix86_expand_epilogue (0); DONE;")
13074 (define_expand "eh_return"
13075   [(use (match_operand 0 "register_operand"))]
13076   ""
13078   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13080   /* Tricky bit: we write the address of the handler to which we will
13081      be returning into someone else's stack frame, one word below the
13082      stack address we wish to restore.  */
13083   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13084   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13085   /* Return address is always in word_mode.  */
13086   tmp = gen_rtx_MEM (word_mode, tmp);
13087   if (GET_MODE (ra) != word_mode)
13088     ra = convert_to_mode (word_mode, ra, 1);
13089   emit_move_insn (tmp, ra);
13091   emit_jump_insn (gen_eh_return_internal ());
13092   emit_barrier ();
13093   DONE;
13096 (define_insn_and_split "eh_return_internal"
13097   [(eh_return)]
13098   ""
13099   "#"
13100   "epilogue_completed"
13101   [(const_int 0)]
13102   "ix86_expand_epilogue (2); DONE;")
13104 (define_expand "@leave_<mode>"
13105   [(parallel
13106     [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13107      (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13108      (clobber (mem:BLK (scratch)))])]
13109   ""
13110   "operands[0] = GEN_INT (<MODE_SIZE>);")
13112 (define_insn "*leave"
13113   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13114    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13115    (clobber (mem:BLK (scratch)))]
13116   "!TARGET_64BIT"
13117   "leave"
13118   [(set_attr "type" "leave")])
13120 (define_insn "*leave_rex64"
13121   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13122    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13123    (clobber (mem:BLK (scratch)))]
13124   "TARGET_64BIT"
13125   "leave"
13126   [(set_attr "type" "leave")])
13128 ;; Handle -fsplit-stack.
13130 (define_expand "split_stack_prologue"
13131   [(const_int 0)]
13132   ""
13134   ix86_expand_split_stack_prologue ();
13135   DONE;
13138 ;; In order to support the call/return predictor, we use a return
13139 ;; instruction which the middle-end doesn't see.
13140 (define_insn "split_stack_return"
13141   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13142                      UNSPECV_SPLIT_STACK_RETURN)]
13143   ""
13145   if (operands[0] == const0_rtx)
13146     return "ret";
13147   else
13148     return "ret\t%0";
13150   [(set_attr "atom_unit" "jeu")
13151    (set_attr "modrm" "0")
13152    (set (attr "length")
13153         (if_then_else (match_operand:SI 0 "const0_operand")
13154                       (const_int 1)
13155                       (const_int 3)))
13156    (set (attr "length_immediate")
13157         (if_then_else (match_operand:SI 0 "const0_operand")
13158                       (const_int 0)
13159                       (const_int 2)))])
13161 ;; If there are operand 0 bytes available on the stack, jump to
13162 ;; operand 1.
13164 (define_expand "split_stack_space_check"
13165   [(set (pc) (if_then_else
13166               (ltu (minus (reg SP_REG)
13167                           (match_operand 0 "register_operand"))
13168                    (match_dup 2))
13169               (label_ref (match_operand 1))
13170               (pc)))]
13171   ""
13173   rtx reg = gen_reg_rtx (Pmode);
13175   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13177   operands[2] = ix86_split_stack_guard ();
13178   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13180   DONE;
13183 ;; Bit manipulation instructions.
13185 (define_expand "ffs<mode>2"
13186   [(set (match_dup 2) (const_int -1))
13187    (parallel [(set (match_dup 3) (match_dup 4))
13188               (set (match_operand:SWI48 0 "register_operand")
13189                    (ctz:SWI48
13190                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13191    (set (match_dup 0) (if_then_else:SWI48
13192                         (eq (match_dup 3) (const_int 0))
13193                         (match_dup 2)
13194                         (match_dup 0)))
13195    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13196               (clobber (reg:CC FLAGS_REG))])]
13197   ""
13199   machine_mode flags_mode;
13201   if (<MODE>mode == SImode && !TARGET_CMOVE)
13202     {
13203       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13204       DONE;
13205     }
13207   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13209   operands[2] = gen_reg_rtx (<MODE>mode);
13210   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13211   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13214 (define_insn_and_split "ffssi2_no_cmove"
13215   [(set (match_operand:SI 0 "register_operand" "=r")
13216         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13217    (clobber (match_scratch:SI 2 "=&q"))
13218    (clobber (reg:CC FLAGS_REG))]
13219   "!TARGET_CMOVE"
13220   "#"
13221   "&& reload_completed"
13222   [(parallel [(set (match_dup 4) (match_dup 5))
13223               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13224    (set (strict_low_part (match_dup 3))
13225         (eq:QI (match_dup 4) (const_int 0)))
13226    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13227               (clobber (reg:CC FLAGS_REG))])
13228    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13229               (clobber (reg:CC FLAGS_REG))])
13230    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13231               (clobber (reg:CC FLAGS_REG))])]
13233   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13235   operands[3] = gen_lowpart (QImode, operands[2]);
13236   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13237   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13239   ix86_expand_clear (operands[2]);
13242 (define_insn_and_split "*tzcnt<mode>_1"
13243   [(set (reg:CCC FLAGS_REG)
13244         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13245                      (const_int 0)))
13246    (set (match_operand:SWI48 0 "register_operand" "=r")
13247         (ctz:SWI48 (match_dup 1)))]
13248   "TARGET_BMI"
13249   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13250   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13251    && optimize_function_for_speed_p (cfun)
13252    && !reg_mentioned_p (operands[0], operands[1])"
13253   [(parallel
13254     [(set (reg:CCC FLAGS_REG)
13255           (compare:CCC (match_dup 1) (const_int 0)))
13256      (set (match_dup 0)
13257           (ctz:SWI48 (match_dup 1)))
13258      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13259   "ix86_expand_clear (operands[0]);"
13260   [(set_attr "type" "alu1")
13261    (set_attr "prefix_0f" "1")
13262    (set_attr "prefix_rep" "1")
13263    (set_attr "btver2_decode" "double")
13264    (set_attr "mode" "<MODE>")])
13266 ; False dependency happens when destination is only updated by tzcnt,
13267 ; lzcnt or popcnt.  There is no false dependency when destination is
13268 ; also used in source.
13269 (define_insn "*tzcnt<mode>_1_falsedep"
13270   [(set (reg:CCC FLAGS_REG)
13271         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13272                      (const_int 0)))
13273    (set (match_operand:SWI48 0 "register_operand" "=r")
13274         (ctz:SWI48 (match_dup 1)))
13275    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13276            UNSPEC_INSN_FALSE_DEP)]
13277   "TARGET_BMI"
13278   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13279   [(set_attr "type" "alu1")
13280    (set_attr "prefix_0f" "1")
13281    (set_attr "prefix_rep" "1")
13282    (set_attr "btver2_decode" "double")
13283    (set_attr "mode" "<MODE>")])
13285 (define_insn "*bsf<mode>_1"
13286   [(set (reg:CCZ FLAGS_REG)
13287         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13288                      (const_int 0)))
13289    (set (match_operand:SWI48 0 "register_operand" "=r")
13290         (ctz:SWI48 (match_dup 1)))]
13291   ""
13292   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13293   [(set_attr "type" "alu1")
13294    (set_attr "prefix_0f" "1")
13295    (set_attr "btver2_decode" "double")
13296    (set_attr "znver1_decode" "vector")
13297    (set_attr "mode" "<MODE>")])
13299 (define_insn_and_split "ctz<mode>2"
13300   [(set (match_operand:SWI48 0 "register_operand" "=r")
13301         (ctz:SWI48
13302           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13303    (clobber (reg:CC FLAGS_REG))]
13304   ""
13306   if (TARGET_BMI)
13307     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13308   else if (optimize_function_for_size_p (cfun))
13309     ;
13310   else if (TARGET_GENERIC)
13311     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13312     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13314   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13316   "(TARGET_BMI || TARGET_GENERIC)
13317    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13318    && optimize_function_for_speed_p (cfun)
13319    && !reg_mentioned_p (operands[0], operands[1])"
13320   [(parallel
13321     [(set (match_dup 0)
13322           (ctz:SWI48 (match_dup 1)))
13323      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13324      (clobber (reg:CC FLAGS_REG))])]
13325   "ix86_expand_clear (operands[0]);"
13326   [(set_attr "type" "alu1")
13327    (set_attr "prefix_0f" "1")
13328    (set (attr "prefix_rep")
13329      (if_then_else
13330        (ior (match_test "TARGET_BMI")
13331             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13332                  (match_test "TARGET_GENERIC")))
13333        (const_string "1")
13334        (const_string "0")))
13335    (set_attr "mode" "<MODE>")])
13337 ; False dependency happens when destination is only updated by tzcnt,
13338 ; lzcnt or popcnt.  There is no false dependency when destination is
13339 ; also used in source.
13340 (define_insn "*ctz<mode>2_falsedep"
13341   [(set (match_operand:SWI48 0 "register_operand" "=r")
13342         (ctz:SWI48
13343           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13344    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13345            UNSPEC_INSN_FALSE_DEP)
13346    (clobber (reg:CC FLAGS_REG))]
13347   ""
13349   if (TARGET_BMI)
13350     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13351   else if (TARGET_GENERIC)
13352     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13353     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13354   else
13355     gcc_unreachable ();
13357   [(set_attr "type" "alu1")
13358    (set_attr "prefix_0f" "1")
13359    (set_attr "prefix_rep" "1")
13360    (set_attr "mode" "<MODE>")])
13362 (define_insn "bsr_rex64"
13363   [(set (match_operand:DI 0 "register_operand" "=r")
13364         (minus:DI (const_int 63)
13365                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13366    (clobber (reg:CC FLAGS_REG))]
13367   "TARGET_64BIT"
13368   "bsr{q}\t{%1, %0|%0, %1}"
13369   [(set_attr "type" "alu1")
13370    (set_attr "prefix_0f" "1")
13371    (set_attr "znver1_decode" "vector")
13372    (set_attr "mode" "DI")])
13374 (define_insn "bsr"
13375   [(set (match_operand:SI 0 "register_operand" "=r")
13376         (minus:SI (const_int 31)
13377                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13378    (clobber (reg:CC FLAGS_REG))]
13379   ""
13380   "bsr{l}\t{%1, %0|%0, %1}"
13381   [(set_attr "type" "alu1")
13382    (set_attr "prefix_0f" "1")
13383    (set_attr "znver1_decode" "vector")
13384    (set_attr "mode" "SI")])
13386 (define_insn "*bsrhi"
13387   [(set (match_operand:HI 0 "register_operand" "=r")
13388         (minus:HI (const_int 15)
13389                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13390    (clobber (reg:CC FLAGS_REG))]
13391   ""
13392   "bsr{w}\t{%1, %0|%0, %1}"
13393   [(set_attr "type" "alu1")
13394    (set_attr "prefix_0f" "1")
13395    (set_attr "znver1_decode" "vector")
13396    (set_attr "mode" "HI")])
13398 (define_expand "clz<mode>2"
13399   [(parallel
13400      [(set (match_operand:SWI48 0 "register_operand")
13401            (minus:SWI48
13402              (match_dup 2)
13403              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13404       (clobber (reg:CC FLAGS_REG))])
13405    (parallel
13406      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13407       (clobber (reg:CC FLAGS_REG))])]
13408   ""
13410   if (TARGET_LZCNT)
13411     {
13412       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13413       DONE;
13414     }
13415   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13418 (define_insn_and_split "clz<mode>2_lzcnt"
13419   [(set (match_operand:SWI48 0 "register_operand" "=r")
13420         (clz:SWI48
13421           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13422    (clobber (reg:CC FLAGS_REG))]
13423   "TARGET_LZCNT"
13424   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13425   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13426    && optimize_function_for_speed_p (cfun)
13427    && !reg_mentioned_p (operands[0], operands[1])"
13428   [(parallel
13429     [(set (match_dup 0)
13430           (clz:SWI48 (match_dup 1)))
13431      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13432      (clobber (reg:CC FLAGS_REG))])]
13433   "ix86_expand_clear (operands[0]);"
13434   [(set_attr "prefix_rep" "1")
13435    (set_attr "type" "bitmanip")
13436    (set_attr "mode" "<MODE>")])
13438 ; False dependency happens when destination is only updated by tzcnt,
13439 ; lzcnt or popcnt.  There is no false dependency when destination is
13440 ; also used in source.
13441 (define_insn "*clz<mode>2_lzcnt_falsedep"
13442   [(set (match_operand:SWI48 0 "register_operand" "=r")
13443         (clz:SWI48
13444           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13445    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13446            UNSPEC_INSN_FALSE_DEP)
13447    (clobber (reg:CC FLAGS_REG))]
13448   "TARGET_LZCNT"
13449   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13450   [(set_attr "prefix_rep" "1")
13451    (set_attr "type" "bitmanip")
13452    (set_attr "mode" "<MODE>")])
13454 (define_int_iterator LT_ZCNT
13455         [(UNSPEC_TZCNT "TARGET_BMI")
13456          (UNSPEC_LZCNT "TARGET_LZCNT")])
13458 (define_int_attr lt_zcnt
13459         [(UNSPEC_TZCNT "tzcnt")
13460          (UNSPEC_LZCNT "lzcnt")])
13462 (define_int_attr lt_zcnt_type
13463         [(UNSPEC_TZCNT "alu1")
13464          (UNSPEC_LZCNT "bitmanip")])
13466 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13467 ;; provides operand size as output when source operand is zero. 
13469 (define_insn_and_split "<lt_zcnt>_<mode>"
13470   [(set (match_operand:SWI48 0 "register_operand" "=r")
13471         (unspec:SWI48
13472           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13473    (clobber (reg:CC FLAGS_REG))]
13474   ""
13475   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13476   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13477    && optimize_function_for_speed_p (cfun)
13478    && !reg_mentioned_p (operands[0], operands[1])"
13479   [(parallel
13480     [(set (match_dup 0)
13481           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13482      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13483      (clobber (reg:CC FLAGS_REG))])]
13484   "ix86_expand_clear (operands[0]);"
13485   [(set_attr "type" "<lt_zcnt_type>")
13486    (set_attr "prefix_0f" "1")
13487    (set_attr "prefix_rep" "1")
13488    (set_attr "mode" "<MODE>")])
13490 ; False dependency happens when destination is only updated by tzcnt,
13491 ; lzcnt or popcnt.  There is no false dependency when destination is
13492 ; also used in source.
13493 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13494   [(set (match_operand:SWI48 0 "register_operand" "=r")
13495         (unspec:SWI48
13496           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13497    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13498            UNSPEC_INSN_FALSE_DEP)
13499    (clobber (reg:CC FLAGS_REG))]
13500   ""
13501   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13502   [(set_attr "type" "<lt_zcnt_type>")
13503    (set_attr "prefix_0f" "1")
13504    (set_attr "prefix_rep" "1")
13505    (set_attr "mode" "<MODE>")])
13507 (define_insn "<lt_zcnt>_hi"
13508   [(set (match_operand:HI 0 "register_operand" "=r")
13509         (unspec:HI
13510           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13511    (clobber (reg:CC FLAGS_REG))]
13512   ""
13513   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13514   [(set_attr "type" "<lt_zcnt_type>")
13515    (set_attr "prefix_0f" "1")
13516    (set_attr "prefix_rep" "1")
13517    (set_attr "mode" "HI")])
13519 ;; BMI instructions.
13521 (define_insn "bmi_bextr_<mode>"
13522   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13523         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13524                        (match_operand:SWI48 2 "register_operand" "r,r")]
13525                       UNSPEC_BEXTR))
13526    (clobber (reg:CC FLAGS_REG))]
13527   "TARGET_BMI"
13528   "bextr\t{%2, %1, %0|%0, %1, %2}"
13529   [(set_attr "type" "bitmanip")
13530    (set_attr "btver2_decode" "direct, double")
13531    (set_attr "mode" "<MODE>")])
13533 (define_insn "*bmi_bextr_<mode>_ccz"
13534   [(set (reg:CCZ FLAGS_REG)
13535         (compare:CCZ
13536           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13537                          (match_operand:SWI48 2 "register_operand" "r,r")]
13538                         UNSPEC_BEXTR)
13539           (const_int 0)))
13540    (clobber (match_scratch:SWI48 0 "=r,r"))]
13541   "TARGET_BMI"
13542   "bextr\t{%2, %1, %0|%0, %1, %2}"
13543   [(set_attr "type" "bitmanip")
13544    (set_attr "btver2_decode" "direct, double")
13545    (set_attr "mode" "<MODE>")])
13547 (define_insn "*bmi_blsi_<mode>"
13548   [(set (match_operand:SWI48 0 "register_operand" "=r")
13549         (and:SWI48
13550           (neg:SWI48
13551             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13552           (match_dup 1)))
13553    (clobber (reg:CC FLAGS_REG))]
13554   "TARGET_BMI"
13555   "blsi\t{%1, %0|%0, %1}"
13556   [(set_attr "type" "bitmanip")
13557    (set_attr "btver2_decode" "double")
13558    (set_attr "mode" "<MODE>")])
13560 (define_insn "*bmi_blsmsk_<mode>"
13561   [(set (match_operand:SWI48 0 "register_operand" "=r")
13562         (xor:SWI48
13563           (plus:SWI48
13564             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13565             (const_int -1))
13566           (match_dup 1)))
13567    (clobber (reg:CC FLAGS_REG))]
13568   "TARGET_BMI"
13569   "blsmsk\t{%1, %0|%0, %1}"
13570   [(set_attr "type" "bitmanip")
13571    (set_attr "btver2_decode" "double")
13572    (set_attr "mode" "<MODE>")])
13574 (define_insn "*bmi_blsr_<mode>"
13575   [(set (match_operand:SWI48 0 "register_operand" "=r")
13576         (and:SWI48
13577           (plus:SWI48
13578             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13579             (const_int -1))
13580           (match_dup 1)))
13581    (clobber (reg:CC FLAGS_REG))]
13582    "TARGET_BMI"
13583    "blsr\t{%1, %0|%0, %1}"
13584   [(set_attr "type" "bitmanip")
13585    (set_attr "btver2_decode" "double")
13586    (set_attr "mode" "<MODE>")])
13588 (define_insn "*bmi_blsr_<mode>_cmp"
13589   [(set (reg:CCZ FLAGS_REG)
13590         (compare:CCZ
13591           (and:SWI48
13592             (plus:SWI48
13593               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13594               (const_int -1))
13595             (match_dup 1))
13596           (const_int 0)))
13597    (set (match_operand:SWI48 0 "register_operand" "=r")
13598         (and:SWI48
13599           (plus:SWI48
13600             (match_dup 1)
13601             (const_int -1))
13602           (match_dup 1)))]
13603    "TARGET_BMI"
13604    "blsr\t{%1, %0|%0, %1}"
13605   [(set_attr "type" "bitmanip")
13606    (set_attr "btver2_decode" "double")
13607    (set_attr "mode" "<MODE>")])
13609 (define_insn "*bmi_blsr_<mode>_ccz"
13610   [(set (reg:CCZ FLAGS_REG)
13611         (compare:CCZ
13612           (and:SWI48
13613             (plus:SWI48
13614               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13615               (const_int -1))
13616             (match_dup 1))
13617           (const_int 0)))
13618    (clobber (match_scratch:SWI48 0 "=r"))]
13619    "TARGET_BMI"
13620    "blsr\t{%1, %0|%0, %1}"
13621   [(set_attr "type" "bitmanip")
13622    (set_attr "btver2_decode" "double")
13623    (set_attr "mode" "<MODE>")])
13625 ;; BMI2 instructions.
13626 (define_expand "bmi2_bzhi_<mode>3"
13627   [(parallel
13628     [(set (match_operand:SWI48 0 "register_operand")
13629           (if_then_else:SWI48
13630             (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13631                               (const_int 255))
13632                    (const_int 0))
13633             (zero_extract:SWI48
13634               (match_operand:SWI48 1 "nonimmediate_operand")
13635               (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13636                           (match_dup 3))
13637               (const_int 0))
13638             (const_int 0)))
13639      (clobber (reg:CC FLAGS_REG))])]
13640   "TARGET_BMI2"
13641   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13643 (define_insn "*bmi2_bzhi_<mode>3"
13644   [(set (match_operand:SWI48 0 "register_operand" "=r")
13645         (if_then_else:SWI48
13646           (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13647                             (const_int 255))
13648                  (const_int 0))
13649           (zero_extract:SWI48
13650             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13651             (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13652                         (match_operand:SWI48 3 "const_int_operand" "n"))
13653             (const_int 0))
13654           (const_int 0)))
13655    (clobber (reg:CC FLAGS_REG))]
13656   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13657   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13658   [(set_attr "type" "bitmanip")
13659    (set_attr "prefix" "vex")
13660    (set_attr "mode" "<MODE>")])
13662 (define_insn "*bmi2_bzhi_<mode>3_1"
13663   [(set (match_operand:SWI48 0 "register_operand" "=r")
13664         (if_then_else:SWI48
13665           (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13666           (zero_extract:SWI48
13667             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13668             (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13669                         (match_operand:SWI48 3 "const_int_operand" "n"))
13670             (const_int 0))
13671           (const_int 0)))
13672    (clobber (reg:CC FLAGS_REG))]
13673   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13674   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13675   [(set_attr "type" "bitmanip")
13676    (set_attr "prefix" "vex")
13677    (set_attr "mode" "<MODE>")])
13679 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13680   [(set (reg:CCZ FLAGS_REG)
13681         (compare:CCZ
13682           (if_then_else:SWI48
13683             (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13684             (zero_extract:SWI48
13685               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13686               (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13687                           (match_operand:SWI48 3 "const_int_operand" "n"))
13688               (const_int 0))
13689             (const_int 0))
13690         (const_int 0)))
13691    (clobber (match_scratch:SWI48 0 "=r"))]
13692   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13693   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13694   [(set_attr "type" "bitmanip")
13695    (set_attr "prefix" "vex")
13696    (set_attr "mode" "<MODE>")])
13698 (define_insn "bmi2_pdep_<mode>3"
13699   [(set (match_operand:SWI48 0 "register_operand" "=r")
13700         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13701                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13702                        UNSPEC_PDEP))]
13703   "TARGET_BMI2"
13704   "pdep\t{%2, %1, %0|%0, %1, %2}"
13705   [(set_attr "type" "bitmanip")
13706    (set_attr "prefix" "vex")
13707    (set_attr "mode" "<MODE>")])
13709 (define_insn "bmi2_pext_<mode>3"
13710   [(set (match_operand:SWI48 0 "register_operand" "=r")
13711         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13712                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13713                        UNSPEC_PEXT))]
13714   "TARGET_BMI2"
13715   "pext\t{%2, %1, %0|%0, %1, %2}"
13716   [(set_attr "type" "bitmanip")
13717    (set_attr "prefix" "vex")
13718    (set_attr "mode" "<MODE>")])
13720 ;; TBM instructions.
13721 (define_expand "tbm_bextri_<mode>"
13722   [(parallel
13723     [(set (match_operand:SWI48 0 "register_operand")
13724           (zero_extract:SWI48
13725             (match_operand:SWI48 1 "nonimmediate_operand")
13726             (match_operand 2 "const_0_to_255_operand" "N")
13727             (match_operand 3 "const_0_to_255_operand" "N")))
13728      (clobber (reg:CC FLAGS_REG))])]
13729   "TARGET_TBM"
13731   if (operands[2] == const0_rtx
13732       || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13733     {
13734       emit_move_insn (operands[0], const0_rtx);
13735       DONE;
13736     }
13737   if (INTVAL (operands[2]) + INTVAL (operands[3])
13738       > <MODE_SIZE> * BITS_PER_UNIT)
13739     operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13742 (define_insn "*tbm_bextri_<mode>"
13743   [(set (match_operand:SWI48 0 "register_operand" "=r")
13744         (zero_extract:SWI48
13745           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13746           (match_operand 2 "const_0_to_255_operand" "N")
13747           (match_operand 3 "const_0_to_255_operand" "N")))
13748    (clobber (reg:CC FLAGS_REG))]
13749    "TARGET_TBM"
13751   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13752   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13754   [(set_attr "type" "bitmanip")
13755    (set_attr "mode" "<MODE>")])
13757 (define_insn "*tbm_blcfill_<mode>"
13758   [(set (match_operand:SWI48 0 "register_operand" "=r")
13759         (and:SWI48
13760           (plus:SWI48
13761             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13762             (const_int 1))
13763           (match_dup 1)))
13764    (clobber (reg:CC FLAGS_REG))]
13765    "TARGET_TBM"
13766    "blcfill\t{%1, %0|%0, %1}"
13767   [(set_attr "type" "bitmanip")
13768    (set_attr "mode" "<MODE>")])
13770 (define_insn "*tbm_blci_<mode>"
13771   [(set (match_operand:SWI48 0 "register_operand" "=r")
13772         (ior:SWI48
13773           (not:SWI48
13774             (plus:SWI48
13775               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13776               (const_int 1)))
13777           (match_dup 1)))
13778    (clobber (reg:CC FLAGS_REG))]
13779    "TARGET_TBM"
13780    "blci\t{%1, %0|%0, %1}"
13781   [(set_attr "type" "bitmanip")
13782    (set_attr "mode" "<MODE>")])
13784 (define_insn "*tbm_blcic_<mode>"
13785   [(set (match_operand:SWI48 0 "register_operand" "=r")
13786         (and:SWI48
13787           (plus:SWI48
13788             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13789             (const_int 1))
13790           (not:SWI48
13791             (match_dup 1))))
13792    (clobber (reg:CC FLAGS_REG))]
13793    "TARGET_TBM"
13794    "blcic\t{%1, %0|%0, %1}"
13795   [(set_attr "type" "bitmanip")
13796    (set_attr "mode" "<MODE>")])
13798 (define_insn "*tbm_blcmsk_<mode>"
13799   [(set (match_operand:SWI48 0 "register_operand" "=r")
13800         (xor:SWI48
13801           (plus:SWI48
13802             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13803             (const_int 1))
13804           (match_dup 1)))
13805    (clobber (reg:CC FLAGS_REG))]
13806    "TARGET_TBM"
13807    "blcmsk\t{%1, %0|%0, %1}"
13808   [(set_attr "type" "bitmanip")
13809    (set_attr "mode" "<MODE>")])
13811 (define_insn "*tbm_blcs_<mode>"
13812   [(set (match_operand:SWI48 0 "register_operand" "=r")
13813         (ior:SWI48
13814           (plus:SWI48
13815             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13816             (const_int 1))
13817           (match_dup 1)))
13818    (clobber (reg:CC FLAGS_REG))]
13819    "TARGET_TBM"
13820    "blcs\t{%1, %0|%0, %1}"
13821   [(set_attr "type" "bitmanip")
13822    (set_attr "mode" "<MODE>")])
13824 (define_insn "*tbm_blsfill_<mode>"
13825   [(set (match_operand:SWI48 0 "register_operand" "=r")
13826         (ior:SWI48
13827           (plus:SWI48
13828             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13829             (const_int -1))
13830           (match_dup 1)))
13831    (clobber (reg:CC FLAGS_REG))]
13832    "TARGET_TBM"
13833    "blsfill\t{%1, %0|%0, %1}"
13834   [(set_attr "type" "bitmanip")
13835    (set_attr "mode" "<MODE>")])
13837 (define_insn "*tbm_blsic_<mode>"
13838   [(set (match_operand:SWI48 0 "register_operand" "=r")
13839         (ior:SWI48
13840           (plus:SWI48
13841             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13842             (const_int -1))
13843           (not:SWI48
13844             (match_dup 1))))
13845    (clobber (reg:CC FLAGS_REG))]
13846    "TARGET_TBM"
13847    "blsic\t{%1, %0|%0, %1}"
13848   [(set_attr "type" "bitmanip")
13849    (set_attr "mode" "<MODE>")])
13851 (define_insn "*tbm_t1mskc_<mode>"
13852   [(set (match_operand:SWI48 0 "register_operand" "=r")
13853         (ior:SWI48
13854           (plus:SWI48
13855             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13856             (const_int 1))
13857           (not:SWI48
13858             (match_dup 1))))
13859    (clobber (reg:CC FLAGS_REG))]
13860    "TARGET_TBM"
13861    "t1mskc\t{%1, %0|%0, %1}"
13862   [(set_attr "type" "bitmanip")
13863    (set_attr "mode" "<MODE>")])
13865 (define_insn "*tbm_tzmsk_<mode>"
13866   [(set (match_operand:SWI48 0 "register_operand" "=r")
13867         (and:SWI48
13868           (plus:SWI48
13869             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13870             (const_int -1))
13871           (not:SWI48
13872             (match_dup 1))))
13873    (clobber (reg:CC FLAGS_REG))]
13874    "TARGET_TBM"
13875    "tzmsk\t{%1, %0|%0, %1}"
13876   [(set_attr "type" "bitmanip")
13877    (set_attr "mode" "<MODE>")])
13879 (define_insn_and_split "popcount<mode>2"
13880   [(set (match_operand:SWI48 0 "register_operand" "=r")
13881         (popcount:SWI48
13882           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13883    (clobber (reg:CC FLAGS_REG))]
13884   "TARGET_POPCNT"
13886 #if TARGET_MACHO
13887   return "popcnt\t{%1, %0|%0, %1}";
13888 #else
13889   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13890 #endif
13892   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13893    && optimize_function_for_speed_p (cfun)
13894    && !reg_mentioned_p (operands[0], operands[1])"
13895   [(parallel
13896     [(set (match_dup 0)
13897           (popcount:SWI48 (match_dup 1)))
13898      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13899      (clobber (reg:CC FLAGS_REG))])]
13900   "ix86_expand_clear (operands[0]);"
13901   [(set_attr "prefix_rep" "1")
13902    (set_attr "type" "bitmanip")
13903    (set_attr "mode" "<MODE>")])
13905 ; False dependency happens when destination is only updated by tzcnt,
13906 ; lzcnt or popcnt.  There is no false dependency when destination is
13907 ; also used in source.
13908 (define_insn "*popcount<mode>2_falsedep"
13909   [(set (match_operand:SWI48 0 "register_operand" "=r")
13910         (popcount:SWI48
13911           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13912    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13913            UNSPEC_INSN_FALSE_DEP)
13914    (clobber (reg:CC FLAGS_REG))]
13915   "TARGET_POPCNT"
13917 #if TARGET_MACHO
13918   return "popcnt\t{%1, %0|%0, %1}";
13919 #else
13920   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13921 #endif
13923   [(set_attr "prefix_rep" "1")
13924    (set_attr "type" "bitmanip")
13925    (set_attr "mode" "<MODE>")])
13927 (define_insn_and_split "*popcounthi2_1"
13928   [(set (match_operand:SI 0 "register_operand")
13929         (popcount:SI
13930           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13931    (clobber (reg:CC FLAGS_REG))]
13932   "TARGET_POPCNT
13933    && can_create_pseudo_p ()"
13934   "#"
13935   "&& 1"
13936   [(const_int 0)]
13938   rtx tmp = gen_reg_rtx (HImode);
13940   emit_insn (gen_popcounthi2 (tmp, operands[1]));
13941   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13942   DONE;
13945 (define_insn "popcounthi2"
13946   [(set (match_operand:HI 0 "register_operand" "=r")
13947         (popcount:HI
13948           (match_operand:HI 1 "nonimmediate_operand" "rm")))
13949    (clobber (reg:CC FLAGS_REG))]
13950   "TARGET_POPCNT"
13952 #if TARGET_MACHO
13953   return "popcnt\t{%1, %0|%0, %1}";
13954 #else
13955   return "popcnt{w}\t{%1, %0|%0, %1}";
13956 #endif
13958   [(set_attr "prefix_rep" "1")
13959    (set_attr "type" "bitmanip")
13960    (set_attr "mode" "HI")])
13962 (define_expand "bswapdi2"
13963   [(set (match_operand:DI 0 "register_operand")
13964         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13965   "TARGET_64BIT"
13967   if (!TARGET_MOVBE)
13968     operands[1] = force_reg (DImode, operands[1]);
13971 (define_expand "bswapsi2"
13972   [(set (match_operand:SI 0 "register_operand")
13973         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13974   ""
13976   if (TARGET_MOVBE)
13977     ;
13978   else if (TARGET_BSWAP)
13979     operands[1] = force_reg (SImode, operands[1]);
13980   else
13981     {
13982       rtx x = operands[0];
13984       emit_move_insn (x, operands[1]);
13985       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13986       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13987       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13988       DONE;
13989     }
13992 (define_insn "*bswap<mode>2_movbe"
13993   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13994         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13995   "TARGET_MOVBE
13996    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13997   "@
13998     bswap\t%0
13999     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14000     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14001   [(set_attr "type" "bitmanip,imov,imov")
14002    (set_attr "modrm" "0,1,1")
14003    (set_attr "prefix_0f" "*,1,1")
14004    (set_attr "prefix_extra" "*,1,1")
14005    (set_attr "mode" "<MODE>")])
14007 (define_insn "*bswap<mode>2"
14008   [(set (match_operand:SWI48 0 "register_operand" "=r")
14009         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14010   "TARGET_BSWAP"
14011   "bswap\t%0"
14012   [(set_attr "type" "bitmanip")
14013    (set_attr "modrm" "0")
14014    (set_attr "mode" "<MODE>")])
14016 (define_expand "bswaphi2"
14017   [(set (match_operand:HI 0 "register_operand")
14018         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14019   "TARGET_MOVBE")
14021 (define_insn "*bswaphi2_movbe"
14022   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14023         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14024   "TARGET_MOVBE
14025    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14026   "@
14027     xchg{b}\t{%h0, %b0|%b0, %h0}
14028     movbe{w}\t{%1, %0|%0, %1}
14029     movbe{w}\t{%1, %0|%0, %1}"
14030   [(set_attr "type" "imov")
14031    (set_attr "modrm" "*,1,1")
14032    (set_attr "prefix_0f" "*,1,1")
14033    (set_attr "prefix_extra" "*,1,1")
14034    (set_attr "pent_pair" "np,*,*")
14035    (set_attr "athlon_decode" "vector,*,*")
14036    (set_attr "amdfam10_decode" "double,*,*")
14037    (set_attr "bdver1_decode" "double,*,*")
14038    (set_attr "mode" "QI,HI,HI")])
14040 (define_peephole2
14041   [(set (match_operand:HI 0 "general_reg_operand")
14042         (bswap:HI (match_dup 0)))]
14043   "TARGET_MOVBE
14044    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14045    && peep2_regno_dead_p (0, FLAGS_REG)"
14046   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14047               (clobber (reg:CC FLAGS_REG))])])
14049 (define_insn "bswaphi_lowpart"
14050   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14051         (bswap:HI (match_dup 0)))
14052    (clobber (reg:CC FLAGS_REG))]
14053   ""
14054   "@
14055     xchg{b}\t{%h0, %b0|%b0, %h0}
14056     rol{w}\t{$8, %0|%0, 8}"
14057   [(set (attr "preferred_for_size")
14058      (cond [(eq_attr "alternative" "0")
14059               (symbol_ref "true")]
14060            (symbol_ref "false")))
14061    (set (attr "preferred_for_speed")
14062      (cond [(eq_attr "alternative" "0")
14063               (symbol_ref "TARGET_USE_XCHGB")]
14064            (symbol_ref "!TARGET_USE_XCHGB")))
14065    (set_attr "length" "2,4")
14066    (set_attr "mode" "QI,HI")])
14068 (define_expand "paritydi2"
14069   [(set (match_operand:DI 0 "register_operand")
14070         (parity:DI (match_operand:DI 1 "register_operand")))]
14071   "! TARGET_POPCNT"
14073   rtx scratch = gen_reg_rtx (QImode);
14075   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14076                                 NULL_RTX, operands[1]));
14078   ix86_expand_setcc (scratch, ORDERED,
14079                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14081   if (TARGET_64BIT)
14082     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14083   else
14084     {
14085       rtx tmp = gen_reg_rtx (SImode);
14087       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14088       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14089     }
14090   DONE;
14093 (define_expand "paritysi2"
14094   [(set (match_operand:SI 0 "register_operand")
14095         (parity:SI (match_operand:SI 1 "register_operand")))]
14096   "! TARGET_POPCNT"
14098   rtx scratch = gen_reg_rtx (QImode);
14100   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14102   ix86_expand_setcc (scratch, ORDERED,
14103                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14105   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14106   DONE;
14109 (define_insn_and_split "paritydi2_cmp"
14110   [(set (reg:CC FLAGS_REG)
14111         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14112                    UNSPEC_PARITY))
14113    (clobber (match_scratch:DI 0 "=r"))
14114    (clobber (match_scratch:SI 1 "=&r"))
14115    (clobber (match_scratch:HI 2 "=Q"))]
14116   "! TARGET_POPCNT"
14117   "#"
14118   "&& reload_completed"
14119   [(parallel
14120      [(set (match_dup 1)
14121            (xor:SI (match_dup 1) (match_dup 4)))
14122       (clobber (reg:CC FLAGS_REG))])
14123    (parallel
14124      [(set (reg:CC FLAGS_REG)
14125            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14126       (clobber (match_dup 1))
14127       (clobber (match_dup 2))])]
14129   operands[4] = gen_lowpart (SImode, operands[3]);
14131   if (TARGET_64BIT)
14132     {
14133       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14134       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14135     }
14136   else
14137     operands[1] = gen_highpart (SImode, operands[3]);
14140 (define_insn_and_split "paritysi2_cmp"
14141   [(set (reg:CC FLAGS_REG)
14142         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14143                    UNSPEC_PARITY))
14144    (clobber (match_scratch:SI 0 "=r"))
14145    (clobber (match_scratch:HI 1 "=&Q"))]
14146   "! TARGET_POPCNT"
14147   "#"
14148   "&& reload_completed"
14149   [(parallel
14150      [(set (match_dup 1)
14151            (xor:HI (match_dup 1) (match_dup 3)))
14152       (clobber (reg:CC FLAGS_REG))])
14153    (parallel
14154      [(set (reg:CC FLAGS_REG)
14155            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14156       (clobber (match_dup 1))])]
14158   operands[3] = gen_lowpart (HImode, operands[2]);
14160   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14161   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14164 (define_insn "*parityhi2_cmp"
14165   [(set (reg:CC FLAGS_REG)
14166         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14167                    UNSPEC_PARITY))
14168    (clobber (match_scratch:HI 0 "=Q"))]
14169   "! TARGET_POPCNT"
14170   "xor{b}\t{%h0, %b0|%b0, %h0}"
14171   [(set_attr "length" "2")
14172    (set_attr "mode" "HI")])
14175 ;; Thread-local storage patterns for ELF.
14177 ;; Note that these code sequences must appear exactly as shown
14178 ;; in order to allow linker relaxation.
14180 (define_insn "*tls_global_dynamic_32_gnu"
14181   [(set (match_operand:SI 0 "register_operand" "=a")
14182         (unspec:SI
14183          [(match_operand:SI 1 "register_operand" "Yb")
14184           (match_operand 2 "tls_symbolic_operand")
14185           (match_operand 3 "constant_call_address_operand" "Bz")
14186           (reg:SI SP_REG)]
14187          UNSPEC_TLS_GD))
14188    (clobber (match_scratch:SI 4 "=d"))
14189    (clobber (match_scratch:SI 5 "=c"))
14190    (clobber (reg:CC FLAGS_REG))]
14191   "!TARGET_64BIT && TARGET_GNU_TLS"
14193   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14194     output_asm_insn
14195       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14196   else
14197     output_asm_insn
14198       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14199   if (TARGET_SUN_TLS)
14200 #ifdef HAVE_AS_IX86_TLSGDPLT
14201     return "call\t%a2@tlsgdplt";
14202 #else
14203     return "call\t%p3@plt";
14204 #endif
14205   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14206     return "call\t%P3";
14207   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14209   [(set_attr "type" "multi")
14210    (set_attr "length" "12")])
14212 (define_expand "tls_global_dynamic_32"
14213   [(parallel
14214     [(set (match_operand:SI 0 "register_operand")
14215           (unspec:SI [(match_operand:SI 2 "register_operand")
14216                       (match_operand 1 "tls_symbolic_operand")
14217                       (match_operand 3 "constant_call_address_operand")
14218                       (reg:SI SP_REG)]
14219                      UNSPEC_TLS_GD))
14220      (clobber (match_scratch:SI 4))
14221      (clobber (match_scratch:SI 5))
14222      (clobber (reg:CC FLAGS_REG))])]
14223   ""
14224   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14226 (define_insn "*tls_global_dynamic_64_<mode>"
14227   [(set (match_operand:P 0 "register_operand" "=a")
14228         (call:P
14229          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14230          (match_operand 3)))
14231    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14232               (reg:P SP_REG)]
14233              UNSPEC_TLS_GD)]
14234   "TARGET_64BIT"
14236   if (!TARGET_X32)
14237     /* The .loc directive has effect for 'the immediately following assembly
14238        instruction'.  So for a sequence:
14239          .loc f l
14240          .byte x
14241          insn1
14242        the 'immediately following assembly instruction' is insn1.
14243        We want to emit an insn prefix here, but if we use .byte (as shown in
14244        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14245        inside the insn sequence, rather than to the start.  After relaxation
14246        of the sequence by the linker, the .loc might point inside an insn.
14247        Use data16 prefix instead, which doesn't have this problem.  */
14248     fputs ("\tdata16", asm_out_file);
14249   output_asm_insn
14250     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14251   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14252     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14253   else
14254     fputs (ASM_BYTE "0x66\n", asm_out_file);
14255   fputs ("\trex64\n", asm_out_file);
14256   if (TARGET_SUN_TLS)
14257     return "call\t%p2@plt";
14258   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14259     return "call\t%P2";
14260   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14262   [(set_attr "type" "multi")
14263    (set (attr "length")
14264         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14266 (define_insn "*tls_global_dynamic_64_largepic"
14267   [(set (match_operand:DI 0 "register_operand" "=a")
14268         (call:DI
14269          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14270                           (match_operand:DI 3 "immediate_operand" "i")))
14271          (match_operand 4)))
14272    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14273                (reg:DI SP_REG)]
14274               UNSPEC_TLS_GD)]
14275   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14276    && GET_CODE (operands[3]) == CONST
14277    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14278    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14280   output_asm_insn
14281     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14282   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14283   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14284   return "call\t{*%%rax|rax}";
14286   [(set_attr "type" "multi")
14287    (set_attr "length" "22")])
14289 (define_expand "@tls_global_dynamic_64_<mode>"
14290   [(parallel
14291     [(set (match_operand:P 0 "register_operand")
14292           (call:P
14293            (mem:QI (match_operand 2))
14294            (const_int 0)))
14295      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14296                 (reg:P SP_REG)]
14297                UNSPEC_TLS_GD)])]
14298   "TARGET_64BIT"
14299   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14301 (define_insn "*tls_local_dynamic_base_32_gnu"
14302   [(set (match_operand:SI 0 "register_operand" "=a")
14303         (unspec:SI
14304          [(match_operand:SI 1 "register_operand" "Yb")
14305           (match_operand 2 "constant_call_address_operand" "Bz")
14306           (reg:SI SP_REG)]
14307          UNSPEC_TLS_LD_BASE))
14308    (clobber (match_scratch:SI 3 "=d"))
14309    (clobber (match_scratch:SI 4 "=c"))
14310    (clobber (reg:CC FLAGS_REG))]
14311   "!TARGET_64BIT && TARGET_GNU_TLS"
14313   output_asm_insn
14314     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14315   if (TARGET_SUN_TLS)
14316     {
14317       if (HAVE_AS_IX86_TLSLDMPLT)
14318         return "call\t%&@tlsldmplt";
14319       else
14320         return "call\t%p2@plt";
14321     }
14322   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14323     return "call\t%P2";
14324   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14326   [(set_attr "type" "multi")
14327    (set_attr "length" "11")])
14329 (define_expand "tls_local_dynamic_base_32"
14330   [(parallel
14331      [(set (match_operand:SI 0 "register_operand")
14332            (unspec:SI
14333             [(match_operand:SI 1 "register_operand")
14334              (match_operand 2 "constant_call_address_operand")
14335              (reg:SI SP_REG)]
14336             UNSPEC_TLS_LD_BASE))
14337       (clobber (match_scratch:SI 3))
14338       (clobber (match_scratch:SI 4))
14339       (clobber (reg:CC FLAGS_REG))])]
14340   ""
14341   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14343 (define_insn "*tls_local_dynamic_base_64_<mode>"
14344   [(set (match_operand:P 0 "register_operand" "=a")
14345         (call:P
14346          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14347          (match_operand 2)))
14348    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14349   "TARGET_64BIT"
14351   output_asm_insn
14352     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14353   if (TARGET_SUN_TLS)
14354     return "call\t%p1@plt";
14355   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14356     return "call\t%P1";
14357   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14359   [(set_attr "type" "multi")
14360    (set_attr "length" "12")])
14362 (define_insn "*tls_local_dynamic_base_64_largepic"
14363   [(set (match_operand:DI 0 "register_operand" "=a")
14364         (call:DI
14365          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14366                           (match_operand:DI 2 "immediate_operand" "i")))
14367          (match_operand 3)))
14368    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14369   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14370    && GET_CODE (operands[2]) == CONST
14371    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14372    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14374   output_asm_insn
14375     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14376   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14377   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14378   return "call\t{*%%rax|rax}";
14380   [(set_attr "type" "multi")
14381    (set_attr "length" "22")])
14383 (define_expand "@tls_local_dynamic_base_64_<mode>"
14384   [(parallel
14385      [(set (match_operand:P 0 "register_operand")
14386            (call:P
14387             (mem:QI (match_operand 1))
14388             (const_int 0)))
14389       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14390   "TARGET_64BIT"
14391   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14393 ;; Local dynamic of a single variable is a lose.  Show combine how
14394 ;; to convert that back to global dynamic.
14396 (define_insn_and_split "*tls_local_dynamic_32_once"
14397   [(set (match_operand:SI 0 "register_operand" "=a")
14398         (plus:SI
14399          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14400                      (match_operand 2 "constant_call_address_operand" "Bz")
14401                      (reg:SI SP_REG)]
14402                     UNSPEC_TLS_LD_BASE)
14403          (const:SI (unspec:SI
14404                     [(match_operand 3 "tls_symbolic_operand")]
14405                     UNSPEC_DTPOFF))))
14406    (clobber (match_scratch:SI 4 "=d"))
14407    (clobber (match_scratch:SI 5 "=c"))
14408    (clobber (reg:CC FLAGS_REG))]
14409   ""
14410   "#"
14411   ""
14412   [(parallel
14413      [(set (match_dup 0)
14414            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14415                        (reg:SI SP_REG)]
14416                       UNSPEC_TLS_GD))
14417       (clobber (match_dup 4))
14418       (clobber (match_dup 5))
14419       (clobber (reg:CC FLAGS_REG))])])
14421 ;; Load and add the thread base pointer from %<tp_seg>:0.
14422 (define_insn_and_split "*load_tp_<mode>"
14423   [(set (match_operand:PTR 0 "register_operand" "=r")
14424         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14425   ""
14426   "#"
14427   ""
14428   [(set (match_dup 0)
14429         (match_dup 1))]
14431   addr_space_t as = DEFAULT_TLS_SEG_REG;
14433   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14434   set_mem_addr_space (operands[1], as);
14437 (define_insn_and_split "*load_tp_x32_zext"
14438   [(set (match_operand:DI 0 "register_operand" "=r")
14439         (zero_extend:DI
14440           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14441   "TARGET_X32"
14442   "#"
14443   ""
14444   [(set (match_dup 0)
14445         (zero_extend:DI (match_dup 1)))]
14447   addr_space_t as = DEFAULT_TLS_SEG_REG;
14449   operands[1] = gen_const_mem (SImode, const0_rtx);
14450   set_mem_addr_space (operands[1], as);
14453 (define_insn_and_split "*add_tp_<mode>"
14454   [(set (match_operand:PTR 0 "register_operand" "=r")
14455         (plus:PTR
14456           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14457           (match_operand:PTR 1 "register_operand" "0")))
14458    (clobber (reg:CC FLAGS_REG))]
14459   ""
14460   "#"
14461   ""
14462   [(parallel
14463      [(set (match_dup 0)
14464            (plus:PTR (match_dup 1) (match_dup 2)))
14465       (clobber (reg:CC FLAGS_REG))])]
14467   addr_space_t as = DEFAULT_TLS_SEG_REG;
14469   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14470   set_mem_addr_space (operands[2], as);
14473 (define_insn_and_split "*add_tp_x32_zext"
14474   [(set (match_operand:DI 0 "register_operand" "=r")
14475         (zero_extend:DI
14476           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14477                    (match_operand:SI 1 "register_operand" "0"))))
14478    (clobber (reg:CC FLAGS_REG))]
14479   "TARGET_X32"
14480   "#"
14481   ""
14482   [(parallel
14483      [(set (match_dup 0)
14484            (zero_extend:DI
14485              (plus:SI (match_dup 1) (match_dup 2))))
14486       (clobber (reg:CC FLAGS_REG))])]
14488   addr_space_t as = DEFAULT_TLS_SEG_REG;
14490   operands[2] = gen_const_mem (SImode, const0_rtx);
14491   set_mem_addr_space (operands[2], as);
14494 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14495 ;; %rax as destination of the initial executable code sequence.
14496 (define_insn "tls_initial_exec_64_sun"
14497   [(set (match_operand:DI 0 "register_operand" "=a")
14498         (unspec:DI
14499          [(match_operand 1 "tls_symbolic_operand")]
14500          UNSPEC_TLS_IE_SUN))
14501    (clobber (reg:CC FLAGS_REG))]
14502   "TARGET_64BIT && TARGET_SUN_TLS"
14504   output_asm_insn
14505     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14506   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14508   [(set_attr "type" "multi")])
14510 ;; GNU2 TLS patterns can be split.
14512 (define_expand "tls_dynamic_gnu2_32"
14513   [(set (match_dup 3)
14514         (plus:SI (match_operand:SI 2 "register_operand")
14515                  (const:SI
14516                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14517                              UNSPEC_TLSDESC))))
14518    (parallel
14519     [(set (match_operand:SI 0 "register_operand")
14520           (unspec:SI [(match_dup 1) (match_dup 3)
14521                       (match_dup 2) (reg:SI SP_REG)]
14522                       UNSPEC_TLSDESC))
14523      (clobber (reg:CC FLAGS_REG))])]
14524   "!TARGET_64BIT && TARGET_GNU2_TLS"
14526   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14527   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14530 (define_insn "*tls_dynamic_gnu2_lea_32"
14531   [(set (match_operand:SI 0 "register_operand" "=r")
14532         (plus:SI (match_operand:SI 1 "register_operand" "b")
14533                  (const:SI
14534                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14535                               UNSPEC_TLSDESC))))]
14536   "!TARGET_64BIT && TARGET_GNU2_TLS"
14537   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14538   [(set_attr "type" "lea")
14539    (set_attr "mode" "SI")
14540    (set_attr "length" "6")
14541    (set_attr "length_address" "4")])
14543 (define_insn "*tls_dynamic_gnu2_call_32"
14544   [(set (match_operand:SI 0 "register_operand" "=a")
14545         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14546                     (match_operand:SI 2 "register_operand" "0")
14547                     ;; we have to make sure %ebx still points to the GOT
14548                     (match_operand:SI 3 "register_operand" "b")
14549                     (reg:SI SP_REG)]
14550                    UNSPEC_TLSDESC))
14551    (clobber (reg:CC FLAGS_REG))]
14552   "!TARGET_64BIT && TARGET_GNU2_TLS"
14553   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14554   [(set_attr "type" "call")
14555    (set_attr "length" "2")
14556    (set_attr "length_address" "0")])
14558 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14559   [(set (match_operand:SI 0 "register_operand" "=&a")
14560         (plus:SI
14561          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14562                      (match_operand:SI 4)
14563                      (match_operand:SI 2 "register_operand" "b")
14564                      (reg:SI SP_REG)]
14565                     UNSPEC_TLSDESC)
14566          (const:SI (unspec:SI
14567                     [(match_operand 1 "tls_symbolic_operand")]
14568                     UNSPEC_DTPOFF))))
14569    (clobber (reg:CC FLAGS_REG))]
14570   "!TARGET_64BIT && TARGET_GNU2_TLS"
14571   "#"
14572   ""
14573   [(set (match_dup 0) (match_dup 5))]
14575   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14576   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14579 (define_expand "tls_dynamic_gnu2_64"
14580   [(set (match_dup 2)
14581         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14582                    UNSPEC_TLSDESC))
14583    (parallel
14584     [(set (match_operand:DI 0 "register_operand")
14585           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14586                      UNSPEC_TLSDESC))
14587      (clobber (reg:CC FLAGS_REG))])]
14588   "TARGET_64BIT && TARGET_GNU2_TLS"
14590   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14591   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14594 (define_insn "*tls_dynamic_gnu2_lea_64"
14595   [(set (match_operand:DI 0 "register_operand" "=r")
14596         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14597                    UNSPEC_TLSDESC))]
14598   "TARGET_64BIT && TARGET_GNU2_TLS"
14599   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14600   [(set_attr "type" "lea")
14601    (set_attr "mode" "DI")
14602    (set_attr "length" "7")
14603    (set_attr "length_address" "4")])
14605 (define_insn "*tls_dynamic_gnu2_call_64"
14606   [(set (match_operand:DI 0 "register_operand" "=a")
14607         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14608                     (match_operand:DI 2 "register_operand" "0")
14609                     (reg:DI SP_REG)]
14610                    UNSPEC_TLSDESC))
14611    (clobber (reg:CC FLAGS_REG))]
14612   "TARGET_64BIT && TARGET_GNU2_TLS"
14613   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14614   [(set_attr "type" "call")
14615    (set_attr "length" "2")
14616    (set_attr "length_address" "0")])
14618 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14619   [(set (match_operand:DI 0 "register_operand" "=&a")
14620         (plus:DI
14621          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14622                      (match_operand:DI 3)
14623                      (reg:DI SP_REG)]
14624                     UNSPEC_TLSDESC)
14625          (const:DI (unspec:DI
14626                     [(match_operand 1 "tls_symbolic_operand")]
14627                     UNSPEC_DTPOFF))))
14628    (clobber (reg:CC FLAGS_REG))]
14629   "TARGET_64BIT && TARGET_GNU2_TLS"
14630   "#"
14631   ""
14632   [(set (match_dup 0) (match_dup 4))]
14634   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14635   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14638 (define_split
14639   [(match_operand 0 "tls_address_pattern")]
14640   "TARGET_TLS_DIRECT_SEG_REFS"
14641   [(match_dup 0)]
14642   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14645 ;; These patterns match the binary 387 instructions for addM3, subM3,
14646 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14647 ;; SFmode.  The first is the normal insn, the second the same insn but
14648 ;; with one operand a conversion, and the third the same insn but with
14649 ;; the other operand a conversion.  The conversion may be SFmode or
14650 ;; SImode if the target mode DFmode, but only SImode if the target mode
14651 ;; is SFmode.
14653 ;; Gcc is slightly more smart about handling normal two address instructions
14654 ;; so use special patterns for add and mull.
14656 (define_insn "*fop_xf_comm_i387"
14657   [(set (match_operand:XF 0 "register_operand" "=f")
14658         (match_operator:XF 3 "binary_fp_operator"
14659                         [(match_operand:XF 1 "register_operand" "%0")
14660                          (match_operand:XF 2 "register_operand" "f")]))]
14661   "TARGET_80387
14662    && COMMUTATIVE_ARITH_P (operands[3])"
14663   "* return output_387_binary_op (insn, operands);"
14664   [(set (attr "type")
14665         (if_then_else (match_operand:XF 3 "mult_operator")
14666            (const_string "fmul")
14667            (const_string "fop")))
14668    (set_attr "mode" "XF")])
14670 (define_insn "*fop_<mode>_comm"
14671   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14672         (match_operator:MODEF 3 "binary_fp_operator"
14673           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14674            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14675   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14676     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14677    && COMMUTATIVE_ARITH_P (operands[3])
14678    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14679   "* return output_387_binary_op (insn, operands);"
14680   [(set (attr "type")
14681         (if_then_else (eq_attr "alternative" "1,2")
14682            (if_then_else (match_operand:MODEF 3 "mult_operator")
14683               (const_string "ssemul")
14684               (const_string "sseadd"))
14685            (if_then_else (match_operand:MODEF 3 "mult_operator")
14686               (const_string "fmul")
14687               (const_string "fop"))))
14688    (set_attr "isa" "*,noavx,avx")
14689    (set_attr "prefix" "orig,orig,vex")
14690    (set_attr "mode" "<MODE>")
14691    (set (attr "enabled")
14692      (if_then_else
14693        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14694        (if_then_else
14695          (eq_attr "alternative" "0")
14696          (symbol_ref "TARGET_MIX_SSE_I387
14697                       && X87_ENABLE_ARITH (<MODE>mode)")
14698          (const_string "*"))
14699        (if_then_else
14700          (eq_attr "alternative" "0")
14701          (symbol_ref "true")
14702          (symbol_ref "false"))))])
14704 (define_insn "*rcpsf2_sse"
14705   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14706         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14707                    UNSPEC_RCP))]
14708   "TARGET_SSE && TARGET_SSE_MATH"
14709   "@
14710    %vrcpss\t{%d1, %0|%0, %d1}
14711    %vrcpss\t{%d1, %0|%0, %d1}
14712    %vrcpss\t{%1, %d0|%d0, %1}"
14713   [(set_attr "type" "sse")
14714    (set_attr "atom_sse_attr" "rcp")
14715    (set_attr "btver2_sse_attr" "rcp")
14716    (set_attr "prefix" "maybe_vex")
14717    (set_attr "mode" "SF")
14718    (set (attr "preferred_for_speed")
14719      (cond [(eq_attr "alternative" "1")
14720               (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14721            (eq_attr "alternative" "2")
14722               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14723            ]
14724            (symbol_ref "true")))])
14726 (define_insn "*fop_xf_1_i387"
14727   [(set (match_operand:XF 0 "register_operand" "=f,f")
14728         (match_operator:XF 3 "binary_fp_operator"
14729                         [(match_operand:XF 1 "register_operand" "0,f")
14730                          (match_operand:XF 2 "register_operand" "f,0")]))]
14731   "TARGET_80387
14732    && !COMMUTATIVE_ARITH_P (operands[3])"
14733   "* return output_387_binary_op (insn, operands);"
14734   [(set (attr "type")
14735         (if_then_else (match_operand:XF 3 "div_operator")
14736            (const_string "fdiv")
14737            (const_string "fop")))
14738    (set_attr "mode" "XF")])
14740 (define_insn "*fop_<mode>_1"
14741   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14742         (match_operator:MODEF 3 "binary_fp_operator"
14743           [(match_operand:MODEF 1
14744              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14745            (match_operand:MODEF 2
14746              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14747   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14748     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14749    && !COMMUTATIVE_ARITH_P (operands[3])
14750    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14751   "* return output_387_binary_op (insn, operands);"
14752   [(set (attr "type")
14753         (if_then_else (eq_attr "alternative" "2,3")
14754            (if_then_else (match_operand:MODEF 3 "div_operator")
14755               (const_string "ssediv")
14756               (const_string "sseadd"))
14757            (if_then_else (match_operand:MODEF 3 "div_operator")
14758               (const_string "fdiv")
14759               (const_string "fop"))))
14760    (set_attr "isa" "*,*,noavx,avx")
14761    (set_attr "prefix" "orig,orig,orig,vex")
14762    (set_attr "mode" "<MODE>")
14763    (set (attr "enabled")
14764      (if_then_else
14765        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14766        (if_then_else
14767          (eq_attr "alternative" "0,1")
14768          (symbol_ref "TARGET_MIX_SSE_I387
14769                       && X87_ENABLE_ARITH (<MODE>mode)")
14770          (const_string "*"))
14771        (if_then_else
14772          (eq_attr "alternative" "0,1")
14773          (symbol_ref "true")
14774          (symbol_ref "false"))))])
14776 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14777   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14778         (match_operator:X87MODEF 3 "binary_fp_operator"
14779           [(float:X87MODEF
14780              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14781            (match_operand:X87MODEF 2 "register_operand" "0")]))]
14782   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14783    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14784    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14785        || optimize_function_for_size_p (cfun))"
14786   "* return output_387_binary_op (insn, operands);"
14787   [(set (attr "type")
14788         (cond [(match_operand:X87MODEF 3 "mult_operator")
14789                  (const_string "fmul")
14790                (match_operand:X87MODEF 3 "div_operator")
14791                  (const_string "fdiv")
14792               ]
14793               (const_string "fop")))
14794    (set_attr "fp_int_src" "true")
14795    (set_attr "mode" "<SWI24:MODE>")])
14797 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14798   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14799         (match_operator:X87MODEF 3 "binary_fp_operator"
14800           [(match_operand:X87MODEF 1 "register_operand" "0")
14801            (float:X87MODEF
14802              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14803   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14804    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14805    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14806        || optimize_function_for_size_p (cfun))"
14807   "* return output_387_binary_op (insn, operands);"
14808   [(set (attr "type")
14809         (cond [(match_operand:X87MODEF 3 "mult_operator")
14810                  (const_string "fmul")
14811                (match_operand:X87MODEF 3 "div_operator")
14812                  (const_string "fdiv")
14813               ]
14814               (const_string "fop")))
14815    (set_attr "fp_int_src" "true")
14816    (set_attr "mode" "<MODE>")])
14818 (define_insn "*fop_xf_4_i387"
14819   [(set (match_operand:XF 0 "register_operand" "=f,f")
14820         (match_operator:XF 3 "binary_fp_operator"
14821            [(float_extend:XF
14822               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14823             (match_operand:XF 2 "register_operand" "0,f")]))]
14824   "TARGET_80387"
14825   "* return output_387_binary_op (insn, operands);"
14826   [(set (attr "type")
14827         (cond [(match_operand:XF 3 "mult_operator")
14828                  (const_string "fmul")
14829                (match_operand:XF 3 "div_operator")
14830                  (const_string "fdiv")
14831               ]
14832               (const_string "fop")))
14833    (set_attr "mode" "<MODE>")])
14835 (define_insn "*fop_df_4_i387"
14836   [(set (match_operand:DF 0 "register_operand" "=f,f")
14837         (match_operator:DF 3 "binary_fp_operator"
14838            [(float_extend:DF
14839              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14840             (match_operand:DF 2 "register_operand" "0,f")]))]
14841   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14842    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14843   "* return output_387_binary_op (insn, operands);"
14844   [(set (attr "type")
14845         (cond [(match_operand:DF 3 "mult_operator")
14846                  (const_string "fmul")
14847                (match_operand:DF 3 "div_operator")
14848                  (const_string "fdiv")
14849               ]
14850               (const_string "fop")))
14851    (set_attr "mode" "SF")])
14853 (define_insn "*fop_xf_5_i387"
14854   [(set (match_operand:XF 0 "register_operand" "=f,f")
14855         (match_operator:XF 3 "binary_fp_operator"
14856           [(match_operand:XF 1 "register_operand" "0,f")
14857            (float_extend:XF
14858              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14859   "TARGET_80387"
14860   "* return output_387_binary_op (insn, operands);"
14861   [(set (attr "type")
14862         (cond [(match_operand:XF 3 "mult_operator")
14863                  (const_string "fmul")
14864                (match_operand:XF 3 "div_operator")
14865                  (const_string "fdiv")
14866               ]
14867               (const_string "fop")))
14868    (set_attr "mode" "<MODE>")])
14870 (define_insn "*fop_df_5_i387"
14871   [(set (match_operand:DF 0 "register_operand" "=f,f")
14872         (match_operator:DF 3 "binary_fp_operator"
14873           [(match_operand:DF 1 "register_operand" "0,f")
14874            (float_extend:DF
14875             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14876   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14877    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14878   "* return output_387_binary_op (insn, operands);"
14879   [(set (attr "type")
14880         (cond [(match_operand:DF 3 "mult_operator")
14881                  (const_string "fmul")
14882                (match_operand:DF 3 "div_operator")
14883                  (const_string "fdiv")
14884               ]
14885               (const_string "fop")))
14886    (set_attr "mode" "SF")])
14888 (define_insn "*fop_xf_6_i387"
14889   [(set (match_operand:XF 0 "register_operand" "=f,f")
14890         (match_operator:XF 3 "binary_fp_operator"
14891           [(float_extend:XF
14892              (match_operand:MODEF 1 "register_operand" "0,f"))
14893            (float_extend:XF
14894              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14895   "TARGET_80387"
14896   "* return output_387_binary_op (insn, operands);"
14897   [(set (attr "type")
14898         (cond [(match_operand:XF 3 "mult_operator")
14899                  (const_string "fmul")
14900                (match_operand:XF 3 "div_operator")
14901                  (const_string "fdiv")
14902               ]
14903               (const_string "fop")))
14904    (set_attr "mode" "<MODE>")])
14906 (define_insn "*fop_df_6_i387"
14907   [(set (match_operand:DF 0 "register_operand" "=f,f")
14908         (match_operator:DF 3 "binary_fp_operator"
14909           [(float_extend:DF
14910             (match_operand:SF 1 "register_operand" "0,f"))
14911            (float_extend:DF
14912             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14913   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14914    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14915   "* return output_387_binary_op (insn, operands);"
14916   [(set (attr "type")
14917         (cond [(match_operand:DF 3 "mult_operator")
14918                  (const_string "fmul")
14919                (match_operand:DF 3 "div_operator")
14920                  (const_string "fdiv")
14921               ]
14922               (const_string "fop")))
14923    (set_attr "mode" "SF")])
14925 ;; FPU special functions.
14927 ;; This pattern implements a no-op XFmode truncation for
14928 ;; all fancy i386 XFmode math functions.
14930 (define_insn "truncxf<mode>2_i387_noop_unspec"
14931   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14932         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14933         UNSPEC_TRUNC_NOOP))]
14934   "TARGET_USE_FANCY_MATH_387"
14935   "* return output_387_reg_move (insn, operands);"
14936   [(set_attr "type" "fmov")
14937    (set_attr "mode" "<MODE>")])
14939 (define_insn "sqrtxf2"
14940   [(set (match_operand:XF 0 "register_operand" "=f")
14941         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14942   "TARGET_USE_FANCY_MATH_387"
14943   "fsqrt"
14944   [(set_attr "type" "fpspc")
14945    (set_attr "mode" "XF")
14946    (set_attr "athlon_decode" "direct")
14947    (set_attr "amdfam10_decode" "direct")
14948    (set_attr "bdver1_decode" "direct")])
14950 (define_insn "*rsqrtsf2_sse"
14951   [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14952         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14953                    UNSPEC_RSQRT))]
14954   "TARGET_SSE && TARGET_SSE_MATH"
14955   "@
14956    %vrsqrtss\t{%d1, %0|%0, %d1}
14957    %vrsqrtss\t{%d1, %0|%0, %d1}
14958    %vrsqrtss\t{%1, %d0|%d0, %1}"
14959   [(set_attr "type" "sse")
14960    (set_attr "atom_sse_attr" "rcp")
14961    (set_attr "btver2_sse_attr" "rcp")
14962    (set_attr "prefix" "maybe_vex")
14963    (set_attr "mode" "SF")
14964    (set (attr "preferred_for_speed")
14965      (cond [(eq_attr "alternative" "1")
14966               (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14967            (eq_attr "alternative" "2")
14968               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14969            ]
14970            (symbol_ref "true")))])
14972 (define_expand "rsqrtsf2"
14973   [(set (match_operand:SF 0 "register_operand")
14974         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14975                    UNSPEC_RSQRT))]
14976   "TARGET_SSE && TARGET_SSE_MATH"
14978   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14979   DONE;
14982 (define_insn "*sqrt<mode>2_sse"
14983   [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
14984         (sqrt:MODEF
14985           (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
14986   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14987   "@
14988    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14989    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14990    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14991   [(set_attr "type" "sse")
14992    (set_attr "atom_sse_attr" "sqrt")
14993    (set_attr "btver2_sse_attr" "sqrt")
14994    (set_attr "prefix" "maybe_vex")
14995    (set_attr "mode" "<MODE>")
14996    (set (attr "preferred_for_speed")
14997      (cond [(eq_attr "alternative" "1")
14998               (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14999            (eq_attr "alternative" "2")
15000               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15001            ]
15002            (symbol_ref "true")))])
15004 (define_expand "sqrt<mode>2"
15005   [(set (match_operand:MODEF 0 "register_operand")
15006         (sqrt:MODEF
15007           (match_operand:MODEF 1 "nonimmediate_operand")))]
15008   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15009    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15011   if (<MODE>mode == SFmode
15012       && TARGET_SSE && TARGET_SSE_MATH
15013       && TARGET_RECIP_SQRT
15014       && !optimize_function_for_size_p (cfun)
15015       && flag_finite_math_only && !flag_trapping_math
15016       && flag_unsafe_math_optimizations)
15017     {
15018       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15019       DONE;
15020     }
15022   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15023     {
15024       rtx op0 = gen_reg_rtx (XFmode);
15025       rtx op1 = gen_reg_rtx (XFmode);
15027       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15028       emit_insn (gen_sqrtxf2 (op0, op1));
15029       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15030       DONE;
15031    }
15034 (define_expand "hypot<mode>3"
15035   [(use (match_operand:MODEF 0 "register_operand"))
15036    (use (match_operand:MODEF 1 "general_operand"))
15037    (use (match_operand:MODEF 2 "general_operand"))]
15038   "TARGET_USE_FANCY_MATH_387
15039    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15040        || TARGET_MIX_SSE_I387)
15041    && flag_finite_math_only
15042    && flag_unsafe_math_optimizations"
15044   rtx op0 = gen_reg_rtx (XFmode);
15045   rtx op1 = gen_reg_rtx (XFmode);
15046   rtx op2 = gen_reg_rtx (XFmode);
15048   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15049   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15051   emit_insn (gen_mulxf3 (op1, op1, op1));
15052   emit_insn (gen_mulxf3 (op2, op2, op2));
15053   emit_insn (gen_addxf3 (op0, op2, op1));
15054   emit_insn (gen_sqrtxf2 (op0, op0));
15056   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15057   DONE;
15060 (define_insn "x86_fnstsw_1"
15061   [(set (match_operand:HI 0 "register_operand" "=a")
15062         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
15063   "TARGET_80387"
15064   "fnstsw\t%0"
15065   [(set_attr "length" "2")
15066    (set_attr "mode" "SI")
15067    (set_attr "unit" "i387")])
15069 (define_insn "fpremxf4_i387"
15070   [(set (match_operand:XF 0 "register_operand" "=f")
15071         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15072                     (match_operand:XF 3 "register_operand" "1")]
15073                    UNSPEC_FPREM_F))
15074    (set (match_operand:XF 1 "register_operand" "=f")
15075         (unspec:XF [(match_dup 2) (match_dup 3)]
15076                    UNSPEC_FPREM_U))
15077    (set (reg:CCFP FPSR_REG)
15078         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15079                      UNSPEC_C2_FLAG))]
15080   "TARGET_USE_FANCY_MATH_387
15081    && flag_finite_math_only"
15082   "fprem"
15083   [(set_attr "type" "fpspc")
15084    (set_attr "znver1_decode" "vector")
15085    (set_attr "mode" "XF")])
15087 (define_expand "fmodxf3"
15088   [(use (match_operand:XF 0 "register_operand"))
15089    (use (match_operand:XF 1 "general_operand"))
15090    (use (match_operand:XF 2 "general_operand"))]
15091   "TARGET_USE_FANCY_MATH_387
15092    && flag_finite_math_only"
15094   rtx_code_label *label = gen_label_rtx ();
15096   rtx op1 = gen_reg_rtx (XFmode);
15097   rtx op2 = gen_reg_rtx (XFmode);
15099   emit_move_insn (op2, operands[2]);
15100   emit_move_insn (op1, operands[1]);
15102   emit_label (label);
15103   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15104   ix86_emit_fp_unordered_jump (label);
15105   LABEL_NUSES (label) = 1;
15107   emit_move_insn (operands[0], op1);
15108   DONE;
15111 (define_expand "fmod<mode>3"
15112   [(use (match_operand:MODEF 0 "register_operand"))
15113    (use (match_operand:MODEF 1 "general_operand"))
15114    (use (match_operand:MODEF 2 "general_operand"))]
15115   "TARGET_USE_FANCY_MATH_387
15116    && flag_finite_math_only"
15118   rtx (*gen_truncxf) (rtx, rtx);
15120   rtx_code_label *label = gen_label_rtx ();
15122   rtx op1 = gen_reg_rtx (XFmode);
15123   rtx op2 = gen_reg_rtx (XFmode);
15125   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15126   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15128   emit_label (label);
15129   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15130   ix86_emit_fp_unordered_jump (label);
15131   LABEL_NUSES (label) = 1;
15133   /* Truncate the result properly for strict SSE math.  */
15134   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15135       && !TARGET_MIX_SSE_I387)
15136     gen_truncxf = gen_truncxf<mode>2;
15137   else
15138     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15140   emit_insn (gen_truncxf (operands[0], op1));
15141   DONE;
15144 (define_insn "fprem1xf4_i387"
15145   [(set (match_operand:XF 0 "register_operand" "=f")
15146         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15147                     (match_operand:XF 3 "register_operand" "1")]
15148                    UNSPEC_FPREM1_F))
15149    (set (match_operand:XF 1 "register_operand" "=f")
15150         (unspec:XF [(match_dup 2) (match_dup 3)]
15151                    UNSPEC_FPREM1_U))
15152    (set (reg:CCFP FPSR_REG)
15153         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15154                      UNSPEC_C2_FLAG))]
15155   "TARGET_USE_FANCY_MATH_387
15156    && flag_finite_math_only"
15157   "fprem1"
15158   [(set_attr "type" "fpspc")
15159    (set_attr "znver1_decode" "vector")
15160    (set_attr "mode" "XF")])
15162 (define_expand "remainderxf3"
15163   [(use (match_operand:XF 0 "register_operand"))
15164    (use (match_operand:XF 1 "general_operand"))
15165    (use (match_operand:XF 2 "general_operand"))]
15166   "TARGET_USE_FANCY_MATH_387
15167    && flag_finite_math_only"
15169   rtx_code_label *label = gen_label_rtx ();
15171   rtx op1 = gen_reg_rtx (XFmode);
15172   rtx op2 = gen_reg_rtx (XFmode);
15174   emit_move_insn (op2, operands[2]);
15175   emit_move_insn (op1, operands[1]);
15177   emit_label (label);
15178   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15179   ix86_emit_fp_unordered_jump (label);
15180   LABEL_NUSES (label) = 1;
15182   emit_move_insn (operands[0], op1);
15183   DONE;
15186 (define_expand "remainder<mode>3"
15187   [(use (match_operand:MODEF 0 "register_operand"))
15188    (use (match_operand:MODEF 1 "general_operand"))
15189    (use (match_operand:MODEF 2 "general_operand"))]
15190   "TARGET_USE_FANCY_MATH_387
15191    && flag_finite_math_only"
15193   rtx (*gen_truncxf) (rtx, rtx);
15195   rtx_code_label *label = gen_label_rtx ();
15197   rtx op1 = gen_reg_rtx (XFmode);
15198   rtx op2 = gen_reg_rtx (XFmode);
15200   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15201   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15203   emit_label (label);
15205   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15206   ix86_emit_fp_unordered_jump (label);
15207   LABEL_NUSES (label) = 1;
15209   /* Truncate the result properly for strict SSE math.  */
15210   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15211       && !TARGET_MIX_SSE_I387)
15212     gen_truncxf = gen_truncxf<mode>2;
15213   else
15214     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15216   emit_insn (gen_truncxf (operands[0], op1));
15217   DONE;
15220 (define_int_iterator SINCOS
15221         [UNSPEC_SIN
15222          UNSPEC_COS])
15224 (define_int_attr sincos
15225         [(UNSPEC_SIN "sin")
15226          (UNSPEC_COS "cos")])
15228 (define_insn "<sincos>xf2"
15229   [(set (match_operand:XF 0 "register_operand" "=f")
15230         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15231                    SINCOS))]
15232   "TARGET_USE_FANCY_MATH_387
15233    && flag_unsafe_math_optimizations"
15234   "f<sincos>"
15235   [(set_attr "type" "fpspc")
15236    (set_attr "znver1_decode" "vector")
15237    (set_attr "mode" "XF")])
15239 (define_expand "<sincos><mode>2"
15240   [(set (match_operand:MODEF 0 "register_operand")
15241         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15242                       SINCOS))]
15243   "TARGET_USE_FANCY_MATH_387
15244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15245        || TARGET_MIX_SSE_I387)
15246    && flag_unsafe_math_optimizations"
15248   rtx op0 = gen_reg_rtx (XFmode);
15249   rtx op1 = gen_reg_rtx (XFmode);
15251   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15252   emit_insn (gen_<sincos>xf2 (op0, op1));
15253   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15254   DONE;
15257 (define_insn "sincosxf3"
15258   [(set (match_operand:XF 0 "register_operand" "=f")
15259         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15260                    UNSPEC_SINCOS_COS))
15261    (set (match_operand:XF 1 "register_operand" "=f")
15262         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && flag_unsafe_math_optimizations"
15265   "fsincos"
15266   [(set_attr "type" "fpspc")
15267    (set_attr "znver1_decode" "vector")
15268    (set_attr "mode" "XF")])
15270 (define_expand "sincos<mode>3"
15271   [(use (match_operand:MODEF 0 "register_operand"))
15272    (use (match_operand:MODEF 1 "register_operand"))
15273    (use (match_operand:MODEF 2 "general_operand"))]
15274   "TARGET_USE_FANCY_MATH_387
15275    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15276        || TARGET_MIX_SSE_I387)
15277    && flag_unsafe_math_optimizations"
15279   rtx op0 = gen_reg_rtx (XFmode);
15280   rtx op1 = gen_reg_rtx (XFmode);
15281   rtx op2 = gen_reg_rtx (XFmode);
15283   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15284   emit_insn (gen_sincosxf3 (op0, op1, op2));
15285   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15286   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15287   DONE;
15290 (define_insn "fptanxf4_i387"
15291   [(set (match_operand:SF 0 "register_operand" "=f")
15292         (match_operand:SF 3 "const1_operand"))
15293    (set (match_operand:XF 1 "register_operand" "=f")
15294         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15295                    UNSPEC_TAN))]
15296   "TARGET_USE_FANCY_MATH_387
15297    && flag_unsafe_math_optimizations"
15298   "fptan"
15299   [(set_attr "type" "fpspc")
15300    (set_attr "znver1_decode" "vector")
15301    (set_attr "mode" "XF")])
15303 (define_expand "tanxf2"
15304   [(use (match_operand:XF 0 "register_operand"))
15305    (use (match_operand:XF 1 "register_operand"))]
15306   "TARGET_USE_FANCY_MATH_387
15307    && flag_unsafe_math_optimizations"
15309   rtx one = gen_reg_rtx (SFmode);
15310   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15311                                 CONST1_RTX (SFmode)));
15312   DONE;
15315 (define_expand "tan<mode>2"
15316   [(use (match_operand:MODEF 0 "register_operand"))
15317    (use (match_operand:MODEF 1 "general_operand"))]
15318   "TARGET_USE_FANCY_MATH_387
15319    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15320        || TARGET_MIX_SSE_I387)
15321    && flag_unsafe_math_optimizations"
15323   rtx op0 = gen_reg_rtx (XFmode);
15324   rtx op1 = gen_reg_rtx (XFmode);
15326   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15327   emit_insn (gen_tanxf2 (op0, op1));
15328   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15329   DONE;
15332 (define_insn "atan2xf3"
15333   [(set (match_operand:XF 0 "register_operand" "=f")
15334         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15335                     (match_operand:XF 2 "register_operand" "f")]
15336                    UNSPEC_FPATAN))
15337    (clobber (match_scratch:XF 3 "=2"))]
15338   "TARGET_USE_FANCY_MATH_387
15339    && flag_unsafe_math_optimizations"
15340   "fpatan"
15341   [(set_attr "type" "fpspc")
15342    (set_attr "znver1_decode" "vector")
15343    (set_attr "mode" "XF")])
15345 (define_expand "atan2<mode>3"
15346   [(use (match_operand:MODEF 0 "register_operand"))
15347    (use (match_operand:MODEF 1 "general_operand"))
15348    (use (match_operand:MODEF 2 "general_operand"))]
15349   "TARGET_USE_FANCY_MATH_387
15350    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15351        || TARGET_MIX_SSE_I387)
15352    && flag_unsafe_math_optimizations"
15354   rtx op0 = gen_reg_rtx (XFmode);
15355   rtx op1 = gen_reg_rtx (XFmode);
15356   rtx op2 = gen_reg_rtx (XFmode);
15358   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15359   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15361   emit_insn (gen_atan2xf3 (op0, op2, op1));
15362   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15363   DONE;
15366 (define_expand "atanxf2"
15367   [(parallel [(set (match_operand:XF 0 "register_operand")
15368                    (unspec:XF [(match_dup 2)
15369                                (match_operand:XF 1 "register_operand")]
15370                               UNSPEC_FPATAN))
15371               (clobber (match_scratch:XF 3))])]
15372   "TARGET_USE_FANCY_MATH_387
15373    && flag_unsafe_math_optimizations"
15374   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15376 (define_expand "atan<mode>2"
15377   [(use (match_operand:MODEF 0 "register_operand"))
15378    (use (match_operand:MODEF 1 "general_operand"))]
15379   "TARGET_USE_FANCY_MATH_387
15380    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15381        || TARGET_MIX_SSE_I387)
15382    && flag_unsafe_math_optimizations"
15384   rtx op0 = gen_reg_rtx (XFmode);
15385   rtx op1 = gen_reg_rtx (XFmode);
15387   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15388   emit_insn (gen_atanxf2 (op0, op1));
15389   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15390   DONE;
15393 (define_expand "asinxf2"
15394   [(set (match_dup 2)
15395         (mult:XF (match_operand:XF 1 "register_operand")
15396                  (match_dup 1)))
15397    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15398    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15399    (parallel [(set (match_operand:XF 0 "register_operand")
15400                    (unspec:XF [(match_dup 5) (match_dup 1)]
15401                               UNSPEC_FPATAN))
15402               (clobber (match_scratch:XF 6))])]
15403   "TARGET_USE_FANCY_MATH_387
15404    && flag_unsafe_math_optimizations"
15406   int i;
15408   for (i = 2; i < 6; i++)
15409     operands[i] = gen_reg_rtx (XFmode);
15411   emit_move_insn (operands[3], CONST1_RTX (XFmode));
15414 (define_expand "asin<mode>2"
15415   [(use (match_operand:MODEF 0 "register_operand"))
15416    (use (match_operand:MODEF 1 "general_operand"))]
15417   "TARGET_USE_FANCY_MATH_387
15418    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15419        || TARGET_MIX_SSE_I387)
15420    && flag_unsafe_math_optimizations"
15422   rtx op0 = gen_reg_rtx (XFmode);
15423   rtx op1 = gen_reg_rtx (XFmode);
15425   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15426   emit_insn (gen_asinxf2 (op0, op1));
15427   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15428   DONE;
15431 (define_expand "acosxf2"
15432   [(set (match_dup 2)
15433         (mult:XF (match_operand:XF 1 "register_operand")
15434                  (match_dup 1)))
15435    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15436    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15437    (parallel [(set (match_operand:XF 0 "register_operand")
15438                    (unspec:XF [(match_dup 1) (match_dup 5)]
15439                               UNSPEC_FPATAN))
15440               (clobber (match_scratch:XF 6))])]
15441   "TARGET_USE_FANCY_MATH_387
15442    && flag_unsafe_math_optimizations"
15444   int i;
15446   for (i = 2; i < 6; i++)
15447     operands[i] = gen_reg_rtx (XFmode);
15449   emit_move_insn (operands[3], CONST1_RTX (XFmode));
15452 (define_expand "acos<mode>2"
15453   [(use (match_operand:MODEF 0 "register_operand"))
15454    (use (match_operand:MODEF 1 "general_operand"))]
15455   "TARGET_USE_FANCY_MATH_387
15456    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15457        || TARGET_MIX_SSE_I387)
15458    && flag_unsafe_math_optimizations"
15460   rtx op0 = gen_reg_rtx (XFmode);
15461   rtx op1 = gen_reg_rtx (XFmode);
15463   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464   emit_insn (gen_acosxf2 (op0, op1));
15465   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15466   DONE;
15469 (define_expand "sinhxf2"
15470   [(use (match_operand:XF 0 "register_operand"))
15471    (use (match_operand:XF 1 "register_operand"))]
15472   "TARGET_USE_FANCY_MATH_387
15473    && flag_finite_math_only
15474    && flag_unsafe_math_optimizations"
15476   ix86_emit_i387_sinh (operands[0], operands[1]);
15477   DONE;
15480 (define_expand "sinh<mode>2"
15481   [(use (match_operand:MODEF 0 "register_operand"))
15482    (use (match_operand:MODEF 1 "general_operand"))]
15483   "TARGET_USE_FANCY_MATH_387
15484    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15485        || TARGET_MIX_SSE_I387)
15486    && flag_finite_math_only
15487    && flag_unsafe_math_optimizations"
15489   rtx op0 = gen_reg_rtx (XFmode);
15490   rtx op1 = gen_reg_rtx (XFmode);
15492   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15493   emit_insn (gen_sinhxf2 (op0, op1));
15494   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15495   DONE;
15498 (define_expand "coshxf2"
15499   [(use (match_operand:XF 0 "register_operand"))
15500    (use (match_operand:XF 1 "register_operand"))]
15501   "TARGET_USE_FANCY_MATH_387
15502    && flag_unsafe_math_optimizations"
15504   ix86_emit_i387_cosh (operands[0], operands[1]);
15505   DONE;
15508 (define_expand "cosh<mode>2"
15509   [(use (match_operand:MODEF 0 "register_operand"))
15510    (use (match_operand:MODEF 1 "general_operand"))]
15511   "TARGET_USE_FANCY_MATH_387
15512    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15513        || TARGET_MIX_SSE_I387)
15514    && flag_unsafe_math_optimizations"
15516   rtx op0 = gen_reg_rtx (XFmode);
15517   rtx op1 = gen_reg_rtx (XFmode);
15519   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15520   emit_insn (gen_coshxf2 (op0, op1));
15521   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15522   DONE;
15525 (define_expand "tanhxf2"
15526   [(use (match_operand:XF 0 "register_operand"))
15527    (use (match_operand:XF 1 "register_operand"))]
15528   "TARGET_USE_FANCY_MATH_387
15529    && flag_unsafe_math_optimizations"
15531   ix86_emit_i387_tanh (operands[0], operands[1]);
15532   DONE;
15535 (define_expand "tanh<mode>2"
15536   [(use (match_operand:MODEF 0 "register_operand"))
15537    (use (match_operand:MODEF 1 "general_operand"))]
15538   "TARGET_USE_FANCY_MATH_387
15539    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15540        || TARGET_MIX_SSE_I387)
15541    && flag_unsafe_math_optimizations"
15543   rtx op0 = gen_reg_rtx (XFmode);
15544   rtx op1 = gen_reg_rtx (XFmode);
15546   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15547   emit_insn (gen_tanhxf2 (op0, op1));
15548   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15549   DONE;
15552 (define_expand "asinhxf2"
15553   [(use (match_operand:XF 0 "register_operand"))
15554    (use (match_operand:XF 1 "register_operand"))]
15555   "TARGET_USE_FANCY_MATH_387
15556    && flag_finite_math_only
15557    && flag_unsafe_math_optimizations"
15559   ix86_emit_i387_asinh (operands[0], operands[1]);
15560   DONE;
15563 (define_expand "asinh<mode>2"
15564   [(use (match_operand:MODEF 0 "register_operand"))
15565    (use (match_operand:MODEF 1 "general_operand"))]
15566   "TARGET_USE_FANCY_MATH_387
15567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15568        || TARGET_MIX_SSE_I387)
15569    && flag_finite_math_only
15570    && flag_unsafe_math_optimizations"
15572   rtx op0 = gen_reg_rtx (XFmode);
15573   rtx op1 = gen_reg_rtx (XFmode);
15575   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15576   emit_insn (gen_asinhxf2 (op0, op1));
15577   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15578   DONE;
15581 (define_expand "acoshxf2"
15582   [(use (match_operand:XF 0 "register_operand"))
15583    (use (match_operand:XF 1 "register_operand"))]
15584   "TARGET_USE_FANCY_MATH_387
15585    && flag_unsafe_math_optimizations"
15587   ix86_emit_i387_acosh (operands[0], operands[1]);
15588   DONE;
15591 (define_expand "acosh<mode>2"
15592   [(use (match_operand:MODEF 0 "register_operand"))
15593    (use (match_operand:MODEF 1 "general_operand"))]
15594   "TARGET_USE_FANCY_MATH_387
15595    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15596        || TARGET_MIX_SSE_I387)
15597    && flag_unsafe_math_optimizations"
15599   rtx op0 = gen_reg_rtx (XFmode);
15600   rtx op1 = gen_reg_rtx (XFmode);
15602   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15603   emit_insn (gen_acoshxf2 (op0, op1));
15604   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15605   DONE;
15608 (define_expand "atanhxf2"
15609   [(use (match_operand:XF 0 "register_operand"))
15610    (use (match_operand:XF 1 "register_operand"))]
15611   "TARGET_USE_FANCY_MATH_387
15612    && flag_unsafe_math_optimizations"
15614   ix86_emit_i387_atanh (operands[0], operands[1]);
15615   DONE;
15618 (define_expand "atanh<mode>2"
15619   [(use (match_operand:MODEF 0 "register_operand"))
15620    (use (match_operand:MODEF 1 "general_operand"))]
15621   "TARGET_USE_FANCY_MATH_387
15622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15623        || TARGET_MIX_SSE_I387)
15624    && flag_unsafe_math_optimizations"
15626   rtx op0 = gen_reg_rtx (XFmode);
15627   rtx op1 = gen_reg_rtx (XFmode);
15629   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15630   emit_insn (gen_atanhxf2 (op0, op1));
15631   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15632   DONE;
15635 (define_insn "fyl2xxf3_i387"
15636   [(set (match_operand:XF 0 "register_operand" "=f")
15637         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15638                     (match_operand:XF 2 "register_operand" "f")]
15639                    UNSPEC_FYL2X))
15640    (clobber (match_scratch:XF 3 "=2"))]
15641   "TARGET_USE_FANCY_MATH_387
15642    && flag_unsafe_math_optimizations"
15643   "fyl2x"
15644   [(set_attr "type" "fpspc")
15645    (set_attr "znver1_decode" "vector")
15646    (set_attr "mode" "XF")])
15648 (define_expand "logxf2"
15649   [(parallel [(set (match_operand:XF 0 "register_operand")
15650                    (unspec:XF [(match_operand:XF 1 "register_operand")
15651                                (match_dup 2)] UNSPEC_FYL2X))
15652               (clobber (match_scratch:XF 3))])]
15653   "TARGET_USE_FANCY_MATH_387
15654    && flag_unsafe_math_optimizations"
15656   operands[2]
15657     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15660 (define_expand "log<mode>2"
15661   [(use (match_operand:MODEF 0 "register_operand"))
15662    (use (match_operand:MODEF 1 "general_operand"))]
15663   "TARGET_USE_FANCY_MATH_387
15664    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15665        || TARGET_MIX_SSE_I387)
15666    && flag_unsafe_math_optimizations"
15668   rtx op0 = gen_reg_rtx (XFmode);
15669   rtx op1 = gen_reg_rtx (XFmode);
15671   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15672   emit_insn (gen_logxf2 (op0, op1));
15673   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15674   DONE;
15677 (define_expand "log10xf2"
15678   [(parallel [(set (match_operand:XF 0 "register_operand")
15679                    (unspec:XF [(match_operand:XF 1 "register_operand")
15680                                (match_dup 2)] UNSPEC_FYL2X))
15681               (clobber (match_scratch:XF 3))])]
15682   "TARGET_USE_FANCY_MATH_387
15683    && flag_unsafe_math_optimizations"
15685   operands[2]
15686     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15689 (define_expand "log10<mode>2"
15690   [(use (match_operand:MODEF 0 "register_operand"))
15691    (use (match_operand:MODEF 1 "general_operand"))]
15692   "TARGET_USE_FANCY_MATH_387
15693    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15694        || TARGET_MIX_SSE_I387)
15695    && flag_unsafe_math_optimizations"
15697   rtx op0 = gen_reg_rtx (XFmode);
15698   rtx op1 = gen_reg_rtx (XFmode);
15700   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15701   emit_insn (gen_log10xf2 (op0, op1));
15702   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15703   DONE;
15706 (define_expand "log2xf2"
15707   [(parallel [(set (match_operand:XF 0 "register_operand")
15708                    (unspec:XF [(match_operand:XF 1 "register_operand")
15709                                (match_dup 2)] UNSPEC_FYL2X))
15710               (clobber (match_scratch:XF 3))])]
15711   "TARGET_USE_FANCY_MATH_387
15712    && flag_unsafe_math_optimizations"
15713   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15715 (define_expand "log2<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_log2xf2 (op0, op1));
15728   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15729   DONE;
15732 (define_insn "fyl2xp1xf3_i387"
15733   [(set (match_operand:XF 0 "register_operand" "=f")
15734         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15735                     (match_operand:XF 2 "register_operand" "f")]
15736                    UNSPEC_FYL2XP1))
15737    (clobber (match_scratch:XF 3 "=2"))]
15738   "TARGET_USE_FANCY_MATH_387
15739    && flag_unsafe_math_optimizations"
15740   "fyl2xp1"
15741   [(set_attr "type" "fpspc")
15742    (set_attr "znver1_decode" "vector")
15743    (set_attr "mode" "XF")])
15745 (define_expand "log1pxf2"
15746   [(use (match_operand:XF 0 "register_operand"))
15747    (use (match_operand:XF 1 "register_operand"))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && flag_unsafe_math_optimizations"
15751   ix86_emit_i387_log1p (operands[0], operands[1]);
15752   DONE;
15755 (define_expand "log1p<mode>2"
15756   [(use (match_operand:MODEF 0 "register_operand"))
15757    (use (match_operand:MODEF 1 "general_operand"))]
15758   "TARGET_USE_FANCY_MATH_387
15759    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15760        || TARGET_MIX_SSE_I387)
15761    && flag_unsafe_math_optimizations"
15763   rtx op0 = gen_reg_rtx (XFmode);
15764   rtx op1 = gen_reg_rtx (XFmode);
15766   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15767   emit_insn (gen_log1pxf2 (op0, op1));
15768   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15769   DONE;
15772 (define_insn "fxtractxf3_i387"
15773   [(set (match_operand:XF 0 "register_operand" "=f")
15774         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15775                    UNSPEC_XTRACT_FRACT))
15776    (set (match_operand:XF 1 "register_operand" "=f")
15777         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15778   "TARGET_USE_FANCY_MATH_387
15779    && flag_unsafe_math_optimizations"
15780   "fxtract"
15781   [(set_attr "type" "fpspc")
15782    (set_attr "znver1_decode" "vector")
15783    (set_attr "mode" "XF")])
15785 (define_expand "logbxf2"
15786   [(parallel [(set (match_dup 2)
15787                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15788                               UNSPEC_XTRACT_FRACT))
15789               (set (match_operand:XF 0 "register_operand")
15790                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15793   "operands[2] = gen_reg_rtx (XFmode);")
15795 (define_expand "logb<mode>2"
15796   [(use (match_operand:MODEF 0 "register_operand"))
15797    (use (match_operand:MODEF 1 "general_operand"))]
15798   "TARGET_USE_FANCY_MATH_387
15799    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15800        || TARGET_MIX_SSE_I387)
15801    && flag_unsafe_math_optimizations"
15803   rtx op0 = gen_reg_rtx (XFmode);
15804   rtx op1 = gen_reg_rtx (XFmode);
15806   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15807   emit_insn (gen_logbxf2 (op0, op1));
15808   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15809   DONE;
15812 (define_expand "ilogbxf2"
15813   [(use (match_operand:SI 0 "register_operand"))
15814    (use (match_operand:XF 1 "register_operand"))]
15815   "TARGET_USE_FANCY_MATH_387
15816    && flag_unsafe_math_optimizations"
15818   rtx op0, op1;
15820   if (optimize_insn_for_size_p ())
15821     FAIL;
15823   op0 = gen_reg_rtx (XFmode);
15824   op1 = gen_reg_rtx (XFmode);
15826   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15827   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15828   DONE;
15831 (define_expand "ilogb<mode>2"
15832   [(use (match_operand:SI 0 "register_operand"))
15833    (use (match_operand:MODEF 1 "general_operand"))]
15834   "TARGET_USE_FANCY_MATH_387
15835    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15836        || TARGET_MIX_SSE_I387)
15837    && flag_unsafe_math_optimizations"
15839   rtx op0, op1, op2;
15841   if (optimize_insn_for_size_p ())
15842     FAIL;
15844   op0 = gen_reg_rtx (XFmode);
15845   op1 = gen_reg_rtx (XFmode);
15846   op2 = gen_reg_rtx (XFmode);
15848   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15849   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15850   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15851   DONE;
15854 (define_insn "*f2xm1xf2_i387"
15855   [(set (match_operand:XF 0 "register_operand" "=f")
15856         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15857                    UNSPEC_F2XM1))]
15858   "TARGET_USE_FANCY_MATH_387
15859    && flag_unsafe_math_optimizations"
15860   "f2xm1"
15861   [(set_attr "type" "fpspc")
15862    (set_attr "znver1_decode" "vector")
15863    (set_attr "mode" "XF")])
15865 (define_insn "fscalexf4_i387"
15866   [(set (match_operand:XF 0 "register_operand" "=f")
15867         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15868                     (match_operand:XF 3 "register_operand" "1")]
15869                    UNSPEC_FSCALE_FRACT))
15870    (set (match_operand:XF 1 "register_operand" "=f")
15871         (unspec:XF [(match_dup 2) (match_dup 3)]
15872                    UNSPEC_FSCALE_EXP))]
15873   "TARGET_USE_FANCY_MATH_387
15874    && flag_unsafe_math_optimizations"
15875   "fscale"
15876   [(set_attr "type" "fpspc")
15877    (set_attr "znver1_decode" "vector")
15878    (set_attr "mode" "XF")])
15880 (define_expand "expNcorexf3"
15881   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15882                                (match_operand:XF 2 "register_operand")))
15883    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15884    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15885    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15886    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15887    (parallel [(set (match_operand:XF 0 "register_operand")
15888                    (unspec:XF [(match_dup 8) (match_dup 4)]
15889                               UNSPEC_FSCALE_FRACT))
15890               (set (match_dup 9)
15891                    (unspec:XF [(match_dup 8) (match_dup 4)]
15892                               UNSPEC_FSCALE_EXP))])]
15893   "TARGET_USE_FANCY_MATH_387
15894    && flag_unsafe_math_optimizations"
15896   int i;
15898   for (i = 3; i < 10; i++)
15899     operands[i] = gen_reg_rtx (XFmode);
15901   emit_move_insn (operands[7], CONST1_RTX (XFmode));
15904 (define_expand "expxf2"
15905   [(use (match_operand:XF 0 "register_operand"))
15906    (use (match_operand:XF 1 "register_operand"))]
15907   "TARGET_USE_FANCY_MATH_387
15908    && flag_unsafe_math_optimizations"
15910   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15912   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15913   DONE;
15916 (define_expand "exp<mode>2"
15917   [(use (match_operand:MODEF 0 "register_operand"))
15918    (use (match_operand:MODEF 1 "general_operand"))]
15919   "TARGET_USE_FANCY_MATH_387
15920    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15921        || TARGET_MIX_SSE_I387)
15922    && flag_unsafe_math_optimizations"
15924   rtx op0 = gen_reg_rtx (XFmode);
15925   rtx op1 = gen_reg_rtx (XFmode);
15927   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15928   emit_insn (gen_expxf2 (op0, op1));
15929   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15930   DONE;
15933 (define_expand "exp10xf2"
15934   [(use (match_operand:XF 0 "register_operand"))
15935    (use (match_operand:XF 1 "register_operand"))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15939   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15941   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15942   DONE;
15945 (define_expand "exp10<mode>2"
15946   [(use (match_operand:MODEF 0 "register_operand"))
15947    (use (match_operand:MODEF 1 "general_operand"))]
15948   "TARGET_USE_FANCY_MATH_387
15949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15950        || TARGET_MIX_SSE_I387)
15951    && flag_unsafe_math_optimizations"
15953   rtx op0 = gen_reg_rtx (XFmode);
15954   rtx op1 = gen_reg_rtx (XFmode);
15956   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15957   emit_insn (gen_exp10xf2 (op0, op1));
15958   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15959   DONE;
15962 (define_expand "exp2xf2"
15963   [(use (match_operand:XF 0 "register_operand"))
15964    (use (match_operand:XF 1 "register_operand"))]
15965   "TARGET_USE_FANCY_MATH_387
15966    && flag_unsafe_math_optimizations"
15968   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15970   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15971   DONE;
15974 (define_expand "exp2<mode>2"
15975   [(use (match_operand:MODEF 0 "register_operand"))
15976    (use (match_operand:MODEF 1 "general_operand"))]
15977   "TARGET_USE_FANCY_MATH_387
15978    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15979        || TARGET_MIX_SSE_I387)
15980    && flag_unsafe_math_optimizations"
15982   rtx op0 = gen_reg_rtx (XFmode);
15983   rtx op1 = gen_reg_rtx (XFmode);
15985   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15986   emit_insn (gen_exp2xf2 (op0, op1));
15987   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15988   DONE;
15991 (define_expand "expm1xf2"
15992   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15993                                (match_dup 2)))
15994    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15995    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15996    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15997    (parallel [(set (match_dup 7)
15998                    (unspec:XF [(match_dup 6) (match_dup 4)]
15999                               UNSPEC_FSCALE_FRACT))
16000               (set (match_dup 8)
16001                    (unspec:XF [(match_dup 6) (match_dup 4)]
16002                               UNSPEC_FSCALE_EXP))])
16003    (parallel [(set (match_dup 10)
16004                    (unspec:XF [(match_dup 9) (match_dup 8)]
16005                               UNSPEC_FSCALE_FRACT))
16006               (set (match_dup 11)
16007                    (unspec:XF [(match_dup 9) (match_dup 8)]
16008                               UNSPEC_FSCALE_EXP))])
16009    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16010    (set (match_operand:XF 0 "register_operand")
16011         (plus:XF (match_dup 12) (match_dup 7)))]
16012   "TARGET_USE_FANCY_MATH_387
16013    && flag_unsafe_math_optimizations"
16015   int i;
16017   for (i = 2; i < 13; i++)
16018     operands[i] = gen_reg_rtx (XFmode);
16020   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16021   emit_move_insn (operands[9], CONST1_RTX (XFmode));
16024 (define_expand "expm1<mode>2"
16025   [(use (match_operand:MODEF 0 "register_operand"))
16026    (use (match_operand:MODEF 1 "general_operand"))]
16027   "TARGET_USE_FANCY_MATH_387
16028    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16029        || TARGET_MIX_SSE_I387)
16030    && flag_unsafe_math_optimizations"
16032   rtx op0 = gen_reg_rtx (XFmode);
16033   rtx op1 = gen_reg_rtx (XFmode);
16035   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16036   emit_insn (gen_expm1xf2 (op0, op1));
16037   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16038   DONE;
16041 (define_expand "ldexpxf3"
16042   [(match_operand:XF 0 "register_operand")
16043    (match_operand:XF 1 "register_operand")
16044    (match_operand:SI 2 "register_operand")]
16045   "TARGET_USE_FANCY_MATH_387
16046    && flag_unsafe_math_optimizations"
16048   rtx tmp1 = gen_reg_rtx (XFmode);
16049   rtx tmp2 = gen_reg_rtx (XFmode);
16051   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16052   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16053                                  operands[1], tmp1));
16054   DONE;
16057 (define_expand "ldexp<mode>3"
16058   [(use (match_operand:MODEF 0 "register_operand"))
16059    (use (match_operand:MODEF 1 "general_operand"))
16060    (use (match_operand:SI 2 "register_operand"))]
16061   "TARGET_USE_FANCY_MATH_387
16062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16063        || TARGET_MIX_SSE_I387)
16064    && flag_unsafe_math_optimizations"
16066   rtx op0 = gen_reg_rtx (XFmode);
16067   rtx op1 = gen_reg_rtx (XFmode);
16069   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16070   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16071   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16072   DONE;
16075 (define_expand "scalbxf3"
16076   [(parallel [(set (match_operand:XF 0 " register_operand")
16077                    (unspec:XF [(match_operand:XF 1 "register_operand")
16078                                (match_operand:XF 2 "register_operand")]
16079                               UNSPEC_FSCALE_FRACT))
16080               (set (match_dup 3)
16081                    (unspec:XF [(match_dup 1) (match_dup 2)]
16082                               UNSPEC_FSCALE_EXP))])]
16083   "TARGET_USE_FANCY_MATH_387
16084    && flag_unsafe_math_optimizations"
16085   "operands[3] = gen_reg_rtx (XFmode);")
16087 (define_expand "scalb<mode>3"
16088   [(use (match_operand:MODEF 0 "register_operand"))
16089    (use (match_operand:MODEF 1 "general_operand"))
16090    (use (match_operand:MODEF 2 "general_operand"))]
16091   "TARGET_USE_FANCY_MATH_387
16092    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16093        || TARGET_MIX_SSE_I387)
16094    && flag_unsafe_math_optimizations"
16096   rtx op0 = gen_reg_rtx (XFmode);
16097   rtx op1 = gen_reg_rtx (XFmode);
16098   rtx op2 = gen_reg_rtx (XFmode);
16100   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16101   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16102   emit_insn (gen_scalbxf3 (op0, op1, op2));
16103   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16104   DONE;
16107 (define_expand "significandxf2"
16108   [(parallel [(set (match_operand:XF 0 "register_operand")
16109                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16110                               UNSPEC_XTRACT_FRACT))
16111               (set (match_dup 2)
16112                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16113   "TARGET_USE_FANCY_MATH_387
16114    && flag_unsafe_math_optimizations"
16115   "operands[2] = gen_reg_rtx (XFmode);")
16117 (define_expand "significand<mode>2"
16118   [(use (match_operand:MODEF 0 "register_operand"))
16119    (use (match_operand:MODEF 1 "general_operand"))]
16120   "TARGET_USE_FANCY_MATH_387
16121    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16122        || TARGET_MIX_SSE_I387)
16123    && flag_unsafe_math_optimizations"
16125   rtx op0 = gen_reg_rtx (XFmode);
16126   rtx op1 = gen_reg_rtx (XFmode);
16128   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16129   emit_insn (gen_significandxf2 (op0, op1));
16130   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16131   DONE;
16135 (define_insn "sse4_1_round<mode>2"
16136   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v")
16137         (unspec:MODEF
16138           [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,vm")
16139            (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n")]
16140           UNSPEC_ROUND))]
16141   "TARGET_SSE4_1"
16142   "@
16143    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16144    %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16145    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16146    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16147   [(set_attr "type" "ssecvt")
16148    (set_attr "prefix_extra" "1,1,1,*")
16149    (set_attr "length_immediate" "*,*,*,1")
16150    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex")
16151    (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f")
16152    (set_attr "mode" "<MODE>")
16153    (set (attr "preferred_for_speed")
16154      (cond [(eq_attr "alternative" "1")
16155               (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16156            (eq_attr "alternative" "2")
16157               (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16158            ]
16159            (symbol_ref "true")))])
16161 (define_insn "rintxf2"
16162   [(set (match_operand:XF 0 "register_operand" "=f")
16163         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16164                    UNSPEC_FRNDINT))]
16165   "TARGET_USE_FANCY_MATH_387"
16166   "frndint"
16167   [(set_attr "type" "fpspc")
16168    (set_attr "znver1_decode" "vector")
16169    (set_attr "mode" "XF")])
16171 (define_expand "rint<mode>2"
16172   [(use (match_operand:MODEF 0 "register_operand"))
16173    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16174   "TARGET_USE_FANCY_MATH_387
16175    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16177   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16178     {
16179       if (TARGET_SSE4_1)
16180         emit_insn (gen_sse4_1_round<mode>2
16181                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16182       else
16183         ix86_expand_rint (operands[0], operands[1]);
16184     }
16185   else
16186     {
16187       rtx op0 = gen_reg_rtx (XFmode);
16188       rtx op1 = gen_reg_rtx (XFmode);
16190       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16191       emit_insn (gen_rintxf2 (op0, op1));
16192       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16193     }
16194   DONE;
16197 (define_expand "nearbyintxf2"
16198   [(set (match_operand:XF 0 "register_operand")
16199         (unspec:XF [(match_operand:XF 1 "register_operand")]
16200                    UNSPEC_FRNDINT))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && !flag_trapping_math")
16204 (define_expand "nearbyint<mode>2"
16205   [(use (match_operand:MODEF 0 "register_operand"))
16206    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16207   "(TARGET_USE_FANCY_MATH_387
16208     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16209           || TARGET_MIX_SSE_I387)
16210     && !flag_trapping_math)
16211    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16213   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16214     emit_insn (gen_sse4_1_round<mode>2
16215                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16216                                                    | ROUND_NO_EXC)));
16217   else
16218     {
16219       rtx op0 = gen_reg_rtx (XFmode);
16220       rtx op1 = gen_reg_rtx (XFmode);
16222       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16223       emit_insn (gen_nearbyintxf2 (op0, op1));
16224       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16225     }
16226   DONE;
16229 (define_expand "round<mode>2"
16230   [(match_operand:X87MODEF 0 "register_operand")
16231    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16232   "(TARGET_USE_FANCY_MATH_387
16233     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16234         || TARGET_MIX_SSE_I387)
16235     && flag_unsafe_math_optimizations
16236     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16237    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16238        && !flag_trapping_math && !flag_rounding_math)"
16240   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16241       && !flag_trapping_math && !flag_rounding_math)
16242     {
16243       if (TARGET_SSE4_1)
16244         {
16245           operands[1] = force_reg (<MODE>mode, operands[1]);
16246           ix86_expand_round_sse4 (operands[0], operands[1]);
16247         }
16248       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16249         ix86_expand_round (operands[0], operands[1]);
16250       else
16251         ix86_expand_rounddf_32 (operands[0], operands[1]);
16252     }
16253   else
16254     {
16255       operands[1] = force_reg (<MODE>mode, operands[1]);
16256       ix86_emit_i387_round (operands[0], operands[1]);
16257     }
16258   DONE;
16261 (define_insn "lrintxfdi2"
16262   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16263         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16264                    UNSPEC_FIST))
16265    (clobber (match_scratch:XF 2 "=&f"))]
16266   "TARGET_USE_FANCY_MATH_387"
16267   "* return output_fix_trunc (insn, operands, false);"
16268   [(set_attr "type" "fpspc")
16269    (set_attr "mode" "DI")])
16271 (define_insn "lrintxf<mode>2"
16272   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16273         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16274                       UNSPEC_FIST))]
16275   "TARGET_USE_FANCY_MATH_387"
16276   "* return output_fix_trunc (insn, operands, false);"
16277   [(set_attr "type" "fpspc")
16278    (set_attr "mode" "<MODE>")])
16280 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16281   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16282      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16283                    UNSPEC_FIX_NOTRUNC))]
16284   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16286 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16287   [(match_operand:SWI248x 0 "nonimmediate_operand")
16288    (match_operand:X87MODEF 1 "register_operand")]
16289   "(TARGET_USE_FANCY_MATH_387
16290     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16291         || TARGET_MIX_SSE_I387)
16292     && flag_unsafe_math_optimizations)
16293    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16294        && <SWI248x:MODE>mode != HImode 
16295        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16296        && !flag_trapping_math && !flag_rounding_math)"
16298   if (optimize_insn_for_size_p ())
16299     FAIL;
16301   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16302       && <SWI248x:MODE>mode != HImode
16303       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16304       && !flag_trapping_math && !flag_rounding_math)
16305     ix86_expand_lround (operands[0], operands[1]);
16306   else
16307     ix86_emit_i387_round (operands[0], operands[1]);
16308   DONE;
16311 (define_int_iterator FRNDINT_ROUNDING
16312         [UNSPEC_FRNDINT_FLOOR
16313          UNSPEC_FRNDINT_CEIL
16314          UNSPEC_FRNDINT_TRUNC])
16316 (define_int_iterator FIST_ROUNDING
16317         [UNSPEC_FIST_FLOOR
16318          UNSPEC_FIST_CEIL])
16320 ;; Base name for define_insn
16321 (define_int_attr rounding_insn
16322         [(UNSPEC_FRNDINT_FLOOR "floor")
16323          (UNSPEC_FRNDINT_CEIL "ceil")
16324          (UNSPEC_FRNDINT_TRUNC "btrunc")
16325          (UNSPEC_FIST_FLOOR "floor")
16326          (UNSPEC_FIST_CEIL "ceil")])
16328 (define_int_attr rounding
16329         [(UNSPEC_FRNDINT_FLOOR "floor")
16330          (UNSPEC_FRNDINT_CEIL "ceil")
16331          (UNSPEC_FRNDINT_TRUNC "trunc")
16332          (UNSPEC_FIST_FLOOR "floor")
16333          (UNSPEC_FIST_CEIL "ceil")])
16335 (define_int_attr ROUNDING
16336         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16337          (UNSPEC_FRNDINT_CEIL "CEIL")
16338          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16339          (UNSPEC_FIST_FLOOR "FLOOR")
16340          (UNSPEC_FIST_CEIL "CEIL")])
16342 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16343 (define_insn_and_split "frndintxf2_<rounding>"
16344   [(set (match_operand:XF 0 "register_operand")
16345         (unspec:XF [(match_operand:XF 1 "register_operand")]
16346                    FRNDINT_ROUNDING))
16347    (clobber (reg:CC FLAGS_REG))]
16348   "TARGET_USE_FANCY_MATH_387
16349    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16350    && can_create_pseudo_p ()"
16351   "#"
16352   "&& 1"
16353   [(const_int 0)]
16355   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16357   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16358   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16360   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16361                                              operands[2], operands[3]));
16362   DONE;
16364   [(set_attr "type" "frndint")
16365    (set_attr "i387_cw" "<rounding>")
16366    (set_attr "mode" "XF")])
16368 (define_insn "frndintxf2_<rounding>_i387"
16369   [(set (match_operand:XF 0 "register_operand" "=f")
16370         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16371                    FRNDINT_ROUNDING))
16372    (use (match_operand:HI 2 "memory_operand" "m"))
16373    (use (match_operand:HI 3 "memory_operand" "m"))]
16374   "TARGET_USE_FANCY_MATH_387
16375    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16376   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16377   [(set_attr "type" "frndint")
16378    (set_attr "i387_cw" "<rounding>")
16379    (set_attr "mode" "XF")])
16381 (define_expand "<rounding_insn>xf2"
16382   [(parallel [(set (match_operand:XF 0 "register_operand")
16383                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16384                               FRNDINT_ROUNDING))
16385               (clobber (reg:CC FLAGS_REG))])]
16386   "TARGET_USE_FANCY_MATH_387
16387    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16389 (define_expand "<rounding_insn><mode>2"
16390   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16391                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16392                                  FRNDINT_ROUNDING))
16393               (clobber (reg:CC FLAGS_REG))])]
16394   "(TARGET_USE_FANCY_MATH_387
16395     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396         || TARGET_MIX_SSE_I387)
16397     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16398    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16399        && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16400            || !flag_trapping_math))"
16402   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16403       && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16404     {
16405       if (TARGET_SSE4_1)
16406         emit_insn (gen_sse4_1_round<mode>2
16407                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16408                                                        | ROUND_NO_EXC)));
16409       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16410         {
16411           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16412             ix86_expand_floorceil (operands[0], operands[1], true);
16413           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16414             ix86_expand_floorceil (operands[0], operands[1], false);
16415           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16416             ix86_expand_trunc (operands[0], operands[1]);
16417           else
16418             gcc_unreachable ();
16419         }
16420       else
16421         {
16422           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16423             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16424           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16425             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16426           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16427             ix86_expand_truncdf_32 (operands[0], operands[1]);
16428           else
16429             gcc_unreachable ();
16430         }
16431     }
16432   else
16433     {
16434       rtx op0 = gen_reg_rtx (XFmode);
16435       rtx op1 = gen_reg_rtx (XFmode);
16437       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16438       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16439       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16440     }
16441   DONE;
16444 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16445 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16446   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16447         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16448                         FIST_ROUNDING))
16449    (clobber (reg:CC FLAGS_REG))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && flag_unsafe_math_optimizations
16452    && can_create_pseudo_p ()"
16453   "#"
16454   "&& 1"
16455   [(const_int 0)]
16457   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16459   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16460   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16462   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16463                                          operands[2], operands[3]));
16464   DONE;
16466   [(set_attr "type" "fistp")
16467    (set_attr "i387_cw" "<rounding>")
16468    (set_attr "mode" "<MODE>")])
16470 (define_insn "fistdi2_<rounding>"
16471   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16472         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16473                    FIST_ROUNDING))
16474    (use (match_operand:HI 2 "memory_operand" "m"))
16475    (use (match_operand:HI 3 "memory_operand" "m"))
16476    (clobber (match_scratch:XF 4 "=&f"))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && flag_unsafe_math_optimizations"
16479   "* return output_fix_trunc (insn, operands, false);"
16480   [(set_attr "type" "fistp")
16481    (set_attr "i387_cw" "<rounding>")
16482    (set_attr "mode" "DI")])
16484 (define_insn "fist<mode>2_<rounding>"
16485   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16486         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16487                       FIST_ROUNDING))
16488    (use (match_operand:HI 2 "memory_operand" "m"))
16489    (use (match_operand:HI 3 "memory_operand" "m"))]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations"
16492   "* return output_fix_trunc (insn, operands, false);"
16493   [(set_attr "type" "fistp")
16494    (set_attr "i387_cw" "<rounding>")
16495    (set_attr "mode" "<MODE>")])
16497 (define_expand "l<rounding_insn>xf<mode>2"
16498   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16499                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16500                                    FIST_ROUNDING))
16501               (clobber (reg:CC FLAGS_REG))])]
16502   "TARGET_USE_FANCY_MATH_387
16503    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16504    && flag_unsafe_math_optimizations")
16506 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16507   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16508                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16509                                  FIST_ROUNDING))
16510               (clobber (reg:CC FLAGS_REG))])]
16511   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16512    && (TARGET_SSE4_1 || !flag_trapping_math)"
16514   if (TARGET_SSE4_1)
16515     {
16516       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16518       emit_insn (gen_sse4_1_round<mode>2
16519                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16520                                              | ROUND_NO_EXC)));
16521       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16522                  (operands[0], tmp));
16523     }
16524   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16525     ix86_expand_lfloorceil (operands[0], operands[1], true);
16526   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16527     ix86_expand_lfloorceil (operands[0], operands[1], false);
16528   else
16529     gcc_unreachable ();
16531   DONE;
16534 (define_insn "fxam<mode>2_i387"
16535   [(set (match_operand:HI 0 "register_operand" "=a")
16536         (unspec:HI
16537           [(match_operand:X87MODEF 1 "register_operand" "f")]
16538           UNSPEC_FXAM))]
16539   "TARGET_USE_FANCY_MATH_387"
16540   "fxam\n\tfnstsw\t%0"
16541   [(set_attr "type" "multi")
16542    (set_attr "length" "4")
16543    (set_attr "unit" "i387")
16544    (set_attr "mode" "<MODE>")])
16546 (define_expand "signbittf2"
16547   [(use (match_operand:SI 0 "register_operand"))
16548    (use (match_operand:TF 1 "register_operand"))]
16549   "TARGET_SSE"
16551   if (TARGET_SSE4_1)
16552     {
16553       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16554       rtx scratch = gen_reg_rtx (QImode);
16556       emit_insn (gen_ptesttf2 (operands[1], mask));
16557         ix86_expand_setcc (scratch, NE,
16558                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16560       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16561     }
16562   else
16563     {
16564       emit_insn (gen_sse_movmskps (operands[0],
16565                                    gen_lowpart (V4SFmode, operands[1])));
16566       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16567     }
16568   DONE;
16571 (define_expand "signbitxf2"
16572   [(use (match_operand:SI 0 "register_operand"))
16573    (use (match_operand:XF 1 "register_operand"))]
16574   "TARGET_USE_FANCY_MATH_387"
16576   rtx scratch = gen_reg_rtx (HImode);
16578   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16579   emit_insn (gen_andsi3 (operands[0],
16580              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16581   DONE;
16584 (define_insn "movmsk_df"
16585   [(set (match_operand:SI 0 "register_operand" "=r")
16586         (unspec:SI
16587           [(match_operand:DF 1 "register_operand" "x")]
16588           UNSPEC_MOVMSK))]
16589   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16590   "%vmovmskpd\t{%1, %0|%0, %1}"
16591   [(set_attr "type" "ssemov")
16592    (set_attr "prefix" "maybe_vex")
16593    (set_attr "mode" "DF")])
16595 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16596 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16597 (define_expand "signbitdf2"
16598   [(use (match_operand:SI 0 "register_operand"))
16599    (use (match_operand:DF 1 "register_operand"))]
16600   "TARGET_USE_FANCY_MATH_387
16601    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16603   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16604     {
16605       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16606       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16607     }
16608   else
16609     {
16610       rtx scratch = gen_reg_rtx (HImode);
16612       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16613       emit_insn (gen_andsi3 (operands[0],
16614                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16615     }
16616   DONE;
16619 (define_expand "signbitsf2"
16620   [(use (match_operand:SI 0 "register_operand"))
16621    (use (match_operand:SF 1 "register_operand"))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16625   rtx scratch = gen_reg_rtx (HImode);
16627   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16628   emit_insn (gen_andsi3 (operands[0],
16629              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16630   DONE;
16633 ;; Block operation instructions
16635 (define_insn "cld"
16636   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16637   ""
16638   "cld"
16639   [(set_attr "length" "1")
16640    (set_attr "length_immediate" "0")
16641    (set_attr "modrm" "0")])
16643 (define_expand "movmem<mode>"
16644   [(use (match_operand:BLK 0 "memory_operand"))
16645    (use (match_operand:BLK 1 "memory_operand"))
16646    (use (match_operand:SWI48 2 "nonmemory_operand"))
16647    (use (match_operand:SWI48 3 "const_int_operand"))
16648    (use (match_operand:SI 4 "const_int_operand"))
16649    (use (match_operand:SI 5 "const_int_operand"))
16650    (use (match_operand:SI 6 ""))
16651    (use (match_operand:SI 7 ""))
16652    (use (match_operand:SI 8 ""))]
16653   ""
16655  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16656                                 operands[2], NULL, operands[3],
16657                                 operands[4], operands[5],
16658                                 operands[6], operands[7],
16659                                 operands[8], false))
16660    DONE;
16661  else
16662    FAIL;
16665 ;; Most CPUs don't like single string operations
16666 ;; Handle this case here to simplify previous expander.
16668 (define_expand "strmov"
16669   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16670    (set (match_operand 1 "memory_operand") (match_dup 4))
16671    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16672               (clobber (reg:CC FLAGS_REG))])
16673    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16674               (clobber (reg:CC FLAGS_REG))])]
16675   ""
16677   /* Can't use this for non-default address spaces.  */
16678   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16679     FAIL;
16681   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16683   /* If .md ever supports :P for Pmode, these can be directly
16684      in the pattern above.  */
16685   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16686   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16688   /* Can't use this if the user has appropriated esi or edi.  */
16689   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16690       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16691     {
16692       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16693                                       operands[2], operands[3],
16694                                       operands[5], operands[6]));
16695       DONE;
16696     }
16698   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16701 (define_expand "strmov_singleop"
16702   [(parallel [(set (match_operand 1 "memory_operand")
16703                    (match_operand 3 "memory_operand"))
16704               (set (match_operand 0 "register_operand")
16705                    (match_operand 4))
16706               (set (match_operand 2 "register_operand")
16707                    (match_operand 5))])]
16708   ""
16710   if (TARGET_CLD)
16711     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16714 (define_insn "*strmovdi_rex_1"
16715   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16716         (mem:DI (match_operand:P 3 "register_operand" "1")))
16717    (set (match_operand:P 0 "register_operand" "=D")
16718         (plus:P (match_dup 2)
16719                 (const_int 8)))
16720    (set (match_operand:P 1 "register_operand" "=S")
16721         (plus:P (match_dup 3)
16722                 (const_int 8)))]
16723   "TARGET_64BIT
16724    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16725    && ix86_check_no_addr_space (insn)"
16726   "%^movsq"
16727   [(set_attr "type" "str")
16728    (set_attr "memory" "both")
16729    (set_attr "mode" "DI")])
16731 (define_insn "*strmovsi_1"
16732   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16733         (mem:SI (match_operand:P 3 "register_operand" "1")))
16734    (set (match_operand:P 0 "register_operand" "=D")
16735         (plus:P (match_dup 2)
16736                 (const_int 4)))
16737    (set (match_operand:P 1 "register_operand" "=S")
16738         (plus:P (match_dup 3)
16739                 (const_int 4)))]
16740   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16741    && ix86_check_no_addr_space (insn)"
16742   "%^movs{l|d}"
16743   [(set_attr "type" "str")
16744    (set_attr "memory" "both")
16745    (set_attr "mode" "SI")])
16747 (define_insn "*strmovhi_1"
16748   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16749         (mem:HI (match_operand:P 3 "register_operand" "1")))
16750    (set (match_operand:P 0 "register_operand" "=D")
16751         (plus:P (match_dup 2)
16752                 (const_int 2)))
16753    (set (match_operand:P 1 "register_operand" "=S")
16754         (plus:P (match_dup 3)
16755                 (const_int 2)))]
16756   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16757    && ix86_check_no_addr_space (insn)"
16758   "%^movsw"
16759   [(set_attr "type" "str")
16760    (set_attr "memory" "both")
16761    (set_attr "mode" "HI")])
16763 (define_insn "*strmovqi_1"
16764   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16765         (mem:QI (match_operand:P 3 "register_operand" "1")))
16766    (set (match_operand:P 0 "register_operand" "=D")
16767         (plus:P (match_dup 2)
16768                 (const_int 1)))
16769    (set (match_operand:P 1 "register_operand" "=S")
16770         (plus:P (match_dup 3)
16771                 (const_int 1)))]
16772   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16773    && ix86_check_no_addr_space (insn)"
16774   "%^movsb"
16775   [(set_attr "type" "str")
16776    (set_attr "memory" "both")
16777    (set (attr "prefix_rex")
16778         (if_then_else
16779           (match_test "<P:MODE>mode == DImode")
16780           (const_string "0")
16781           (const_string "*")))
16782    (set_attr "mode" "QI")])
16784 (define_expand "rep_mov"
16785   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16786               (set (match_operand 0 "register_operand")
16787                    (match_operand 5))
16788               (set (match_operand 2 "register_operand")
16789                    (match_operand 6))
16790               (set (match_operand 1 "memory_operand")
16791                    (match_operand 3 "memory_operand"))
16792               (use (match_dup 4))])]
16793   ""
16795   if (TARGET_CLD)
16796     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16799 (define_insn "*rep_movdi_rex64"
16800   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16801    (set (match_operand:P 0 "register_operand" "=D")
16802         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16803                           (const_int 3))
16804                 (match_operand:P 3 "register_operand" "0")))
16805    (set (match_operand:P 1 "register_operand" "=S")
16806         (plus:P (ashift:P (match_dup 5) (const_int 3))
16807                 (match_operand:P 4 "register_operand" "1")))
16808    (set (mem:BLK (match_dup 3))
16809         (mem:BLK (match_dup 4)))
16810    (use (match_dup 5))]
16811   "TARGET_64BIT
16812    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16813    && ix86_check_no_addr_space (insn)"
16814   "%^rep{%;} movsq"
16815   [(set_attr "type" "str")
16816    (set_attr "prefix_rep" "1")
16817    (set_attr "memory" "both")
16818    (set_attr "mode" "DI")])
16820 (define_insn "*rep_movsi"
16821   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16822    (set (match_operand:P 0 "register_operand" "=D")
16823         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16824                           (const_int 2))
16825                  (match_operand:P 3 "register_operand" "0")))
16826    (set (match_operand:P 1 "register_operand" "=S")
16827         (plus:P (ashift:P (match_dup 5) (const_int 2))
16828                 (match_operand:P 4 "register_operand" "1")))
16829    (set (mem:BLK (match_dup 3))
16830         (mem:BLK (match_dup 4)))
16831    (use (match_dup 5))]
16832   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16833    && ix86_check_no_addr_space (insn)"
16834   "%^rep{%;} movs{l|d}"
16835   [(set_attr "type" "str")
16836    (set_attr "prefix_rep" "1")
16837    (set_attr "memory" "both")
16838    (set_attr "mode" "SI")])
16840 (define_insn "*rep_movqi"
16841   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16842    (set (match_operand:P 0 "register_operand" "=D")
16843         (plus:P (match_operand:P 3 "register_operand" "0")
16844                 (match_operand:P 5 "register_operand" "2")))
16845    (set (match_operand:P 1 "register_operand" "=S")
16846         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16847    (set (mem:BLK (match_dup 3))
16848         (mem:BLK (match_dup 4)))
16849    (use (match_dup 5))]
16850   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16851    && ix86_check_no_addr_space (insn)"
16852   "%^rep{%;} movsb"
16853   [(set_attr "type" "str")
16854    (set_attr "prefix_rep" "1")
16855    (set_attr "memory" "both")
16856    (set_attr "mode" "QI")])
16858 (define_expand "setmem<mode>"
16859    [(use (match_operand:BLK 0 "memory_operand"))
16860     (use (match_operand:SWI48 1 "nonmemory_operand"))
16861     (use (match_operand:QI 2 "nonmemory_operand"))
16862     (use (match_operand 3 "const_int_operand"))
16863     (use (match_operand:SI 4 "const_int_operand"))
16864     (use (match_operand:SI 5 "const_int_operand"))
16865     (use (match_operand:SI 6 ""))
16866     (use (match_operand:SI 7 ""))
16867     (use (match_operand:SI 8 ""))]
16868   ""
16870  if (ix86_expand_set_or_movmem (operands[0], NULL,
16871                                 operands[1], operands[2],
16872                                 operands[3], operands[4],
16873                                 operands[5], operands[6],
16874                                 operands[7], operands[8], true))
16875    DONE;
16876  else
16877    FAIL;
16880 ;; Most CPUs don't like single string operations
16881 ;; Handle this case here to simplify previous expander.
16883 (define_expand "strset"
16884   [(set (match_operand 1 "memory_operand")
16885         (match_operand 2 "register_operand"))
16886    (parallel [(set (match_operand 0 "register_operand")
16887                    (match_dup 3))
16888               (clobber (reg:CC FLAGS_REG))])]
16889   ""
16891   /* Can't use this for non-default address spaces.  */
16892   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16893     FAIL;
16895   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16896     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16898   /* If .md ever supports :P for Pmode, this can be directly
16899      in the pattern above.  */
16900   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16901                               GEN_INT (GET_MODE_SIZE (GET_MODE
16902                                                       (operands[2]))));
16903   /* Can't use this if the user has appropriated eax or edi.  */
16904   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16905       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16906     {
16907       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16908                                       operands[3]));
16909       DONE;
16910     }
16913 (define_expand "strset_singleop"
16914   [(parallel [(set (match_operand 1 "memory_operand")
16915                    (match_operand 2 "register_operand"))
16916               (set (match_operand 0 "register_operand")
16917                    (match_operand 3))
16918               (unspec [(const_int 0)] UNSPEC_STOS)])]
16919   ""
16921   if (TARGET_CLD)
16922     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16925 (define_insn "*strsetdi_rex_1"
16926   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16927         (match_operand:DI 2 "register_operand" "a"))
16928    (set (match_operand:P 0 "register_operand" "=D")
16929         (plus:P (match_dup 1)
16930                 (const_int 8)))
16931    (unspec [(const_int 0)] UNSPEC_STOS)]
16932   "TARGET_64BIT
16933    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16934    && ix86_check_no_addr_space (insn)"
16935   "%^stosq"
16936   [(set_attr "type" "str")
16937    (set_attr "memory" "store")
16938    (set_attr "mode" "DI")])
16940 (define_insn "*strsetsi_1"
16941   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16942         (match_operand:SI 2 "register_operand" "a"))
16943    (set (match_operand:P 0 "register_operand" "=D")
16944         (plus:P (match_dup 1)
16945                 (const_int 4)))
16946    (unspec [(const_int 0)] UNSPEC_STOS)]
16947   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16948    && ix86_check_no_addr_space (insn)"
16949   "%^stos{l|d}"
16950   [(set_attr "type" "str")
16951    (set_attr "memory" "store")
16952    (set_attr "mode" "SI")])
16954 (define_insn "*strsethi_1"
16955   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16956         (match_operand:HI 2 "register_operand" "a"))
16957    (set (match_operand:P 0 "register_operand" "=D")
16958         (plus:P (match_dup 1)
16959                 (const_int 2)))
16960    (unspec [(const_int 0)] UNSPEC_STOS)]
16961   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16962    && ix86_check_no_addr_space (insn)"
16963   "%^stosw"
16964   [(set_attr "type" "str")
16965    (set_attr "memory" "store")
16966    (set_attr "mode" "HI")])
16968 (define_insn "*strsetqi_1"
16969   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16970         (match_operand:QI 2 "register_operand" "a"))
16971    (set (match_operand:P 0 "register_operand" "=D")
16972         (plus:P (match_dup 1)
16973                 (const_int 1)))
16974    (unspec [(const_int 0)] UNSPEC_STOS)]
16975   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16976    && ix86_check_no_addr_space (insn)"
16977   "%^stosb"
16978   [(set_attr "type" "str")
16979    (set_attr "memory" "store")
16980    (set (attr "prefix_rex")
16981         (if_then_else
16982           (match_test "<P:MODE>mode == DImode")
16983           (const_string "0")
16984           (const_string "*")))
16985    (set_attr "mode" "QI")])
16987 (define_expand "rep_stos"
16988   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16989               (set (match_operand 0 "register_operand")
16990                    (match_operand 4))
16991               (set (match_operand 2 "memory_operand") (const_int 0))
16992               (use (match_operand 3 "register_operand"))
16993               (use (match_dup 1))])]
16994   ""
16996   if (TARGET_CLD)
16997     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17000 (define_insn "*rep_stosdi_rex64"
17001   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17002    (set (match_operand:P 0 "register_operand" "=D")
17003         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17004                           (const_int 3))
17005                  (match_operand:P 3 "register_operand" "0")))
17006    (set (mem:BLK (match_dup 3))
17007         (const_int 0))
17008    (use (match_operand:DI 2 "register_operand" "a"))
17009    (use (match_dup 4))]
17010   "TARGET_64BIT
17011    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17012    && ix86_check_no_addr_space (insn)"
17013   "%^rep{%;} stosq"
17014   [(set_attr "type" "str")
17015    (set_attr "prefix_rep" "1")
17016    (set_attr "memory" "store")
17017    (set_attr "mode" "DI")])
17019 (define_insn "*rep_stossi"
17020   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17021    (set (match_operand:P 0 "register_operand" "=D")
17022         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17023                           (const_int 2))
17024                  (match_operand:P 3 "register_operand" "0")))
17025    (set (mem:BLK (match_dup 3))
17026         (const_int 0))
17027    (use (match_operand:SI 2 "register_operand" "a"))
17028    (use (match_dup 4))]
17029   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17030    && ix86_check_no_addr_space (insn)"
17031   "%^rep{%;} stos{l|d}"
17032   [(set_attr "type" "str")
17033    (set_attr "prefix_rep" "1")
17034    (set_attr "memory" "store")
17035    (set_attr "mode" "SI")])
17037 (define_insn "*rep_stosqi"
17038   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17039    (set (match_operand:P 0 "register_operand" "=D")
17040         (plus:P (match_operand:P 3 "register_operand" "0")
17041                 (match_operand:P 4 "register_operand" "1")))
17042    (set (mem:BLK (match_dup 3))
17043         (const_int 0))
17044    (use (match_operand:QI 2 "register_operand" "a"))
17045    (use (match_dup 4))]
17046   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17047    && ix86_check_no_addr_space (insn)"
17048   "%^rep{%;} stosb"
17049   [(set_attr "type" "str")
17050    (set_attr "prefix_rep" "1")
17051    (set_attr "memory" "store")
17052    (set (attr "prefix_rex")
17053         (if_then_else
17054           (match_test "<P:MODE>mode == DImode")
17055           (const_string "0")
17056           (const_string "*")))
17057    (set_attr "mode" "QI")])
17059 (define_expand "cmpstrnsi"
17060   [(set (match_operand:SI 0 "register_operand")
17061         (compare:SI (match_operand:BLK 1 "general_operand")
17062                     (match_operand:BLK 2 "general_operand")))
17063    (use (match_operand 3 "general_operand"))
17064    (use (match_operand 4 "immediate_operand"))]
17065   ""
17067   rtx addr1, addr2, out, outlow, count, countreg, align;
17069   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17070     FAIL;
17072   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17073   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17074     FAIL;
17076   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17077      will have rewritten the length arg to be the minimum of the const string
17078      length and the actual length arg.  If both strings are the same and
17079      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17080      will incorrectly base the results on chars past the 0 byte.  */
17081   tree t1 = MEM_EXPR (operands[1]);
17082   tree t2 = MEM_EXPR (operands[2]);
17083   if (!((t1 && TREE_CODE (t1) == MEM_REF
17084          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17085          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17086       || (t2 && TREE_CODE (t2) == MEM_REF
17087           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17088           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17089     FAIL;
17091   out = operands[0];
17092   if (!REG_P (out))
17093     out = gen_reg_rtx (SImode);
17095   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17096   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17097   if (addr1 != XEXP (operands[1], 0))
17098     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17099   if (addr2 != XEXP (operands[2], 0))
17100     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17102   count = operands[3];
17103   countreg = ix86_zero_extend_to_Pmode (count);
17105   /* %%% Iff we are testing strict equality, we can use known alignment
17106      to good advantage.  This may be possible with combine, particularly
17107      once cc0 is dead.  */
17108   align = operands[4];
17110   if (CONST_INT_P (count))
17111     {
17112       if (INTVAL (count) == 0)
17113         {
17114           emit_move_insn (operands[0], const0_rtx);
17115           DONE;
17116         }
17117       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17118                                      operands[1], operands[2]));
17119     }
17120   else
17121     {
17122       rtx (*gen_cmp) (rtx, rtx);
17124       gen_cmp = (TARGET_64BIT
17125                  ? gen_cmpdi_1 : gen_cmpsi_1);
17127       emit_insn (gen_cmp (countreg, countreg));
17128       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17129                                   operands[1], operands[2]));
17130     }
17132   outlow = gen_lowpart (QImode, out);
17133   emit_insn (gen_cmpintqi (outlow));
17134   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17136   if (operands[0] != out)
17137     emit_move_insn (operands[0], out);
17139   DONE;
17142 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17144 (define_expand "cmpintqi"
17145   [(set (match_dup 1)
17146         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17147    (set (match_dup 2)
17148         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17149    (parallel [(set (match_operand:QI 0 "register_operand")
17150                    (minus:QI (match_dup 1)
17151                              (match_dup 2)))
17152               (clobber (reg:CC FLAGS_REG))])]
17153   ""
17155   operands[1] = gen_reg_rtx (QImode);
17156   operands[2] = gen_reg_rtx (QImode);
17159 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17160 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17162 (define_expand "cmpstrnqi_nz_1"
17163   [(parallel [(set (reg:CC FLAGS_REG)
17164                    (compare:CC (match_operand 4 "memory_operand")
17165                                (match_operand 5 "memory_operand")))
17166               (use (match_operand 2 "register_operand"))
17167               (use (match_operand:SI 3 "immediate_operand"))
17168               (clobber (match_operand 0 "register_operand"))
17169               (clobber (match_operand 1 "register_operand"))
17170               (clobber (match_dup 2))])]
17171   ""
17173   if (TARGET_CLD)
17174     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17177 (define_insn "*cmpstrnqi_nz_1"
17178   [(set (reg:CC FLAGS_REG)
17179         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17180                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17181    (use (match_operand:P 6 "register_operand" "2"))
17182    (use (match_operand:SI 3 "immediate_operand" "i"))
17183    (clobber (match_operand:P 0 "register_operand" "=S"))
17184    (clobber (match_operand:P 1 "register_operand" "=D"))
17185    (clobber (match_operand:P 2 "register_operand" "=c"))]
17186   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17187    && ix86_check_no_addr_space (insn)"
17188   "%^repz{%;} cmpsb"
17189   [(set_attr "type" "str")
17190    (set_attr "mode" "QI")
17191    (set (attr "prefix_rex")
17192         (if_then_else
17193           (match_test "<P:MODE>mode == DImode")
17194           (const_string "0")
17195           (const_string "*")))
17196    (set_attr "prefix_rep" "1")])
17198 ;; The same, but the count is not known to not be zero.
17200 (define_expand "cmpstrnqi_1"
17201   [(parallel [(set (reg:CC FLAGS_REG)
17202                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17203                                      (const_int 0))
17204                   (compare:CC (match_operand 4 "memory_operand")
17205                               (match_operand 5 "memory_operand"))
17206                   (const_int 0)))
17207               (use (match_operand:SI 3 "immediate_operand"))
17208               (use (reg:CC FLAGS_REG))
17209               (clobber (match_operand 0 "register_operand"))
17210               (clobber (match_operand 1 "register_operand"))
17211               (clobber (match_dup 2))])]
17212   ""
17214   if (TARGET_CLD)
17215     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17218 (define_insn "*cmpstrnqi_1"
17219   [(set (reg:CC FLAGS_REG)
17220         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17221                              (const_int 0))
17222           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17223                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17224           (const_int 0)))
17225    (use (match_operand:SI 3 "immediate_operand" "i"))
17226    (use (reg:CC FLAGS_REG))
17227    (clobber (match_operand:P 0 "register_operand" "=S"))
17228    (clobber (match_operand:P 1 "register_operand" "=D"))
17229    (clobber (match_operand:P 2 "register_operand" "=c"))]
17230   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17231    && ix86_check_no_addr_space (insn)"
17232   "%^repz{%;} cmpsb"
17233   [(set_attr "type" "str")
17234    (set_attr "mode" "QI")
17235    (set (attr "prefix_rex")
17236         (if_then_else
17237           (match_test "<P:MODE>mode == DImode")
17238           (const_string "0")
17239           (const_string "*")))
17240    (set_attr "prefix_rep" "1")])
17242 (define_expand "strlen<mode>"
17243   [(set (match_operand:P 0 "register_operand")
17244         (unspec:P [(match_operand:BLK 1 "general_operand")
17245                    (match_operand:QI 2 "immediate_operand")
17246                    (match_operand 3 "immediate_operand")]
17247                   UNSPEC_SCAS))]
17248   ""
17250  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17251    DONE;
17252  else
17253    FAIL;
17256 (define_expand "strlenqi_1"
17257   [(parallel [(set (match_operand 0 "register_operand")
17258                    (match_operand 2))
17259               (clobber (match_operand 1 "register_operand"))
17260               (clobber (reg:CC FLAGS_REG))])]
17261   ""
17263   if (TARGET_CLD)
17264     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17267 (define_insn "*strlenqi_1"
17268   [(set (match_operand:P 0 "register_operand" "=&c")
17269         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17270                    (match_operand:QI 2 "register_operand" "a")
17271                    (match_operand:P 3 "immediate_operand" "i")
17272                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17273    (clobber (match_operand:P 1 "register_operand" "=D"))
17274    (clobber (reg:CC FLAGS_REG))]
17275   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17276    && ix86_check_no_addr_space (insn)"
17277   "%^repnz{%;} scasb"
17278   [(set_attr "type" "str")
17279    (set_attr "mode" "QI")
17280    (set (attr "prefix_rex")
17281         (if_then_else
17282           (match_test "<P:MODE>mode == DImode")
17283           (const_string "0")
17284           (const_string "*")))
17285    (set_attr "prefix_rep" "1")])
17287 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17288 ;; handled in combine, but it is not currently up to the task.
17289 ;; When used for their truth value, the cmpstrn* expanders generate
17290 ;; code like this:
17292 ;;   repz cmpsb
17293 ;;   seta       %al
17294 ;;   setb       %dl
17295 ;;   cmpb       %al, %dl
17296 ;;   jcc        label
17298 ;; The intermediate three instructions are unnecessary.
17300 ;; This one handles cmpstrn*_nz_1...
17301 (define_peephole2
17302   [(parallel[
17303      (set (reg:CC FLAGS_REG)
17304           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17305                       (mem:BLK (match_operand 5 "register_operand"))))
17306      (use (match_operand 6 "register_operand"))
17307      (use (match_operand:SI 3 "immediate_operand"))
17308      (clobber (match_operand 0 "register_operand"))
17309      (clobber (match_operand 1 "register_operand"))
17310      (clobber (match_operand 2 "register_operand"))])
17311    (set (match_operand:QI 7 "register_operand")
17312         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17313    (set (match_operand:QI 8 "register_operand")
17314         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17315    (set (reg FLAGS_REG)
17316         (compare (match_dup 7) (match_dup 8)))
17317   ]
17318   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17319   [(parallel[
17320      (set (reg:CC FLAGS_REG)
17321           (compare:CC (mem:BLK (match_dup 4))
17322                       (mem:BLK (match_dup 5))))
17323      (use (match_dup 6))
17324      (use (match_dup 3))
17325      (clobber (match_dup 0))
17326      (clobber (match_dup 1))
17327      (clobber (match_dup 2))])])
17329 ;; ...and this one handles cmpstrn*_1.
17330 (define_peephole2
17331   [(parallel[
17332      (set (reg:CC FLAGS_REG)
17333           (if_then_else:CC (ne (match_operand 6 "register_operand")
17334                                (const_int 0))
17335             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17336                         (mem:BLK (match_operand 5 "register_operand")))
17337             (const_int 0)))
17338      (use (match_operand:SI 3 "immediate_operand"))
17339      (use (reg:CC FLAGS_REG))
17340      (clobber (match_operand 0 "register_operand"))
17341      (clobber (match_operand 1 "register_operand"))
17342      (clobber (match_operand 2 "register_operand"))])
17343    (set (match_operand:QI 7 "register_operand")
17344         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17345    (set (match_operand:QI 8 "register_operand")
17346         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17347    (set (reg FLAGS_REG)
17348         (compare (match_dup 7) (match_dup 8)))
17349   ]
17350   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17351   [(parallel[
17352      (set (reg:CC FLAGS_REG)
17353           (if_then_else:CC (ne (match_dup 6)
17354                                (const_int 0))
17355             (compare:CC (mem:BLK (match_dup 4))
17356                         (mem:BLK (match_dup 5)))
17357             (const_int 0)))
17358      (use (match_dup 3))
17359      (use (reg:CC FLAGS_REG))
17360      (clobber (match_dup 0))
17361      (clobber (match_dup 1))
17362      (clobber (match_dup 2))])])
17364 ;; Conditional move instructions.
17366 (define_expand "mov<mode>cc"
17367   [(set (match_operand:SWIM 0 "register_operand")
17368         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17369                            (match_operand:SWIM 2 "<general_operand>")
17370                            (match_operand:SWIM 3 "<general_operand>")))]
17371   ""
17372   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17374 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17375 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17376 ;; So just document what we're doing explicitly.
17378 (define_expand "x86_mov<mode>cc_0_m1"
17379   [(parallel
17380     [(set (match_operand:SWI48 0 "register_operand")
17381           (if_then_else:SWI48
17382             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17383              [(match_operand 1 "flags_reg_operand")
17384               (const_int 0)])
17385             (const_int -1)
17386             (const_int 0)))
17387      (clobber (reg:CC FLAGS_REG))])])
17389 (define_insn "*x86_mov<mode>cc_0_m1"
17390   [(set (match_operand:SWI48 0 "register_operand" "=r")
17391         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17392                              [(reg FLAGS_REG) (const_int 0)])
17393           (const_int -1)
17394           (const_int 0)))
17395    (clobber (reg:CC FLAGS_REG))]
17396   ""
17397   "sbb{<imodesuffix>}\t%0, %0"
17398   [(set_attr "type" "alu1")
17399    (set_attr "use_carry" "1")
17400    (set_attr "pent_pair" "pu")
17401    (set_attr "mode" "<MODE>")
17402    (set_attr "length_immediate" "0")])
17404 (define_insn "*x86_mov<mode>cc_0_m1_se"
17405   [(set (match_operand:SWI48 0 "register_operand" "=r")
17406         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17407                              [(reg FLAGS_REG) (const_int 0)])
17408                             (const_int 1)
17409                             (const_int 0)))
17410    (clobber (reg:CC FLAGS_REG))]
17411   ""
17412   "sbb{<imodesuffix>}\t%0, %0"
17413   [(set_attr "type" "alu1")
17414    (set_attr "use_carry" "1")
17415    (set_attr "pent_pair" "pu")
17416    (set_attr "mode" "<MODE>")
17417    (set_attr "length_immediate" "0")])
17419 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17420   [(set (match_operand:SWI48 0 "register_operand" "=r")
17421         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17422                     [(reg FLAGS_REG) (const_int 0)])))
17423    (clobber (reg:CC FLAGS_REG))]
17424   ""
17425   "sbb{<imodesuffix>}\t%0, %0"
17426   [(set_attr "type" "alu1")
17427    (set_attr "use_carry" "1")
17428    (set_attr "pent_pair" "pu")
17429    (set_attr "mode" "<MODE>")
17430    (set_attr "length_immediate" "0")])
17432 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17433   [(set (match_operand:SWI48 0 "register_operand" "=r")
17434         (neg:SWI48
17435           (leu:SWI48
17436             (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17437             (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17438    (clobber (reg:CC FLAGS_REG))]
17439   "CONST_INT_P (operands[2])
17440    && INTVAL (operands[2]) != -1
17441    && INTVAL (operands[2]) != 2147483647"
17442   "#"
17443   ""
17444   [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17445    (parallel [(set (match_dup 0)
17446                    (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17447               (clobber (reg:CC FLAGS_REG))])]
17448   "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17450 (define_insn "*mov<mode>cc_noc"
17451   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17452         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17453                                [(reg FLAGS_REG) (const_int 0)])
17454           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17455           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17456   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17457   "@
17458    cmov%O2%C1\t{%2, %0|%0, %2}
17459    cmov%O2%c1\t{%3, %0|%0, %3}"
17460   [(set_attr "type" "icmov")
17461    (set_attr "mode" "<MODE>")])
17463 (define_insn "*movsicc_noc_zext"
17464   [(set (match_operand:DI 0 "register_operand" "=r,r")
17465         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17466                            [(reg FLAGS_REG) (const_int 0)])
17467           (zero_extend:DI
17468             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17469           (zero_extend:DI
17470             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17471   "TARGET_64BIT
17472    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17473   "@
17474    cmov%O2%C1\t{%2, %k0|%k0, %2}
17475    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17476   [(set_attr "type" "icmov")
17477    (set_attr "mode" "SI")])
17479 ;; Don't do conditional moves with memory inputs.  This splitter helps
17480 ;; register starved x86_32 by forcing inputs into registers before reload.
17481 (define_split
17482   [(set (match_operand:SWI248 0 "register_operand")
17483         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17484                                [(reg FLAGS_REG) (const_int 0)])
17485           (match_operand:SWI248 2 "nonimmediate_operand")
17486           (match_operand:SWI248 3 "nonimmediate_operand")))]
17487   "!TARGET_64BIT && TARGET_CMOVE
17488    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17489    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17490    && can_create_pseudo_p ()
17491    && optimize_insn_for_speed_p ()"
17492   [(set (match_dup 0)
17493         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17495   if (MEM_P (operands[2]))
17496     operands[2] = force_reg (<MODE>mode, operands[2]);
17497   if (MEM_P (operands[3]))
17498     operands[3] = force_reg (<MODE>mode, operands[3]);
17501 (define_insn "*movqicc_noc"
17502   [(set (match_operand:QI 0 "register_operand" "=r,r")
17503         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17504                            [(reg FLAGS_REG) (const_int 0)])
17505                       (match_operand:QI 2 "register_operand" "r,0")
17506                       (match_operand:QI 3 "register_operand" "0,r")))]
17507   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17508   "#"
17509   [(set_attr "type" "icmov")
17510    (set_attr "mode" "QI")])
17512 (define_split
17513   [(set (match_operand:SWI12 0 "register_operand")
17514         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17515                               [(reg FLAGS_REG) (const_int 0)])
17516                       (match_operand:SWI12 2 "register_operand")
17517                       (match_operand:SWI12 3 "register_operand")))]
17518   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17519    && reload_completed"
17520   [(set (match_dup 0)
17521         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17523   operands[0] = gen_lowpart (SImode, operands[0]);
17524   operands[2] = gen_lowpart (SImode, operands[2]);
17525   operands[3] = gen_lowpart (SImode, operands[3]);
17528 ;; Don't do conditional moves with memory inputs
17529 (define_peephole2
17530   [(match_scratch:SWI248 4 "r")
17531    (set (match_operand:SWI248 0 "register_operand")
17532         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17533                                [(reg FLAGS_REG) (const_int 0)])
17534           (match_operand:SWI248 2 "nonimmediate_operand")
17535           (match_operand:SWI248 3 "nonimmediate_operand")))]
17536   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17537    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17538    && optimize_insn_for_speed_p ()"
17539   [(set (match_dup 4) (match_dup 5))
17540    (set (match_dup 0)
17541         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17543   if (MEM_P (operands[2]))
17544     {
17545       operands[5] = operands[2];
17546       operands[2] = operands[4];
17547     }
17548   else if (MEM_P (operands[3]))
17549     {
17550       operands[5] = operands[3];
17551       operands[3] = operands[4];
17552     }
17553   else
17554     gcc_unreachable ();
17557 (define_peephole2
17558   [(match_scratch:SI 4 "r")
17559    (set (match_operand:DI 0 "register_operand")
17560         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17561                            [(reg FLAGS_REG) (const_int 0)])
17562           (zero_extend:DI
17563             (match_operand:SI 2 "nonimmediate_operand"))
17564           (zero_extend:DI
17565             (match_operand:SI 3 "nonimmediate_operand"))))]
17566   "TARGET_64BIT
17567    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17568    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17569    && optimize_insn_for_speed_p ()"
17570   [(set (match_dup 4) (match_dup 5))
17571    (set (match_dup 0)
17572         (if_then_else:DI (match_dup 1)
17573           (zero_extend:DI (match_dup 2))
17574           (zero_extend:DI (match_dup 3))))]
17576   if (MEM_P (operands[2]))
17577     {
17578       operands[5] = operands[2];
17579       operands[2] = operands[4];
17580     }
17581   else if (MEM_P (operands[3]))
17582     {
17583       operands[5] = operands[3];
17584       operands[3] = operands[4];
17585     }
17586   else
17587     gcc_unreachable ();
17590 (define_expand "mov<mode>cc"
17591   [(set (match_operand:X87MODEF 0 "register_operand")
17592         (if_then_else:X87MODEF
17593           (match_operand 1 "comparison_operator")
17594           (match_operand:X87MODEF 2 "register_operand")
17595           (match_operand:X87MODEF 3 "register_operand")))]
17596   "(TARGET_80387 && TARGET_CMOVE)
17597    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17598   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17600 (define_insn "*movxfcc_1"
17601   [(set (match_operand:XF 0 "register_operand" "=f,f")
17602         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17603                                 [(reg FLAGS_REG) (const_int 0)])
17604                       (match_operand:XF 2 "register_operand" "f,0")
17605                       (match_operand:XF 3 "register_operand" "0,f")))]
17606   "TARGET_80387 && TARGET_CMOVE"
17607   "@
17608    fcmov%F1\t{%2, %0|%0, %2}
17609    fcmov%f1\t{%3, %0|%0, %3}"
17610   [(set_attr "type" "fcmov")
17611    (set_attr "mode" "XF")])
17613 (define_insn "*movdfcc_1"
17614   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17615         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17616                                 [(reg FLAGS_REG) (const_int 0)])
17617                       (match_operand:DF 2 "nonimmediate_operand"
17618                                                "f ,0,rm,0 ,rm,0")
17619                       (match_operand:DF 3 "nonimmediate_operand"
17620                                                "0 ,f,0 ,rm,0, rm")))]
17621   "TARGET_80387 && TARGET_CMOVE
17622    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17623   "@
17624    fcmov%F1\t{%2, %0|%0, %2}
17625    fcmov%f1\t{%3, %0|%0, %3}
17626    #
17627    #
17628    cmov%O2%C1\t{%2, %0|%0, %2}
17629    cmov%O2%c1\t{%3, %0|%0, %3}"
17630   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17631    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17632    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17634 (define_split
17635   [(set (match_operand:DF 0 "general_reg_operand")
17636         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17637                                 [(reg FLAGS_REG) (const_int 0)])
17638                       (match_operand:DF 2 "nonimmediate_operand")
17639                       (match_operand:DF 3 "nonimmediate_operand")))]
17640   "!TARGET_64BIT && reload_completed"
17641   [(set (match_dup 2)
17642         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17643    (set (match_dup 3)
17644         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17646   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17647   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17650 (define_insn "*movsfcc_1_387"
17651   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17652         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17653                                 [(reg FLAGS_REG) (const_int 0)])
17654                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17655                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17656   "TARGET_80387 && TARGET_CMOVE
17657    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17658   "@
17659    fcmov%F1\t{%2, %0|%0, %2}
17660    fcmov%f1\t{%3, %0|%0, %3}
17661    cmov%O2%C1\t{%2, %0|%0, %2}
17662    cmov%O2%c1\t{%3, %0|%0, %3}"
17663   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17664    (set_attr "mode" "SF,SF,SI,SI")])
17666 ;; Don't do conditional moves with memory inputs.  This splitter helps
17667 ;; register starved x86_32 by forcing inputs into registers before reload.
17668 (define_split
17669   [(set (match_operand:MODEF 0 "register_operand")
17670         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17671                               [(reg FLAGS_REG) (const_int 0)])
17672           (match_operand:MODEF 2 "nonimmediate_operand")
17673           (match_operand:MODEF 3 "nonimmediate_operand")))]
17674   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17675    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17676    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17677    && can_create_pseudo_p ()
17678    && optimize_insn_for_speed_p ()"
17679   [(set (match_dup 0)
17680         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17682   if (MEM_P (operands[2]))
17683     operands[2] = force_reg (<MODE>mode, operands[2]);
17684   if (MEM_P (operands[3]))
17685     operands[3] = force_reg (<MODE>mode, operands[3]);
17688 ;; Don't do conditional moves with memory inputs
17689 (define_peephole2
17690   [(match_scratch:MODEF 4 "r")
17691    (set (match_operand:MODEF 0 "general_reg_operand")
17692         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17693                               [(reg FLAGS_REG) (const_int 0)])
17694           (match_operand:MODEF 2 "nonimmediate_operand")
17695           (match_operand:MODEF 3 "nonimmediate_operand")))]
17696   "(<MODE>mode != DFmode || TARGET_64BIT)
17697    && TARGET_80387 && TARGET_CMOVE
17698    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17699    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17700    && optimize_insn_for_speed_p ()"
17701   [(set (match_dup 4) (match_dup 5))
17702    (set (match_dup 0)
17703         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17705   if (MEM_P (operands[2]))
17706     {
17707       operands[5] = operands[2];
17708       operands[2] = operands[4];
17709     }
17710   else if (MEM_P (operands[3]))
17711     {
17712       operands[5] = operands[3];
17713       operands[3] = operands[4];
17714     }
17715   else
17716     gcc_unreachable ();
17719 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17720 ;; the scalar versions to have only XMM registers as operands.
17722 ;; XOP conditional move
17723 (define_insn "*xop_pcmov_<mode>"
17724   [(set (match_operand:MODEF 0 "register_operand" "=x")
17725         (if_then_else:MODEF
17726           (match_operand:MODEF 1 "register_operand" "x")
17727           (match_operand:MODEF 2 "register_operand" "x")
17728           (match_operand:MODEF 3 "register_operand" "x")))]
17729   "TARGET_XOP"
17730   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17731   [(set_attr "type" "sse4arg")])
17733 ;; These versions of the min/max patterns are intentionally ignorant of
17734 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17735 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17736 ;; are undefined in this condition, we're certain this is correct.
17738 (define_insn "<code><mode>3"
17739   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17740         (smaxmin:MODEF
17741           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17742           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17743   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17744   "@
17745    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17746    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17747   [(set_attr "isa" "noavx,avx")
17748    (set_attr "prefix" "orig,vex")
17749    (set_attr "type" "sseadd")
17750    (set_attr "mode" "<MODE>")])
17752 ;; These versions of the min/max patterns implement exactly the operations
17753 ;;   min = (op1 < op2 ? op1 : op2)
17754 ;;   max = (!(op1 < op2) ? op1 : op2)
17755 ;; Their operands are not commutative, and thus they may be used in the
17756 ;; presence of -0.0 and NaN.
17758 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17759   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17760         (unspec:MODEF
17761           [(match_operand:MODEF 1 "register_operand" "0,v")
17762            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17763           IEEE_MAXMIN))]
17764   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17765   "@
17766    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17767    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17768   [(set_attr "isa" "noavx,avx")
17769    (set_attr "prefix" "orig,maybe_evex")
17770    (set_attr "type" "sseadd")
17771    (set_attr "mode" "<MODE>")])
17773 ;; Make two stack loads independent:
17774 ;;   fld aa              fld aa
17775 ;;   fld %st(0)     ->   fld bb
17776 ;;   fmul bb             fmul %st(1), %st
17778 ;; Actually we only match the last two instructions for simplicity.
17780 (define_peephole2
17781   [(set (match_operand 0 "fp_register_operand")
17782         (match_operand 1 "fp_register_operand"))
17783    (set (match_dup 0)
17784         (match_operator 2 "binary_fp_operator"
17785            [(match_dup 0)
17786             (match_operand 3 "memory_operand")]))]
17787   "REGNO (operands[0]) != REGNO (operands[1])"
17788   [(set (match_dup 0) (match_dup 3))
17789    (set (match_dup 0)
17790         (match_op_dup 2
17791           [(match_dup 5) (match_dup 4)]))]
17793   operands[4] = operands[0];
17794   operands[5] = operands[1];
17796   /* The % modifier is not operational anymore in peephole2's, so we have to
17797      swap the operands manually in the case of addition and multiplication. */
17798   if (COMMUTATIVE_ARITH_P (operands[2]))
17799     std::swap (operands[4], operands[5]);
17802 (define_peephole2
17803   [(set (match_operand 0 "fp_register_operand")
17804         (match_operand 1 "fp_register_operand"))
17805    (set (match_dup 0)
17806         (match_operator 2 "binary_fp_operator"
17807            [(match_operand 3 "memory_operand")
17808             (match_dup 0)]))]
17809   "REGNO (operands[0]) != REGNO (operands[1])"
17810   [(set (match_dup 0) (match_dup 3))
17811    (set (match_dup 0)
17812         (match_op_dup 2
17813           [(match_dup 4) (match_dup 5)]))]
17815   operands[4] = operands[0];
17816   operands[5] = operands[1];
17818   /* The % modifier is not operational anymore in peephole2's, so we have to
17819      swap the operands manually in the case of addition and multiplication. */
17820   if (COMMUTATIVE_ARITH_P (operands[2]))
17821     std::swap (operands[4], operands[5]);
17824 ;; Conditional addition patterns
17825 (define_expand "add<mode>cc"
17826   [(match_operand:SWI 0 "register_operand")
17827    (match_operand 1 "ordered_comparison_operator")
17828    (match_operand:SWI 2 "register_operand")
17829    (match_operand:SWI 3 "const_int_operand")]
17830   ""
17831   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17833 ;; Misc patterns (?)
17835 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17836 ;; Otherwise there will be nothing to keep
17838 ;; [(set (reg ebp) (reg esp))]
17839 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17840 ;;  (clobber (eflags)]
17841 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17843 ;; in proper program order.
17845 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
17846   [(set (match_operand:P 0 "register_operand" "=r,r")
17847         (plus:P (match_operand:P 1 "register_operand" "0,r")
17848                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17849    (clobber (reg:CC FLAGS_REG))
17850    (clobber (mem:BLK (scratch)))]
17851   ""
17853   switch (get_attr_type (insn))
17854     {
17855     case TYPE_IMOV:
17856       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17858     case TYPE_ALU:
17859       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17860       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17861         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17863       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17865     default:
17866       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17867       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17868     }
17870   [(set (attr "type")
17871         (cond [(and (eq_attr "alternative" "0")
17872                     (not (match_test "TARGET_OPT_AGU")))
17873                  (const_string "alu")
17874                (match_operand:<MODE> 2 "const0_operand")
17875                  (const_string "imov")
17876               ]
17877               (const_string "lea")))
17878    (set (attr "length_immediate")
17879         (cond [(eq_attr "type" "imov")
17880                  (const_string "0")
17881                (and (eq_attr "type" "alu")
17882                     (match_operand 2 "const128_operand"))
17883                  (const_string "1")
17884               ]
17885               (const_string "*")))
17886    (set_attr "mode" "<MODE>")])
17888 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
17889   [(set (match_operand:P 0 "register_operand" "=r")
17890         (minus:P (match_operand:P 1 "register_operand" "0")
17891                  (match_operand:P 2 "register_operand" "r")))
17892    (clobber (reg:CC FLAGS_REG))
17893    (clobber (mem:BLK (scratch)))]
17894   ""
17895   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17896   [(set_attr "type" "alu")
17897    (set_attr "mode" "<MODE>")])
17899 (define_insn "@allocate_stack_worker_probe_<mode>"
17900   [(set (match_operand:P 0 "register_operand" "=a")
17901         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17902                             UNSPECV_STACK_PROBE))
17903    (clobber (reg:CC FLAGS_REG))]
17904   "ix86_target_stack_probe ()"
17905   "call\t___chkstk_ms"
17906   [(set_attr "type" "multi")
17907    (set_attr "length" "5")])
17909 (define_expand "allocate_stack"
17910   [(match_operand 0 "register_operand")
17911    (match_operand 1 "general_operand")]
17912   "ix86_target_stack_probe ()"
17914   rtx x;
17916 #ifndef CHECK_STACK_LIMIT
17917 #define CHECK_STACK_LIMIT 0
17918 #endif
17920   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17921       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17922     x = operands[1];
17923   else
17924     {
17925       x = copy_to_mode_reg (Pmode, operands[1]);
17927       emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
17928     }
17930   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17931                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17933   if (x != stack_pointer_rtx)
17934     emit_move_insn (stack_pointer_rtx, x);
17936   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17937   DONE;
17940 (define_expand "probe_stack"
17941   [(match_operand 0 "memory_operand")]
17942   ""
17944   emit_insn (gen_probe_stack_1
17945              (word_mode, operands[0], const0_rtx));
17946   DONE;
17949 ;; Use OR for stack probes, this is shorter.
17950 (define_insn "@probe_stack_1_<mode>"
17951   [(set (match_operand:W 0 "memory_operand" "=m")
17952         (unspec:W [(match_operand:W 1 "const0_operand")]
17953                   UNSPEC_PROBE_STACK))
17954    (clobber (reg:CC FLAGS_REG))]
17955   ""
17956   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17957   [(set_attr "type" "alu1")
17958    (set_attr "mode" "<MODE>")
17959    (set_attr "length_immediate" "1")])
17960   
17961 (define_insn "@adjust_stack_and_probe_<mode>"
17962   [(set (match_operand:P 0 "register_operand" "=r")
17963         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17964                             UNSPECV_PROBE_STACK_RANGE))
17965    (set (reg:P SP_REG)
17966         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17967    (clobber (reg:CC FLAGS_REG))
17968    (clobber (mem:BLK (scratch)))]
17969   ""
17970   "* return output_adjust_stack_and_probe (operands[0]);"
17971   [(set_attr "type" "multi")])
17973 (define_insn "@probe_stack_range_<mode>"
17974   [(set (match_operand:P 0 "register_operand" "=r")
17975         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17976                             (match_operand:P 2 "const_int_operand" "n")]
17977                             UNSPECV_PROBE_STACK_RANGE))
17978    (clobber (reg:CC FLAGS_REG))]
17979   ""
17980   "* return output_probe_stack_range (operands[0], operands[2]);"
17981   [(set_attr "type" "multi")])
17983 (define_expand "builtin_setjmp_receiver"
17984   [(label_ref (match_operand 0))]
17985   "!TARGET_64BIT && flag_pic"
17987 #if TARGET_MACHO
17988   if (TARGET_MACHO)
17989     {
17990       rtx xops[3];
17991       rtx_code_label *label_rtx = gen_label_rtx ();
17992       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17993       xops[0] = xops[1] = pic_offset_table_rtx;
17994       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17995       ix86_expand_binary_operator (MINUS, SImode, xops);
17996     }
17997   else
17998 #endif
17999     emit_insn (gen_set_got (pic_offset_table_rtx));
18000   DONE;
18003 (define_expand "save_stack_nonlocal"
18004   [(set (match_operand 0 "memory_operand")
18005         (match_operand 1 "register_operand"))]
18006   ""
18008   rtx stack_slot;
18009   if ((flag_cf_protection & CF_RETURN))
18010     {
18011       /* Copy shadow stack pointer to the first slot and stack ppointer
18012          to the second slot.  */
18013       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18014       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18015       rtx ssp = gen_reg_rtx (word_mode);
18016       emit_insn ((word_mode == SImode)
18017                  ? gen_rdsspsi (ssp)
18018                  : gen_rdsspdi (ssp));
18019       emit_move_insn (ssp_slot, ssp);
18020     }
18021   else
18022     stack_slot = adjust_address (operands[0], Pmode, 0);
18023   emit_move_insn (stack_slot, operands[1]);
18024   DONE;
18027 (define_expand "restore_stack_nonlocal"
18028   [(set (match_operand 0 "register_operand" "")
18029         (match_operand 1 "memory_operand" ""))]
18030   ""
18032   rtx stack_slot;
18033   if ((flag_cf_protection & CF_RETURN))
18034     {
18035       /* Restore shadow stack pointer from the first slot and stack
18036          pointer from the second slot.  */
18037       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18038       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18040       rtx flags, jump, noadj_label, inc_label, loop_label;
18041       rtx reg_adj, reg_ssp, tmp, clob;
18043       /* Get the current shadow stack pointer.  The code below will check if
18044          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18045          is a NOP.  */
18046       reg_ssp = gen_reg_rtx (word_mode);
18047       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18048       emit_insn ((word_mode == SImode)
18049                  ? gen_rdsspsi (reg_ssp)
18050                  : gen_rdsspdi (reg_ssp));
18052       /* Compare through substraction the saved and the current ssp to decide
18053          if ssp has to be adjusted.  */
18054       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18055                                                  ssp_slot));
18056       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18057       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18058       emit_insn (tmp);
18060       /* Compare and jump over adjustment code.  */
18061       noadj_label = gen_label_rtx ();
18062       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18063       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18064       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18065                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18066                                   pc_rtx);
18067       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18068       JUMP_LABEL (jump) = noadj_label;
18070       /* Compute the numebr of frames to adjust.  */
18071       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18072       tmp = gen_rtx_SET (reg_adj,
18073                          gen_rtx_LSHIFTRT (ptr_mode,
18074                                            negate_rtx (ptr_mode, reg_adj),
18075                                            GEN_INT ((word_mode == SImode)
18076                                                     ? 2
18077                                                     : 3)));
18078       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18079       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18080       emit_insn (tmp);
18082       /* Check if number of frames <= 255 so no loop is needed.  */
18083       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18084       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18085       emit_insn (gen_rtx_SET (flags, tmp));
18087       inc_label = gen_label_rtx ();
18088       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18089       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18090                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
18091                                   pc_rtx);
18092       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18093       JUMP_LABEL (jump) = inc_label;
18095       rtx reg_255 = gen_reg_rtx (word_mode);
18096       emit_move_insn (reg_255, GEN_INT (255));
18098       /* Adjust the ssp in a loop.  */
18099       loop_label = gen_label_rtx ();
18100       emit_label (loop_label);
18101       LABEL_NUSES (loop_label) = 1;
18103       emit_insn ((word_mode == SImode)
18104                  ? gen_incsspsi (reg_255)
18105                  : gen_incsspdi (reg_255));
18106       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18107                                                  reg_adj,
18108                                                  GEN_INT (255)));
18109       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18110       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18111       emit_insn (tmp);
18113       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18114       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18115       emit_insn (gen_rtx_SET (flags, tmp));
18117       /* Jump to the loop label.  */
18118       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18119       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18120                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
18121                                   pc_rtx);
18122       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18123       JUMP_LABEL (jump) = loop_label;
18125       emit_label (inc_label);
18126       LABEL_NUSES (inc_label) = 1;
18127       emit_insn ((word_mode == SImode)
18128                  ? gen_incsspsi (reg_ssp)
18129                  : gen_incsspdi (reg_ssp));
18131       emit_label (noadj_label);
18132       LABEL_NUSES (noadj_label) = 1;
18133     }
18134   else
18135     stack_slot = adjust_address (operands[1], Pmode, 0);
18136   emit_move_insn (operands[0], stack_slot);
18137   DONE;
18141 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18142 ;; Do not split instructions with mask registers.
18143 (define_split
18144   [(set (match_operand 0 "general_reg_operand")
18145         (match_operator 3 "promotable_binary_operator"
18146            [(match_operand 1 "general_reg_operand")
18147             (match_operand 2 "aligned_operand")]))
18148    (clobber (reg:CC FLAGS_REG))]
18149   "! TARGET_PARTIAL_REG_STALL && reload_completed
18150    && ((GET_MODE (operands[0]) == HImode
18151         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18152             /* ??? next two lines just !satisfies_constraint_K (...) */
18153             || !CONST_INT_P (operands[2])
18154             || satisfies_constraint_K (operands[2])))
18155        || (GET_MODE (operands[0]) == QImode
18156            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18157   [(parallel [(set (match_dup 0)
18158                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18159               (clobber (reg:CC FLAGS_REG))])]
18161   operands[0] = gen_lowpart (SImode, operands[0]);
18162   operands[1] = gen_lowpart (SImode, operands[1]);
18163   if (GET_CODE (operands[3]) != ASHIFT)
18164     operands[2] = gen_lowpart (SImode, operands[2]);
18165   operands[3] = shallow_copy_rtx (operands[3]);
18166   PUT_MODE (operands[3], SImode);
18169 ; Promote the QImode tests, as i386 has encoding of the AND
18170 ; instruction with 32-bit sign-extended immediate and thus the
18171 ; instruction size is unchanged, except in the %eax case for
18172 ; which it is increased by one byte, hence the ! optimize_size.
18173 (define_split
18174   [(set (match_operand 0 "flags_reg_operand")
18175         (match_operator 2 "compare_operator"
18176           [(and (match_operand 3 "aligned_operand")
18177                 (match_operand 4 "const_int_operand"))
18178            (const_int 0)]))
18179    (set (match_operand 1 "register_operand")
18180         (and (match_dup 3) (match_dup 4)))]
18181   "! TARGET_PARTIAL_REG_STALL && reload_completed
18182    && optimize_insn_for_speed_p ()
18183    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18184        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18185    /* Ensure that the operand will remain sign-extended immediate.  */
18186    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18187   [(parallel [(set (match_dup 0)
18188                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18189                                     (const_int 0)]))
18190               (set (match_dup 1)
18191                    (and:SI (match_dup 3) (match_dup 4)))])]
18193   operands[4]
18194     = gen_int_mode (INTVAL (operands[4])
18195                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18196   operands[1] = gen_lowpart (SImode, operands[1]);
18197   operands[3] = gen_lowpart (SImode, operands[3]);
18200 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18201 ; the TEST instruction with 32-bit sign-extended immediate and thus
18202 ; the instruction size would at least double, which is not what we
18203 ; want even with ! optimize_size.
18204 (define_split
18205   [(set (match_operand 0 "flags_reg_operand")
18206         (match_operator 1 "compare_operator"
18207           [(and (match_operand:HI 2 "aligned_operand")
18208                 (match_operand:HI 3 "const_int_operand"))
18209            (const_int 0)]))]
18210   "! TARGET_PARTIAL_REG_STALL && reload_completed
18211    && ! TARGET_FAST_PREFIX
18212    && optimize_insn_for_speed_p ()
18213    /* Ensure that the operand will remain sign-extended immediate.  */
18214    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18215   [(set (match_dup 0)
18216         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18217                          (const_int 0)]))]
18219   operands[3]
18220     = gen_int_mode (INTVAL (operands[3])
18221                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18222   operands[2] = gen_lowpart (SImode, operands[2]);
18225 (define_split
18226   [(set (match_operand 0 "register_operand")
18227         (neg (match_operand 1 "register_operand")))
18228    (clobber (reg:CC FLAGS_REG))]
18229   "! TARGET_PARTIAL_REG_STALL && reload_completed
18230    && (GET_MODE (operands[0]) == HImode
18231        || (GET_MODE (operands[0]) == QImode
18232            && (TARGET_PROMOTE_QImode
18233                || optimize_insn_for_size_p ())))"
18234   [(parallel [(set (match_dup 0)
18235                    (neg:SI (match_dup 1)))
18236               (clobber (reg:CC FLAGS_REG))])]
18238   operands[0] = gen_lowpart (SImode, operands[0]);
18239   operands[1] = gen_lowpart (SImode, operands[1]);
18242 ;; Do not split instructions with mask regs.
18243 (define_split
18244   [(set (match_operand 0 "general_reg_operand")
18245         (not (match_operand 1 "general_reg_operand")))]
18246   "! TARGET_PARTIAL_REG_STALL && reload_completed
18247    && (GET_MODE (operands[0]) == HImode
18248        || (GET_MODE (operands[0]) == QImode
18249            && (TARGET_PROMOTE_QImode
18250                || optimize_insn_for_size_p ())))"
18251   [(set (match_dup 0)
18252         (not:SI (match_dup 1)))]
18254   operands[0] = gen_lowpart (SImode, operands[0]);
18255   operands[1] = gen_lowpart (SImode, operands[1]);
18258 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18259 ;; transform a complex memory operation into two memory to register operations.
18261 ;; Don't push memory operands
18262 (define_peephole2
18263   [(set (match_operand:SWI 0 "push_operand")
18264         (match_operand:SWI 1 "memory_operand"))
18265    (match_scratch:SWI 2 "<r>")]
18266   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18267    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18268   [(set (match_dup 2) (match_dup 1))
18269    (set (match_dup 0) (match_dup 2))])
18271 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18272 ;; SImode pushes.
18273 (define_peephole2
18274   [(set (match_operand:SF 0 "push_operand")
18275         (match_operand:SF 1 "memory_operand"))
18276    (match_scratch:SF 2 "r")]
18277   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18278    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18279   [(set (match_dup 2) (match_dup 1))
18280    (set (match_dup 0) (match_dup 2))])
18282 ;; Don't move an immediate directly to memory when the instruction
18283 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18284 (define_peephole2
18285   [(match_scratch:SWI124 1 "<r>")
18286    (set (match_operand:SWI124 0 "memory_operand")
18287         (const_int 0))]
18288   "optimize_insn_for_speed_p ()
18289    && ((<MODE>mode == HImode
18290        && TARGET_LCP_STALL)
18291        || (!TARGET_USE_MOV0
18292           && TARGET_SPLIT_LONG_MOVES
18293           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18294    && peep2_regno_dead_p (0, FLAGS_REG)"
18295   [(parallel [(set (match_dup 2) (const_int 0))
18296               (clobber (reg:CC FLAGS_REG))])
18297    (set (match_dup 0) (match_dup 1))]
18298   "operands[2] = gen_lowpart (SImode, operands[1]);")
18300 (define_peephole2
18301   [(match_scratch:SWI124 2 "<r>")
18302    (set (match_operand:SWI124 0 "memory_operand")
18303         (match_operand:SWI124 1 "immediate_operand"))]
18304   "optimize_insn_for_speed_p ()
18305    && ((<MODE>mode == HImode
18306        && TARGET_LCP_STALL)
18307        || (TARGET_SPLIT_LONG_MOVES
18308           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18309   [(set (match_dup 2) (match_dup 1))
18310    (set (match_dup 0) (match_dup 2))])
18312 ;; Don't compare memory with zero, load and use a test instead.
18313 (define_peephole2
18314   [(set (match_operand 0 "flags_reg_operand")
18315         (match_operator 1 "compare_operator"
18316           [(match_operand:SI 2 "memory_operand")
18317            (const_int 0)]))
18318    (match_scratch:SI 3 "r")]
18319   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18320   [(set (match_dup 3) (match_dup 2))
18321    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18323 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18324 ;; Don't split NOTs with a displacement operand, because resulting XOR
18325 ;; will not be pairable anyway.
18327 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18328 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18329 ;; so this split helps here as well.
18331 ;; Note: Can't do this as a regular split because we can't get proper
18332 ;; lifetime information then.
18334 (define_peephole2
18335   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18336         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18337   "optimize_insn_for_speed_p ()
18338    && ((TARGET_NOT_UNPAIRABLE
18339         && (!MEM_P (operands[0])
18340             || !memory_displacement_operand (operands[0], <MODE>mode)))
18341        || (TARGET_NOT_VECTORMODE
18342            && long_memory_operand (operands[0], <MODE>mode)))
18343    && peep2_regno_dead_p (0, FLAGS_REG)"
18344   [(parallel [(set (match_dup 0)
18345                    (xor:SWI124 (match_dup 1) (const_int -1)))
18346               (clobber (reg:CC FLAGS_REG))])])
18348 ;; Non pairable "test imm, reg" instructions can be translated to
18349 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18350 ;; byte opcode instead of two, have a short form for byte operands),
18351 ;; so do it for other CPUs as well.  Given that the value was dead,
18352 ;; this should not create any new dependencies.  Pass on the sub-word
18353 ;; versions if we're concerned about partial register stalls.
18355 (define_peephole2
18356   [(set (match_operand 0 "flags_reg_operand")
18357         (match_operator 1 "compare_operator"
18358           [(and:SI (match_operand:SI 2 "register_operand")
18359                    (match_operand:SI 3 "immediate_operand"))
18360            (const_int 0)]))]
18361   "ix86_match_ccmode (insn, CCNOmode)
18362    && (REGNO (operands[2]) != AX_REG
18363        || satisfies_constraint_K (operands[3]))
18364    && peep2_reg_dead_p (1, operands[2])"
18365   [(parallel
18366      [(set (match_dup 0)
18367            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18368                             (const_int 0)]))
18369       (set (match_dup 2)
18370            (and:SI (match_dup 2) (match_dup 3)))])])
18372 ;; We don't need to handle HImode case, because it will be promoted to SImode
18373 ;; on ! TARGET_PARTIAL_REG_STALL
18375 (define_peephole2
18376   [(set (match_operand 0 "flags_reg_operand")
18377         (match_operator 1 "compare_operator"
18378           [(and:QI (match_operand:QI 2 "register_operand")
18379                    (match_operand:QI 3 "immediate_operand"))
18380            (const_int 0)]))]
18381   "! TARGET_PARTIAL_REG_STALL
18382    && ix86_match_ccmode (insn, CCNOmode)
18383    && REGNO (operands[2]) != AX_REG
18384    && peep2_reg_dead_p (1, operands[2])"
18385   [(parallel
18386      [(set (match_dup 0)
18387            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18388                             (const_int 0)]))
18389       (set (match_dup 2)
18390            (and:QI (match_dup 2) (match_dup 3)))])])
18392 (define_peephole2
18393   [(set (match_operand 0 "flags_reg_operand")
18394         (match_operator 1 "compare_operator"
18395           [(and:QI
18396              (subreg:QI
18397                (zero_extract:SI (match_operand 2 "QIreg_operand")
18398                                 (const_int 8)
18399                                 (const_int 8)) 0)
18400              (match_operand 3 "const_int_operand"))
18401            (const_int 0)]))]
18402   "! TARGET_PARTIAL_REG_STALL
18403    && ix86_match_ccmode (insn, CCNOmode)
18404    && REGNO (operands[2]) != AX_REG
18405    && peep2_reg_dead_p (1, operands[2])"
18406   [(parallel
18407      [(set (match_dup 0)
18408            (match_op_dup 1
18409              [(and:QI
18410                 (subreg:QI
18411                   (zero_extract:SI (match_dup 2)
18412                                    (const_int 8)
18413                                    (const_int 8)) 0)
18414                 (match_dup 3))
18415               (const_int 0)]))
18416       (set (zero_extract:SI (match_dup 2)
18417                             (const_int 8)
18418                             (const_int 8))
18419            (subreg:SI
18420              (and:QI
18421                (subreg:QI
18422                  (zero_extract:SI (match_dup 2)
18423                                   (const_int 8)
18424                                   (const_int 8)) 0)
18425                (match_dup 3)) 0))])])
18427 ;; Don't do logical operations with memory inputs.
18428 (define_peephole2
18429   [(match_scratch:SWI 2 "<r>")
18430    (parallel [(set (match_operand:SWI 0 "register_operand")
18431                    (match_operator:SWI 3 "arith_or_logical_operator"
18432                      [(match_dup 0)
18433                       (match_operand:SWI 1 "memory_operand")]))
18434               (clobber (reg:CC FLAGS_REG))])]
18435   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18436   [(set (match_dup 2) (match_dup 1))
18437    (parallel [(set (match_dup 0)
18438                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18439               (clobber (reg:CC FLAGS_REG))])])
18441 (define_peephole2
18442   [(match_scratch:SWI 2 "<r>")
18443    (parallel [(set (match_operand:SWI 0 "register_operand")
18444                    (match_operator:SWI 3 "arith_or_logical_operator"
18445                      [(match_operand:SWI 1 "memory_operand")
18446                       (match_dup 0)]))
18447               (clobber (reg:CC FLAGS_REG))])]
18448   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18449   [(set (match_dup 2) (match_dup 1))
18450    (parallel [(set (match_dup 0)
18451                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18452               (clobber (reg:CC FLAGS_REG))])])
18454 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18455 ;; the memory address refers to the destination of the load!
18457 (define_peephole2
18458   [(set (match_operand:SWI 0 "general_reg_operand")
18459         (match_operand:SWI 1 "general_reg_operand"))
18460    (parallel [(set (match_dup 0)
18461                    (match_operator:SWI 3 "commutative_operator"
18462                      [(match_dup 0)
18463                       (match_operand:SWI 2 "memory_operand")]))
18464               (clobber (reg:CC FLAGS_REG))])]
18465   "REGNO (operands[0]) != REGNO (operands[1])
18466    && (<MODE>mode != QImode
18467        || any_QIreg_operand (operands[1], QImode))"
18468   [(set (match_dup 0) (match_dup 4))
18469    (parallel [(set (match_dup 0)
18470                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18471               (clobber (reg:CC FLAGS_REG))])]
18472   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18474 (define_peephole2
18475   [(set (match_operand 0 "mmx_reg_operand")
18476         (match_operand 1 "mmx_reg_operand"))
18477    (set (match_dup 0)
18478         (match_operator 3 "commutative_operator"
18479           [(match_dup 0)
18480            (match_operand 2 "memory_operand")]))]
18481   "REGNO (operands[0]) != REGNO (operands[1])"
18482   [(set (match_dup 0) (match_dup 2))
18483    (set (match_dup 0)
18484         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18486 (define_peephole2
18487   [(set (match_operand 0 "sse_reg_operand")
18488         (match_operand 1 "sse_reg_operand"))
18489    (set (match_dup 0)
18490         (match_operator 3 "commutative_operator"
18491           [(match_dup 0)
18492            (match_operand 2 "memory_operand")]))]
18493   "REGNO (operands[0]) != REGNO (operands[1])"
18494   [(set (match_dup 0) (match_dup 2))
18495    (set (match_dup 0)
18496         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18498 ; Don't do logical operations with memory outputs
18500 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18501 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18502 ; the same decoder scheduling characteristics as the original.
18504 (define_peephole2
18505   [(match_scratch:SWI 2 "<r>")
18506    (parallel [(set (match_operand:SWI 0 "memory_operand")
18507                    (match_operator:SWI 3 "arith_or_logical_operator"
18508                      [(match_dup 0)
18509                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18510               (clobber (reg:CC FLAGS_REG))])]
18511   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18512   [(set (match_dup 2) (match_dup 0))
18513    (parallel [(set (match_dup 2)
18514                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18515               (clobber (reg:CC FLAGS_REG))])
18516    (set (match_dup 0) (match_dup 2))])
18518 (define_peephole2
18519   [(match_scratch:SWI 2 "<r>")
18520    (parallel [(set (match_operand:SWI 0 "memory_operand")
18521                    (match_operator:SWI 3 "arith_or_logical_operator"
18522                      [(match_operand:SWI 1 "<nonmemory_operand>")
18523                       (match_dup 0)]))
18524               (clobber (reg:CC FLAGS_REG))])]
18525   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18526   [(set (match_dup 2) (match_dup 0))
18527    (parallel [(set (match_dup 2)
18528                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18529               (clobber (reg:CC FLAGS_REG))])
18530    (set (match_dup 0) (match_dup 2))])
18532 ;; Attempt to use arith or logical operations with memory outputs with
18533 ;; setting of flags.
18534 (define_peephole2
18535   [(set (match_operand:SWI 0 "register_operand")
18536         (match_operand:SWI 1 "memory_operand"))
18537    (parallel [(set (match_dup 0)
18538                    (match_operator:SWI 3 "plusminuslogic_operator"
18539                      [(match_dup 0)
18540                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18541               (clobber (reg:CC FLAGS_REG))])
18542    (set (match_dup 1) (match_dup 0))
18543    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18544   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18545    && peep2_reg_dead_p (4, operands[0])
18546    && !reg_overlap_mentioned_p (operands[0], operands[1])
18547    && !reg_overlap_mentioned_p (operands[0], operands[2])
18548    && (<MODE>mode != QImode
18549        || immediate_operand (operands[2], QImode)
18550        || any_QIreg_operand (operands[2], QImode))
18551    && ix86_match_ccmode (peep2_next_insn (3),
18552                          (GET_CODE (operands[3]) == PLUS
18553                           || GET_CODE (operands[3]) == MINUS)
18554                          ? CCGOCmode : CCNOmode)"
18555   [(parallel [(set (match_dup 4) (match_dup 6))
18556               (set (match_dup 1) (match_dup 5))])]
18558   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18559   operands[5]
18560     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18561                       copy_rtx (operands[1]),
18562                       operands[2]);
18563   operands[6]
18564     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18565                        copy_rtx (operands[5]),
18566                        const0_rtx);
18569 ;; Likewise for cmpelim optimized pattern.
18570 (define_peephole2
18571   [(set (match_operand:SWI 0 "register_operand")
18572         (match_operand:SWI 1 "memory_operand"))
18573    (parallel [(set (reg FLAGS_REG)
18574                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
18575                               [(match_dup 0)
18576                                (match_operand:SWI 2 "<nonmemory_operand>")])
18577                             (const_int 0)))
18578               (set (match_dup 0) (match_dup 3))])
18579    (set (match_dup 1) (match_dup 0))]
18580   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18581    && peep2_reg_dead_p (3, operands[0])
18582    && !reg_overlap_mentioned_p (operands[0], operands[1])
18583    && !reg_overlap_mentioned_p (operands[0], operands[2])
18584    && ix86_match_ccmode (peep2_next_insn (1),
18585                          (GET_CODE (operands[3]) == PLUS
18586                           || GET_CODE (operands[3]) == MINUS)
18587                          ? CCGOCmode : CCNOmode)"
18588   [(parallel [(set (match_dup 4) (match_dup 6))
18589               (set (match_dup 1) (match_dup 5))])]
18591   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18592   operands[5]
18593     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18594                       copy_rtx (operands[1]), operands[2]);
18595   operands[6]
18596     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18597                        const0_rtx);
18600 ;; Likewise for instances where we have a lea pattern.
18601 (define_peephole2
18602   [(set (match_operand:SWI 0 "register_operand")
18603         (match_operand:SWI 1 "memory_operand"))
18604    (set (match_operand:<LEAMODE> 3 "register_operand")
18605         (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18606                         (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18607    (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18608    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18609   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18610    && REGNO (operands[4]) == REGNO (operands[0])
18611    && REGNO (operands[5]) == REGNO (operands[3])
18612    && peep2_reg_dead_p (4, operands[3])
18613    && ((REGNO (operands[0]) == REGNO (operands[3]))
18614        || peep2_reg_dead_p (2, operands[0]))
18615    && !reg_overlap_mentioned_p (operands[0], operands[1])
18616    && !reg_overlap_mentioned_p (operands[3], operands[1])
18617    && !reg_overlap_mentioned_p (operands[0], operands[2])
18618    && (<MODE>mode != QImode
18619        || immediate_operand (operands[2], QImode)
18620        || any_QIreg_operand (operands[2], QImode))
18621    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18622   [(parallel [(set (match_dup 6) (match_dup 8))
18623               (set (match_dup 1) (match_dup 7))])]
18625   operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18626   operands[7]
18627     = gen_rtx_PLUS (<MODE>mode,
18628                     copy_rtx (operands[1]),
18629                     gen_lowpart (<MODE>mode, operands[2]));
18630   operands[8]
18631     = gen_rtx_COMPARE (GET_MODE (operands[6]),
18632                        copy_rtx (operands[7]),
18633                        const0_rtx);
18636 (define_peephole2
18637   [(parallel [(set (match_operand:SWI 0 "register_operand")
18638                    (match_operator:SWI 2 "plusminuslogic_operator"
18639                      [(match_dup 0)
18640                       (match_operand:SWI 1 "memory_operand")]))
18641               (clobber (reg:CC FLAGS_REG))])
18642    (set (match_dup 1) (match_dup 0))
18643    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18644   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18645    && COMMUTATIVE_ARITH_P (operands[2])
18646    && peep2_reg_dead_p (3, operands[0])
18647    && !reg_overlap_mentioned_p (operands[0], operands[1])
18648    && ix86_match_ccmode (peep2_next_insn (2),
18649                          GET_CODE (operands[2]) == PLUS
18650                          ? CCGOCmode : CCNOmode)"
18651   [(parallel [(set (match_dup 3) (match_dup 5))
18652               (set (match_dup 1) (match_dup 4))])]
18654   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18655   operands[4]
18656     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18657                       copy_rtx (operands[1]),
18658                       operands[0]);
18659   operands[5]
18660     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18661                        copy_rtx (operands[4]),
18662                        const0_rtx);
18665 ;; Likewise for cmpelim optimized pattern.
18666 (define_peephole2
18667   [(parallel [(set (reg FLAGS_REG)
18668                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
18669                               [(match_operand:SWI 0 "register_operand")
18670                                (match_operand:SWI 1 "memory_operand")])
18671                             (const_int 0)))
18672               (set (match_dup 0) (match_dup 2))])
18673    (set (match_dup 1) (match_dup 0))]
18674   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18675    && COMMUTATIVE_ARITH_P (operands[2])
18676    && peep2_reg_dead_p (2, operands[0])
18677    && !reg_overlap_mentioned_p (operands[0], operands[1])
18678    && ix86_match_ccmode (peep2_next_insn (0),
18679                          GET_CODE (operands[2]) == PLUS
18680                          ? CCGOCmode : CCNOmode)"
18681   [(parallel [(set (match_dup 3) (match_dup 5))
18682               (set (match_dup 1) (match_dup 4))])]
18684   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18685   operands[4]
18686     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18687                       copy_rtx (operands[1]), operands[0]);
18688   operands[5]
18689     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18690                        const0_rtx);
18693 (define_peephole2
18694   [(set (match_operand:SWI12 0 "register_operand")
18695         (match_operand:SWI12 1 "memory_operand"))
18696    (parallel [(set (match_operand:SI 4 "register_operand")
18697                    (match_operator:SI 3 "plusminuslogic_operator"
18698                      [(match_dup 4)
18699                       (match_operand:SI 2 "nonmemory_operand")]))
18700               (clobber (reg:CC FLAGS_REG))])
18701    (set (match_dup 1) (match_dup 0))
18702    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18703   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18704    && REGNO (operands[0]) == REGNO (operands[4])
18705    && peep2_reg_dead_p (4, operands[0])
18706    && (<MODE>mode != QImode
18707        || immediate_operand (operands[2], SImode)
18708        || any_QIreg_operand (operands[2], SImode))
18709    && !reg_overlap_mentioned_p (operands[0], operands[1])
18710    && !reg_overlap_mentioned_p (operands[0], operands[2])
18711    && ix86_match_ccmode (peep2_next_insn (3),
18712                          (GET_CODE (operands[3]) == PLUS
18713                           || GET_CODE (operands[3]) == MINUS)
18714                          ? CCGOCmode : CCNOmode)"
18715   [(parallel [(set (match_dup 5) (match_dup 7))
18716               (set (match_dup 1) (match_dup 6))])]
18718   operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
18719   operands[6]
18720     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18721                       copy_rtx (operands[1]),
18722                       gen_lowpart (<MODE>mode, operands[2]));
18723   operands[7]
18724     = gen_rtx_COMPARE (GET_MODE (operands[5]),
18725                        copy_rtx (operands[6]),
18726                        const0_rtx);
18729 ;; peephole2 comes before regcprop, so deal also with a case that
18730 ;; would be cleaned up by regcprop.
18731 (define_peephole2
18732   [(set (match_operand:SWI 0 "register_operand")
18733         (match_operand:SWI 1 "memory_operand"))
18734    (parallel [(set (match_dup 0)
18735                    (match_operator:SWI 3 "plusminuslogic_operator"
18736                      [(match_dup 0)
18737                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18738               (clobber (reg:CC FLAGS_REG))])
18739    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18740    (set (match_dup 1) (match_dup 4))
18741    (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
18742   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18743    && peep2_reg_dead_p (3, operands[0])
18744    && peep2_reg_dead_p (5, operands[4])
18745    && !reg_overlap_mentioned_p (operands[0], operands[1])
18746    && !reg_overlap_mentioned_p (operands[0], operands[2])
18747    && !reg_overlap_mentioned_p (operands[4], operands[1])
18748    && (<MODE>mode != QImode
18749        || immediate_operand (operands[2], QImode)
18750        || any_QIreg_operand (operands[2], QImode))
18751    && ix86_match_ccmode (peep2_next_insn (4),
18752                          (GET_CODE (operands[3]) == PLUS
18753                           || GET_CODE (operands[3]) == MINUS)
18754                          ? CCGOCmode : CCNOmode)"
18755   [(parallel [(set (match_dup 5) (match_dup 7))
18756               (set (match_dup 1) (match_dup 6))])]
18758   operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
18759   operands[6]
18760     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18761                       copy_rtx (operands[1]),
18762                       operands[2]);
18763   operands[7]
18764     = gen_rtx_COMPARE (GET_MODE (operands[5]),
18765                        copy_rtx (operands[6]),
18766                        const0_rtx);
18769 (define_peephole2
18770   [(set (match_operand:SWI12 0 "register_operand")
18771         (match_operand:SWI12 1 "memory_operand"))
18772    (parallel [(set (match_operand:SI 4 "register_operand")
18773                    (match_operator:SI 3 "plusminuslogic_operator"
18774                      [(match_dup 4)
18775                       (match_operand:SI 2 "nonmemory_operand")]))
18776               (clobber (reg:CC FLAGS_REG))])
18777    (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
18778    (set (match_dup 1) (match_dup 5))
18779    (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18780   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18781    && REGNO (operands[0]) == REGNO (operands[4])
18782    && peep2_reg_dead_p (3, operands[0])
18783    && peep2_reg_dead_p (5, operands[5])
18784    && (<MODE>mode != QImode
18785        || immediate_operand (operands[2], SImode)
18786        || any_QIreg_operand (operands[2], SImode))
18787    && !reg_overlap_mentioned_p (operands[0], operands[1])
18788    && !reg_overlap_mentioned_p (operands[0], operands[2])
18789    && !reg_overlap_mentioned_p (operands[5], operands[1])
18790    && ix86_match_ccmode (peep2_next_insn (4),
18791                          (GET_CODE (operands[3]) == PLUS
18792                           || GET_CODE (operands[3]) == MINUS)
18793                          ? CCGOCmode : CCNOmode)"
18794   [(parallel [(set (match_dup 6) (match_dup 8))
18795               (set (match_dup 1) (match_dup 7))])]
18797   operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
18798   operands[7]
18799     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18800                       copy_rtx (operands[1]),
18801                       gen_lowpart (<MODE>mode, operands[2]));
18802   operands[8]
18803     = gen_rtx_COMPARE (GET_MODE (operands[6]),
18804                        copy_rtx (operands[7]),
18805                        const0_rtx);
18808 ;; Likewise for cmpelim optimized pattern.
18809 (define_peephole2
18810   [(set (match_operand:SWI 0 "register_operand")
18811         (match_operand:SWI 1 "memory_operand"))
18812    (parallel [(set (reg FLAGS_REG)
18813                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
18814                               [(match_dup 0)
18815                                (match_operand:SWI 2 "<nonmemory_operand>")])
18816                             (const_int 0)))
18817               (set (match_dup 0) (match_dup 3))])
18818    (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18819    (set (match_dup 1) (match_dup 4))]
18820   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18821    && peep2_reg_dead_p (3, operands[0])
18822    && peep2_reg_dead_p (4, operands[4])
18823    && !reg_overlap_mentioned_p (operands[0], operands[1])
18824    && !reg_overlap_mentioned_p (operands[0], operands[2])
18825    && !reg_overlap_mentioned_p (operands[4], operands[1])
18826    && ix86_match_ccmode (peep2_next_insn (1),
18827                          (GET_CODE (operands[3]) == PLUS
18828                           || GET_CODE (operands[3]) == MINUS)
18829                          ? CCGOCmode : CCNOmode)"
18830   [(parallel [(set (match_dup 5) (match_dup 7))
18831               (set (match_dup 1) (match_dup 6))])]
18833   operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18834   operands[6]
18835     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18836                       copy_rtx (operands[1]), operands[2]);
18837   operands[7]
18838     = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
18839                        const0_rtx);
18842 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
18843 ;; into x = z; x ^= y; x != z
18844 (define_peephole2
18845   [(set (match_operand:SWI 0 "register_operand")
18846         (match_operand:SWI 1 "memory_operand"))
18847    (set (match_operand:SWI 3 "register_operand") (match_dup 0))
18848    (parallel [(set (match_operand:SWI 4 "register_operand")
18849                    (xor:SWI (match_dup 4)
18850                             (match_operand:SWI 2 "<nonmemory_operand>")))
18851               (clobber (reg:CC FLAGS_REG))])
18852    (set (match_dup 1) (match_dup 4))
18853    (set (reg:CCZ FLAGS_REG)
18854         (compare:CCZ (match_operand:SWI 5 "register_operand")
18855                      (match_operand:SWI 6 "<nonmemory_operand>")))]
18856   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18857    && (REGNO (operands[4]) == REGNO (operands[0])
18858        || REGNO (operands[4]) == REGNO (operands[3]))
18859    && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18860                              ? 3 : 0], operands[5])
18861        ? rtx_equal_p (operands[2], operands[6])
18862        : rtx_equal_p (operands[2], operands[5])
18863          && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18864                                   ? 3 : 0], operands[6]))
18865    && peep2_reg_dead_p (4, operands[4])
18866    && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
18867                                     ? 3 : 0])
18868    && !reg_overlap_mentioned_p (operands[0], operands[1])
18869    && !reg_overlap_mentioned_p (operands[0], operands[2])
18870    && !reg_overlap_mentioned_p (operands[3], operands[0])
18871    && !reg_overlap_mentioned_p (operands[3], operands[1])
18872    && !reg_overlap_mentioned_p (operands[3], operands[2])
18873    && (<MODE>mode != QImode
18874        || immediate_operand (operands[2], QImode)
18875        || any_QIreg_operand (operands[2], QImode))"
18876   [(parallel [(set (match_dup 7) (match_dup 9))
18877               (set (match_dup 1) (match_dup 8))])]
18879   operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
18880   operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18881                              operands[2]);
18882   operands[9]
18883     = gen_rtx_COMPARE (GET_MODE (operands[7]),
18884                        copy_rtx (operands[8]),
18885                        const0_rtx);
18888 (define_peephole2
18889   [(set (match_operand:SWI12 0 "register_operand")
18890         (match_operand:SWI12 1 "memory_operand"))
18891    (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
18892    (parallel [(set (match_operand:SI 4 "register_operand")
18893                    (xor:SI (match_dup 4)
18894                            (match_operand:SI 2 "<nonmemory_operand>")))
18895               (clobber (reg:CC FLAGS_REG))])
18896    (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
18897    (set (reg:CCZ FLAGS_REG)
18898         (compare:CCZ (match_operand:SWI12 6 "register_operand")
18899                      (match_operand:SWI12 7 "<nonmemory_operand>")))]
18900   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18901    && (REGNO (operands[5]) == REGNO (operands[0])
18902        || REGNO (operands[5]) == REGNO (operands[3]))
18903    && REGNO (operands[5]) == REGNO (operands[4])
18904    && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18905                              ? 3 : 0], operands[6])
18906        ? (REG_P (operands[2])
18907           ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
18908           : rtx_equal_p (operands[2], operands[7]))
18909        : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18910                                 ? 3 : 0], operands[7])
18911           && REG_P (operands[2])
18912           && REGNO (operands[2]) == REGNO (operands[6])))
18913    && peep2_reg_dead_p (4, operands[5])
18914    && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
18915                                     ? 3 : 0])
18916    && !reg_overlap_mentioned_p (operands[0], operands[1])
18917    && !reg_overlap_mentioned_p (operands[0], operands[2])
18918    && !reg_overlap_mentioned_p (operands[3], operands[0])
18919    && !reg_overlap_mentioned_p (operands[3], operands[1])
18920    && !reg_overlap_mentioned_p (operands[3], operands[2])
18921    && (<MODE>mode != QImode
18922        || immediate_operand (operands[2], SImode)
18923        || any_QIreg_operand (operands[2], SImode))"
18924   [(parallel [(set (match_dup 8) (match_dup 10))
18925               (set (match_dup 1) (match_dup 9))])]
18927   operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
18928   operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18929                              gen_lowpart (<MODE>mode, operands[2]));
18930   operands[10]
18931     = gen_rtx_COMPARE (GET_MODE (operands[8]),
18932                        copy_rtx (operands[9]),
18933                        const0_rtx);
18936 ;; Attempt to optimize away memory stores of values the memory already
18937 ;; has.  See PR79593.
18938 (define_peephole2
18939   [(set (match_operand 0 "register_operand")
18940         (match_operand 1 "memory_operand"))
18941    (set (match_operand 2 "memory_operand") (match_dup 0))]
18942   "!MEM_VOLATILE_P (operands[1])
18943    && !MEM_VOLATILE_P (operands[2])
18944    && rtx_equal_p (operands[1], operands[2])
18945    && !reg_overlap_mentioned_p (operands[0], operands[2])"
18946   [(set (match_dup 0) (match_dup 1))])
18948 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18949 (define_peephole2
18950   [(set (match_operand 0 "general_reg_operand")
18951         (match_operand 1 "const0_operand"))]
18952   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18953    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18954    && peep2_regno_dead_p (0, FLAGS_REG)"
18955   [(parallel [(set (match_dup 0) (const_int 0))
18956               (clobber (reg:CC FLAGS_REG))])]
18957   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18959 (define_peephole2
18960   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18961         (const_int 0))]
18962   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18963    && peep2_regno_dead_p (0, FLAGS_REG)"
18964   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18965               (clobber (reg:CC FLAGS_REG))])])
18967 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18968 (define_peephole2
18969   [(set (match_operand:SWI248 0 "general_reg_operand")
18970         (const_int -1))]
18971   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18972    && peep2_regno_dead_p (0, FLAGS_REG)"
18973   [(parallel [(set (match_dup 0) (const_int -1))
18974               (clobber (reg:CC FLAGS_REG))])]
18976   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18977     operands[0] = gen_lowpart (SImode, operands[0]);
18980 ;; Attempt to convert simple lea to add/shift.
18981 ;; These can be created by move expanders.
18982 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18983 ;; relevant lea instructions were already split.
18985 (define_peephole2
18986   [(set (match_operand:SWI48 0 "register_operand")
18987         (plus:SWI48 (match_dup 0)
18988                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18989   "!TARGET_OPT_AGU
18990    && peep2_regno_dead_p (0, FLAGS_REG)"
18991   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18992               (clobber (reg:CC FLAGS_REG))])])
18994 (define_peephole2
18995   [(set (match_operand:SWI48 0 "register_operand")
18996         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18997                     (match_dup 0)))]
18998   "!TARGET_OPT_AGU
18999    && peep2_regno_dead_p (0, FLAGS_REG)"
19000   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19001               (clobber (reg:CC FLAGS_REG))])])
19003 (define_peephole2
19004   [(set (match_operand:DI 0 "register_operand")
19005         (zero_extend:DI
19006           (plus:SI (match_operand:SI 1 "register_operand")
19007                    (match_operand:SI 2 "nonmemory_operand"))))]
19008   "TARGET_64BIT && !TARGET_OPT_AGU
19009    && REGNO (operands[0]) == REGNO (operands[1])
19010    && peep2_regno_dead_p (0, FLAGS_REG)"
19011   [(parallel [(set (match_dup 0)
19012                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19013               (clobber (reg:CC FLAGS_REG))])])
19015 (define_peephole2
19016   [(set (match_operand:DI 0 "register_operand")
19017         (zero_extend:DI
19018           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19019                    (match_operand:SI 2 "register_operand"))))]
19020   "TARGET_64BIT && !TARGET_OPT_AGU
19021    && REGNO (operands[0]) == REGNO (operands[2])
19022    && peep2_regno_dead_p (0, FLAGS_REG)"
19023   [(parallel [(set (match_dup 0)
19024                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19025               (clobber (reg:CC FLAGS_REG))])])
19027 (define_peephole2
19028   [(set (match_operand:SWI48 0 "register_operand")
19029         (mult:SWI48 (match_dup 0)
19030                     (match_operand:SWI48 1 "const_int_operand")))]
19031   "pow2p_hwi (INTVAL (operands[1]))
19032    && peep2_regno_dead_p (0, FLAGS_REG)"
19033   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19034               (clobber (reg:CC FLAGS_REG))])]
19035   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19037 (define_peephole2
19038   [(set (match_operand:DI 0 "register_operand")
19039         (zero_extend:DI
19040           (mult:SI (match_operand:SI 1 "register_operand")
19041                    (match_operand:SI 2 "const_int_operand"))))]
19042   "TARGET_64BIT
19043    && pow2p_hwi (INTVAL (operands[2]))
19044    && REGNO (operands[0]) == REGNO (operands[1])
19045    && peep2_regno_dead_p (0, FLAGS_REG)"
19046   [(parallel [(set (match_dup 0)
19047                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19048               (clobber (reg:CC FLAGS_REG))])]
19049   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19051 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19052 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19053 ;; On many CPUs it is also faster, since special hardware to avoid esp
19054 ;; dependencies is present.
19056 ;; While some of these conversions may be done using splitters, we use
19057 ;; peepholes in order to allow combine_stack_adjustments pass to see
19058 ;; nonobfuscated RTL.
19060 ;; Convert prologue esp subtractions to push.
19061 ;; We need register to push.  In order to keep verify_flow_info happy we have
19062 ;; two choices
19063 ;; - use scratch and clobber it in order to avoid dependencies
19064 ;; - use already live register
19065 ;; We can't use the second way right now, since there is no reliable way how to
19066 ;; verify that given register is live.  First choice will also most likely in
19067 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19068 ;; call clobbered registers are dead.  We may want to use base pointer as an
19069 ;; alternative when no register is available later.
19071 (define_peephole2
19072   [(match_scratch:W 1 "r")
19073    (parallel [(set (reg:P SP_REG)
19074                    (plus:P (reg:P SP_REG)
19075                            (match_operand:P 0 "const_int_operand")))
19076               (clobber (reg:CC FLAGS_REG))
19077               (clobber (mem:BLK (scratch)))])]
19078   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19079    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19080    && ix86_red_zone_size == 0"
19081   [(clobber (match_dup 1))
19082    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19083               (clobber (mem:BLK (scratch)))])])
19085 (define_peephole2
19086   [(match_scratch:W 1 "r")
19087    (parallel [(set (reg:P SP_REG)
19088                    (plus:P (reg:P SP_REG)
19089                            (match_operand:P 0 "const_int_operand")))
19090               (clobber (reg:CC FLAGS_REG))
19091               (clobber (mem:BLK (scratch)))])]
19092   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19093    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19094    && ix86_red_zone_size == 0"
19095   [(clobber (match_dup 1))
19096    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19097    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19098               (clobber (mem:BLK (scratch)))])])
19100 ;; Convert esp subtractions to push.
19101 (define_peephole2
19102   [(match_scratch:W 1 "r")
19103    (parallel [(set (reg:P SP_REG)
19104                    (plus:P (reg:P SP_REG)
19105                            (match_operand:P 0 "const_int_operand")))
19106               (clobber (reg:CC FLAGS_REG))])]
19107   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19108    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19109    && ix86_red_zone_size == 0"
19110   [(clobber (match_dup 1))
19111    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19113 (define_peephole2
19114   [(match_scratch:W 1 "r")
19115    (parallel [(set (reg:P SP_REG)
19116                    (plus:P (reg:P SP_REG)
19117                            (match_operand:P 0 "const_int_operand")))
19118               (clobber (reg:CC FLAGS_REG))])]
19119   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19120    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19121    && ix86_red_zone_size == 0"
19122   [(clobber (match_dup 1))
19123    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19124    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19126 ;; Convert epilogue deallocator to pop.
19127 (define_peephole2
19128   [(match_scratch:W 1 "r")
19129    (parallel [(set (reg:P SP_REG)
19130                    (plus:P (reg:P SP_REG)
19131                            (match_operand:P 0 "const_int_operand")))
19132               (clobber (reg:CC FLAGS_REG))
19133               (clobber (mem:BLK (scratch)))])]
19134   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19135    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19136   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19137               (clobber (mem:BLK (scratch)))])])
19139 ;; Two pops case is tricky, since pop causes dependency
19140 ;; on destination register.  We use two registers if available.
19141 (define_peephole2
19142   [(match_scratch:W 1 "r")
19143    (match_scratch:W 2 "r")
19144    (parallel [(set (reg:P SP_REG)
19145                    (plus:P (reg:P SP_REG)
19146                            (match_operand:P 0 "const_int_operand")))
19147               (clobber (reg:CC FLAGS_REG))
19148               (clobber (mem:BLK (scratch)))])]
19149   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19150    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19151   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19152               (clobber (mem:BLK (scratch)))])
19153    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19155 (define_peephole2
19156   [(match_scratch:W 1 "r")
19157    (parallel [(set (reg:P SP_REG)
19158                    (plus:P (reg:P SP_REG)
19159                            (match_operand:P 0 "const_int_operand")))
19160               (clobber (reg:CC FLAGS_REG))
19161               (clobber (mem:BLK (scratch)))])]
19162   "optimize_insn_for_size_p ()
19163    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19164   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19165               (clobber (mem:BLK (scratch)))])
19166    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19168 ;; Convert esp additions to pop.
19169 (define_peephole2
19170   [(match_scratch:W 1 "r")
19171    (parallel [(set (reg:P SP_REG)
19172                    (plus:P (reg:P SP_REG)
19173                            (match_operand:P 0 "const_int_operand")))
19174               (clobber (reg:CC FLAGS_REG))])]
19175   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19176   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19178 ;; Two pops case is tricky, since pop causes dependency
19179 ;; on destination register.  We use two registers if available.
19180 (define_peephole2
19181   [(match_scratch:W 1 "r")
19182    (match_scratch:W 2 "r")
19183    (parallel [(set (reg:P SP_REG)
19184                    (plus:P (reg:P SP_REG)
19185                            (match_operand:P 0 "const_int_operand")))
19186               (clobber (reg:CC FLAGS_REG))])]
19187   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19188   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19189    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19191 (define_peephole2
19192   [(match_scratch:W 1 "r")
19193    (parallel [(set (reg:P SP_REG)
19194                    (plus:P (reg:P SP_REG)
19195                            (match_operand:P 0 "const_int_operand")))
19196               (clobber (reg:CC FLAGS_REG))])]
19197   "optimize_insn_for_size_p ()
19198    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19199   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19200    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19202 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19203 ;; required and register dies.  Similarly for 128 to -128.
19204 (define_peephole2
19205   [(set (match_operand 0 "flags_reg_operand")
19206         (match_operator 1 "compare_operator"
19207           [(match_operand 2 "register_operand")
19208            (match_operand 3 "const_int_operand")]))]
19209   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19210      && incdec_operand (operands[3], GET_MODE (operands[3])))
19211     || (!TARGET_FUSE_CMP_AND_BRANCH
19212         && INTVAL (operands[3]) == 128))
19213    && ix86_match_ccmode (insn, CCGCmode)
19214    && peep2_reg_dead_p (1, operands[2])"
19215   [(parallel [(set (match_dup 0)
19216                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19217               (clobber (match_dup 2))])])
19219 ;; Convert imul by three, five and nine into lea
19220 (define_peephole2
19221   [(parallel
19222     [(set (match_operand:SWI48 0 "register_operand")
19223           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19224                       (match_operand:SWI48 2 "const359_operand")))
19225      (clobber (reg:CC FLAGS_REG))])]
19226   "!TARGET_PARTIAL_REG_STALL
19227    || <MODE>mode == SImode
19228    || optimize_function_for_size_p (cfun)"
19229   [(set (match_dup 0)
19230         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19231                     (match_dup 1)))]
19232   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19234 (define_peephole2
19235   [(parallel
19236     [(set (match_operand:SWI48 0 "register_operand")
19237           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19238                       (match_operand:SWI48 2 "const359_operand")))
19239      (clobber (reg:CC FLAGS_REG))])]
19240   "optimize_insn_for_speed_p ()
19241    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19242   [(set (match_dup 0) (match_dup 1))
19243    (set (match_dup 0)
19244         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19245                     (match_dup 0)))]
19246   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19248 ;; imul $32bit_imm, mem, reg is vector decoded, while
19249 ;; imul $32bit_imm, reg, reg is direct decoded.
19250 (define_peephole2
19251   [(match_scratch:SWI48 3 "r")
19252    (parallel [(set (match_operand:SWI48 0 "register_operand")
19253                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19254                                (match_operand:SWI48 2 "immediate_operand")))
19255               (clobber (reg:CC FLAGS_REG))])]
19256   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19257    && !satisfies_constraint_K (operands[2])"
19258   [(set (match_dup 3) (match_dup 1))
19259    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19260               (clobber (reg:CC FLAGS_REG))])])
19262 (define_peephole2
19263   [(match_scratch:SI 3 "r")
19264    (parallel [(set (match_operand:DI 0 "register_operand")
19265                    (zero_extend:DI
19266                      (mult:SI (match_operand:SI 1 "memory_operand")
19267                               (match_operand:SI 2 "immediate_operand"))))
19268               (clobber (reg:CC FLAGS_REG))])]
19269   "TARGET_64BIT
19270    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19271    && !satisfies_constraint_K (operands[2])"
19272   [(set (match_dup 3) (match_dup 1))
19273    (parallel [(set (match_dup 0)
19274                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19275               (clobber (reg:CC FLAGS_REG))])])
19277 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19278 ;; Convert it into imul reg, reg
19279 ;; It would be better to force assembler to encode instruction using long
19280 ;; immediate, but there is apparently no way to do so.
19281 (define_peephole2
19282   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19283                    (mult:SWI248
19284                     (match_operand:SWI248 1 "nonimmediate_operand")
19285                     (match_operand:SWI248 2 "const_int_operand")))
19286               (clobber (reg:CC FLAGS_REG))])
19287    (match_scratch:SWI248 3 "r")]
19288   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19289    && satisfies_constraint_K (operands[2])"
19290   [(set (match_dup 3) (match_dup 2))
19291    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19292               (clobber (reg:CC FLAGS_REG))])]
19294   if (!rtx_equal_p (operands[0], operands[1]))
19295     emit_move_insn (operands[0], operands[1]);
19298 ;; After splitting up read-modify operations, array accesses with memory
19299 ;; operands might end up in form:
19300 ;;  sall    $2, %eax
19301 ;;  movl    4(%esp), %edx
19302 ;;  addl    %edx, %eax
19303 ;; instead of pre-splitting:
19304 ;;  sall    $2, %eax
19305 ;;  addl    4(%esp), %eax
19306 ;; Turn it into:
19307 ;;  movl    4(%esp), %edx
19308 ;;  leal    (%edx,%eax,4), %eax
19310 (define_peephole2
19311   [(match_scratch:W 5 "r")
19312    (parallel [(set (match_operand 0 "register_operand")
19313                    (ashift (match_operand 1 "register_operand")
19314                            (match_operand 2 "const_int_operand")))
19315                (clobber (reg:CC FLAGS_REG))])
19316    (parallel [(set (match_operand 3 "register_operand")
19317                    (plus (match_dup 0)
19318                          (match_operand 4 "x86_64_general_operand")))
19319                    (clobber (reg:CC FLAGS_REG))])]
19320   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19321    /* Validate MODE for lea.  */
19322    && ((!TARGET_PARTIAL_REG_STALL
19323         && (GET_MODE (operands[0]) == QImode
19324             || GET_MODE (operands[0]) == HImode))
19325        || GET_MODE (operands[0]) == SImode
19326        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19327    && (rtx_equal_p (operands[0], operands[3])
19328        || peep2_reg_dead_p (2, operands[0]))
19329    /* We reorder load and the shift.  */
19330    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19331   [(set (match_dup 5) (match_dup 4))
19332    (set (match_dup 0) (match_dup 1))]
19334   machine_mode op1mode = GET_MODE (operands[1]);
19335   machine_mode mode = op1mode == DImode ? DImode : SImode;
19336   int scale = 1 << INTVAL (operands[2]);
19337   rtx index = gen_lowpart (word_mode, operands[1]);
19338   rtx base = gen_lowpart (word_mode, operands[5]);
19339   rtx dest = gen_lowpart (mode, operands[3]);
19341   operands[1] = gen_rtx_PLUS (word_mode, base,
19342                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19343   if (mode != word_mode)
19344     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19346   operands[5] = base;
19347   if (op1mode != word_mode)
19348     operands[5] = gen_lowpart (op1mode, operands[5]);
19350   operands[0] = dest;
19353 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19354 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19355 ;; caught for use by garbage collectors and the like.  Using an insn that
19356 ;; maps to SIGILL makes it more likely the program will rightfully die.
19357 ;; Keeping with tradition, "6" is in honor of #UD.
19358 (define_insn "trap"
19359   [(trap_if (const_int 1) (const_int 6))]
19360   ""
19362 #ifdef HAVE_AS_IX86_UD2
19363   return "ud2";
19364 #else
19365   return ASM_SHORT "0x0b0f";
19366 #endif
19368   [(set_attr "length" "2")])
19370 (define_insn "ud2"
19371   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19372   ""
19374 #ifdef HAVE_AS_IX86_UD2
19375   return "ud2";
19376 #else
19377   return ASM_SHORT "0x0b0f";
19378 #endif
19380   [(set_attr "length" "2")])
19382 (define_expand "prefetch"
19383   [(prefetch (match_operand 0 "address_operand")
19384              (match_operand:SI 1 "const_int_operand")
19385              (match_operand:SI 2 "const_int_operand"))]
19386   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19388   bool write = INTVAL (operands[1]) != 0;
19389   int locality = INTVAL (operands[2]);
19391   gcc_assert (IN_RANGE (locality, 0, 3));
19393   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19394      supported by SSE counterpart (non-SSE2 athlon machines) or the
19395      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19396      prefetch as it allows specifying of locality.  */
19398   if (write)
19399     {
19400       if (TARGET_PREFETCHWT1)
19401         operands[2] = GEN_INT (MAX (locality, 2)); 
19402       else if (TARGET_PRFCHW)
19403         operands[2] = GEN_INT (3);
19404       else if (TARGET_3DNOW && !TARGET_SSE2)
19405         operands[2] = GEN_INT (3);
19406       else if (TARGET_PREFETCH_SSE)
19407         operands[1] = const0_rtx;
19408       else
19409         {
19410           gcc_assert (TARGET_3DNOW);
19411           operands[2] = GEN_INT (3);
19412         }
19413     }
19414   else
19415     {
19416       if (TARGET_PREFETCH_SSE)
19417         ;
19418       else
19419         {
19420           gcc_assert (TARGET_3DNOW);
19421           operands[2] = GEN_INT (3);
19422         }
19423     }
19426 (define_insn "*prefetch_sse"
19427   [(prefetch (match_operand 0 "address_operand" "p")
19428              (const_int 0)
19429              (match_operand:SI 1 "const_int_operand"))]
19430   "TARGET_PREFETCH_SSE"
19432   static const char * const patterns[4] = {
19433    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19434   };
19436   int locality = INTVAL (operands[1]);
19437   gcc_assert (IN_RANGE (locality, 0, 3));
19439   return patterns[locality];
19441   [(set_attr "type" "sse")
19442    (set_attr "atom_sse_attr" "prefetch")
19443    (set (attr "length_address")
19444         (symbol_ref "memory_address_length (operands[0], false)"))
19445    (set_attr "memory" "none")])
19447 (define_insn "*prefetch_3dnow"
19448   [(prefetch (match_operand 0 "address_operand" "p")
19449              (match_operand:SI 1 "const_int_operand" "n")
19450              (const_int 3))]
19451   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19453   if (INTVAL (operands[1]) == 0)
19454     return "prefetch\t%a0";
19455   else
19456     return "prefetchw\t%a0";
19458   [(set_attr "type" "mmx")
19459    (set (attr "length_address")
19460         (symbol_ref "memory_address_length (operands[0], false)"))
19461    (set_attr "memory" "none")])
19463 (define_insn "*prefetch_prefetchwt1"
19464   [(prefetch (match_operand 0 "address_operand" "p")
19465              (const_int 1)
19466              (const_int 2))]
19467   "TARGET_PREFETCHWT1"
19468   "prefetchwt1\t%a0";
19469   [(set_attr "type" "sse")
19470    (set (attr "length_address")
19471         (symbol_ref "memory_address_length (operands[0], false)"))
19472    (set_attr "memory" "none")])
19474 (define_expand "stack_protect_set"
19475   [(match_operand 0 "memory_operand")
19476    (match_operand 1 "memory_operand")]
19477   ""
19479   emit_insn (gen_stack_protect_set_1
19480              (ptr_mode, operands[0], operands[1]));
19481   DONE;
19484 (define_insn "@stack_protect_set_1_<mode>"
19485   [(set (match_operand:PTR 0 "memory_operand" "=m")
19486         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19487                     UNSPEC_SP_SET))
19488    (set (match_scratch:PTR 2 "=&r") (const_int 0))
19489    (clobber (reg:CC FLAGS_REG))]
19490   ""
19491   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19492   [(set_attr "type" "multi")])
19494 (define_expand "stack_protect_test"
19495   [(match_operand 0 "memory_operand")
19496    (match_operand 1 "memory_operand")
19497    (match_operand 2)]
19498   ""
19500   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19502   emit_insn (gen_stack_protect_test_1
19503              (ptr_mode, flags, operands[0], operands[1]));
19505   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19506                                   flags, const0_rtx, operands[2]));
19507   DONE;
19510 (define_insn "@stack_protect_test_1_<mode>"
19511   [(set (match_operand:CCZ 0 "flags_reg_operand")
19512         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19513                      (match_operand:PTR 2 "memory_operand" "m")]
19514                     UNSPEC_SP_TEST))
19515    (clobber (match_scratch:PTR 3 "=&r"))]
19516   ""
19517   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;sub{<imodesuffix>}\t{%2, %3|%3, %2}"
19518   [(set_attr "type" "multi")])
19520 (define_insn "sse4_2_crc32<mode>"
19521   [(set (match_operand:SI 0 "register_operand" "=r")
19522         (unspec:SI
19523           [(match_operand:SI 1 "register_operand" "0")
19524            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19525           UNSPEC_CRC32))]
19526   "TARGET_SSE4_2 || TARGET_CRC32"
19527   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19528   [(set_attr "type" "sselog1")
19529    (set_attr "prefix_rep" "1")
19530    (set_attr "prefix_extra" "1")
19531    (set (attr "prefix_data16")
19532      (if_then_else (match_operand:HI 2)
19533        (const_string "1")
19534        (const_string "*")))
19535    (set (attr "prefix_rex")
19536      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19537        (const_string "1")
19538        (const_string "*")))
19539    (set_attr "mode" "SI")])
19541 (define_insn "sse4_2_crc32di"
19542   [(set (match_operand:DI 0 "register_operand" "=r")
19543         (unspec:DI
19544           [(match_operand:DI 1 "register_operand" "0")
19545            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19546           UNSPEC_CRC32))]
19547   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19548   "crc32{q}\t{%2, %0|%0, %2}"
19549   [(set_attr "type" "sselog1")
19550    (set_attr "prefix_rep" "1")
19551    (set_attr "prefix_extra" "1")
19552    (set_attr "mode" "DI")])
19554 (define_insn "rdpmc"
19555   [(set (match_operand:DI 0 "register_operand" "=A")
19556         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19557                             UNSPECV_RDPMC))]
19558   "!TARGET_64BIT"
19559   "rdpmc"
19560   [(set_attr "type" "other")
19561    (set_attr "length" "2")])
19563 (define_insn "rdpmc_rex64"
19564   [(set (match_operand:DI 0 "register_operand" "=a")
19565         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19566                             UNSPECV_RDPMC))
19567    (set (match_operand:DI 1 "register_operand" "=d")
19568         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19569   "TARGET_64BIT"
19570   "rdpmc"
19571   [(set_attr "type" "other")
19572    (set_attr "length" "2")])
19574 (define_insn "rdtsc"
19575   [(set (match_operand:DI 0 "register_operand" "=A")
19576         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19577   "!TARGET_64BIT"
19578   "rdtsc"
19579   [(set_attr "type" "other")
19580    (set_attr "length" "2")])
19582 (define_insn "rdtsc_rex64"
19583   [(set (match_operand:DI 0 "register_operand" "=a")
19584         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19585    (set (match_operand:DI 1 "register_operand" "=d")
19586         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19587   "TARGET_64BIT"
19588   "rdtsc"
19589   [(set_attr "type" "other")
19590    (set_attr "length" "2")])
19592 (define_insn "rdtscp"
19593   [(set (match_operand:DI 0 "register_operand" "=A")
19594         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19595    (set (match_operand:SI 1 "register_operand" "=c")
19596         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19597   "!TARGET_64BIT"
19598   "rdtscp"
19599   [(set_attr "type" "other")
19600    (set_attr "length" "3")])
19602 (define_insn "rdtscp_rex64"
19603   [(set (match_operand:DI 0 "register_operand" "=a")
19604         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19605    (set (match_operand:DI 1 "register_operand" "=d")
19606         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19607    (set (match_operand:SI 2 "register_operand" "=c")
19608         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19609   "TARGET_64BIT"
19610   "rdtscp"
19611   [(set_attr "type" "other")
19612    (set_attr "length" "3")])
19614 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19616 ;; FXSR, XSAVE and XSAVEOPT instructions
19618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19620 (define_insn "fxsave"
19621   [(set (match_operand:BLK 0 "memory_operand" "=m")
19622         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19623   "TARGET_FXSR"
19624   "fxsave\t%0"
19625   [(set_attr "type" "other")
19626    (set_attr "memory" "store")
19627    (set (attr "length")
19628         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19630 (define_insn "fxsave64"
19631   [(set (match_operand:BLK 0 "memory_operand" "=m")
19632         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19633   "TARGET_64BIT && TARGET_FXSR"
19634   "fxsave64\t%0"
19635   [(set_attr "type" "other")
19636    (set_attr "memory" "store")
19637    (set (attr "length")
19638         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19640 (define_insn "fxrstor"
19641   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19642                     UNSPECV_FXRSTOR)]
19643   "TARGET_FXSR"
19644   "fxrstor\t%0"
19645   [(set_attr "type" "other")
19646    (set_attr "memory" "load")
19647    (set (attr "length")
19648         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19650 (define_insn "fxrstor64"
19651   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19652                     UNSPECV_FXRSTOR64)]
19653   "TARGET_64BIT && TARGET_FXSR"
19654   "fxrstor64\t%0"
19655   [(set_attr "type" "other")
19656    (set_attr "memory" "load")
19657    (set (attr "length")
19658         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19660 (define_int_iterator ANY_XSAVE
19661         [UNSPECV_XSAVE
19662          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19663          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19664          (UNSPECV_XSAVES "TARGET_XSAVES")])
19666 (define_int_iterator ANY_XSAVE64
19667         [UNSPECV_XSAVE64
19668          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19669          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19670          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19672 (define_int_attr xsave
19673         [(UNSPECV_XSAVE "xsave")
19674          (UNSPECV_XSAVE64 "xsave64")
19675          (UNSPECV_XSAVEOPT "xsaveopt")
19676          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19677          (UNSPECV_XSAVEC "xsavec")
19678          (UNSPECV_XSAVEC64 "xsavec64")
19679          (UNSPECV_XSAVES "xsaves")
19680          (UNSPECV_XSAVES64 "xsaves64")])
19682 (define_int_iterator ANY_XRSTOR
19683         [UNSPECV_XRSTOR
19684          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19686 (define_int_iterator ANY_XRSTOR64
19687         [UNSPECV_XRSTOR64
19688          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19690 (define_int_attr xrstor
19691         [(UNSPECV_XRSTOR "xrstor")
19692          (UNSPECV_XRSTOR64 "xrstor")
19693          (UNSPECV_XRSTORS "xrstors")
19694          (UNSPECV_XRSTORS64 "xrstors")])
19696 (define_insn "<xsave>"
19697   [(set (match_operand:BLK 0 "memory_operand" "=m")
19698         (unspec_volatile:BLK
19699          [(match_operand:DI 1 "register_operand" "A")]
19700          ANY_XSAVE))]
19701   "!TARGET_64BIT && TARGET_XSAVE"
19702   "<xsave>\t%0"
19703   [(set_attr "type" "other")
19704    (set_attr "memory" "store")
19705    (set (attr "length")
19706         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19708 (define_insn "<xsave>_rex64"
19709   [(set (match_operand:BLK 0 "memory_operand" "=m")
19710         (unspec_volatile:BLK
19711          [(match_operand:SI 1 "register_operand" "a")
19712           (match_operand:SI 2 "register_operand" "d")]
19713          ANY_XSAVE))]
19714   "TARGET_64BIT && TARGET_XSAVE"
19715   "<xsave>\t%0"
19716   [(set_attr "type" "other")
19717    (set_attr "memory" "store")
19718    (set (attr "length")
19719         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19721 (define_insn "<xsave>"
19722   [(set (match_operand:BLK 0 "memory_operand" "=m")
19723         (unspec_volatile:BLK
19724          [(match_operand:SI 1 "register_operand" "a")
19725           (match_operand:SI 2 "register_operand" "d")]
19726          ANY_XSAVE64))]
19727   "TARGET_64BIT && TARGET_XSAVE"
19728   "<xsave>\t%0"
19729   [(set_attr "type" "other")
19730    (set_attr "memory" "store")
19731    (set (attr "length")
19732         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19734 (define_insn "<xrstor>"
19735    [(unspec_volatile:BLK
19736      [(match_operand:BLK 0 "memory_operand" "m")
19737       (match_operand:DI 1 "register_operand" "A")]
19738      ANY_XRSTOR)]
19739   "!TARGET_64BIT && TARGET_XSAVE"
19740   "<xrstor>\t%0"
19741   [(set_attr "type" "other")
19742    (set_attr "memory" "load")
19743    (set (attr "length")
19744         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19746 (define_insn "<xrstor>_rex64"
19747    [(unspec_volatile:BLK
19748      [(match_operand:BLK 0 "memory_operand" "m")
19749       (match_operand:SI 1 "register_operand" "a")
19750       (match_operand:SI 2 "register_operand" "d")]
19751      ANY_XRSTOR)]
19752   "TARGET_64BIT && TARGET_XSAVE"
19753   "<xrstor>\t%0"
19754   [(set_attr "type" "other")
19755    (set_attr "memory" "load")
19756    (set (attr "length")
19757         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19759 (define_insn "<xrstor>64"
19760    [(unspec_volatile:BLK
19761      [(match_operand:BLK 0 "memory_operand" "m")
19762       (match_operand:SI 1 "register_operand" "a")
19763       (match_operand:SI 2 "register_operand" "d")]
19764      ANY_XRSTOR64)]
19765   "TARGET_64BIT && TARGET_XSAVE"
19766   "<xrstor>64\t%0"
19767   [(set_attr "type" "other")
19768    (set_attr "memory" "load")
19769    (set (attr "length")
19770         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19772 (define_insn "xsetbv"
19773   [(unspec_volatile:SI
19774          [(match_operand:SI 0 "register_operand" "c")
19775           (match_operand:DI 1 "register_operand" "A")]
19776          UNSPECV_XSETBV)]
19777   "!TARGET_64BIT && TARGET_XSAVE"
19778   "xsetbv"
19779   [(set_attr "type" "other")])
19781 (define_insn "xsetbv_rex64"
19782   [(unspec_volatile:SI
19783          [(match_operand:SI 0 "register_operand" "c")
19784           (match_operand:SI 1 "register_operand" "a")
19785           (match_operand:SI 2 "register_operand" "d")]
19786          UNSPECV_XSETBV)]
19787   "TARGET_64BIT && TARGET_XSAVE"
19788   "xsetbv"
19789   [(set_attr "type" "other")])
19791 (define_insn "xgetbv"
19792   [(set (match_operand:DI 0 "register_operand" "=A")
19793         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19794                             UNSPECV_XGETBV))]
19795   "!TARGET_64BIT && TARGET_XSAVE"
19796   "xgetbv"
19797   [(set_attr "type" "other")])
19799 (define_insn "xgetbv_rex64"
19800   [(set (match_operand:DI 0 "register_operand" "=a")
19801         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19802                             UNSPECV_XGETBV))
19803    (set (match_operand:DI 1 "register_operand" "=d")
19804         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19805   "TARGET_64BIT && TARGET_XSAVE"
19806   "xgetbv"
19807   [(set_attr "type" "other")])
19809 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19811 ;; Floating-point instructions for atomic compound assignments
19813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19815 ; Clobber all floating-point registers on environment save and restore
19816 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19817 (define_insn "fnstenv"
19818   [(set (match_operand:BLK 0 "memory_operand" "=m")
19819         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19820    (clobber (reg:XF ST0_REG))
19821    (clobber (reg:XF ST1_REG))
19822    (clobber (reg:XF ST2_REG))
19823    (clobber (reg:XF ST3_REG))
19824    (clobber (reg:XF ST4_REG))
19825    (clobber (reg:XF ST5_REG))
19826    (clobber (reg:XF ST6_REG))
19827    (clobber (reg:XF ST7_REG))]
19828   "TARGET_80387"
19829   "fnstenv\t%0"
19830   [(set_attr "type" "other")
19831    (set_attr "memory" "store")
19832    (set (attr "length")
19833         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19835 (define_insn "fldenv"
19836   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19837                     UNSPECV_FLDENV)
19838    (clobber (reg:XF ST0_REG))
19839    (clobber (reg:XF ST1_REG))
19840    (clobber (reg:XF ST2_REG))
19841    (clobber (reg:XF ST3_REG))
19842    (clobber (reg:XF ST4_REG))
19843    (clobber (reg:XF ST5_REG))
19844    (clobber (reg:XF ST6_REG))
19845    (clobber (reg:XF ST7_REG))]
19846   "TARGET_80387"
19847   "fldenv\t%0"
19848   [(set_attr "type" "other")
19849    (set_attr "memory" "load")
19850    (set (attr "length")
19851         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19853 (define_insn "fnstsw"
19854   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19855         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19856   "TARGET_80387"
19857   "fnstsw\t%0"
19858   [(set_attr "type" "other,other")
19859    (set_attr "memory" "none,store")
19860    (set (attr "length")
19861         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19863 (define_insn "fnclex"
19864   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19865   "TARGET_80387"
19866   "fnclex"
19867   [(set_attr "type" "other")
19868    (set_attr "memory" "none")
19869    (set_attr "length" "2")])
19871 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19873 ;; LWP instructions
19875 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19877 (define_expand "lwp_llwpcb"
19878   [(unspec_volatile [(match_operand 0 "register_operand")]
19879                     UNSPECV_LLWP_INTRINSIC)]
19880   "TARGET_LWP")
19882 (define_insn "*lwp_llwpcb<mode>1"
19883   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19884                     UNSPECV_LLWP_INTRINSIC)]
19885   "TARGET_LWP"
19886   "llwpcb\t%0"
19887   [(set_attr "type" "lwp")
19888    (set_attr "mode" "<MODE>")
19889    (set_attr "length" "5")])
19891 (define_expand "lwp_slwpcb"
19892   [(set (match_operand 0 "register_operand")
19893         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19894   "TARGET_LWP"
19896   rtx (*insn)(rtx);
19898   insn = (Pmode == DImode
19899           ? gen_lwp_slwpcbdi
19900           : gen_lwp_slwpcbsi);
19902   emit_insn (insn (operands[0]));
19903   DONE;
19906 (define_insn "lwp_slwpcb<mode>"
19907   [(set (match_operand:P 0 "register_operand" "=r")
19908         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19909   "TARGET_LWP"
19910   "slwpcb\t%0"
19911   [(set_attr "type" "lwp")
19912    (set_attr "mode" "<MODE>")
19913    (set_attr "length" "5")])
19915 (define_expand "lwp_lwpval<mode>3"
19916   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19917                      (match_operand:SI 2 "nonimmediate_operand")
19918                      (match_operand:SI 3 "const_int_operand")]
19919                     UNSPECV_LWPVAL_INTRINSIC)]
19920   "TARGET_LWP"
19921   ;; Avoid unused variable warning.
19922   "(void) operands[0];")
19924 (define_insn "*lwp_lwpval<mode>3_1"
19925   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19926                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19927                      (match_operand:SI 2 "const_int_operand" "i")]
19928                     UNSPECV_LWPVAL_INTRINSIC)]
19929   "TARGET_LWP"
19930   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19931   [(set_attr "type" "lwp")
19932    (set_attr "mode" "<MODE>")
19933    (set (attr "length")
19934         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19936 (define_expand "lwp_lwpins<mode>3"
19937   [(set (reg:CCC FLAGS_REG)
19938         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19939                               (match_operand:SI 2 "nonimmediate_operand")
19940                               (match_operand:SI 3 "const_int_operand")]
19941                              UNSPECV_LWPINS_INTRINSIC))
19942    (set (match_operand:QI 0 "nonimmediate_operand")
19943         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19944   "TARGET_LWP")
19946 (define_insn "*lwp_lwpins<mode>3_1"
19947   [(set (reg:CCC FLAGS_REG)
19948         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19949                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19950                               (match_operand:SI 2 "const_int_operand" "i")]
19951                              UNSPECV_LWPINS_INTRINSIC))]
19952   "TARGET_LWP"
19953   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19954   [(set_attr "type" "lwp")
19955    (set_attr "mode" "<MODE>")
19956    (set (attr "length")
19957         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19959 (define_int_iterator RDFSGSBASE
19960         [UNSPECV_RDFSBASE
19961          UNSPECV_RDGSBASE])
19963 (define_int_iterator WRFSGSBASE
19964         [UNSPECV_WRFSBASE
19965          UNSPECV_WRGSBASE])
19967 (define_int_attr fsgs
19968         [(UNSPECV_RDFSBASE "fs")
19969          (UNSPECV_RDGSBASE "gs")
19970          (UNSPECV_WRFSBASE "fs")
19971          (UNSPECV_WRGSBASE "gs")])
19973 (define_insn "rd<fsgs>base<mode>"
19974   [(set (match_operand:SWI48 0 "register_operand" "=r")
19975         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19976   "TARGET_64BIT && TARGET_FSGSBASE"
19977   "rd<fsgs>base\t%0"
19978   [(set_attr "type" "other")
19979    (set_attr "prefix_extra" "2")])
19981 (define_insn "wr<fsgs>base<mode>"
19982   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19983                     WRFSGSBASE)]
19984   "TARGET_64BIT && TARGET_FSGSBASE"
19985   "wr<fsgs>base\t%0"
19986   [(set_attr "type" "other")
19987    (set_attr "prefix_extra" "2")])
19989 (define_insn "ptwrite<mode>"
19990   [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
19991                     UNSPECV_PTWRITE)]
19992   "TARGET_PTWRITE"
19993   "ptwrite\t%0"
19994   [(set_attr "type" "other")
19995    (set_attr "prefix_extra" "2")])
19997 (define_insn "rdrand<mode>_1"
19998   [(set (match_operand:SWI248 0 "register_operand" "=r")
19999         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20000    (set (reg:CCC FLAGS_REG)
20001         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20002   "TARGET_RDRND"
20003   "rdrand\t%0"
20004   [(set_attr "type" "other")
20005    (set_attr "prefix_extra" "1")])
20007 (define_insn "rdseed<mode>_1"
20008   [(set (match_operand:SWI248 0 "register_operand" "=r")
20009         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20010    (set (reg:CCC FLAGS_REG)
20011         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20012   "TARGET_RDSEED"
20013   "rdseed\t%0"
20014   [(set_attr "type" "other")
20015    (set_attr "prefix_extra" "1")])
20017 (define_expand "pause"
20018   [(set (match_dup 0)
20019         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20020   ""
20022   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20023   MEM_VOLATILE_P (operands[0]) = 1;
20026 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20027 ;; They have the same encoding.
20028 (define_insn "*pause"
20029   [(set (match_operand:BLK 0)
20030         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20031   ""
20032   "rep%; nop"
20033   [(set_attr "length" "2")
20034    (set_attr "memory" "unknown")])
20036 ;; CET instructions
20037 (define_insn "rdssp<mode>"
20038   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20039         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20040   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20041   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20042   [(set_attr "length" "6")
20043    (set_attr "type" "other")])
20045 (define_insn "incssp<mode>"
20046   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20047                     UNSPECV_INCSSP)]
20048   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20049   "incssp<mskmodesuffix>\t%0"
20050   [(set_attr "length" "4")
20051    (set_attr "type" "other")])
20053 (define_insn "saveprevssp"
20054   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20055   "TARGET_SHSTK"
20056   "saveprevssp"
20057   [(set_attr "length" "5")
20058    (set_attr "type" "other")])
20060 (define_expand "rstorssp"
20061   [(unspec_volatile [(match_operand 0 "memory_operand")]
20062                     UNSPECV_RSTORSSP)]
20063   "TARGET_SHSTK")
20065 (define_insn "*rstorssp<mode>"
20066   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20067                     UNSPECV_RSTORSSP)]
20068   "TARGET_SHSTK"
20069   "rstorssp\t%0"
20070   [(set_attr "length" "5")
20071    (set_attr "type" "other")])
20073 (define_insn "wrss<mode>"
20074   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20075                      (match_operand:SWI48x 1 "memory_operand" "m")]
20076                     UNSPECV_WRSS)]
20077   "TARGET_SHSTK"
20078   "wrss<mskmodesuffix>\t%0, %1"
20079   [(set_attr "length" "3")
20080    (set_attr "type" "other")])
20082 (define_insn "wruss<mode>"
20083   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20084                      (match_operand:SWI48x 1 "memory_operand" "m")]
20085                     UNSPECV_WRUSS)]
20086   "TARGET_SHSTK"
20087   "wruss<mskmodesuffix>\t%0, %1"
20088   [(set_attr "length" "4")
20089    (set_attr "type" "other")])
20091 (define_insn "setssbsy"
20092   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20093   "TARGET_SHSTK"
20094   "setssbsy"
20095   [(set_attr "length" "4")
20096    (set_attr "type" "other")])
20098 (define_expand "clrssbsy"
20099   [(unspec_volatile [(match_operand 0 "memory_operand")]
20100                     UNSPECV_CLRSSBSY)]
20101   "TARGET_SHSTK")
20103 (define_insn "*clrssbsy<mode>"
20104   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20105                     UNSPECV_CLRSSBSY)]
20106   "TARGET_SHSTK"
20107   "clrssbsy\t%0"
20108   [(set_attr "length" "4")
20109    (set_attr "type" "other")])
20111 (define_insn "nop_endbr"
20112   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20113   "(flag_cf_protection & CF_BRANCH)"
20115   return TARGET_64BIT ? "endbr64" : "endbr32";
20117   [(set_attr "length" "4")
20118    (set_attr "length_immediate" "0")
20119    (set_attr "modrm" "0")])
20121 ;; For RTM support
20122 (define_expand "xbegin"
20123   [(set (match_operand:SI 0 "register_operand")
20124         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20125   "TARGET_RTM"
20127   rtx_code_label *label = gen_label_rtx ();
20129   /* xbegin is emitted as jump_insn, so reload won't be able
20130      to reload its operand.  Force the value into AX hard register.  */
20131   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20132   emit_move_insn (ax_reg, constm1_rtx);
20134   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20136   emit_label (label);
20137   LABEL_NUSES (label) = 1;
20139   emit_move_insn (operands[0], ax_reg);
20141   DONE;
20144 (define_insn "xbegin_1"
20145   [(set (pc)
20146         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20147                           (const_int 0))
20148                       (label_ref (match_operand 1))
20149                       (pc)))
20150    (set (match_operand:SI 0 "register_operand" "+a")
20151         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20152   "TARGET_RTM"
20153   "xbegin\t%l1"
20154   [(set_attr "type" "other")
20155    (set_attr "length" "6")])
20157 (define_insn "xend"
20158   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20159   "TARGET_RTM"
20160   "xend"
20161   [(set_attr "type" "other")
20162    (set_attr "length" "3")])
20164 (define_insn "xabort"
20165   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20166                     UNSPECV_XABORT)]
20167   "TARGET_RTM"
20168   "xabort\t%0"
20169   [(set_attr "type" "other")
20170    (set_attr "length" "3")])
20172 (define_expand "xtest"
20173   [(set (match_operand:QI 0 "register_operand")
20174         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20175   "TARGET_RTM"
20177   emit_insn (gen_xtest_1 ());
20179   ix86_expand_setcc (operands[0], NE,
20180                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20181   DONE;
20184 (define_insn "xtest_1"
20185   [(set (reg:CCZ FLAGS_REG)
20186         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20187   "TARGET_RTM"
20188   "xtest"
20189   [(set_attr "type" "other")
20190    (set_attr "length" "3")])
20192 (define_insn "clwb"
20193   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20194                    UNSPECV_CLWB)]
20195   "TARGET_CLWB"
20196   "clwb\t%a0"
20197   [(set_attr "type" "sse")
20198    (set_attr "atom_sse_attr" "fence")
20199    (set_attr "memory" "unknown")])
20201 (define_insn "clflushopt"
20202   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20203                    UNSPECV_CLFLUSHOPT)]
20204   "TARGET_CLFLUSHOPT"
20205   "clflushopt\t%a0"
20206   [(set_attr "type" "sse")
20207    (set_attr "atom_sse_attr" "fence")
20208    (set_attr "memory" "unknown")])
20210 ;; MONITORX and MWAITX
20211 (define_insn "mwaitx"
20212   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20213                      (match_operand:SI 1 "register_operand" "a")
20214                      (match_operand:SI 2 "register_operand" "b")]
20215                    UNSPECV_MWAITX)]
20216   "TARGET_MWAITX"
20217 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20218 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20219 ;; we only need to set up 32bit registers.
20220   "mwaitx"
20221   [(set_attr "length" "3")])
20223 (define_insn "@monitorx_<mode>"
20224   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20225                      (match_operand:SI 1 "register_operand" "c")
20226                      (match_operand:SI 2 "register_operand" "d")]
20227                    UNSPECV_MONITORX)]
20228   "TARGET_MWAITX"
20229 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20230 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20231 ;; zero extended to 64bit, we only need to set up 32bit registers.
20232   "%^monitorx"
20233   [(set (attr "length")
20234      (symbol_ref ("(Pmode != word_mode) + 3")))])
20236 ;; CLZERO
20237 (define_insn "@clzero_<mode>"
20238   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20239                    UNSPECV_CLZERO)]
20240   "TARGET_CLZERO"
20241   "clzero"
20242   [(set_attr "length" "3")
20243   (set_attr "memory" "unknown")])
20245 ;; RDPKRU and WRPKRU
20247 (define_expand "rdpkru"
20248   [(parallel
20249      [(set (match_operand:SI 0 "register_operand")
20250            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20251       (set (match_dup 2) (const_int 0))])]
20252   "TARGET_PKU"
20254   operands[1] = force_reg (SImode, const0_rtx);
20255   operands[2] = gen_reg_rtx (SImode);
20258 (define_insn "*rdpkru"
20259   [(set (match_operand:SI 0 "register_operand" "=a")
20260         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20261                             UNSPECV_PKU))
20262    (set (match_operand:SI 1 "register_operand" "=d")
20263         (const_int 0))]
20264   "TARGET_PKU"
20265   "rdpkru"
20266   [(set_attr "type" "other")])
20268 (define_expand "wrpkru"
20269   [(unspec_volatile:SI
20270      [(match_operand:SI 0 "register_operand")
20271       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20272   "TARGET_PKU"
20274   operands[1] = force_reg (SImode, const0_rtx);
20275   operands[2] = force_reg (SImode, const0_rtx);
20278 (define_insn "*wrpkru"
20279   [(unspec_volatile:SI
20280      [(match_operand:SI 0 "register_operand" "a")
20281       (match_operand:SI 1 "register_operand" "d")
20282       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20283   "TARGET_PKU"
20284   "wrpkru"
20285   [(set_attr "type" "other")])
20287 (define_insn "rdpid"
20288   [(set (match_operand:SI 0 "register_operand" "=r")
20289         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20290   "!TARGET_64BIT && TARGET_RDPID"
20291   "rdpid\t%0"
20292   [(set_attr "type" "other")])
20294 (define_insn "rdpid_rex64"
20295   [(set (match_operand:DI 0 "register_operand" "=r")
20296         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20297   "TARGET_64BIT && TARGET_RDPID"
20298   "rdpid\t%0"
20299   [(set_attr "type" "other")])
20301 ;; Intirinsics for > i486
20303 (define_insn "wbinvd"
20304   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20305   ""
20306   "wbinvd"
20307   [(set_attr "type" "other")])
20309 (define_insn "wbnoinvd"
20310   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20311   "TARGET_WBNOINVD"
20312   "wbnoinvd"
20313   [(set_attr "type" "other")])
20315 ;; MOVDIRI and MOVDIR64B
20317 (define_insn "movdiri<mode>"
20318   [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20319                            (match_operand:SWI48 1 "register_operand" "r")]
20320                           UNSPECV_MOVDIRI)]
20321   "TARGET_MOVDIRI"
20322   "movdiri\t{%1, %0|%0, %1}"
20323   [(set_attr "type" "other")])
20325 (define_insn "@movdir64b_<mode>"
20326   [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20327                         (match_operand:XI 1 "memory_operand")]
20328                        UNSPECV_MOVDIR64B)]
20329   "TARGET_MOVDIR64B"
20330   "movdir64b\t{%1, %0|%0, %1}"
20331   [(set_attr "type" "other")])
20333 ;; ENQCMD and ENQCMDS
20335 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20336 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20338 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20339   [(set (reg:CCZ FLAGS_REG)
20340         (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20341                               (match_operand:XI 1 "memory_operand" "m")]
20342                              ENQCMD))]
20343   "TARGET_ENQCMD"
20344   "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20345   [(set_attr "type" "other")])
20347 ;; WAITPKG
20349 (define_insn "umwait"
20350   [(set (reg:CCC FLAGS_REG)
20351         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20352                               (match_operand:DI 1 "register_operand" "A")]
20353                              UNSPECV_UMWAIT))]
20354   "!TARGET_64BIT && TARGET_WAITPKG"
20355   "umwait\t%0"
20356   [(set_attr "length" "3")])
20358 (define_insn "umwait_rex64"
20359   [(set (reg:CCC FLAGS_REG)
20360         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20361                               (match_operand:SI 1 "register_operand" "a")
20362                               (match_operand:SI 2 "register_operand" "d")]
20363                              UNSPECV_UMWAIT))]
20364   "TARGET_64BIT && TARGET_WAITPKG"
20365   "umwait\t%0"
20366   [(set_attr "length" "3")])
20368 (define_insn "umonitor_<mode>"
20369   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20370                     UNSPECV_UMONITOR)]
20371   "TARGET_WAITPKG"
20372   "umonitor\t%0"
20373   [(set (attr "length")
20374      (symbol_ref ("(Pmode != word_mode) + 3")))])
20376 (define_insn "tpause"
20377   [(set (reg:CCC FLAGS_REG)
20378         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20379                               (match_operand:DI 1 "register_operand" "A")]
20380                              UNSPECV_TPAUSE))]
20381   "!TARGET_64BIT && TARGET_WAITPKG"
20382   "tpause\t%0"
20383   [(set_attr "length" "3")])
20385 (define_insn "tpause_rex64"
20386   [(set (reg:CCC FLAGS_REG)
20387         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20388                               (match_operand:SI 1 "register_operand" "a")
20389                               (match_operand:SI 2 "register_operand" "d")]
20390                              UNSPECV_TPAUSE))]
20391   "TARGET_64BIT && TARGET_WAITPKG"
20392   "tpause\t%0"
20393   [(set_attr "length" "3")])
20395 (define_insn "cldemote"
20396   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20397                  UNSPECV_CLDEMOTE)]
20398   "TARGET_CLDEMOTE"
20399   "cldemote\t%a0"
20400   [(set_attr "type" "other")
20401    (set_attr "memory" "unknown")])
20403 (define_insn "speculation_barrier"
20404   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20405   ""
20406   "lfence"
20407   [(set_attr "type" "other")
20408    (set_attr "length" "3")])
20410 (include "mmx.md")
20411 (include "sse.md")
20412 (include "sync.md")