PR target/87674
[official-gcc.git] / gcc / config / i386 / i386.md
blob7fb2b144f4780cc8dfb7529e61bfd4c0e1701409
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print 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_IEEE_MIN       ; not commutative
128   UNSPEC_IEEE_MAX       ; not commutative
130   ;; x87 Floating point
131   UNSPEC_SIN
132   UNSPEC_COS
133   UNSPEC_FPATAN
134   UNSPEC_FYL2X
135   UNSPEC_FYL2XP1
136   UNSPEC_FRNDINT
137   UNSPEC_FIST
138   UNSPEC_F2XM1
139   UNSPEC_TAN
140   UNSPEC_FXAM
142   ;; x87 Rounding
143   UNSPEC_FRNDINT_FLOOR
144   UNSPEC_FRNDINT_CEIL
145   UNSPEC_FRNDINT_TRUNC
146   UNSPEC_FIST_FLOOR
147   UNSPEC_FIST_CEIL
149   ;; x87 Double output FP
150   UNSPEC_SINCOS_COS
151   UNSPEC_SINCOS_SIN
152   UNSPEC_XTRACT_FRACT
153   UNSPEC_XTRACT_EXP
154   UNSPEC_FSCALE_FRACT
155   UNSPEC_FSCALE_EXP
156   UNSPEC_FPREM_F
157   UNSPEC_FPREM_U
158   UNSPEC_FPREM1_F
159   UNSPEC_FPREM1_U
161   UNSPEC_C2_FLAG
162   UNSPEC_FXAM_MEM
164   ;; SSP patterns
165   UNSPEC_SP_SET
166   UNSPEC_SP_TEST
168   ;; For ROUND support
169   UNSPEC_ROUND
171   ;; For CRC32 support
172   UNSPEC_CRC32
174   ;; For LZCNT suppoprt
175   UNSPEC_LZCNT
177   ;; For BMI support
178   UNSPEC_TZCNT
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; IRET support
186   UNSPEC_INTERRUPT_RETURN
189 (define_c_enum "unspecv" [
190   UNSPECV_UD2
191   UNSPECV_BLOCKAGE
192   UNSPECV_STACK_PROBE
193   UNSPECV_PROBE_STACK_RANGE
194   UNSPECV_ALIGN
195   UNSPECV_PROLOGUE_USE
196   UNSPECV_SPLIT_STACK_RETURN
197   UNSPECV_CLD
198   UNSPECV_NOPS
199   UNSPECV_RDTSC
200   UNSPECV_RDTSCP
201   UNSPECV_RDPMC
202   UNSPECV_LLWP_INTRINSIC
203   UNSPECV_SLWP_INTRINSIC
204   UNSPECV_LWPVAL_INTRINSIC
205   UNSPECV_LWPINS_INTRINSIC
206   UNSPECV_RDFSBASE
207   UNSPECV_RDGSBASE
208   UNSPECV_WRFSBASE
209   UNSPECV_WRGSBASE
210   UNSPECV_FXSAVE
211   UNSPECV_FXRSTOR
212   UNSPECV_FXSAVE64
213   UNSPECV_FXRSTOR64
214   UNSPECV_XSAVE
215   UNSPECV_XRSTOR
216   UNSPECV_XSAVE64
217   UNSPECV_XRSTOR64
218   UNSPECV_XSAVEOPT
219   UNSPECV_XSAVEOPT64
220   UNSPECV_XSAVES
221   UNSPECV_XRSTORS
222   UNSPECV_XSAVES64
223   UNSPECV_XRSTORS64
224   UNSPECV_XSAVEC
225   UNSPECV_XSAVEC64
226   UNSPECV_XGETBV
227   UNSPECV_XSETBV
228   UNSPECV_WBINVD
229   UNSPECV_WBNOINVD
231   ;; For atomic compound assignments.
232   UNSPECV_FNSTENV
233   UNSPECV_FLDENV
234   UNSPECV_FNSTSW
235   UNSPECV_FNCLEX
237   ;; For RDRAND support
238   UNSPECV_RDRAND
240   ;; For RDSEED support
241   UNSPECV_RDSEED
243   ;; For RTM support
244   UNSPECV_XBEGIN
245   UNSPECV_XEND
246   UNSPECV_XABORT
247   UNSPECV_XTEST
249   UNSPECV_NLGR
251   ;; For CLWB support
252   UNSPECV_CLWB
254   ;; For CLFLUSHOPT support
255   UNSPECV_CLFLUSHOPT
257   ;; For MONITORX and MWAITX support 
258   UNSPECV_MONITORX
259   UNSPECV_MWAITX
261   ;; For CLZERO support
262   UNSPECV_CLZERO
264   ;; For RDPKRU and WRPKRU support
265   UNSPECV_PKU
267   ;; For RDPID support
268   UNSPECV_RDPID
270   ;; For CET support
271   UNSPECV_NOP_ENDBR
272   UNSPECV_NOP_RDSSP
273   UNSPECV_INCSSP
274   UNSPECV_SAVEPREVSSP
275   UNSPECV_RSTORSSP
276   UNSPECV_WRSS
277   UNSPECV_WRUSS
278   UNSPECV_SETSSBSY
279   UNSPECV_CLRSSBSY
281   ;; For MOVDIRI and MOVDIR64B support
282   UNSPECV_MOVDIRI
283   UNSPECV_MOVDIR64B
285   ;; For WAITPKG support
286   UNSPECV_UMWAIT
287   UNSPECV_UMONITOR
288   UNSPECV_TPAUSE
290   ;; For CLDEMOTE support
291   UNSPECV_CLDEMOTE
293   ;; For Speculation Barrier support
294   UNSPECV_SPECULATION_BARRIER
297 ;; Constants to represent rounding modes in the ROUND instruction
298 (define_constants
299   [(ROUND_FLOOR                 0x1)
300    (ROUND_CEIL                  0x2)
301    (ROUND_TRUNC                 0x3)
302    (ROUND_MXCSR                 0x4)
303    (ROUND_NO_EXC                0x8)
304   ])
306 ;; Constants to represent AVX512F embeded rounding
307 (define_constants
308   [(ROUND_NEAREST_INT                   0)
309    (ROUND_NEG_INF                       1)
310    (ROUND_POS_INF                       2)
311    (ROUND_ZERO                          3)
312    (NO_ROUND                            4)
313    (ROUND_SAE                           8)
314   ])
316 ;; Constants to represent pcomtrue/pcomfalse variants
317 (define_constants
318   [(PCOM_FALSE                  0)
319    (PCOM_TRUE                   1)
320    (COM_FALSE_S                 2)
321    (COM_FALSE_P                 3)
322    (COM_TRUE_S                  4)
323    (COM_TRUE_P                  5)
324   ])
326 ;; Constants used in the XOP pperm instruction
327 (define_constants
328   [(PPERM_SRC                   0x00)   /* copy source */
329    (PPERM_INVERT                0x20)   /* invert source */
330    (PPERM_REVERSE               0x40)   /* bit reverse source */
331    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
332    (PPERM_ZERO                  0x80)   /* all 0's */
333    (PPERM_ONES                  0xa0)   /* all 1's */
334    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
335    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
336    (PPERM_SRC1                  0x00)   /* use first source byte */
337    (PPERM_SRC2                  0x10)   /* use second source byte */
338    ])
340 ;; Registers by name.
341 (define_constants
342   [(AX_REG                       0)
343    (DX_REG                       1)
344    (CX_REG                       2)
345    (BX_REG                       3)
346    (SI_REG                       4)
347    (DI_REG                       5)
348    (BP_REG                       6)
349    (SP_REG                       7)
350    (ST0_REG                      8)
351    (ST1_REG                      9)
352    (ST2_REG                     10)
353    (ST3_REG                     11)
354    (ST4_REG                     12)
355    (ST5_REG                     13)
356    (ST6_REG                     14)
357    (ST7_REG                     15)
358    (ARGP_REG                    16)
359    (FLAGS_REG                   17)
360    (FPSR_REG                    18)
361    (FRAME_REG                   19)
362    (XMM0_REG                    20)
363    (XMM1_REG                    21)
364    (XMM2_REG                    22)
365    (XMM3_REG                    23)
366    (XMM4_REG                    24)
367    (XMM5_REG                    25)
368    (XMM6_REG                    26)
369    (XMM7_REG                    27)
370    (MM0_REG                     28)
371    (MM1_REG                     29)
372    (MM2_REG                     30)
373    (MM3_REG                     31)
374    (MM4_REG                     32)
375    (MM5_REG                     33)
376    (MM6_REG                     34)
377    (MM7_REG                     35)
378    (R8_REG                      36)
379    (R9_REG                      37)
380    (R10_REG                     38)
381    (R11_REG                     39)
382    (R12_REG                     40)
383    (R13_REG                     41)
384    (R14_REG                     42)
385    (R15_REG                     43)
386    (XMM8_REG                    44)
387    (XMM9_REG                    45)
388    (XMM10_REG                   46)
389    (XMM11_REG                   47)
390    (XMM12_REG                   48)
391    (XMM13_REG                   49)
392    (XMM14_REG                   50)
393    (XMM15_REG                   51)
394    (XMM16_REG                   52)
395    (XMM17_REG                   53)
396    (XMM18_REG                   54)
397    (XMM19_REG                   55)
398    (XMM20_REG                   56)
399    (XMM21_REG                   57)
400    (XMM22_REG                   58)
401    (XMM23_REG                   59)
402    (XMM24_REG                   60)
403    (XMM25_REG                   61)
404    (XMM26_REG                   62)
405    (XMM27_REG                   63)
406    (XMM28_REG                   64)
407    (XMM29_REG                   65)
408    (XMM30_REG                   66)
409    (XMM31_REG                   67)
410    (MASK0_REG                   68)
411    (MASK1_REG                   69)
412    (MASK2_REG                   70)
413    (MASK3_REG                   71)
414    (MASK4_REG                   72)
415    (MASK5_REG                   73)
416    (MASK6_REG                   74)
417    (MASK7_REG                   75)
418    (FIRST_PSEUDO_REG            76)
419   ])
421 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
422 ;; from i386.c.
424 ;; In C guard expressions, put expressions which may be compile-time
425 ;; constants first.  This allows for better optimization.  For
426 ;; example, write "TARGET_64BIT && reload_completed", not
427 ;; "reload_completed && TARGET_64BIT".
430 ;; Processor type.
431 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
432                     atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
433                     bdver4,btver2,znver1"
434   (const (symbol_ref "ix86_schedule")))
436 ;; A basic instruction type.  Refinements due to arguments to be
437 ;; provided in other attributes.
438 (define_attr "type"
439   "other,multi,
440    alu,alu1,negnot,imov,imovx,lea,
441    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
442    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
443    push,pop,call,callv,leave,
444    str,bitmanip,
445    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
446    fxch,fistp,fisttp,frndint,
447    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
448    ssemul,sseimul,ssediv,sselog,sselog1,
449    sseishft,sseishft1,ssecmp,ssecomi,
450    ssecvt,ssecvt1,sseicvt,sseins,
451    sseshuf,sseshuf1,ssemuladd,sse4arg,
452    lwp,mskmov,msklog,
453    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
454   (const_string "other"))
456 ;; Main data type used by the insn
457 (define_attr "mode"
458   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
459   V2DF,V2SF,V1DF,V8DF"
460   (const_string "unknown"))
462 ;; The CPU unit operations uses.
463 (define_attr "unit" "integer,i387,sse,mmx,unknown"
464   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
465                           fxch,fistp,fisttp,frndint")
466            (const_string "i387")
467          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
468                           ssemul,sseimul,ssediv,sselog,sselog1,
469                           sseishft,sseishft1,ssecmp,ssecomi,
470                           ssecvt,ssecvt1,sseicvt,sseins,
471                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
472            (const_string "sse")
473          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
474            (const_string "mmx")
475          (eq_attr "type" "other")
476            (const_string "unknown")]
477          (const_string "integer")))
479 ;; The (bounding maximum) length of an instruction immediate.
480 (define_attr "length_immediate" ""
481   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
482                           bitmanip,imulx,msklog,mskmov")
483            (const_int 0)
484          (eq_attr "unit" "i387,sse,mmx")
485            (const_int 0)
486          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
487                           rotate,rotatex,rotate1,imul,icmp,push,pop")
488            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
489          (eq_attr "type" "imov,test")
490            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
491          (eq_attr "type" "call")
492            (if_then_else (match_operand 0 "constant_call_address_operand")
493              (const_int 4)
494              (const_int 0))
495          (eq_attr "type" "callv")
496            (if_then_else (match_operand 1 "constant_call_address_operand")
497              (const_int 4)
498              (const_int 0))
499          ;; We don't know the size before shorten_branches.  Expect
500          ;; the instruction to fit for better scheduling.
501          (eq_attr "type" "ibr")
502            (const_int 1)
503          ]
504          (symbol_ref "/* Update immediate_length and other attributes! */
505                       gcc_unreachable (),1")))
507 ;; The (bounding maximum) length of an instruction address.
508 (define_attr "length_address" ""
509   (cond [(eq_attr "type" "str,other,multi,fxch")
510            (const_int 0)
511          (and (eq_attr "type" "call")
512               (match_operand 0 "constant_call_address_operand"))
513              (const_int 0)
514          (and (eq_attr "type" "callv")
515               (match_operand 1 "constant_call_address_operand"))
516              (const_int 0)
517          ]
518          (symbol_ref "ix86_attr_length_address_default (insn)")))
520 ;; Set when length prefix is used.
521 (define_attr "prefix_data16" ""
522   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
523            (const_int 0)
524          (eq_attr "mode" "HI")
525            (const_int 1)
526          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
527            (const_int 1)
528         ]
529         (const_int 0)))
531 ;; Set when string REP prefix is used.
532 (define_attr "prefix_rep" ""
533   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
534            (const_int 0)
535          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
536            (const_int 1)
537         ]
538         (const_int 0)))
540 ;; Set when 0f opcode prefix is used.
541 (define_attr "prefix_0f" ""
542   (if_then_else
543     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
544          (eq_attr "unit" "sse,mmx"))
545     (const_int 1)
546     (const_int 0)))
548 ;; Set when REX opcode prefix is used.
549 (define_attr "prefix_rex" ""
550   (cond [(not (match_test "TARGET_64BIT"))
551            (const_int 0)
552          (and (eq_attr "mode" "DI")
553               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
554                    (eq_attr "unit" "!mmx")))
555            (const_int 1)
556          (and (eq_attr "mode" "QI")
557               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
558            (const_int 1)
559          (match_test "x86_extended_reg_mentioned_p (insn)")
560            (const_int 1)
561          (and (eq_attr "type" "imovx")
562               (match_operand:QI 1 "ext_QIreg_operand"))
563            (const_int 1)
564         ]
565         (const_int 0)))
567 ;; There are also additional prefixes in 3DNOW, SSSE3.
568 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
569 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
570 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
571 (define_attr "prefix_extra" ""
572   (cond [(eq_attr "type" "ssemuladd,sse4arg")
573            (const_int 2)
574          (eq_attr "type" "sseiadd1,ssecvt1")
575            (const_int 1)
576         ]
577         (const_int 0)))
579 ;; Prefix used: original, VEX or maybe VEX.
580 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
581   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
582            (const_string "vex")
583          (eq_attr "mode" "XI,V16SF,V8DF")
584            (const_string "evex")
585         ]
586         (const_string "orig")))
588 ;; VEX W bit is used.
589 (define_attr "prefix_vex_w" "" (const_int 0))
591 ;; The length of VEX prefix
592 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
593 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
594 ;; still prefix_0f 1, with prefix_extra 1.
595 (define_attr "length_vex" ""
596   (if_then_else (and (eq_attr "prefix_0f" "1")
597                      (eq_attr "prefix_extra" "0"))
598     (if_then_else (eq_attr "prefix_vex_w" "1")
599       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
600       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
601     (if_then_else (eq_attr "prefix_vex_w" "1")
602       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
603       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
605 ;; 4-bytes evex prefix and 1 byte opcode.
606 (define_attr "length_evex" "" (const_int 5))
608 ;; Set when modrm byte is used.
609 (define_attr "modrm" ""
610   (cond [(eq_attr "type" "str,leave")
611            (const_int 0)
612          (eq_attr "unit" "i387")
613            (const_int 0)
614          (and (eq_attr "type" "incdec")
615               (and (not (match_test "TARGET_64BIT"))
616                    (ior (match_operand:SI 1 "register_operand")
617                         (match_operand:HI 1 "register_operand"))))
618            (const_int 0)
619          (and (eq_attr "type" "push")
620               (not (match_operand 1 "memory_operand")))
621            (const_int 0)
622          (and (eq_attr "type" "pop")
623               (not (match_operand 0 "memory_operand")))
624            (const_int 0)
625          (and (eq_attr "type" "imov")
626               (and (not (eq_attr "mode" "DI"))
627                    (ior (and (match_operand 0 "register_operand")
628                              (match_operand 1 "immediate_operand"))
629                         (ior (and (match_operand 0 "ax_reg_operand")
630                                   (match_operand 1 "memory_displacement_only_operand"))
631                              (and (match_operand 0 "memory_displacement_only_operand")
632                                   (match_operand 1 "ax_reg_operand"))))))
633            (const_int 0)
634          (and (eq_attr "type" "call")
635               (match_operand 0 "constant_call_address_operand"))
636              (const_int 0)
637          (and (eq_attr "type" "callv")
638               (match_operand 1 "constant_call_address_operand"))
639              (const_int 0)
640          (and (eq_attr "type" "alu,alu1,icmp,test")
641               (match_operand 0 "ax_reg_operand"))
642              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
643          ]
644          (const_int 1)))
646 ;; The (bounding maximum) length of an instruction in bytes.
647 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
648 ;; Later we may want to split them and compute proper length as for
649 ;; other insns.
650 (define_attr "length" ""
651   (cond [(eq_attr "type" "other,multi,fistp,frndint")
652            (const_int 16)
653          (eq_attr "type" "fcmp")
654            (const_int 4)
655          (eq_attr "unit" "i387")
656            (plus (const_int 2)
657                  (plus (attr "prefix_data16")
658                        (attr "length_address")))
659          (ior (eq_attr "prefix" "evex")
660               (and (ior (eq_attr "prefix" "maybe_evex")
661                         (eq_attr "prefix" "maybe_vex"))
662                    (match_test "TARGET_AVX512F")))
663            (plus (attr "length_evex")
664                  (plus (attr "length_immediate")
665                        (plus (attr "modrm")
666                              (attr "length_address"))))
667          (ior (eq_attr "prefix" "vex")
668               (and (ior (eq_attr "prefix" "maybe_vex")
669                         (eq_attr "prefix" "maybe_evex"))
670                    (match_test "TARGET_AVX")))
671            (plus (attr "length_vex")
672                  (plus (attr "length_immediate")
673                        (plus (attr "modrm")
674                              (attr "length_address"))))]
675          (plus (plus (attr "modrm")
676                      (plus (attr "prefix_0f")
677                            (plus (attr "prefix_rex")
678                                  (plus (attr "prefix_extra")
679                                        (const_int 1)))))
680                (plus (attr "prefix_rep")
681                      (plus (attr "prefix_data16")
682                            (plus (attr "length_immediate")
683                                  (attr "length_address")))))))
685 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
686 ;; `store' if there is a simple memory reference therein, or `unknown'
687 ;; if the instruction is complex.
689 (define_attr "memory" "none,load,store,both,unknown"
690   (cond [(eq_attr "type" "other,multi,str,lwp")
691            (const_string "unknown")
692          (eq_attr "type" "lea,fcmov,fpspc")
693            (const_string "none")
694          (eq_attr "type" "fistp,leave")
695            (const_string "both")
696          (eq_attr "type" "frndint")
697            (const_string "load")
698          (eq_attr "type" "push")
699            (if_then_else (match_operand 1 "memory_operand")
700              (const_string "both")
701              (const_string "store"))
702          (eq_attr "type" "pop")
703            (if_then_else (match_operand 0 "memory_operand")
704              (const_string "both")
705              (const_string "load"))
706          (eq_attr "type" "setcc")
707            (if_then_else (match_operand 0 "memory_operand")
708              (const_string "store")
709              (const_string "none"))
710          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
711            (if_then_else (ior (match_operand 0 "memory_operand")
712                               (match_operand 1 "memory_operand"))
713              (const_string "load")
714              (const_string "none"))
715          (eq_attr "type" "ibr")
716            (if_then_else (match_operand 0 "memory_operand")
717              (const_string "load")
718              (const_string "none"))
719          (eq_attr "type" "call")
720            (if_then_else (match_operand 0 "constant_call_address_operand")
721              (const_string "none")
722              (const_string "load"))
723          (eq_attr "type" "callv")
724            (if_then_else (match_operand 1 "constant_call_address_operand")
725              (const_string "none")
726              (const_string "load"))
727          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
728               (match_operand 1 "memory_operand"))
729            (const_string "both")
730          (and (match_operand 0 "memory_operand")
731               (match_operand 1 "memory_operand"))
732            (const_string "both")
733          (match_operand 0 "memory_operand")
734            (const_string "store")
735          (match_operand 1 "memory_operand")
736            (const_string "load")
737          (and (eq_attr "type"
738                  "!alu1,negnot,ishift1,rotate1,
739                    imov,imovx,icmp,test,bitmanip,
740                    fmov,fcmp,fsgn,
741                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
742                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
743                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
744               (match_operand 2 "memory_operand"))
745            (const_string "load")
746          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
747               (match_operand 3 "memory_operand"))
748            (const_string "load")
749         ]
750         (const_string "none")))
752 ;; Indicates if an instruction has both an immediate and a displacement.
754 (define_attr "imm_disp" "false,true,unknown"
755   (cond [(eq_attr "type" "other,multi")
756            (const_string "unknown")
757          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
758               (and (match_operand 0 "memory_displacement_operand")
759                    (match_operand 1 "immediate_operand")))
760            (const_string "true")
761          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
762               (and (match_operand 0 "memory_displacement_operand")
763                    (match_operand 2 "immediate_operand")))
764            (const_string "true")
765         ]
766         (const_string "false")))
768 ;; Indicates if an FP operation has an integer source.
770 (define_attr "fp_int_src" "false,true"
771   (const_string "false"))
773 ;; Defines rounding mode of an FP operation.
775 (define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
776   (const_string "any"))
778 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
779 (define_attr "use_carry" "0,1" (const_string "0"))
781 ;; Define attribute to indicate unaligned ssemov insns
782 (define_attr "movu" "0,1" (const_string "0"))
784 ;; Used to control the "enabled" attribute on a per-instruction basis.
785 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
786                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
787                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
788                     avx512bw,noavx512bw,avx512dq,noavx512dq,
789                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
790   (const_string "base"))
792 (define_attr "enabled" ""
793   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
794          (eq_attr "isa" "x64_sse2")
795            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
796          (eq_attr "isa" "x64_sse4")
797            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
798          (eq_attr "isa" "x64_sse4_noavx")
799            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
800          (eq_attr "isa" "x64_avx")
801            (symbol_ref "TARGET_64BIT && TARGET_AVX")
802          (eq_attr "isa" "x64_avx512dq")
803            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
804          (eq_attr "isa" "x64_avx512bw")
805            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
806          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
807          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
808          (eq_attr "isa" "sse2_noavx")
809            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
810          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
811          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
812          (eq_attr "isa" "sse4_noavx")
813            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
814          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
815          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
816          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
817          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
818          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
819          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
820          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
821          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
822          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
823          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
824          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
825          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
826          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
827          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
828          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
829          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
830         ]
831         (const_int 1)))
833 (define_attr "preferred_for_size" "" (const_int 1))
834 (define_attr "preferred_for_speed" "" (const_int 1))
836 ;; Describe a user's asm statement.
837 (define_asm_attributes
838   [(set_attr "length" "128")
839    (set_attr "type" "multi")])
841 (define_code_iterator plusminus [plus minus])
843 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
845 (define_code_iterator multdiv [mult div])
847 ;; Base name for define_insn
848 (define_code_attr plusminus_insn
849   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
850    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
852 ;; Base name for insn mnemonic.
853 (define_code_attr plusminus_mnemonic
854   [(plus "add") (ss_plus "adds") (us_plus "addus")
855    (minus "sub") (ss_minus "subs") (us_minus "subus")])
856 (define_code_attr multdiv_mnemonic
857   [(mult "mul") (div "div")])
859 ;; Mark commutative operators as such in constraints.
860 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
861                         (minus "") (ss_minus "") (us_minus "")])
863 ;; Mapping of max and min
864 (define_code_iterator maxmin [smax smin umax umin])
866 ;; Mapping of signed max and min
867 (define_code_iterator smaxmin [smax smin])
869 ;; Mapping of unsigned max and min
870 (define_code_iterator umaxmin [umax umin])
872 ;; Base name for integer and FP insn mnemonic
873 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
874                               (umax "maxu") (umin "minu")])
875 (define_code_attr maxmin_float [(smax "max") (smin "min")])
877 (define_int_iterator IEEE_MAXMIN
878         [UNSPEC_IEEE_MAX
879          UNSPEC_IEEE_MIN])
881 (define_int_attr ieee_maxmin
882         [(UNSPEC_IEEE_MAX "max")
883          (UNSPEC_IEEE_MIN "min")])
885 ;; Mapping of logic operators
886 (define_code_iterator any_logic [and ior xor])
887 (define_code_iterator any_or [ior xor])
888 (define_code_iterator fpint_logic [and xor])
890 ;; Base name for insn mnemonic.
891 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
893 ;; Mapping of logic-shift operators
894 (define_code_iterator any_lshift [ashift lshiftrt])
896 ;; Mapping of shift-right operators
897 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
899 ;; Mapping of all shift operators
900 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
902 ;; Base name for define_insn
903 (define_code_attr shift_insn
904   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
906 ;; Base name for insn mnemonic.
907 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
908 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
910 ;; Mapping of rotate operators
911 (define_code_iterator any_rotate [rotate rotatert])
913 ;; Base name for define_insn
914 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
916 ;; Base name for insn mnemonic.
917 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
919 ;; Mapping of abs neg operators
920 (define_code_iterator absneg [abs neg])
922 ;; Base name for x87 insn mnemonic.
923 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
925 ;; Used in signed and unsigned widening multiplications.
926 (define_code_iterator any_extend [sign_extend zero_extend])
928 ;; Prefix for insn menmonic.
929 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
931 ;; Prefix for define_insn
932 (define_code_attr u [(sign_extend "") (zero_extend "u")])
933 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
934 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
936 ;; Used in signed and unsigned truncations.
937 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
938 ;; Instruction suffix for truncations.
939 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
941 ;; Used in signed and unsigned fix.
942 (define_code_iterator any_fix [fix unsigned_fix])
943 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
944 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
945 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
947 ;; Used in signed and unsigned float.
948 (define_code_iterator any_float [float unsigned_float])
949 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
950 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
951 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
953 ;; All integer modes.
954 (define_mode_iterator SWI1248x [QI HI SI DI])
956 ;; All integer modes without QImode.
957 (define_mode_iterator SWI248x [HI SI DI])
959 ;; All integer modes without QImode and HImode.
960 (define_mode_iterator SWI48x [SI DI])
962 ;; All integer modes without SImode and DImode.
963 (define_mode_iterator SWI12 [QI HI])
965 ;; All integer modes without DImode.
966 (define_mode_iterator SWI124 [QI HI SI])
968 ;; All integer modes without QImode and DImode.
969 (define_mode_iterator SWI24 [HI SI])
971 ;; Single word integer modes.
972 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
974 ;; Single word integer modes without QImode.
975 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
977 ;; Single word integer modes without QImode and HImode.
978 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
980 ;; All math-dependant single and double word integer modes.
981 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
982                              (HI "TARGET_HIMODE_MATH")
983                              SI DI (TI "TARGET_64BIT")])
985 ;; Math-dependant single word integer modes.
986 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
987                             (HI "TARGET_HIMODE_MATH")
988                             SI (DI "TARGET_64BIT")])
990 ;; Math-dependant integer modes without DImode.
991 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
992                                (HI "TARGET_HIMODE_MATH")
993                                SI])
995 ;; Math-dependant integer modes with DImode.
996 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
997                                  (HI "TARGET_HIMODE_MATH")
998                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1000 ;; Math-dependant single word integer modes without QImode.
1001 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1002                                SI (DI "TARGET_64BIT")])
1004 ;; Double word integer modes.
1005 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1006                            (TI "TARGET_64BIT")])
1008 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1009 ;; compile time constant, it is faster to use <MODE_SIZE> than
1010 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1011 ;; command line options just use GET_MODE_SIZE macro.
1012 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1013                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1014                              (V16QI "16") (V32QI "32") (V64QI "64")
1015                              (V8HI "16") (V16HI "32") (V32HI "64")
1016                              (V4SI "16") (V8SI "32") (V16SI "64")
1017                              (V2DI "16") (V4DI "32") (V8DI "64")
1018                              (V1TI "16") (V2TI "32") (V4TI "64")
1019                              (V2DF "16") (V4DF "32") (V8DF "64")
1020                              (V4SF "16") (V8SF "32") (V16SF "64")])
1022 ;; Double word integer modes as mode attribute.
1023 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1024 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1026 ;; LEA mode corresponding to an integer mode
1027 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1029 ;; Half mode for double word integer modes.
1030 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1031                             (DI "TARGET_64BIT")])
1033 ;; Instruction suffix for integer modes.
1034 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1036 ;; Instruction suffix for masks.
1037 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1039 ;; Pointer size prefix for integer modes (Intel asm dialect)
1040 (define_mode_attr iptrsize [(QI "BYTE")
1041                             (HI "WORD")
1042                             (SI "DWORD")
1043                             (DI "QWORD")])
1045 ;; Register class for integer modes.
1046 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1048 ;; Immediate operand constraint for integer modes.
1049 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1051 ;; General operand constraint for word modes.
1052 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1054 ;; Immediate operand constraint for double integer modes.
1055 (define_mode_attr di [(SI "nF") (DI "Wd")])
1057 ;; Immediate operand constraint for shifts.
1058 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1060 ;; Print register name in the specified mode.
1061 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1063 ;; General operand predicate for integer modes.
1064 (define_mode_attr general_operand
1065         [(QI "general_operand")
1066          (HI "general_operand")
1067          (SI "x86_64_general_operand")
1068          (DI "x86_64_general_operand")
1069          (TI "x86_64_general_operand")])
1071 ;; General operand predicate for integer modes, where for TImode
1072 ;; we need both words of the operand to be general operands.
1073 (define_mode_attr general_hilo_operand
1074         [(QI "general_operand")
1075          (HI "general_operand")
1076          (SI "x86_64_general_operand")
1077          (DI "x86_64_general_operand")
1078          (TI "x86_64_hilo_general_operand")])
1080 ;; General sign extend operand predicate for integer modes,
1081 ;; which disallows VOIDmode operands and thus it is suitable
1082 ;; for use inside sign_extend.
1083 (define_mode_attr general_sext_operand
1084         [(QI "sext_operand")
1085          (HI "sext_operand")
1086          (SI "x86_64_sext_operand")
1087          (DI "x86_64_sext_operand")])
1089 ;; General sign/zero extend operand predicate for integer modes.
1090 (define_mode_attr general_szext_operand
1091         [(QI "general_operand")
1092          (HI "general_operand")
1093          (SI "x86_64_szext_general_operand")
1094          (DI "x86_64_szext_general_operand")])
1096 ;; Immediate operand predicate for integer modes.
1097 (define_mode_attr immediate_operand
1098         [(QI "immediate_operand")
1099          (HI "immediate_operand")
1100          (SI "x86_64_immediate_operand")
1101          (DI "x86_64_immediate_operand")])
1103 ;; Nonmemory operand predicate for integer modes.
1104 (define_mode_attr nonmemory_operand
1105         [(QI "nonmemory_operand")
1106          (HI "nonmemory_operand")
1107          (SI "x86_64_nonmemory_operand")
1108          (DI "x86_64_nonmemory_operand")])
1110 ;; Operand predicate for shifts.
1111 (define_mode_attr shift_operand
1112         [(QI "nonimmediate_operand")
1113          (HI "nonimmediate_operand")
1114          (SI "nonimmediate_operand")
1115          (DI "shiftdi_operand")
1116          (TI "register_operand")])
1118 ;; Operand predicate for shift argument.
1119 (define_mode_attr shift_immediate_operand
1120         [(QI "const_1_to_31_operand")
1121          (HI "const_1_to_31_operand")
1122          (SI "const_1_to_31_operand")
1123          (DI "const_1_to_63_operand")])
1125 ;; Input operand predicate for arithmetic left shifts.
1126 (define_mode_attr ashl_input_operand
1127         [(QI "nonimmediate_operand")
1128          (HI "nonimmediate_operand")
1129          (SI "nonimmediate_operand")
1130          (DI "ashldi_input_operand")
1131          (TI "reg_or_pm1_operand")])
1133 ;; SSE and x87 SFmode and DFmode floating point modes
1134 (define_mode_iterator MODEF [SF DF])
1136 ;; All x87 floating point modes
1137 (define_mode_iterator X87MODEF [SF DF XF])
1139 ;; SSE instruction suffix for various modes
1140 (define_mode_attr ssemodesuffix
1141   [(SF "ss") (DF "sd")
1142    (V16SF "ps") (V8DF "pd")
1143    (V8SF "ps") (V4DF "pd")
1144    (V4SF "ps") (V2DF "pd")
1145    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1146    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1147    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1149 ;; SSE vector suffix for floating point modes
1150 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1152 ;; SSE vector mode corresponding to a scalar mode
1153 (define_mode_attr ssevecmode
1154   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1155 (define_mode_attr ssevecmodelower
1156   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1158 ;; AVX512F vector mode corresponding to a scalar mode
1159 (define_mode_attr avx512fvecmode
1160   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1162 ;; Instruction suffix for REX 64bit operators.
1163 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1164 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1166 ;; This mode iterator allows :P to be used for patterns that operate on
1167 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1168 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1170 ;; This mode iterator allows :W to be used for patterns that operate on
1171 ;; word_mode sized quantities.
1172 (define_mode_iterator W
1173   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1175 ;; This mode iterator allows :PTR to be used for patterns that operate on
1176 ;; ptr_mode sized quantities.
1177 (define_mode_iterator PTR
1178   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1180 ;; Scheduling descriptions
1182 (include "pentium.md")
1183 (include "ppro.md")
1184 (include "k6.md")
1185 (include "athlon.md")
1186 (include "bdver1.md")
1187 (include "bdver3.md")
1188 (include "btver2.md")
1189 (include "znver1.md")
1190 (include "geode.md")
1191 (include "atom.md")
1192 (include "slm.md")
1193 (include "glm.md")
1194 (include "core2.md")
1195 (include "haswell.md")
1198 ;; Operand and operator predicates and constraints
1200 (include "predicates.md")
1201 (include "constraints.md")
1204 ;; Compare and branch/compare and store instructions.
1206 (define_expand "cbranch<mode>4"
1207   [(set (reg:CC FLAGS_REG)
1208         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1209                     (match_operand:SDWIM 2 "<general_operand>")))
1210    (set (pc) (if_then_else
1211                (match_operator 0 "ordered_comparison_operator"
1212                 [(reg:CC FLAGS_REG) (const_int 0)])
1213                (label_ref (match_operand 3))
1214                (pc)))]
1215   ""
1217   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1218     operands[1] = force_reg (<MODE>mode, operands[1]);
1219   ix86_expand_branch (GET_CODE (operands[0]),
1220                       operands[1], operands[2], operands[3]);
1221   DONE;
1224 (define_expand "cstore<mode>4"
1225   [(set (reg:CC FLAGS_REG)
1226         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1227                     (match_operand:SWIM 3 "<general_operand>")))
1228    (set (match_operand:QI 0 "register_operand")
1229         (match_operator 1 "ordered_comparison_operator"
1230           [(reg:CC FLAGS_REG) (const_int 0)]))]
1231   ""
1233   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1234     operands[2] = force_reg (<MODE>mode, operands[2]);
1235   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1236                      operands[2], operands[3]);
1237   DONE;
1240 (define_expand "cmp<mode>_1"
1241   [(set (reg:CC FLAGS_REG)
1242         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1243                     (match_operand:SWI48 1 "<general_operand>")))])
1245 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1246   [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1247    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1249 (define_insn "*cmp<mode>_ccz_1"
1250   [(set (reg FLAGS_REG)
1251         (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1252                         "nonimmediate_operand" "<r>,?m<r>,$k")
1253                  (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1254   "ix86_match_ccmode (insn, CCZmode)"
1255   "@
1256    test{<imodesuffix>}\t%0, %0
1257    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1258    ktest<mskmodesuffix>\t%0, %0"
1259   [(set_attr "type" "test,icmp,msklog")
1260    (set_attr "length_immediate" "0,1,*")
1261    (set_attr "prefix" "*,*,vex")
1262    (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmp<mode>_ccno_1"
1265   [(set (reg FLAGS_REG)
1266         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1267                  (match_operand:SWI 1 "const0_operand")))]
1268   "ix86_match_ccmode (insn, CCNOmode)"
1269   "@
1270    test{<imodesuffix>}\t%0, %0
1271    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1272   [(set_attr "type" "test,icmp")
1273    (set_attr "length_immediate" "0,1")
1274    (set_attr "mode" "<MODE>")])
1276 (define_insn "*cmp<mode>_1"
1277   [(set (reg FLAGS_REG)
1278         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1279                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1280   "ix86_match_ccmode (insn, CCmode)"
1281   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1282   [(set_attr "type" "icmp")
1283    (set_attr "mode" "<MODE>")])
1285 (define_insn "*cmp<mode>_minus_1"
1286   [(set (reg FLAGS_REG)
1287         (compare
1288           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1289                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1290           (const_int 0)))]
1291   "ix86_match_ccmode (insn, CCGOCmode)"
1292   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1293   [(set_attr "type" "icmp")
1294    (set_attr "mode" "<MODE>")])
1296 (define_insn "*cmpqi_ext_1"
1297   [(set (reg FLAGS_REG)
1298         (compare
1299           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1300           (subreg:QI
1301             (zero_extract:SI
1302               (match_operand 1 "ext_register_operand" "Q,Q")
1303               (const_int 8)
1304               (const_int 8)) 0)))]
1305   "ix86_match_ccmode (insn, CCmode)"
1306   "cmp{b}\t{%h1, %0|%0, %h1}"
1307   [(set_attr "isa" "*,nox64")
1308    (set_attr "type" "icmp")
1309    (set_attr "mode" "QI")])
1311 (define_insn "*cmpqi_ext_2"
1312   [(set (reg FLAGS_REG)
1313         (compare
1314           (subreg:QI
1315             (zero_extract:SI
1316               (match_operand 0 "ext_register_operand" "Q")
1317               (const_int 8)
1318               (const_int 8)) 0)
1319           (match_operand:QI 1 "const0_operand")))]
1320   "ix86_match_ccmode (insn, CCNOmode)"
1321   "test{b}\t%h0, %h0"
1322   [(set_attr "type" "test")
1323    (set_attr "length_immediate" "0")
1324    (set_attr "mode" "QI")])
1326 (define_expand "cmpqi_ext_3"
1327   [(set (reg:CC FLAGS_REG)
1328         (compare:CC
1329           (subreg:QI
1330             (zero_extract:SI
1331               (match_operand 0 "ext_register_operand")
1332               (const_int 8)
1333               (const_int 8)) 0)
1334           (match_operand:QI 1 "const_int_operand")))])
1336 (define_insn "*cmpqi_ext_3"
1337   [(set (reg FLAGS_REG)
1338         (compare
1339           (subreg:QI
1340             (zero_extract:SI
1341               (match_operand 0 "ext_register_operand" "Q,Q")
1342               (const_int 8)
1343               (const_int 8)) 0)
1344           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1345   "ix86_match_ccmode (insn, CCmode)"
1346   "cmp{b}\t{%1, %h0|%h0, %1}"
1347   [(set_attr "isa" "*,nox64")
1348    (set_attr "type" "icmp")
1349    (set_attr "mode" "QI")])
1351 (define_insn "*cmpqi_ext_4"
1352   [(set (reg FLAGS_REG)
1353         (compare
1354           (subreg:QI
1355             (zero_extract:SI
1356               (match_operand 0 "ext_register_operand" "Q")
1357               (const_int 8)
1358               (const_int 8)) 0)
1359           (subreg:QI
1360             (zero_extract:SI
1361               (match_operand 1 "ext_register_operand" "Q")
1362               (const_int 8)
1363               (const_int 8)) 0)))]
1364   "ix86_match_ccmode (insn, CCmode)"
1365   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1366   [(set_attr "type" "icmp")
1367    (set_attr "mode" "QI")])
1369 ;; These implement float point compares.
1370 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1371 ;; which would allow mix and match FP modes on the compares.  Which is what
1372 ;; the old patterns did, but with many more of them.
1374 (define_expand "cbranchxf4"
1375   [(set (reg:CC FLAGS_REG)
1376         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1377                     (match_operand:XF 2 "nonmemory_operand")))
1378    (set (pc) (if_then_else
1379               (match_operator 0 "ix86_fp_comparison_operator"
1380                [(reg:CC FLAGS_REG)
1381                 (const_int 0)])
1382               (label_ref (match_operand 3))
1383               (pc)))]
1384   "TARGET_80387"
1386   ix86_expand_branch (GET_CODE (operands[0]),
1387                       operands[1], operands[2], operands[3]);
1388   DONE;
1391 (define_expand "cstorexf4"
1392   [(set (reg:CC FLAGS_REG)
1393         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1394                     (match_operand:XF 3 "nonmemory_operand")))
1395    (set (match_operand:QI 0 "register_operand")
1396               (match_operator 1 "ix86_fp_comparison_operator"
1397                [(reg:CC FLAGS_REG)
1398                 (const_int 0)]))]
1399   "TARGET_80387"
1401   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1402                      operands[2], operands[3]);
1403   DONE;
1406 (define_expand "cbranch<mode>4"
1407   [(set (reg:CC FLAGS_REG)
1408         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1409                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1410    (set (pc) (if_then_else
1411               (match_operator 0 "ix86_fp_comparison_operator"
1412                [(reg:CC FLAGS_REG)
1413                 (const_int 0)])
1414               (label_ref (match_operand 3))
1415               (pc)))]
1416   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1418   ix86_expand_branch (GET_CODE (operands[0]),
1419                       operands[1], operands[2], operands[3]);
1420   DONE;
1423 (define_expand "cstore<mode>4"
1424   [(set (reg:CC FLAGS_REG)
1425         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1426                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1427    (set (match_operand:QI 0 "register_operand")
1428               (match_operator 1 "ix86_fp_comparison_operator"
1429                [(reg:CC FLAGS_REG)
1430                 (const_int 0)]))]
1431   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1433   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1434                      operands[2], operands[3]);
1435   DONE;
1438 (define_expand "cbranchcc4"
1439   [(set (pc) (if_then_else
1440               (match_operator 0 "comparison_operator"
1441                [(match_operand 1 "flags_reg_operand")
1442                 (match_operand 2 "const0_operand")])
1443               (label_ref (match_operand 3))
1444               (pc)))]
1445   ""
1447   ix86_expand_branch (GET_CODE (operands[0]),
1448                       operands[1], operands[2], operands[3]);
1449   DONE;
1452 (define_expand "cstorecc4"
1453   [(set (match_operand:QI 0 "register_operand")
1454               (match_operator 1 "comparison_operator"
1455                [(match_operand 2 "flags_reg_operand")
1456                 (match_operand 3 "const0_operand")]))]
1457   ""
1459   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1460                      operands[2], operands[3]);
1461   DONE;
1464 ;; FP compares, step 1:
1465 ;; Set the FP condition codes and move fpsr to ax.
1467 ;; We may not use "#" to split and emit these
1468 ;; due to reg-stack pops killing fpsr.
1470 (define_insn "*cmpxf_i387"
1471   [(set (match_operand:HI 0 "register_operand" "=a")
1472         (unspec:HI
1473           [(compare:CCFP
1474              (match_operand:XF 1 "register_operand" "f")
1475              (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1476           UNSPEC_FNSTSW))]
1477   "TARGET_80387"
1478   "* return output_fp_compare (insn, operands, false, false);"
1479   [(set_attr "type" "multi")
1480    (set_attr "unit" "i387")
1481    (set_attr "mode" "XF")])
1483 (define_insn "*cmp<mode>_i387"
1484   [(set (match_operand:HI 0 "register_operand" "=a")
1485         (unspec:HI
1486           [(compare:CCFP
1487              (match_operand:MODEF 1 "register_operand" "f")
1488              (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1489           UNSPEC_FNSTSW))]
1490   "TARGET_80387"
1491   "* return output_fp_compare (insn, operands, false, false);"
1492   [(set_attr "type" "multi")
1493    (set_attr "unit" "i387")
1494    (set_attr "mode" "<MODE>")])
1496 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1497   [(set (match_operand:HI 0 "register_operand" "=a")
1498         (unspec:HI
1499           [(compare:CCFP
1500              (match_operand:X87MODEF 1 "register_operand" "f")
1501              (float:X87MODEF
1502                (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1503           UNSPEC_FNSTSW))]
1504   "TARGET_80387
1505    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1506        || optimize_function_for_size_p (cfun))"
1507   "* return output_fp_compare (insn, operands, false, false);"
1508   [(set_attr "type" "multi")
1509    (set_attr "unit" "i387")
1510    (set_attr "fp_int_src" "true")
1511    (set_attr "mode" "<SWI24:MODE>")])
1513 (define_insn "*cmpu<mode>_i387"
1514   [(set (match_operand:HI 0 "register_operand" "=a")
1515         (unspec:HI
1516           [(unspec:CCFP
1517              [(compare:CCFP
1518                 (match_operand:X87MODEF 1 "register_operand" "f")
1519                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1520              UNSPEC_NOTRAP)]
1521           UNSPEC_FNSTSW))]
1522   "TARGET_80387"
1523   "* return output_fp_compare (insn, operands, false, true);"
1524   [(set_attr "type" "multi")
1525    (set_attr "unit" "i387")
1526    (set_attr "mode" "<MODE>")])
1528 ;; FP compares, step 2:
1529 ;; Get ax into flags, general case.
1531 (define_insn "x86_sahf_1"
1532   [(set (reg:CC FLAGS_REG)
1533         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1534                    UNSPEC_SAHF))]
1535   "TARGET_SAHF"
1537 #ifndef HAVE_AS_IX86_SAHF
1538   if (TARGET_64BIT)
1539     return ASM_BYTE "0x9e";
1540   else
1541 #endif
1542   return "sahf";
1544   [(set_attr "length" "1")
1545    (set_attr "athlon_decode" "vector")
1546    (set_attr "amdfam10_decode" "direct")
1547    (set_attr "bdver1_decode" "direct")
1548    (set_attr "mode" "SI")])
1550 ;; Pentium Pro can do both steps in one go.
1551 ;; (these instructions set flags directly)
1553 (define_subst_attr "unord" "unord_subst" "" "u")
1554 (define_subst_attr "unordered" "unord_subst" "false" "true")
1556 (define_subst "unord_subst"
1557   [(set (match_operand:CCFP 0)
1558         (match_operand:CCFP 1))]
1559   ""
1560   [(set (match_dup 0)
1561         (unspec:CCFP
1562           [(match_dup 1)]
1563           UNSPEC_NOTRAP))])
1565 (define_insn "*cmpi<unord>xf_i387"
1566   [(set (reg:CCFP FLAGS_REG)
1567         (compare:CCFP
1568           (match_operand:XF 0 "register_operand" "f")
1569           (match_operand:XF 1 "register_operand" "f")))]
1570   "TARGET_80387 && TARGET_CMOVE"
1571   "* return output_fp_compare (insn, operands, true, <unordered>);"
1572   [(set_attr "type" "fcmp")
1573    (set_attr "mode" "XF")
1574    (set_attr "athlon_decode" "vector")
1575    (set_attr "amdfam10_decode" "direct")
1576    (set_attr "bdver1_decode" "double")
1577    (set_attr "znver1_decode" "double")])
1579 (define_insn "*cmpi<unord><MODEF:mode>"
1580   [(set (reg:CCFP FLAGS_REG)
1581         (compare:CCFP
1582           (match_operand:MODEF 0 "register_operand" "f,v")
1583           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1584   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1585    || (TARGET_80387 && TARGET_CMOVE)"
1586   "@
1587    * return output_fp_compare (insn, operands, true, <unordered>);
1588    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1589   [(set_attr "type" "fcmp,ssecomi")
1590    (set_attr "prefix" "orig,maybe_vex")
1591    (set_attr "mode" "<MODEF:MODE>")
1592    (set_attr "prefix_rep" "*,0")
1593    (set (attr "prefix_data16")
1594         (cond [(eq_attr "alternative" "0")
1595                  (const_string "*")
1596                (eq_attr "mode" "DF")
1597                  (const_string "1")
1598               ]
1599               (const_string "0")))
1600    (set_attr "athlon_decode" "vector")
1601    (set_attr "amdfam10_decode" "direct")
1602    (set_attr "bdver1_decode" "double")
1603    (set_attr "znver1_decode" "double")
1604    (set (attr "enabled")
1605      (if_then_else
1606        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1607        (if_then_else
1608          (eq_attr "alternative" "0")
1609          (symbol_ref "TARGET_MIX_SSE_I387")
1610          (symbol_ref "true"))
1611        (if_then_else
1612          (eq_attr "alternative" "0")
1613          (symbol_ref "true")
1614          (symbol_ref "false"))))])
1616 ;; Push/pop instructions.
1618 (define_insn "*push<mode>2"
1619   [(set (match_operand:DWI 0 "push_operand" "=<")
1620         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1621   ""
1622   "#"
1623   [(set_attr "type" "multi")
1624    (set_attr "mode" "<MODE>")])
1626 (define_split
1627   [(set (match_operand:DWI 0 "push_operand")
1628         (match_operand:DWI 1 "general_gr_operand"))]
1629   "reload_completed"
1630   [(const_int 0)]
1631   "ix86_split_long_move (operands); DONE;")
1633 (define_insn "*pushdi2_rex64"
1634   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1635         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1636   "TARGET_64BIT"
1637   "@
1638    push{q}\t%1
1639    #"
1640   [(set_attr "type" "push,multi")
1641    (set_attr "mode" "DI")])
1643 ;; Convert impossible pushes of immediate to existing instructions.
1644 ;; First try to get scratch register and go through it.  In case this
1645 ;; fails, push sign extended lower part first and then overwrite
1646 ;; upper part by 32bit move.
1647 (define_peephole2
1648   [(match_scratch:DI 2 "r")
1649    (set (match_operand:DI 0 "push_operand")
1650         (match_operand:DI 1 "immediate_operand"))]
1651   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1652    && !x86_64_immediate_operand (operands[1], DImode)"
1653   [(set (match_dup 2) (match_dup 1))
1654    (set (match_dup 0) (match_dup 2))])
1656 ;; We need to define this as both peepholer and splitter for case
1657 ;; peephole2 pass is not run.
1658 ;; "&& 1" is needed to keep it from matching the previous pattern.
1659 (define_peephole2
1660   [(set (match_operand:DI 0 "push_operand")
1661         (match_operand:DI 1 "immediate_operand"))]
1662   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1663    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1664   [(set (match_dup 0) (match_dup 1))
1665    (set (match_dup 2) (match_dup 3))]
1667   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1669   operands[1] = gen_lowpart (DImode, operands[2]);
1670   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1671                                                    GEN_INT (4)));
1674 (define_split
1675   [(set (match_operand:DI 0 "push_operand")
1676         (match_operand:DI 1 "immediate_operand"))]
1677   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1678                     ? epilogue_completed : reload_completed)
1679    && !symbolic_operand (operands[1], DImode)
1680    && !x86_64_immediate_operand (operands[1], DImode)"
1681   [(set (match_dup 0) (match_dup 1))
1682    (set (match_dup 2) (match_dup 3))]
1684   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1686   operands[1] = gen_lowpart (DImode, operands[2]);
1687   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1688                                                    GEN_INT (4)));
1691 (define_insn "*pushsi2"
1692   [(set (match_operand:SI 0 "push_operand" "=<")
1693         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1694   "!TARGET_64BIT"
1695   "push{l}\t%1"
1696   [(set_attr "type" "push")
1697    (set_attr "mode" "SI")])
1699 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1700 ;; "push a byte/word".  But actually we use pushl, which has the effect
1701 ;; of rounding the amount pushed up to a word.
1703 ;; For TARGET_64BIT we always round up to 8 bytes.
1704 (define_insn "*push<mode>2_rex64"
1705   [(set (match_operand:SWI124 0 "push_operand" "=X")
1706         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1707   "TARGET_64BIT"
1708   "push{q}\t%q1"
1709   [(set_attr "type" "push")
1710    (set_attr "mode" "DI")])
1712 (define_insn "*push<mode>2"
1713   [(set (match_operand:SWI12 0 "push_operand" "=X")
1714         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1715   "!TARGET_64BIT"
1716   "push{l}\t%k1"
1717   [(set_attr "type" "push")
1718    (set_attr "mode" "SI")])
1720 (define_insn "*push<mode>2_prologue"
1721   [(set (match_operand:W 0 "push_operand" "=<")
1722         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1723    (clobber (mem:BLK (scratch)))]
1724   ""
1725   "push{<imodesuffix>}\t%1"
1726   [(set_attr "type" "push")
1727    (set_attr "mode" "<MODE>")])
1729 (define_insn "*pop<mode>1"
1730   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1731         (match_operand:W 1 "pop_operand" ">"))]
1732   ""
1733   "pop{<imodesuffix>}\t%0"
1734   [(set_attr "type" "pop")
1735    (set_attr "mode" "<MODE>")])
1737 (define_insn "*pop<mode>1_epilogue"
1738   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1739         (match_operand:W 1 "pop_operand" ">"))
1740    (clobber (mem:BLK (scratch)))]
1741   ""
1742   "pop{<imodesuffix>}\t%0"
1743   [(set_attr "type" "pop")
1744    (set_attr "mode" "<MODE>")])
1746 (define_insn "*pushfl<mode>2"
1747   [(set (match_operand:W 0 "push_operand" "=<")
1748         (match_operand:W 1 "flags_reg_operand"))]
1749   ""
1750   "pushf{<imodesuffix>}"
1751   [(set_attr "type" "push")
1752    (set_attr "mode" "<MODE>")])
1754 (define_insn "*popfl<mode>1"
1755   [(set (match_operand:W 0 "flags_reg_operand")
1756         (match_operand:W 1 "pop_operand" ">"))]
1757   ""
1758   "popf{<imodesuffix>}"
1759   [(set_attr "type" "pop")
1760    (set_attr "mode" "<MODE>")])
1763 ;; Reload patterns to support multi-word load/store
1764 ;; with non-offsetable address.
1765 (define_expand "reload_noff_store"
1766   [(parallel [(match_operand 0 "memory_operand" "=m")
1767               (match_operand 1 "register_operand" "r")
1768               (match_operand:DI 2 "register_operand" "=&r")])]
1769   "TARGET_64BIT"
1771   rtx mem = operands[0];
1772   rtx addr = XEXP (mem, 0);
1774   emit_move_insn (operands[2], addr);
1775   mem = replace_equiv_address_nv (mem, operands[2]);
1777   emit_insn (gen_rtx_SET (mem, operands[1]));
1778   DONE;
1781 (define_expand "reload_noff_load"
1782   [(parallel [(match_operand 0 "register_operand" "=r")
1783               (match_operand 1 "memory_operand" "m")
1784               (match_operand:DI 2 "register_operand" "=r")])]
1785   "TARGET_64BIT"
1787   rtx mem = operands[1];
1788   rtx addr = XEXP (mem, 0);
1790   emit_move_insn (operands[2], addr);
1791   mem = replace_equiv_address_nv (mem, operands[2]);
1793   emit_insn (gen_rtx_SET (operands[0], mem));
1794   DONE;
1797 ;; Move instructions.
1799 (define_expand "movxi"
1800   [(set (match_operand:XI 0 "nonimmediate_operand")
1801         (match_operand:XI 1 "general_operand"))]
1802   "TARGET_AVX512F"
1803   "ix86_expand_vector_move (XImode, operands); DONE;")
1805 (define_expand "movoi"
1806   [(set (match_operand:OI 0 "nonimmediate_operand")
1807         (match_operand:OI 1 "general_operand"))]
1808   "TARGET_AVX"
1809   "ix86_expand_vector_move (OImode, operands); DONE;")
1811 (define_expand "movti"
1812   [(set (match_operand:TI 0 "nonimmediate_operand")
1813         (match_operand:TI 1 "general_operand"))]
1814   "TARGET_64BIT || TARGET_SSE"
1816   if (TARGET_64BIT)
1817     ix86_expand_move (TImode, operands);
1818   else
1819     ix86_expand_vector_move (TImode, operands);
1820   DONE;
1823 ;; This expands to what emit_move_complex would generate if we didn't
1824 ;; have a movti pattern.  Having this avoids problems with reload on
1825 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1826 ;; to have around all the time.
1827 (define_expand "movcdi"
1828   [(set (match_operand:CDI 0 "nonimmediate_operand")
1829         (match_operand:CDI 1 "general_operand"))]
1830   ""
1832   if (push_operand (operands[0], CDImode))
1833     emit_move_complex_push (CDImode, operands[0], operands[1]);
1834   else
1835     emit_move_complex_parts (operands[0], operands[1]);
1836   DONE;
1839 (define_expand "mov<mode>"
1840   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1841         (match_operand:SWI1248x 1 "general_operand"))]
1842   ""
1843   "ix86_expand_move (<MODE>mode, operands); DONE;")
1845 (define_insn "*mov<mode>_xor"
1846   [(set (match_operand:SWI48 0 "register_operand" "=r")
1847         (match_operand:SWI48 1 "const0_operand"))
1848    (clobber (reg:CC FLAGS_REG))]
1849   "reload_completed"
1850   "xor{l}\t%k0, %k0"
1851   [(set_attr "type" "alu1")
1852    (set_attr "mode" "SI")
1853    (set_attr "length_immediate" "0")])
1855 (define_insn "*mov<mode>_or"
1856   [(set (match_operand:SWI48 0 "register_operand" "=r")
1857         (match_operand:SWI48 1 "constm1_operand"))
1858    (clobber (reg:CC FLAGS_REG))]
1859   "reload_completed"
1860   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1861   [(set_attr "type" "alu1")
1862    (set_attr "mode" "<MODE>")
1863    (set_attr "length_immediate" "1")])
1865 (define_insn "*movxi_internal_avx512f"
1866   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
1867         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1868   "TARGET_AVX512F
1869    && (register_operand (operands[0], XImode)
1870        || register_operand (operands[1], XImode))"
1872   switch (get_attr_type (insn))
1873     {
1874     case TYPE_SSELOG1:
1875       return standard_sse_constant_opcode (insn, operands);
1877     case TYPE_SSEMOV:
1878       if (misaligned_operand (operands[0], XImode)
1879           || misaligned_operand (operands[1], XImode))
1880         return "vmovdqu32\t{%1, %0|%0, %1}";
1881       else
1882         return "vmovdqa32\t{%1, %0|%0, %1}";
1884     default:
1885       gcc_unreachable ();
1886     }
1888   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1889    (set_attr "prefix" "evex")
1890    (set_attr "mode" "XI")])
1892 (define_insn "*movoi_internal_avx"
1893   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
1894         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1895   "TARGET_AVX
1896    && (register_operand (operands[0], OImode)
1897        || register_operand (operands[1], OImode))"
1899   switch (get_attr_type (insn))
1900     {
1901     case TYPE_SSELOG1:
1902       return standard_sse_constant_opcode (insn, operands);
1904     case TYPE_SSEMOV:
1905       if (misaligned_operand (operands[0], OImode)
1906           || misaligned_operand (operands[1], OImode))
1907         {
1908           if (get_attr_mode (insn) == MODE_V8SF)
1909             return "vmovups\t{%1, %0|%0, %1}";
1910           else if (get_attr_mode (insn) == MODE_XI)
1911             return "vmovdqu32\t{%1, %0|%0, %1}";
1912           else
1913             return "vmovdqu\t{%1, %0|%0, %1}";
1914         }
1915       else
1916         {
1917           if (get_attr_mode (insn) == MODE_V8SF)
1918             return "vmovaps\t{%1, %0|%0, %1}";
1919           else if (get_attr_mode (insn) == MODE_XI)
1920             return "vmovdqa32\t{%1, %0|%0, %1}";
1921           else
1922             return "vmovdqa\t{%1, %0|%0, %1}";
1923         }
1925     default:
1926       gcc_unreachable ();
1927     }
1929   [(set_attr "isa" "*,avx2,*,*")
1930    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1931    (set_attr "prefix" "vex")
1932    (set (attr "mode")
1933         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1934                     (match_operand 1 "ext_sse_reg_operand"))
1935                  (const_string "XI")
1936                (and (eq_attr "alternative" "1")
1937                     (match_test "TARGET_AVX512VL"))
1938                  (const_string "XI")
1939                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1940                     (and (eq_attr "alternative" "3")
1941                          (match_test "TARGET_SSE_TYPELESS_STORES")))
1942                  (const_string "V8SF")
1943               ]
1944               (const_string "OI")))])
1946 (define_insn "*movti_internal"
1947   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1948         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
1949   "(TARGET_64BIT
1950     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1951    || (TARGET_SSE
1952        && nonimmediate_or_sse_const_operand (operands[1], TImode)
1953        && (register_operand (operands[0], TImode)
1954            || register_operand (operands[1], TImode)))"
1956   switch (get_attr_type (insn))
1957     {
1958     case TYPE_MULTI:
1959       return "#";
1961     case TYPE_SSELOG1:
1962       return standard_sse_constant_opcode (insn, operands);
1964     case TYPE_SSEMOV:
1965       /* TDmode values are passed as TImode on the stack.  Moving them
1966          to stack may result in unaligned memory access.  */
1967       if (misaligned_operand (operands[0], TImode)
1968           || misaligned_operand (operands[1], TImode))
1969         {
1970           if (get_attr_mode (insn) == MODE_V4SF)
1971             return "%vmovups\t{%1, %0|%0, %1}";
1972           else if (get_attr_mode (insn) == MODE_XI)
1973             return "vmovdqu32\t{%1, %0|%0, %1}";
1974           else
1975             return "%vmovdqu\t{%1, %0|%0, %1}";
1976         }
1977       else
1978         {
1979           if (get_attr_mode (insn) == MODE_V4SF)
1980             return "%vmovaps\t{%1, %0|%0, %1}";
1981           else if (get_attr_mode (insn) == MODE_XI)
1982             return "vmovdqa32\t{%1, %0|%0, %1}";
1983           else
1984             return "%vmovdqa\t{%1, %0|%0, %1}";
1985         }
1987     default:
1988       gcc_unreachable ();
1989     }
1991   [(set (attr "isa")
1992      (cond [(eq_attr "alternative" "0,1,6,7")
1993               (const_string "x64")
1994             (eq_attr "alternative" "3")
1995               (const_string "sse2")
1996            ]
1997            (const_string "*")))
1998    (set (attr "type")
1999      (cond [(eq_attr "alternative" "0,1,6,7")
2000               (const_string "multi")
2001             (eq_attr "alternative" "2,3")
2002               (const_string "sselog1")
2003            ]
2004            (const_string "ssemov")))
2005    (set (attr "prefix")
2006      (if_then_else (eq_attr "type" "sselog1,ssemov")
2007        (const_string "maybe_vex")
2008        (const_string "orig")))
2009    (set (attr "mode")
2010         (cond [(eq_attr "alternative" "0,1")
2011                  (const_string "DI")
2012                (ior (match_operand 0 "ext_sse_reg_operand")
2013                     (match_operand 1 "ext_sse_reg_operand"))
2014                  (const_string "XI")
2015                (and (eq_attr "alternative" "3")
2016                     (match_test "TARGET_AVX512VL"))
2017                  (const_string "XI")
2018                (ior (not (match_test "TARGET_SSE2"))
2019                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2020                          (and (eq_attr "alternative" "5")
2021                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2022                  (const_string "V4SF")
2023                (match_test "TARGET_AVX")
2024                  (const_string "TI")
2025                (match_test "optimize_function_for_size_p (cfun)")
2026                  (const_string "V4SF")
2027                ]
2028                (const_string "TI")))
2029    (set (attr "preferred_for_speed")
2030      (cond [(eq_attr "alternative" "6")
2031               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2032             (eq_attr "alternative" "7")
2033               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2034            ]
2035            (symbol_ref "true")))])
2037 (define_split
2038   [(set (match_operand:TI 0 "sse_reg_operand")
2039         (match_operand:TI 1 "general_reg_operand"))]
2040   "TARGET_64BIT && TARGET_SSE4_1
2041    && reload_completed"
2042   [(set (match_dup 2)
2043         (vec_merge:V2DI
2044           (vec_duplicate:V2DI (match_dup 3))
2045           (match_dup 2)
2046           (const_int 2)))]
2048   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2049   operands[3] = gen_highpart (DImode, operands[1]);
2051   emit_move_insn (gen_lowpart (DImode, operands[0]),
2052                   gen_lowpart (DImode, operands[1]));
2055 (define_insn "*movdi_internal"
2056   [(set (match_operand:DI 0 "nonimmediate_operand"
2057     "=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")
2058         (match_operand:DI 1 "general_operand"
2059     "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"))]
2060   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2062   switch (get_attr_type (insn))
2063     {
2064     case TYPE_MSKMOV:
2065       return "kmovq\t{%1, %0|%0, %1}";
2067     case TYPE_MULTI:
2068       return "#";
2070     case TYPE_MMX:
2071       return "pxor\t%0, %0";
2073     case TYPE_MMXMOV:
2074       /* Handle broken assemblers that require movd instead of movq.  */
2075       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2076           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2077         return "movd\t{%1, %0|%0, %1}";
2078       return "movq\t{%1, %0|%0, %1}";
2080     case TYPE_SSELOG1:
2081       return standard_sse_constant_opcode (insn, operands);
2083     case TYPE_SSEMOV:
2084       switch (get_attr_mode (insn))
2085         {
2086         case MODE_DI:
2087           /* Handle broken assemblers that require movd instead of movq.  */
2088           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2089               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2090             return "%vmovd\t{%1, %0|%0, %1}";
2091           return "%vmovq\t{%1, %0|%0, %1}";
2093         case MODE_TI:
2094           /* Handle AVX512 registers set.  */
2095           if (EXT_REX_SSE_REG_P (operands[0])
2096               || EXT_REX_SSE_REG_P (operands[1]))
2097             return "vmovdqa64\t{%1, %0|%0, %1}";
2098           return "%vmovdqa\t{%1, %0|%0, %1}";
2100         case MODE_V2SF:
2101           gcc_assert (!TARGET_AVX);
2102           return "movlps\t{%1, %0|%0, %1}";
2103         case MODE_V4SF:
2104           return "%vmovaps\t{%1, %0|%0, %1}";
2106         default:
2107           gcc_unreachable ();
2108         }
2110     case TYPE_SSECVT:
2111       if (SSE_REG_P (operands[0]))
2112         return "movq2dq\t{%1, %0|%0, %1}";
2113       else
2114         return "movdq2q\t{%1, %0|%0, %1}";
2116     case TYPE_LEA:
2117       return "lea{q}\t{%E1, %0|%0, %E1}";
2119     case TYPE_IMOV:
2120       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2121       if (get_attr_mode (insn) == MODE_SI)
2122         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2123       else if (which_alternative == 4)
2124         return "movabs{q}\t{%1, %0|%0, %1}";
2125       else if (ix86_use_lea_for_mov (insn, operands))
2126         return "lea{q}\t{%E1, %0|%0, %E1}";
2127       else
2128         return "mov{q}\t{%1, %0|%0, %1}";
2130     default:
2131       gcc_unreachable ();
2132     }
2134   [(set (attr "isa")
2135      (cond [(eq_attr "alternative" "0,1,17,18")
2136               (const_string "nox64")
2137             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2138               (const_string "x64")
2139             (eq_attr "alternative" "19,20")
2140               (const_string "x64_sse2")
2141             (eq_attr "alternative" "21,22")
2142               (const_string "sse2")
2143            ]
2144            (const_string "*")))
2145    (set (attr "type")
2146      (cond [(eq_attr "alternative" "0,1,17,18")
2147               (const_string "multi")
2148             (eq_attr "alternative" "6")
2149               (const_string "mmx")
2150             (eq_attr "alternative" "7,8,9,10,11")
2151               (const_string "mmxmov")
2152             (eq_attr "alternative" "12")
2153               (const_string "sselog1")
2154             (eq_attr "alternative" "13,14,15,16,19,20")
2155               (const_string "ssemov")
2156             (eq_attr "alternative" "21,22")
2157               (const_string "ssecvt")
2158             (eq_attr "alternative" "23,24,25,26")
2159               (const_string "mskmov")
2160             (and (match_operand 0 "register_operand")
2161                  (match_operand 1 "pic_32bit_operand"))
2162               (const_string "lea")
2163            ]
2164            (const_string "imov")))
2165    (set (attr "modrm")
2166      (if_then_else
2167        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2168        (const_string "0")
2169        (const_string "*")))
2170    (set (attr "length_immediate")
2171      (if_then_else
2172        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2173        (const_string "8")
2174        (const_string "*")))
2175    (set (attr "prefix_rex")
2176      (if_then_else
2177        (eq_attr "alternative" "10,11,19,20")
2178        (const_string "1")
2179        (const_string "*")))
2180    (set (attr "prefix")
2181      (if_then_else (eq_attr "type" "sselog1,ssemov")
2182        (const_string "maybe_vex")
2183        (const_string "orig")))
2184    (set (attr "prefix_data16")
2185      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2186        (const_string "1")
2187        (const_string "*")))
2188    (set (attr "mode")
2189      (cond [(eq_attr "alternative" "2")
2190               (const_string "SI")
2191             (eq_attr "alternative" "12,13")
2192               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2193                           (match_operand 1 "ext_sse_reg_operand"))
2194                        (const_string "TI")
2195                      (ior (not (match_test "TARGET_SSE2"))
2196                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2197                        (const_string "V4SF")
2198                      (match_test "TARGET_AVX")
2199                        (const_string "TI")
2200                      (match_test "optimize_function_for_size_p (cfun)")
2201                        (const_string "V4SF")
2202                     ]
2203                     (const_string "TI"))
2205             (and (eq_attr "alternative" "14,15,16")
2206                  (not (match_test "TARGET_SSE2")))
2207               (const_string "V2SF")
2208            ]
2209            (const_string "DI")))
2210    (set (attr "preferred_for_speed")
2211      (cond [(eq_attr "alternative" "10,17,19")
2212               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2213             (eq_attr "alternative" "11,18,20")
2214               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2215            ]
2216            (symbol_ref "true")))
2217    (set (attr "enabled")
2218      (cond [(eq_attr "alternative" "15")
2219               (if_then_else
2220                 (match_test "TARGET_STV && TARGET_SSE2")
2221                 (symbol_ref "false")
2222                 (const_string "*"))
2223             (eq_attr "alternative" "16")
2224               (if_then_else
2225                 (match_test "TARGET_STV && TARGET_SSE2")
2226                 (symbol_ref "true")
2227                 (symbol_ref "false"))
2228            ]
2229            (const_string "*")))])
2231 (define_split
2232   [(set (match_operand:<DWI> 0 "general_reg_operand")
2233         (match_operand:<DWI> 1 "sse_reg_operand"))]
2234   "TARGET_SSE4_1
2235    && reload_completed"
2236   [(set (match_dup 2)
2237         (vec_select:DWIH
2238           (match_dup 3)
2239           (parallel [(const_int 1)])))]
2241   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2242   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2244   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2245                   gen_lowpart (<MODE>mode, operands[1]));
2248 (define_split
2249   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2250         (match_operand:DWI 1 "general_gr_operand"))]
2251   "reload_completed"
2252   [(const_int 0)]
2253   "ix86_split_long_move (operands); DONE;")
2255 (define_split
2256   [(set (match_operand:DI 0 "sse_reg_operand")
2257         (match_operand:DI 1 "general_reg_operand"))]
2258   "!TARGET_64BIT && TARGET_SSE4_1
2259    && reload_completed"
2260   [(set (match_dup 2)
2261         (vec_merge:V4SI
2262           (vec_duplicate:V4SI (match_dup 3))
2263           (match_dup 2)
2264           (const_int 2)))]
2266   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2267   operands[3] = gen_highpart (SImode, operands[1]);
2269   emit_move_insn (gen_lowpart (SImode, operands[0]),
2270                   gen_lowpart (SImode, operands[1]));
2273 ;; movabsq $0x0012345678000000, %rax is longer
2274 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2275 (define_peephole2
2276   [(set (match_operand:DI 0 "register_operand")
2277         (match_operand:DI 1 "const_int_operand"))]
2278   "TARGET_64BIT
2279    && optimize_insn_for_size_p ()
2280    && LEGACY_INT_REG_P (operands[0])
2281    && !x86_64_immediate_operand (operands[1], DImode)
2282    && !x86_64_zext_immediate_operand (operands[1], DImode)
2283    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2284         & ~(HOST_WIDE_INT) 0xffffffff)
2285    && peep2_regno_dead_p (0, FLAGS_REG)"
2286   [(set (match_dup 0) (match_dup 1))
2287    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2288               (clobber (reg:CC FLAGS_REG))])]
2290   int shift = ctz_hwi (UINTVAL (operands[1]));
2291   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2292   operands[2] = gen_int_mode (shift, QImode);
2295 (define_insn "*movsi_internal"
2296   [(set (match_operand:SI 0 "nonimmediate_operand"
2297     "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2298         (match_operand:SI 1 "general_operand"
2299     "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k"))]
2300   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2302   switch (get_attr_type (insn))
2303     {
2304     case TYPE_SSELOG1:
2305       return standard_sse_constant_opcode (insn, operands);
2307     case TYPE_MSKMOV:
2308       return "kmovd\t{%1, %0|%0, %1}";
2310     case TYPE_SSEMOV:
2311       switch (get_attr_mode (insn))
2312         {
2313         case MODE_SI:
2314           return "%vmovd\t{%1, %0|%0, %1}";
2315         case MODE_TI:
2316           return "%vmovdqa\t{%1, %0|%0, %1}";
2317         case MODE_XI:
2318           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2320         case MODE_V4SF:
2321           return "%vmovaps\t{%1, %0|%0, %1}";
2323         case MODE_SF:
2324           gcc_assert (!TARGET_AVX);
2325           return "movss\t{%1, %0|%0, %1}";
2327         default:
2328           gcc_unreachable ();
2329         }
2331     case TYPE_MMX:
2332       return "pxor\t%0, %0";
2334     case TYPE_MMXMOV:
2335       switch (get_attr_mode (insn))
2336         {
2337         case MODE_DI:
2338           return "movq\t{%1, %0|%0, %1}";
2339         case MODE_SI:
2340           return "movd\t{%1, %0|%0, %1}";
2342         default:
2343           gcc_unreachable ();
2344         }
2346     case TYPE_LEA:
2347       return "lea{l}\t{%E1, %0|%0, %E1}";
2349     case TYPE_IMOV:
2350       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2351       if (ix86_use_lea_for_mov (insn, operands))
2352         return "lea{l}\t{%E1, %0|%0, %E1}";
2353       else
2354         return "mov{l}\t{%1, %0|%0, %1}";
2356     default:
2357       gcc_unreachable ();
2358     }
2360   [(set (attr "isa")
2361      (cond [(eq_attr "alternative" "12,13")
2362               (const_string "sse2")
2363            ]
2364            (const_string "*")))
2365    (set (attr "type")
2366      (cond [(eq_attr "alternative" "2")
2367               (const_string "mmx")
2368             (eq_attr "alternative" "3,4,5,6,7")
2369               (const_string "mmxmov")
2370             (eq_attr "alternative" "8")
2371               (const_string "sselog1")
2372             (eq_attr "alternative" "9,10,11,12,13")
2373               (const_string "ssemov")
2374             (eq_attr "alternative" "14,15,16")
2375               (const_string "mskmov")
2376             (and (match_operand 0 "register_operand")
2377                  (match_operand 1 "pic_32bit_operand"))
2378               (const_string "lea")
2379            ]
2380            (const_string "imov")))
2381    (set (attr "prefix")
2382      (if_then_else (eq_attr "type" "sselog1,ssemov")
2383        (const_string "maybe_vex")
2384        (const_string "orig")))
2385    (set (attr "prefix_data16")
2386      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2387        (const_string "1")
2388        (const_string "*")))
2389    (set (attr "mode")
2390      (cond [(eq_attr "alternative" "2,3")
2391               (const_string "DI")
2392             (eq_attr "alternative" "8,9")
2393               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2394                           (match_operand 1 "ext_sse_reg_operand"))
2395                        (const_string "XI")
2396                      (ior (not (match_test "TARGET_SSE2"))
2397                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2398                        (const_string "V4SF")
2399                      (match_test "TARGET_AVX")
2400                        (const_string "TI")
2401                      (match_test "optimize_function_for_size_p (cfun)")
2402                        (const_string "V4SF")
2403                     ]
2404                     (const_string "TI"))
2406             (and (eq_attr "alternative" "10,11")
2407                  (not (match_test "TARGET_SSE2")))
2408               (const_string "SF")
2409            ]
2410            (const_string "SI")))
2411    (set (attr "preferred_for_speed")
2412      (cond [(eq_attr "alternative" "6,12")
2413               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2414             (eq_attr "alternative" "7,13")
2415               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2416            ]
2417            (symbol_ref "true")))])
2419 (define_insn "*movhi_internal"
2420   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2421         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2422   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2424   switch (get_attr_type (insn))
2425     {
2426     case TYPE_IMOVX:
2427       /* movzwl is faster than movw on p2 due to partial word stalls,
2428          though not as fast as an aligned movl.  */
2429       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2431     case TYPE_MSKMOV:
2432       switch (which_alternative)
2433         {
2434         case 4:
2435           return "kmovw\t{%k1, %0|%0, %k1}";
2436         case 6:
2437           return "kmovw\t{%1, %k0|%k0, %1}";
2438         case 5:
2439         case 7:
2440           return "kmovw\t{%1, %0|%0, %1}";
2441         default:
2442           gcc_unreachable ();
2443         }
2445     default:
2446       if (get_attr_mode (insn) == MODE_SI)
2447         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2448       else
2449         return "mov{w}\t{%1, %0|%0, %1}";
2450     }
2452   [(set (attr "type")
2453      (cond [(eq_attr "alternative" "4,5,6,7")
2454               (const_string "mskmov")
2455             (match_test "optimize_function_for_size_p (cfun)")
2456               (const_string "imov")
2457             (and (eq_attr "alternative" "0")
2458                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2459                       (not (match_test "TARGET_HIMODE_MATH"))))
2460               (const_string "imov")
2461             (and (eq_attr "alternative" "1,2")
2462                  (match_operand:HI 1 "aligned_operand"))
2463               (const_string "imov")
2464             (and (match_test "TARGET_MOVX")
2465                  (eq_attr "alternative" "0,2"))
2466               (const_string "imovx")
2467            ]
2468            (const_string "imov")))
2469     (set (attr "prefix")
2470       (if_then_else (eq_attr "alternative" "4,5,6,7")
2471         (const_string "vex")
2472         (const_string "orig")))
2473     (set (attr "mode")
2474       (cond [(eq_attr "type" "imovx")
2475                (const_string "SI")
2476              (and (eq_attr "alternative" "1,2")
2477                   (match_operand:HI 1 "aligned_operand"))
2478                (const_string "SI")
2479              (and (eq_attr "alternative" "0")
2480                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2481                        (not (match_test "TARGET_HIMODE_MATH"))))
2482                (const_string "SI")
2483             ]
2484             (const_string "HI")))])
2486 ;; Situation is quite tricky about when to choose full sized (SImode) move
2487 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2488 ;; partial register dependency machines (such as AMD Athlon), where QImode
2489 ;; moves issue extra dependency and for partial register stalls machines
2490 ;; that don't use QImode patterns (and QImode move cause stall on the next
2491 ;; instruction).
2493 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2494 ;; register stall machines with, where we use QImode instructions, since
2495 ;; partial register stall can be caused there.  Then we use movzx.
2497 (define_insn "*movqi_internal"
2498   [(set (match_operand:QI 0 "nonimmediate_operand"
2499                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2500         (match_operand:QI 1 "general_operand"
2501                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2502   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2504   static char buf[128];
2505   const char *ops;
2506   const char *suffix;
2508   switch (get_attr_type (insn))
2509     {
2510     case TYPE_IMOVX:
2511       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2512       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2514     case TYPE_MSKMOV:
2515       switch (which_alternative)
2516         {
2517         case 9:
2518           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2519           break;
2520         case 11:
2521           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2522           break;
2523         case 12:
2524         case 13:
2525           gcc_assert (TARGET_AVX512DQ);
2526           /* FALLTHRU */
2527         case 10:
2528           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2529           break;
2530         default:
2531           gcc_unreachable ();
2532         }
2534       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2536       snprintf (buf, sizeof (buf), ops, suffix);
2537       return buf;
2539     default:
2540       if (get_attr_mode (insn) == MODE_SI)
2541         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2542       else
2543         return "mov{b}\t{%1, %0|%0, %1}";
2544     }
2546   [(set (attr "isa")
2547      (cond [(eq_attr "alternative" "1,2")
2548               (const_string "x64")
2549             (eq_attr "alternative" "12,13")
2550               (const_string "avx512dq")
2551            ]
2552            (const_string "*")))
2553    (set (attr "type")
2554      (cond [(eq_attr "alternative" "9,10,11,12,13")
2555               (const_string "mskmov")
2556             (and (eq_attr "alternative" "7")
2557                  (not (match_operand:QI 1 "aligned_operand")))
2558               (const_string "imovx")
2559             (match_test "optimize_function_for_size_p (cfun)")
2560               (const_string "imov")
2561             (and (eq_attr "alternative" "5")
2562                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2563                       (not (match_test "TARGET_QIMODE_MATH"))))
2564               (const_string "imov")
2565             (eq_attr "alternative" "5,7")
2566               (const_string "imovx")
2567             (and (match_test "TARGET_MOVX")
2568                  (eq_attr "alternative" "4"))
2569               (const_string "imovx")
2570            ]
2571            (const_string "imov")))
2572    (set (attr "prefix")
2573      (if_then_else (eq_attr "alternative" "9,10,11")
2574        (const_string "vex")
2575        (const_string "orig")))
2576    (set (attr "mode")
2577       (cond [(eq_attr "alternative" "5,6,7")
2578                (const_string "SI")
2579              (eq_attr "alternative" "8")
2580                (const_string "QI")
2581              (and (eq_attr "alternative" "9,10,11")
2582                   (not (match_test "TARGET_AVX512DQ")))
2583                (const_string "HI")
2584              (eq_attr "type" "imovx")
2585                (const_string "SI")
2586              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2587              ;; ones.
2588              (and (eq_attr "type" "imov")
2589                   (and (eq_attr "alternative" "3")
2590                        (match_test "optimize_function_for_size_p (cfun)")))
2591                (const_string "QI")
2592              ;; For -Os, movl where one or both operands are NON_Q_REGS
2593              ;; and both are LEGACY_REGS is shorter than movb.
2594              ;; Otherwise movb and movl sizes are the same, so decide purely
2595              ;; based on speed factors.
2596              (and (eq_attr "type" "imov")
2597                   (and (eq_attr "alternative" "1")
2598                        (match_test "optimize_function_for_size_p (cfun)")))
2599                (const_string "SI")
2600              (and (eq_attr "type" "imov")
2601                   (and (eq_attr "alternative" "0,1,2,3")
2602                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2603                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2604                (const_string "SI")
2605              ;; Avoid partial register stalls when not using QImode arithmetic
2606              (and (eq_attr "type" "imov")
2607                   (and (eq_attr "alternative" "0,1,2,3")
2608                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2609                             (not (match_test "TARGET_QIMODE_MATH")))))
2610                (const_string "SI")
2611            ]
2612            (const_string "QI")))])
2614 ;; Stores and loads of ax to arbitrary constant address.
2615 ;; We fake an second form of instruction to force reload to load address
2616 ;; into register when rax is not available
2617 (define_insn "*movabs<mode>_1"
2618   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2619         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2620   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2622   /* Recover the full memory rtx.  */
2623   operands[0] = SET_DEST (PATTERN (insn));
2624   switch (which_alternative)
2625     {
2626     case 0:
2627       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2628     case 1:
2629       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2630     default:
2631       gcc_unreachable ();
2632     }
2634   [(set_attr "type" "imov")
2635    (set_attr "modrm" "0,*")
2636    (set_attr "length_address" "8,0")
2637    (set_attr "length_immediate" "0,*")
2638    (set_attr "memory" "store")
2639    (set_attr "mode" "<MODE>")])
2641 (define_insn "*movabs<mode>_2"
2642   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2643         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2644   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2646   /* Recover the full memory rtx.  */
2647   operands[1] = SET_SRC (PATTERN (insn));
2648   switch (which_alternative)
2649     {
2650     case 0:
2651       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2652     case 1:
2653       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2654     default:
2655       gcc_unreachable ();
2656     }
2658   [(set_attr "type" "imov")
2659    (set_attr "modrm" "0,*")
2660    (set_attr "length_address" "8,0")
2661    (set_attr "length_immediate" "0")
2662    (set_attr "memory" "load")
2663    (set_attr "mode" "<MODE>")])
2665 (define_insn "*swap<mode>"
2666   [(set (match_operand:SWI48 0 "register_operand" "+r")
2667         (match_operand:SWI48 1 "register_operand" "+r"))
2668    (set (match_dup 1)
2669         (match_dup 0))]
2670   ""
2671   "xchg{<imodesuffix>}\t%1, %0"
2672   [(set_attr "type" "imov")
2673    (set_attr "mode" "<MODE>")
2674    (set_attr "pent_pair" "np")
2675    (set_attr "athlon_decode" "vector")
2676    (set_attr "amdfam10_decode" "double")
2677    (set_attr "bdver1_decode" "double")])
2679 (define_insn "*swap<mode>"
2680   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2681         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2682    (set (match_dup 1)
2683         (match_dup 0))]
2684   ""
2685   "@
2686    xchg{<imodesuffix>}\t%1, %0
2687    xchg{l}\t%k1, %k0"
2688   [(set_attr "type" "imov")
2689    (set_attr "mode" "<MODE>,SI")
2690    (set (attr "preferred_for_size")
2691      (cond [(eq_attr "alternative" "0")
2692               (symbol_ref "false")]
2693            (symbol_ref "true")))
2694    ;; Potential partial reg stall on alternative 1.
2695    (set (attr "preferred_for_speed")
2696      (cond [(eq_attr "alternative" "1")
2697               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2698            (symbol_ref "true")))
2699    (set_attr "pent_pair" "np")
2700    (set_attr "athlon_decode" "vector")
2701    (set_attr "amdfam10_decode" "double")
2702    (set_attr "bdver1_decode" "double")])
2704 (define_expand "movstrict<mode>"
2705   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2706         (match_operand:SWI12 1 "general_operand"))]
2707   ""
2709   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2710     FAIL;
2711   if (SUBREG_P (operands[0])
2712       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2713     FAIL;
2714   /* Don't generate memory->memory moves, go through a register */
2715   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2716     operands[1] = force_reg (<MODE>mode, operands[1]);
2719 (define_insn "*movstrict<mode>_1"
2720   [(set (strict_low_part
2721           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2722         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2723   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2724    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2725   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2726   [(set_attr "type" "imov")
2727    (set_attr "mode" "<MODE>")])
2729 (define_insn "*movstrict<mode>_xor"
2730   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2731         (match_operand:SWI12 1 "const0_operand"))
2732    (clobber (reg:CC FLAGS_REG))]
2733   "reload_completed"
2734   "xor{<imodesuffix>}\t%0, %0"
2735   [(set_attr "type" "alu1")
2736    (set_attr "mode" "<MODE>")
2737    (set_attr "length_immediate" "0")])
2739 (define_expand "extv<mode>"
2740   [(set (match_operand:SWI24 0 "register_operand")
2741         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2742                             (match_operand:SI 2 "const_int_operand")
2743                             (match_operand:SI 3 "const_int_operand")))]
2744   ""
2746   /* Handle extractions from %ah et al.  */
2747   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2748     FAIL;
2750   unsigned int regno = reg_or_subregno (operands[1]);
2752   /* Be careful to expand only with registers having upper parts.  */
2753   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2754     operands[1] = copy_to_reg (operands[1]);
2757 (define_insn "*extv<mode>"
2758   [(set (match_operand:SWI24 0 "register_operand" "=R")
2759         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2760                             (const_int 8)
2761                             (const_int 8)))]
2762   ""
2763   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2764   [(set_attr "type" "imovx")
2765    (set_attr "mode" "SI")])
2767 (define_expand "extzv<mode>"
2768   [(set (match_operand:SWI248 0 "register_operand")
2769         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2770                              (match_operand:SI 2 "const_int_operand")
2771                              (match_operand:SI 3 "const_int_operand")))]
2772   ""
2774   if (ix86_expand_pextr (operands))
2775     DONE;
2777   /* Handle extractions from %ah et al.  */
2778   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2779     FAIL;
2781   unsigned int regno = reg_or_subregno (operands[1]);
2783   /* Be careful to expand only with registers having upper parts.  */
2784   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2785     operands[1] = copy_to_reg (operands[1]);
2788 (define_insn "*extzvqi_mem_rex64"
2789   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2790         (subreg:QI
2791           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2792                            (const_int 8)
2793                            (const_int 8)) 0))]
2794   "TARGET_64BIT && reload_completed"
2795   "mov{b}\t{%h1, %0|%0, %h1}"
2796   [(set_attr "type" "imov")
2797    (set_attr "mode" "QI")])
2799 (define_insn "*extzv<mode>"
2800   [(set (match_operand:SWI248 0 "register_operand" "=R")
2801         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2802                              (const_int 8)
2803                              (const_int 8)))]
2804   ""
2805   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2806   [(set_attr "type" "imovx")
2807    (set_attr "mode" "SI")])
2809 (define_insn "*extzvqi"
2810   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2811         (subreg:QI
2812           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2813                            (const_int 8)
2814                            (const_int 8)) 0))]
2815   ""
2817   switch (get_attr_type (insn))
2818     {
2819     case TYPE_IMOVX:
2820       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2821     default:
2822       return "mov{b}\t{%h1, %0|%0, %h1}";
2823     }
2825   [(set_attr "isa" "*,*,nox64")
2826    (set (attr "type")
2827      (if_then_else (and (match_operand:QI 0 "register_operand")
2828                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2829                              (match_test "TARGET_MOVX")))
2830         (const_string "imovx")
2831         (const_string "imov")))
2832    (set (attr "mode")
2833      (if_then_else (eq_attr "type" "imovx")
2834         (const_string "SI")
2835         (const_string "QI")))])
2837 (define_peephole2
2838   [(set (match_operand:QI 0 "register_operand")
2839         (subreg:QI
2840           (zero_extract:SI (match_operand 1 "ext_register_operand")
2841                            (const_int 8)
2842                            (const_int 8)) 0))
2843    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2844   "TARGET_64BIT
2845    && peep2_reg_dead_p (2, operands[0])"
2846   [(set (match_dup 2)
2847         (subreg:QI
2848           (zero_extract:SI (match_dup 1)
2849                            (const_int 8)
2850                            (const_int 8)) 0))])
2852 (define_expand "insv<mode>"
2853   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2854                              (match_operand:SI 1 "const_int_operand")
2855                              (match_operand:SI 2 "const_int_operand"))
2856         (match_operand:SWI248 3 "register_operand"))]
2857   ""
2859   rtx dst;
2861   if (ix86_expand_pinsr (operands))
2862     DONE;
2864   /* Handle insertions to %ah et al.  */
2865   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2866     FAIL;
2868   unsigned int regno = reg_or_subregno (operands[0]);
2870   /* Be careful to expand only with registers having upper parts.  */
2871   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2872     dst = copy_to_reg (operands[0]);
2873   else
2874     dst = operands[0];
2876   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2878   /* Fix up the destination if needed.  */
2879   if (dst != operands[0])
2880     emit_move_insn (operands[0], dst);
2882   DONE;
2885 (define_insn "*insvqi_1_mem_rex64"
2886   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2887                          (const_int 8)
2888                          (const_int 8))
2889         (subreg:SI
2890           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2891   "TARGET_64BIT && reload_completed"
2892   "mov{b}\t{%1, %h0|%h0, %1}"
2893   [(set_attr "type" "imov")
2894    (set_attr "mode" "QI")])
2896 (define_insn "insv<mode>_1"
2897   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2898                              (const_int 8)
2899                              (const_int 8))
2900         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2901   ""
2903   if (CONST_INT_P (operands[1]))
2904     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2905   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2907   [(set_attr "isa" "*,nox64")
2908    (set_attr "type" "imov")
2909    (set_attr "mode" "QI")])
2911 (define_insn "*insvqi_1"
2912   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2913                          (const_int 8)
2914                          (const_int 8))
2915         (subreg:SI
2916           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2917   ""
2918   "mov{b}\t{%1, %h0|%h0, %1}"
2919   [(set_attr "isa" "*,nox64")
2920    (set_attr "type" "imov")
2921    (set_attr "mode" "QI")])
2923 (define_peephole2
2924   [(set (match_operand:QI 0 "register_operand")
2925         (match_operand:QI 1 "norex_memory_operand"))
2926    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2927                          (const_int 8)
2928                          (const_int 8))
2929         (subreg:SI (match_dup 0) 0))]
2930   "TARGET_64BIT
2931    && peep2_reg_dead_p (2, operands[0])"
2932   [(set (zero_extract:SI (match_dup 2)
2933                          (const_int 8)
2934                          (const_int 8))
2935            (subreg:SI (match_dup 1) 0))])
2937 (define_code_iterator any_extract [sign_extract zero_extract])
2939 (define_insn "*insvqi_2"
2940   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2941                          (const_int 8)
2942                          (const_int 8))
2943         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
2944                         (const_int 8)
2945                         (const_int 8)))]
2946   ""
2947   "mov{b}\t{%h1, %h0|%h0, %h1}"
2948   [(set_attr "type" "imov")
2949    (set_attr "mode" "QI")])
2951 (define_insn "*insvqi_3"
2952   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2953                          (const_int 8)
2954                          (const_int 8))
2955         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2956                         (const_int 8)))]
2957   ""
2958   "mov{b}\t{%h1, %h0|%h0, %h1}"
2959   [(set_attr "type" "imov")
2960    (set_attr "mode" "QI")])
2962 ;; Floating point push instructions.
2964 (define_insn "*pushtf"
2965   [(set (match_operand:TF 0 "push_operand" "=<,<")
2966         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
2967   "TARGET_64BIT || TARGET_SSE"
2969   /* This insn should be already split before reg-stack.  */
2970   gcc_unreachable ();
2972   [(set_attr "isa" "*,x64")
2973    (set_attr "type" "multi")
2974    (set_attr "unit" "sse,*")
2975    (set_attr "mode" "TF,DI")])
2977 ;; %%% Kill this when call knows how to work this out.
2978 (define_split
2979   [(set (match_operand:TF 0 "push_operand")
2980         (match_operand:TF 1 "sse_reg_operand"))]
2981   "TARGET_SSE && reload_completed"
2982   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2983    (set (match_dup 0) (match_dup 1))]
2985   /* Preserve memory attributes. */
2986   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2989 (define_insn_and_split "*pushxf_rounded"
2990   [(set (mem:XF
2991           (pre_modify:P
2992             (reg:P SP_REG)
2993             (plus:P (reg:P SP_REG) (const_int -16))))
2994         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
2995   "TARGET_64BIT"
2996   "#"
2997   "&& 1"
2998   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2999    (set (match_dup 1) (match_dup 0))]
3001   rtx pat = PATTERN (curr_insn);
3002   operands[1] = SET_DEST (pat);
3004   /* Preserve memory attributes. */
3005   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3007   [(set_attr "type" "multi")
3008    (set_attr "unit" "i387,*,*,*")
3009    (set (attr "mode")
3010         (cond [(eq_attr "alternative" "1,2,3")
3011                  (const_string "DI")
3012               ]
3013               (const_string "XF")))
3014    (set (attr "preferred_for_size")
3015      (cond [(eq_attr "alternative" "1")
3016               (symbol_ref "false")]
3017            (symbol_ref "true")))])
3019 (define_insn "*pushxf"
3020   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3021         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3022   ""
3024   /* This insn should be already split before reg-stack.  */
3025   gcc_unreachable ();
3027   [(set_attr "isa" "*,*,*,nox64,x64")
3028    (set_attr "type" "multi")
3029    (set_attr "unit" "i387,*,*,*,*")
3030    (set (attr "mode")
3031         (cond [(eq_attr "alternative" "1,2,3,4")
3032                  (if_then_else (match_test "TARGET_64BIT")
3033                    (const_string "DI")
3034                    (const_string "SI"))
3035               ]
3036               (const_string "XF")))
3037    (set (attr "preferred_for_size")
3038      (cond [(eq_attr "alternative" "1")
3039               (symbol_ref "false")]
3040            (symbol_ref "true")))])
3042 ;; %%% Kill this when call knows how to work this out.
3043 (define_split
3044   [(set (match_operand:XF 0 "push_operand")
3045         (match_operand:XF 1 "fp_register_operand"))]
3046   "reload_completed"
3047   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3048    (set (match_dup 0) (match_dup 1))]
3050   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3051   /* Preserve memory attributes. */
3052   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3055 (define_insn "*pushdf"
3056   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3057         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3058   ""
3060   /* This insn should be already split before reg-stack.  */
3061   gcc_unreachable ();
3063   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3064    (set_attr "type" "multi")
3065    (set_attr "unit" "i387,*,*,*,*,sse")
3066    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3067    (set (attr "preferred_for_size")
3068      (cond [(eq_attr "alternative" "1")
3069               (symbol_ref "false")]
3070            (symbol_ref "true")))
3071    (set (attr "preferred_for_speed")
3072      (cond [(eq_attr "alternative" "1")
3073               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3074            (symbol_ref "true")))])
3075    
3076 ;; %%% Kill this when call knows how to work this out.
3077 (define_split
3078   [(set (match_operand:DF 0 "push_operand")
3079         (match_operand:DF 1 "any_fp_register_operand"))]
3080   "reload_completed"
3081   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3082    (set (match_dup 0) (match_dup 1))]
3084   /* Preserve memory attributes. */
3085   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3088 (define_insn "*pushsf_rex64"
3089   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3090         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3091   "TARGET_64BIT"
3093   /* Anything else should be already split before reg-stack.  */
3094   gcc_assert (which_alternative == 1);
3095   return "push{q}\t%q1";
3097   [(set_attr "type" "multi,push,multi")
3098    (set_attr "unit" "i387,*,*")
3099    (set_attr "mode" "SF,DI,SF")])
3101 (define_insn "*pushsf"
3102   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3103         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3104   "!TARGET_64BIT"
3106   /* Anything else should be already split before reg-stack.  */
3107   gcc_assert (which_alternative == 1);
3108   return "push{l}\t%1";
3110   [(set_attr "type" "multi,push,multi")
3111    (set_attr "unit" "i387,*,*")
3112    (set_attr "mode" "SF,SI,SF")])
3114 ;; %%% Kill this when call knows how to work this out.
3115 (define_split
3116   [(set (match_operand:SF 0 "push_operand")
3117         (match_operand:SF 1 "any_fp_register_operand"))]
3118   "reload_completed"
3119   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3120    (set (match_dup 0) (match_dup 1))]
3122   rtx op = XEXP (operands[0], 0);
3123   if (GET_CODE (op) == PRE_DEC)
3124     {
3125       gcc_assert (!TARGET_64BIT);
3126       op = GEN_INT (-4);
3127     }
3128   else
3129     {
3130       op = XEXP (XEXP (op, 1), 1);
3131       gcc_assert (CONST_INT_P (op));
3132     }
3133   operands[2] = op;
3134   /* Preserve memory attributes. */
3135   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3138 (define_split
3139   [(set (match_operand:SF 0 "push_operand")
3140         (match_operand:SF 1 "memory_operand"))]
3141   "reload_completed
3142    && find_constant_src (insn)"
3143   [(set (match_dup 0) (match_dup 2))]
3144   "operands[2] = find_constant_src (curr_insn);")
3146 (define_split
3147   [(set (match_operand 0 "push_operand")
3148         (match_operand 1 "general_gr_operand"))]
3149   "reload_completed
3150    && (GET_MODE (operands[0]) == TFmode
3151        || GET_MODE (operands[0]) == XFmode
3152        || GET_MODE (operands[0]) == DFmode)"
3153   [(const_int 0)]
3154   "ix86_split_long_move (operands); DONE;")
3156 ;; Floating point move instructions.
3158 (define_expand "movtf"
3159   [(set (match_operand:TF 0 "nonimmediate_operand")
3160         (match_operand:TF 1 "nonimmediate_operand"))]
3161   "TARGET_64BIT || TARGET_SSE"
3162   "ix86_expand_move (TFmode, operands); DONE;")
3164 (define_expand "mov<mode>"
3165   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3166         (match_operand:X87MODEF 1 "general_operand"))]
3167   ""
3168   "ix86_expand_move (<MODE>mode, operands); DONE;")
3170 (define_insn "*movtf_internal"
3171   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3172         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3173   "(TARGET_64BIT || TARGET_SSE)
3174    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3175    && (lra_in_progress || reload_completed
3176        || !CONST_DOUBLE_P (operands[1])
3177        || ((optimize_function_for_size_p (cfun)
3178             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3179            && standard_sse_constant_p (operands[1], TFmode) == 1
3180            && !memory_operand (operands[0], TFmode))
3181        || (!TARGET_MEMORY_MISMATCH_STALL
3182            && memory_operand (operands[0], TFmode)))"
3184   switch (get_attr_type (insn))
3185     {
3186     case TYPE_SSELOG1:
3187       return standard_sse_constant_opcode (insn, operands);
3189     case TYPE_SSEMOV:
3190       /* Handle misaligned load/store since we
3191          don't have movmisaligntf pattern. */
3192       if (misaligned_operand (operands[0], TFmode)
3193           || misaligned_operand (operands[1], TFmode))
3194         {
3195           if (get_attr_mode (insn) == MODE_V4SF)
3196             return "%vmovups\t{%1, %0|%0, %1}";
3197           else if (TARGET_AVX512VL
3198                    && (EXT_REX_SSE_REG_P (operands[0])
3199                        || EXT_REX_SSE_REG_P (operands[1])))
3200             return "vmovdqu64\t{%1, %0|%0, %1}";
3201           else
3202             return "%vmovdqu\t{%1, %0|%0, %1}";
3203         }
3204       else
3205         {
3206           if (get_attr_mode (insn) == MODE_V4SF)
3207             return "%vmovaps\t{%1, %0|%0, %1}";
3208           else if (TARGET_AVX512VL
3209                    && (EXT_REX_SSE_REG_P (operands[0])
3210                        || EXT_REX_SSE_REG_P (operands[1])))
3211             return "vmovdqa64\t{%1, %0|%0, %1}";
3212           else
3213             return "%vmovdqa\t{%1, %0|%0, %1}";
3214         }
3216     case TYPE_MULTI:
3217         return "#";
3219     default:
3220       gcc_unreachable ();
3221     }
3223   [(set_attr "isa" "*,*,*,x64,x64")
3224    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3225    (set (attr "prefix")
3226      (if_then_else (eq_attr "type" "sselog1,ssemov")
3227        (const_string "maybe_vex")
3228        (const_string "orig")))
3229    (set (attr "mode")
3230         (cond [(eq_attr "alternative" "3,4")
3231                  (const_string "DI")
3232                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3233                  (const_string "V4SF")
3234                (and (eq_attr "alternative" "2")
3235                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3236                  (const_string "V4SF")
3237                (match_test "TARGET_AVX")
3238                  (const_string "TI")
3239                (ior (not (match_test "TARGET_SSE2"))
3240                     (match_test "optimize_function_for_size_p (cfun)"))
3241                  (const_string "V4SF")
3242                ]
3243                (const_string "TI")))])
3245 (define_split
3246   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3247         (match_operand:TF 1 "general_gr_operand"))]
3248   "reload_completed"
3249   [(const_int 0)]
3250   "ix86_split_long_move (operands); DONE;")
3252 ;; Possible store forwarding (partial memory) stall
3253 ;; in alternatives 4, 6, 7 and 8.
3254 (define_insn "*movxf_internal"
3255   [(set (match_operand:XF 0 "nonimmediate_operand"
3256          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3257         (match_operand:XF 1 "general_operand"
3258          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3259   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3260    && (lra_in_progress || reload_completed
3261        || !CONST_DOUBLE_P (operands[1])
3262        || ((optimize_function_for_size_p (cfun)
3263             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3264            && standard_80387_constant_p (operands[1]) > 0
3265            && !memory_operand (operands[0], XFmode))
3266        || (!TARGET_MEMORY_MISMATCH_STALL
3267            && memory_operand (operands[0], XFmode))
3268        || !TARGET_HARD_XF_REGS)"
3270   switch (get_attr_type (insn))
3271     {
3272     case TYPE_FMOV:
3273       if (which_alternative == 2)
3274         return standard_80387_constant_opcode (operands[1]);
3275       return output_387_reg_move (insn, operands);
3277     case TYPE_MULTI:
3278       return "#";
3280     default:
3281       gcc_unreachable ();
3282     }
3284   [(set (attr "isa")
3285         (cond [(eq_attr "alternative" "7,10")
3286                  (const_string "nox64")
3287                (eq_attr "alternative" "8,11")
3288                  (const_string "x64")
3289               ]
3290               (const_string "*")))
3291    (set (attr "type")
3292         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3293                  (const_string "multi")
3294               ]
3295               (const_string "fmov")))
3296    (set (attr "mode")
3297         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3298                  (if_then_else (match_test "TARGET_64BIT")
3299                    (const_string "DI")
3300                    (const_string "SI"))
3301               ]
3302               (const_string "XF")))
3303    (set (attr "preferred_for_size")
3304      (cond [(eq_attr "alternative" "3,4")
3305               (symbol_ref "false")]
3306            (symbol_ref "true")))
3307    (set (attr "enabled")
3308      (cond [(eq_attr "alternative" "9,10,11")
3309               (if_then_else
3310                 (match_test "TARGET_HARD_XF_REGS")
3311                 (symbol_ref "false")
3312                 (const_string "*"))
3313             (not (match_test "TARGET_HARD_XF_REGS"))
3314               (symbol_ref "false")
3315            ]
3316            (const_string "*")))])
3317    
3318 (define_split
3319   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3320         (match_operand:XF 1 "general_gr_operand"))]
3321   "reload_completed"
3322   [(const_int 0)]
3323   "ix86_split_long_move (operands); DONE;")
3325 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3326 (define_insn "*movdf_internal"
3327   [(set (match_operand:DF 0 "nonimmediate_operand"
3328     "=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")
3329         (match_operand:DF 1 "general_operand"
3330     "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"))]
3331   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3332    && (lra_in_progress || reload_completed
3333        || !CONST_DOUBLE_P (operands[1])
3334        || ((optimize_function_for_size_p (cfun)
3335             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3336            && ((IS_STACK_MODE (DFmode)
3337                 && standard_80387_constant_p (operands[1]) > 0)
3338                || (TARGET_SSE2 && TARGET_SSE_MATH
3339                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3340            && !memory_operand (operands[0], DFmode))
3341        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3342            && memory_operand (operands[0], DFmode))
3343        || !TARGET_HARD_DF_REGS)"
3345   switch (get_attr_type (insn))
3346     {
3347     case TYPE_FMOV:
3348       if (which_alternative == 2)
3349         return standard_80387_constant_opcode (operands[1]);
3350       return output_387_reg_move (insn, operands);
3352     case TYPE_MULTI:
3353       return "#";
3355     case TYPE_IMOV:
3356       if (get_attr_mode (insn) == MODE_SI)
3357         return "mov{l}\t{%1, %k0|%k0, %1}";
3358       else if (which_alternative == 11)
3359         return "movabs{q}\t{%1, %0|%0, %1}";
3360       else
3361         return "mov{q}\t{%1, %0|%0, %1}";
3363     case TYPE_SSELOG1:
3364       return standard_sse_constant_opcode (insn, operands);
3366     case TYPE_SSEMOV:
3367       switch (get_attr_mode (insn))
3368         {
3369         case MODE_DF:
3370           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3371             return "vmovsd\t{%d1, %0|%0, %d1}";
3372           return "%vmovsd\t{%1, %0|%0, %1}";
3374         case MODE_V4SF:
3375           return "%vmovaps\t{%1, %0|%0, %1}";
3376         case MODE_V8DF:
3377           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3378         case MODE_V2DF:
3379           return "%vmovapd\t{%1, %0|%0, %1}";
3381         case MODE_V2SF:
3382           gcc_assert (!TARGET_AVX);
3383           return "movlps\t{%1, %0|%0, %1}";
3384         case MODE_V1DF:
3385           gcc_assert (!TARGET_AVX);
3386           return "movlpd\t{%1, %0|%0, %1}";
3388         case MODE_DI:
3389           /* Handle broken assemblers that require movd instead of movq.  */
3390           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3391               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3392             return "%vmovd\t{%1, %0|%0, %1}";
3393           return "%vmovq\t{%1, %0|%0, %1}";
3395         default:
3396           gcc_unreachable ();
3397         }
3399     default:
3400       gcc_unreachable ();
3401     }
3403   [(set (attr "isa")
3404         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3405                  (const_string "nox64")
3406                (eq_attr "alternative" "8,9,10,11,24,25")
3407                  (const_string "x64")
3408                (eq_attr "alternative" "12,13,14,15")
3409                  (const_string "sse2")
3410                (eq_attr "alternative" "20,21")
3411                  (const_string "x64_sse2")
3412               ]
3413               (const_string "*")))
3414    (set (attr "type")
3415         (cond [(eq_attr "alternative" "0,1,2")
3416                  (const_string "fmov")
3417                (eq_attr "alternative" "3,4,5,6,7,22,23")
3418                  (const_string "multi")
3419                (eq_attr "alternative" "8,9,10,11,24,25")
3420                  (const_string "imov")
3421                (eq_attr "alternative" "12,16")
3422                  (const_string "sselog1")
3423               ]
3424               (const_string "ssemov")))
3425    (set (attr "modrm")
3426      (if_then_else (eq_attr "alternative" "11")
3427        (const_string "0")
3428        (const_string "*")))
3429    (set (attr "length_immediate")
3430      (if_then_else (eq_attr "alternative" "11")
3431        (const_string "8")
3432        (const_string "*")))
3433    (set (attr "prefix")
3434      (if_then_else (eq_attr "type" "sselog1,ssemov")
3435        (const_string "maybe_vex")
3436        (const_string "orig")))
3437    (set (attr "prefix_data16")
3438      (if_then_else
3439        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3440             (eq_attr "mode" "V1DF"))
3441        (const_string "1")
3442        (const_string "*")))
3443    (set (attr "mode")
3444         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3445                  (const_string "SI")
3446                (eq_attr "alternative" "8,9,11,20,21,24,25")
3447                  (const_string "DI")
3449                /* xorps is one byte shorter for non-AVX targets.  */
3450                (eq_attr "alternative" "12,16")
3451                  (cond [(not (match_test "TARGET_SSE2"))
3452                           (const_string "V4SF")
3453                         (and (match_test "TARGET_AVX512F")
3454                           (not (match_test "TARGET_PREFER_AVX256")))
3455                           (const_string "XI")
3456                         (match_test "TARGET_AVX")
3457                           (const_string "V2DF")
3458                         (match_test "optimize_function_for_size_p (cfun)")
3459                           (const_string "V4SF")
3460                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3461                           (const_string "TI")
3462                        ]
3463                        (const_string "V2DF"))
3465                /* For architectures resolving dependencies on
3466                   whole SSE registers use movapd to break dependency
3467                   chains, otherwise use short move to avoid extra work.  */
3469                /* movaps is one byte shorter for non-AVX targets.  */
3470                (eq_attr "alternative" "13,17")
3471                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3472                                   (not (match_test "TARGET_AVX512VL")))
3473                              (ior (match_operand 0 "ext_sse_reg_operand")
3474                                   (match_operand 1 "ext_sse_reg_operand")))
3475                           (const_string "V8DF")
3476                         (ior (not (match_test "TARGET_SSE2"))
3477                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3478                           (const_string "V4SF")
3479                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3480                           (const_string "V2DF")
3481                         (match_test "TARGET_AVX")
3482                           (const_string "DF")
3483                         (match_test "optimize_function_for_size_p (cfun)")
3484                           (const_string "V4SF")
3485                        ]
3486                        (const_string "DF"))
3488                /* For architectures resolving dependencies on register
3489                   parts we may avoid extra work to zero out upper part
3490                   of register.  */
3491                (eq_attr "alternative" "14,18")
3492                  (cond [(not (match_test "TARGET_SSE2"))
3493                           (const_string "V2SF")
3494                         (match_test "TARGET_AVX")
3495                           (const_string "DF")
3496                         (match_test "TARGET_SSE_SPLIT_REGS")
3497                           (const_string "V1DF")
3498                        ]
3499                        (const_string "DF"))
3501                (and (eq_attr "alternative" "15,19")
3502                     (not (match_test "TARGET_SSE2")))
3503                  (const_string "V2SF")
3504               ]
3505               (const_string "DF")))
3506    (set (attr "preferred_for_size")
3507      (cond [(eq_attr "alternative" "3,4")
3508               (symbol_ref "false")]
3509            (symbol_ref "true")))
3510    (set (attr "preferred_for_speed")
3511      (cond [(eq_attr "alternative" "3,4")
3512               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3513             (eq_attr "alternative" "20")
3514               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3515             (eq_attr "alternative" "21")
3516               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3517            ]
3518            (symbol_ref "true")))
3519    (set (attr "enabled")
3520      (cond [(eq_attr "alternative" "22,23,24,25")
3521               (if_then_else
3522                 (match_test "TARGET_HARD_DF_REGS")
3523                 (symbol_ref "false")
3524                 (const_string "*"))
3525             (not (match_test "TARGET_HARD_DF_REGS"))
3526               (symbol_ref "false")
3527            ]
3528            (const_string "*")))])
3530 (define_split
3531   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3532         (match_operand:DF 1 "general_gr_operand"))]
3533   "!TARGET_64BIT && reload_completed"
3534   [(const_int 0)]
3535   "ix86_split_long_move (operands); DONE;")
3537 (define_insn "*movsf_internal"
3538   [(set (match_operand:SF 0 "nonimmediate_operand"
3539           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
3540         (match_operand:SF 1 "general_operand"
3541           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
3542   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3543    && (lra_in_progress || reload_completed
3544        || !CONST_DOUBLE_P (operands[1])
3545        || ((optimize_function_for_size_p (cfun)
3546             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3547            && ((IS_STACK_MODE (SFmode)
3548                 && standard_80387_constant_p (operands[1]) > 0)
3549                || (TARGET_SSE && TARGET_SSE_MATH
3550                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3551        || memory_operand (operands[0], SFmode)
3552        || !TARGET_HARD_SF_REGS)"
3554   switch (get_attr_type (insn))
3555     {
3556     case TYPE_FMOV:
3557       if (which_alternative == 2)
3558         return standard_80387_constant_opcode (operands[1]);
3559       return output_387_reg_move (insn, operands);
3561     case TYPE_IMOV:
3562       return "mov{l}\t{%1, %0|%0, %1}";
3564     case TYPE_SSELOG1:
3565       return standard_sse_constant_opcode (insn, operands);
3567     case TYPE_SSEMOV:
3568       switch (get_attr_mode (insn))
3569         {
3570         case MODE_SF:
3571           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3572             return "vmovss\t{%d1, %0|%0, %d1}";
3573           return "%vmovss\t{%1, %0|%0, %1}";
3575         case MODE_V16SF:
3576           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3577         case MODE_V4SF:
3578           return "%vmovaps\t{%1, %0|%0, %1}";
3580         case MODE_SI:
3581           return "%vmovd\t{%1, %0|%0, %1}";
3583         default:
3584           gcc_unreachable ();
3585         }
3587     case TYPE_MMXMOV:
3588       switch (get_attr_mode (insn))
3589         {
3590         case MODE_DI:
3591           return "movq\t{%1, %0|%0, %1}";
3592         case MODE_SI:
3593           return "movd\t{%1, %0|%0, %1}";
3595         default:
3596           gcc_unreachable ();
3597         }
3599     default:
3600       gcc_unreachable ();
3601     }
3603   [(set (attr "isa")
3604      (cond [(eq_attr "alternative" "14,15")
3605               (const_string "sse2")
3606            ]
3607            (const_string "*")))
3608    (set (attr "type")
3609         (cond [(eq_attr "alternative" "0,1,2")
3610                  (const_string "fmov")
3611                (eq_attr "alternative" "3,4,16,17")
3612                  (const_string "imov")
3613                (eq_attr "alternative" "5")
3614                  (const_string "sselog1")
3615                (eq_attr "alternative" "11,12,13,14,15")
3616                  (const_string "mmxmov")
3617               ]
3618               (const_string "ssemov")))
3619    (set (attr "prefix")
3620      (if_then_else (eq_attr "type" "sselog1,ssemov")
3621        (const_string "maybe_vex")
3622        (const_string "orig")))
3623    (set (attr "prefix_data16")
3624      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3625        (const_string "1")
3626        (const_string "*")))
3627    (set (attr "mode")
3628         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3629                  (const_string "SI")
3630                (eq_attr "alternative" "11")
3631                  (const_string "DI")
3632                (eq_attr "alternative" "5")
3633                  (cond [(not (match_test "TARGET_SSE2"))
3634                           (const_string "V4SF")
3635                         (and (match_test "TARGET_AVX512F")
3636                           (not (match_test "TARGET_PREFER_AVX256")))
3637                           (const_string "V16SF")
3638                         (match_test "TARGET_AVX")
3639                           (const_string "V4SF")
3640                         (match_test "optimize_function_for_size_p (cfun)")
3641                           (const_string "V4SF")
3642                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3643                           (const_string "TI")
3644                        ]
3645                        (const_string "V4SF"))
3647                /* For architectures resolving dependencies on
3648                   whole SSE registers use APS move to break dependency
3649                   chains, otherwise use short move to avoid extra work.
3651                   Do the same for architectures resolving dependencies on
3652                   the parts.  While in DF mode it is better to always handle
3653                   just register parts, the SF mode is different due to lack
3654                   of instructions to load just part of the register.  It is
3655                   better to maintain the whole registers in single format
3656                   to avoid problems on using packed logical operations.  */
3657                (eq_attr "alternative" "6")
3658                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3659                                   (not (match_test "TARGET_AVX512VL")))
3660                              (ior (match_operand 0 "ext_sse_reg_operand")
3661                                   (match_operand 1 "ext_sse_reg_operand")))
3662                           (const_string "V16SF")
3663                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3664                              (match_test "TARGET_SSE_SPLIT_REGS"))
3665                           (const_string "V4SF")
3666                        ]
3667                        (const_string "SF"))
3668               ]
3669               (const_string "SF")))
3670    (set (attr "preferred_for_speed")
3671      (cond [(eq_attr "alternative" "9,14")
3672               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3673             (eq_attr "alternative" "10,15")
3674               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3675            ]
3676            (symbol_ref "true")))
3677    (set (attr "enabled")
3678      (cond [(eq_attr "alternative" "16,17")
3679               (if_then_else
3680                 (match_test "TARGET_HARD_SF_REGS")
3681                 (symbol_ref "false")
3682                 (const_string "*"))
3683             (not (match_test "TARGET_HARD_SF_REGS"))
3684               (symbol_ref "false")
3685            ]
3686            (const_string "*")))])
3688 (define_split
3689   [(set (match_operand 0 "any_fp_register_operand")
3690         (match_operand 1 "memory_operand"))]
3691   "reload_completed
3692    && (GET_MODE (operands[0]) == TFmode
3693        || GET_MODE (operands[0]) == XFmode
3694        || GET_MODE (operands[0]) == DFmode
3695        || GET_MODE (operands[0]) == SFmode)
3696    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3697   [(set (match_dup 0) (match_dup 2))]
3698   "operands[2] = find_constant_src (curr_insn);")
3700 (define_split
3701   [(set (match_operand 0 "any_fp_register_operand")
3702         (float_extend (match_operand 1 "memory_operand")))]
3703   "reload_completed
3704    && (GET_MODE (operands[0]) == TFmode
3705        || GET_MODE (operands[0]) == XFmode
3706        || GET_MODE (operands[0]) == DFmode)
3707    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3708   [(set (match_dup 0) (match_dup 2))]
3709   "operands[2] = find_constant_src (curr_insn);")
3711 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3712 (define_split
3713   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3714         (match_operand:X87MODEF 1 "immediate_operand"))]
3715   "reload_completed
3716    && (standard_80387_constant_p (operands[1]) == 8
3717        || standard_80387_constant_p (operands[1]) == 9)"
3718   [(set (match_dup 0)(match_dup 1))
3719    (set (match_dup 0)
3720         (neg:X87MODEF (match_dup 0)))]
3722   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3723     operands[1] = CONST0_RTX (<MODE>mode);
3724   else
3725     operands[1] = CONST1_RTX (<MODE>mode);
3728 (define_insn "*swapxf"
3729   [(set (match_operand:XF 0 "register_operand" "+f")
3730         (match_operand:XF 1 "register_operand" "+f"))
3731    (set (match_dup 1)
3732         (match_dup 0))]
3733   "TARGET_80387"
3735   if (STACK_TOP_P (operands[0]))
3736     return "fxch\t%1";
3737   else
3738     return "fxch\t%0";
3740   [(set_attr "type" "fxch")
3741    (set_attr "mode" "XF")])
3744 ;; Zero extension instructions
3746 (define_expand "zero_extendsidi2"
3747   [(set (match_operand:DI 0 "nonimmediate_operand")
3748         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3750 (define_insn "*zero_extendsidi2"
3751   [(set (match_operand:DI 0 "nonimmediate_operand"
3752                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3753         (zero_extend:DI
3754          (match_operand:SI 1 "x86_64_zext_operand"
3755                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k")))]
3756   ""
3758   switch (get_attr_type (insn))
3759     {
3760     case TYPE_IMOVX:
3761       if (ix86_use_lea_for_mov (insn, operands))
3762         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3763       else
3764         return "mov{l}\t{%1, %k0|%k0, %1}";
3766     case TYPE_MULTI:
3767       return "#";
3769     case TYPE_MMXMOV:
3770       return "movd\t{%1, %0|%0, %1}";
3772     case TYPE_SSEMOV:
3773       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3774         {
3775           if (EXT_REX_SSE_REG_P (operands[0])
3776               || EXT_REX_SSE_REG_P (operands[1]))
3777             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3778           else
3779             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3780         }
3782       if (GENERAL_REG_P (operands[0]))
3783         return "%vmovd\t{%1, %k0|%k0, %1}";
3785       return "%vmovd\t{%1, %0|%0, %1}";
3787     case TYPE_MSKMOV:
3788       return "kmovd\t{%1, %k0|%k0, %1}";
3790     default:
3791       gcc_unreachable ();
3792     }
3794   [(set (attr "isa")
3795      (cond [(eq_attr "alternative" "0,1,2")
3796               (const_string "nox64")
3797             (eq_attr "alternative" "3")
3798               (const_string "x64")
3799             (eq_attr "alternative" "7,8,9")
3800               (const_string "sse2")
3801             (eq_attr "alternative" "10")
3802               (const_string "sse4")
3803             (eq_attr "alternative" "11")
3804               (const_string "avx512f")
3805             (eq_attr "alternative" "12")
3806               (const_string "x64_avx512bw")
3807            ]
3808            (const_string "*")))
3809    (set (attr "type")
3810      (cond [(eq_attr "alternative" "0,1,2,4")
3811               (const_string "multi")
3812             (eq_attr "alternative" "5,6")
3813               (const_string "mmxmov")
3814             (eq_attr "alternative" "7")
3815               (if_then_else (match_test "TARGET_64BIT")
3816                 (const_string "ssemov")
3817                 (const_string "multi"))
3818             (eq_attr "alternative" "8,9,10,11")
3819               (const_string "ssemov")
3820             (eq_attr "alternative" "12")
3821               (const_string "mskmov")
3822            ]
3823            (const_string "imovx")))
3824    (set (attr "prefix_extra")
3825      (if_then_else (eq_attr "alternative" "10,11")
3826        (const_string "1")
3827        (const_string "*")))
3828    (set (attr "prefix")
3829      (if_then_else (eq_attr "type" "ssemov")
3830        (const_string "maybe_vex")
3831        (const_string "orig")))
3832    (set (attr "prefix_0f")
3833      (if_then_else (eq_attr "type" "imovx")
3834        (const_string "0")
3835        (const_string "*")))
3836    (set (attr "mode")
3837      (cond [(eq_attr "alternative" "5,6")
3838               (const_string "DI")
3839             (and (eq_attr "alternative" "7")
3840                  (match_test "TARGET_64BIT"))
3841               (const_string "TI")
3842             (eq_attr "alternative" "8,10,11")
3843               (const_string "TI")
3844            ]
3845            (const_string "SI")))
3846    (set (attr "preferred_for_speed")
3847      (cond [(eq_attr "alternative" "7")
3848               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3849             (eq_attr "alternative" "5,8")
3850               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3851            ]
3852            (symbol_ref "true")))])
3854 (define_split
3855   [(set (match_operand:DI 0 "memory_operand")
3856         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3857   "reload_completed"
3858   [(set (match_dup 4) (const_int 0))]
3859   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3861 (define_split
3862   [(set (match_operand:DI 0 "general_reg_operand")
3863         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3864   "!TARGET_64BIT && reload_completed
3865    && REGNO (operands[0]) == REGNO (operands[1])"
3866   [(set (match_dup 4) (const_int 0))]
3867   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3869 (define_split
3870   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3871         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3872   "!TARGET_64BIT && reload_completed
3873    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3874   [(set (match_dup 3) (match_dup 1))
3875    (set (match_dup 4) (const_int 0))]
3876   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3878 (define_mode_attr kmov_isa
3879   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3881 (define_insn "zero_extend<mode>di2"
3882   [(set (match_operand:DI 0 "register_operand" "=r,*r")
3883         (zero_extend:DI
3884          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3885   "TARGET_64BIT"
3886   "@
3887    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3888    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3889   [(set_attr "isa" "*,<kmov_isa>")
3890    (set_attr "type" "imovx,mskmov")
3891    (set_attr "mode" "SI,<MODE>")])
3893 (define_expand "zero_extend<mode>si2"
3894   [(set (match_operand:SI 0 "register_operand")
3895         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3896   ""
3898   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3899     {
3900       operands[1] = force_reg (<MODE>mode, operands[1]);
3901       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3902       DONE;
3903     }
3906 (define_insn_and_split "zero_extend<mode>si2_and"
3907   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3908         (zero_extend:SI
3909           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3910    (clobber (reg:CC FLAGS_REG))]
3911   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3912   "#"
3913   "&& reload_completed"
3914   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3915               (clobber (reg:CC FLAGS_REG))])]
3917   if (!REG_P (operands[1])
3918       || REGNO (operands[0]) != REGNO (operands[1]))
3919     {
3920       ix86_expand_clear (operands[0]);
3922       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3923       emit_insn (gen_movstrict<mode>
3924                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3925       DONE;
3926     }
3928   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3930   [(set_attr "type" "alu1")
3931    (set_attr "mode" "SI")])
3933 (define_insn "*zero_extend<mode>si2"
3934   [(set (match_operand:SI 0 "register_operand" "=r,*r")
3935         (zero_extend:SI
3936           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3937   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3938   "@
3939    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3940    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3941   [(set_attr "isa" "*,<kmov_isa>")
3942    (set_attr "type" "imovx,mskmov")
3943    (set_attr "mode" "SI,<MODE>")])
3945 (define_expand "zero_extendqihi2"
3946   [(set (match_operand:HI 0 "register_operand")
3947         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3948   ""
3950   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3951     {
3952       operands[1] = force_reg (QImode, operands[1]);
3953       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3954       DONE;
3955     }
3958 (define_insn_and_split "zero_extendqihi2_and"
3959   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3960         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3961    (clobber (reg:CC FLAGS_REG))]
3962   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3963   "#"
3964   "&& reload_completed"
3965   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3966               (clobber (reg:CC FLAGS_REG))])]
3968   if (!REG_P (operands[1])
3969       || REGNO (operands[0]) != REGNO (operands[1]))
3970     {
3971       ix86_expand_clear (operands[0]);
3973       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3974       emit_insn (gen_movstrictqi
3975                   (gen_lowpart (QImode, operands[0]), operands[1]));
3976       DONE;
3977     }
3979   operands[0] = gen_lowpart (SImode, operands[0]);
3981   [(set_attr "type" "alu1")
3982    (set_attr "mode" "SI")])
3984 ; zero extend to SImode to avoid partial register stalls
3985 (define_insn "*zero_extendqihi2"
3986   [(set (match_operand:HI 0 "register_operand" "=r,*r")
3987         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3988   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3989   "@
3990    movz{bl|x}\t{%1, %k0|%k0, %1}
3991    kmovb\t{%1, %k0|%k0, %1}"
3992   [(set_attr "isa" "*,avx512dq")
3993    (set_attr "type" "imovx,mskmov")
3994    (set_attr "mode" "SI,QI")])
3996 (define_insn_and_split "*zext<mode>_doubleword_and"
3997   [(set (match_operand:DI 0 "register_operand" "=&<r>")
3998         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3999   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4000    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4001   "#"
4002   "&& reload_completed && GENERAL_REG_P (operands[0])"
4003   [(set (match_dup 2) (const_int 0))]
4005   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4007   emit_move_insn (operands[0], const0_rtx);
4009   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4010   emit_insn (gen_movstrict<mode>
4011              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4014 (define_insn_and_split "*zext<mode>_doubleword"
4015   [(set (match_operand:DI 0 "register_operand" "=r")
4016         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4017   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4018    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4019   "#"
4020   "&& reload_completed && GENERAL_REG_P (operands[0])"
4021   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4022    (set (match_dup 2) (const_int 0))]
4023   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4025 (define_insn_and_split "*zextsi_doubleword"
4026   [(set (match_operand:DI 0 "register_operand" "=r")
4027         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4028   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4029   "#"
4030   "&& reload_completed && GENERAL_REG_P (operands[0])"
4031   [(set (match_dup 0) (match_dup 1))
4032    (set (match_dup 2) (const_int 0))]
4033   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4035 ;; Sign extension instructions
4037 (define_expand "extendsidi2"
4038   [(set (match_operand:DI 0 "register_operand")
4039         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4040   ""
4042   if (!TARGET_64BIT)
4043     {
4044       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4045       DONE;
4046     }
4049 (define_insn "*extendsidi2_rex64"
4050   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4051         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4052   "TARGET_64BIT"
4053   "@
4054    {cltq|cdqe}
4055    movs{lq|x}\t{%1, %0|%0, %1}"
4056   [(set_attr "type" "imovx")
4057    (set_attr "mode" "DI")
4058    (set_attr "prefix_0f" "0")
4059    (set_attr "modrm" "0,1")])
4061 (define_insn "extendsidi2_1"
4062   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4063         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4064    (clobber (reg:CC FLAGS_REG))
4065    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4066   "!TARGET_64BIT"
4067   "#")
4069 ;; Split the memory case.  If the source register doesn't die, it will stay
4070 ;; this way, if it does die, following peephole2s take care of it.
4071 (define_split
4072   [(set (match_operand:DI 0 "memory_operand")
4073         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4074    (clobber (reg:CC FLAGS_REG))
4075    (clobber (match_operand:SI 2 "register_operand"))]
4076   "reload_completed"
4077   [(const_int 0)]
4079   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4081   emit_move_insn (operands[3], operands[1]);
4083   /* Generate a cltd if possible and doing so it profitable.  */
4084   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4085       && REGNO (operands[1]) == AX_REG
4086       && REGNO (operands[2]) == DX_REG)
4087     {
4088       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4089     }
4090   else
4091     {
4092       emit_move_insn (operands[2], operands[1]);
4093       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4094     }
4095   emit_move_insn (operands[4], operands[2]);
4096   DONE;
4099 ;; Peepholes for the case where the source register does die, after
4100 ;; being split with the above splitter.
4101 (define_peephole2
4102   [(set (match_operand:SI 0 "memory_operand")
4103         (match_operand:SI 1 "general_reg_operand"))
4104    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4105    (parallel [(set (match_dup 2)
4106                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4107                (clobber (reg:CC FLAGS_REG))])
4108    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4109   "REGNO (operands[1]) != REGNO (operands[2])
4110    && peep2_reg_dead_p (2, operands[1])
4111    && peep2_reg_dead_p (4, operands[2])
4112    && !reg_mentioned_p (operands[2], operands[3])"
4113   [(set (match_dup 0) (match_dup 1))
4114    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4115               (clobber (reg:CC FLAGS_REG))])
4116    (set (match_dup 3) (match_dup 1))])
4118 (define_peephole2
4119   [(set (match_operand:SI 0 "memory_operand")
4120         (match_operand:SI 1 "general_reg_operand"))
4121    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4122                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4123                (clobber (reg:CC FLAGS_REG))])
4124    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4125   "/* cltd is shorter than sarl $31, %eax */
4126    !optimize_function_for_size_p (cfun)
4127    && REGNO (operands[1]) == AX_REG
4128    && REGNO (operands[2]) == DX_REG
4129    && peep2_reg_dead_p (2, operands[1])
4130    && peep2_reg_dead_p (3, operands[2])
4131    && !reg_mentioned_p (operands[2], operands[3])"
4132   [(set (match_dup 0) (match_dup 1))
4133    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4134               (clobber (reg:CC FLAGS_REG))])
4135    (set (match_dup 3) (match_dup 1))])
4137 ;; Extend to register case.  Optimize case where source and destination
4138 ;; registers match and cases where we can use cltd.
4139 (define_split
4140   [(set (match_operand:DI 0 "register_operand")
4141         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4142    (clobber (reg:CC FLAGS_REG))
4143    (clobber (match_scratch:SI 2))]
4144   "reload_completed"
4145   [(const_int 0)]
4147   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4149   if (REGNO (operands[3]) != REGNO (operands[1]))
4150     emit_move_insn (operands[3], operands[1]);
4152   /* Generate a cltd if possible and doing so it profitable.  */
4153   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4154       && REGNO (operands[3]) == AX_REG
4155       && REGNO (operands[4]) == DX_REG)
4156     {
4157       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4158       DONE;
4159     }
4161   if (REGNO (operands[4]) != REGNO (operands[1]))
4162     emit_move_insn (operands[4], operands[1]);
4164   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4165   DONE;
4168 (define_insn "extend<mode>di2"
4169   [(set (match_operand:DI 0 "register_operand" "=r")
4170         (sign_extend:DI
4171          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4172   "TARGET_64BIT"
4173   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4174   [(set_attr "type" "imovx")
4175    (set_attr "mode" "DI")])
4177 (define_insn "extendhisi2"
4178   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4179         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4180   ""
4182   switch (get_attr_prefix_0f (insn))
4183     {
4184     case 0:
4185       return "{cwtl|cwde}";
4186     default:
4187       return "movs{wl|x}\t{%1, %0|%0, %1}";
4188     }
4190   [(set_attr "type" "imovx")
4191    (set_attr "mode" "SI")
4192    (set (attr "prefix_0f")
4193      ;; movsx is short decodable while cwtl is vector decoded.
4194      (if_then_else (and (eq_attr "cpu" "!k6")
4195                         (eq_attr "alternative" "0"))
4196         (const_string "0")
4197         (const_string "1")))
4198    (set (attr "znver1_decode")
4199      (if_then_else (eq_attr "prefix_0f" "0")
4200         (const_string "double")
4201         (const_string "direct")))
4202    (set (attr "modrm")
4203      (if_then_else (eq_attr "prefix_0f" "0")
4204         (const_string "0")
4205         (const_string "1")))])
4207 (define_insn "*extendhisi2_zext"
4208   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4209         (zero_extend:DI
4210          (sign_extend:SI
4211           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4212   "TARGET_64BIT"
4214   switch (get_attr_prefix_0f (insn))
4215     {
4216     case 0:
4217       return "{cwtl|cwde}";
4218     default:
4219       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4220     }
4222   [(set_attr "type" "imovx")
4223    (set_attr "mode" "SI")
4224    (set (attr "prefix_0f")
4225      ;; movsx is short decodable while cwtl is vector decoded.
4226      (if_then_else (and (eq_attr "cpu" "!k6")
4227                         (eq_attr "alternative" "0"))
4228         (const_string "0")
4229         (const_string "1")))
4230    (set (attr "modrm")
4231      (if_then_else (eq_attr "prefix_0f" "0")
4232         (const_string "0")
4233         (const_string "1")))])
4235 (define_insn "extendqisi2"
4236   [(set (match_operand:SI 0 "register_operand" "=r")
4237         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4238   ""
4239   "movs{bl|x}\t{%1, %0|%0, %1}"
4240    [(set_attr "type" "imovx")
4241     (set_attr "mode" "SI")])
4243 (define_insn "*extendqisi2_zext"
4244   [(set (match_operand:DI 0 "register_operand" "=r")
4245         (zero_extend:DI
4246           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4247   "TARGET_64BIT"
4248   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4249    [(set_attr "type" "imovx")
4250     (set_attr "mode" "SI")])
4252 (define_insn "extendqihi2"
4253   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4254         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4255   ""
4257   switch (get_attr_prefix_0f (insn))
4258     {
4259     case 0:
4260       return "{cbtw|cbw}";
4261     default:
4262       return "movs{bw|x}\t{%1, %0|%0, %1}";
4263     }
4265   [(set_attr "type" "imovx")
4266    (set_attr "mode" "HI")
4267    (set (attr "prefix_0f")
4268      ;; movsx is short decodable while cwtl is vector decoded.
4269      (if_then_else (and (eq_attr "cpu" "!k6")
4270                         (eq_attr "alternative" "0"))
4271         (const_string "0")
4272         (const_string "1")))
4273    (set (attr "modrm")
4274      (if_then_else (eq_attr "prefix_0f" "0")
4275         (const_string "0")
4276         (const_string "1")))])
4278 ;; Conversions between float and double.
4280 ;; These are all no-ops in the model used for the 80387.
4281 ;; So just emit moves.
4283 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4284 (define_split
4285   [(set (match_operand:DF 0 "push_operand")
4286         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4287   "reload_completed"
4288   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4289    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4291 (define_split
4292   [(set (match_operand:XF 0 "push_operand")
4293         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4294   "reload_completed"
4295   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4296    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4297   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4299 (define_expand "extendsfdf2"
4300   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4301         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4302   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4304   /* ??? Needed for compress_float_constant since all fp constants
4305      are TARGET_LEGITIMATE_CONSTANT_P.  */
4306   if (CONST_DOUBLE_P (operands[1]))
4307     {
4308       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4309           && standard_80387_constant_p (operands[1]) > 0)
4310         {
4311           operands[1] = simplify_const_unary_operation
4312             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4313           emit_move_insn_1 (operands[0], operands[1]);
4314           DONE;
4315         }
4316       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4317     }
4320 (define_insn "*extendsfdf2"
4321   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4322         (float_extend:DF
4323           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4324   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4326   switch (which_alternative)
4327     {
4328     case 0:
4329     case 1:
4330       return output_387_reg_move (insn, operands);
4332     case 2:
4333       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4335     default:
4336       gcc_unreachable ();
4337     }
4339   [(set_attr "type" "fmov,fmov,ssecvt")
4340    (set_attr "prefix" "orig,orig,maybe_vex")
4341    (set_attr "mode" "SF,XF,DF")
4342    (set (attr "enabled")
4343      (if_then_else
4344        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4345        (if_then_else
4346          (eq_attr "alternative" "0,1")
4347          (symbol_ref "TARGET_MIX_SSE_I387")
4348          (symbol_ref "true"))
4349        (if_then_else
4350          (eq_attr "alternative" "0,1")
4351          (symbol_ref "true")
4352          (symbol_ref "false"))))])
4354 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4355    cvtss2sd:
4356       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4357       cvtps2pd xmm2,xmm1
4358    We do the conversion post reload to avoid producing of 128bit spills
4359    that might lead to ICE on 32bit target.  The sequence unlikely combine
4360    anyway.  */
4361 (define_split
4362   [(set (match_operand:DF 0 "sse_reg_operand")
4363         (float_extend:DF
4364           (match_operand:SF 1 "nonimmediate_operand")))]
4365   "TARGET_USE_VECTOR_FP_CONVERTS
4366    && optimize_insn_for_speed_p ()
4367    && reload_completed
4368    && (!EXT_REX_SSE_REG_P (operands[0])
4369        || TARGET_AVX512VL)"
4370    [(set (match_dup 2)
4371          (float_extend:V2DF
4372            (vec_select:V2SF
4373              (match_dup 3)
4374              (parallel [(const_int 0) (const_int 1)]))))]
4376   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4377   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4378   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4379      Try to avoid move when unpacking can be done in source.  */
4380   if (REG_P (operands[1]))
4381     {
4382       /* If it is unsafe to overwrite upper half of source, we need
4383          to move to destination and unpack there.  */
4384       if (REGNO (operands[0]) != REGNO (operands[1])
4385           || (EXT_REX_SSE_REG_P (operands[1])
4386               && !TARGET_AVX512VL))
4387         {
4388           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4389           emit_move_insn (tmp, operands[1]);
4390         }
4391       else
4392         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4393       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4394          =v, v, then vbroadcastss will be only needed for AVX512F without
4395          AVX512VL.  */
4396       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4397         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4398                                                operands[3]));
4399       else
4400         {
4401           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4402           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4403         }
4404     }
4405   else
4406     emit_insn (gen_vec_setv4sf_0 (operands[3],
4407                                   CONST0_RTX (V4SFmode), operands[1]));
4410 ;; It's more profitable to split and then extend in the same register.
4411 (define_peephole2
4412   [(set (match_operand:DF 0 "sse_reg_operand")
4413         (float_extend:DF
4414           (match_operand:SF 1 "memory_operand")))]
4415   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4416    && optimize_insn_for_speed_p ()"
4417   [(set (match_dup 2) (match_dup 1))
4418    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4419   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4421 ;; Break partial reg stall for cvtss2sd.  This splitter should split
4422 ;; late in the pass sequence (after register rename pass),
4423 ;; so allocated registers won't change anymore.
4425 (define_split
4426   [(set (match_operand:DF 0 "sse_reg_operand")
4427         (float_extend:DF
4428           (match_operand:SF 1 "nonimmediate_operand")))]
4429   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4430    && optimize_function_for_speed_p (cfun)
4431    && (!REG_P (operands[1])
4432        || REGNO (operands[0]) != REGNO (operands[1]))
4433    && (!EXT_REX_SSE_REG_P (operands[0])
4434        || TARGET_AVX512VL)"
4435   [(set (match_dup 0)
4436         (vec_merge:V2DF
4437           (vec_duplicate:V2DF
4438             (float_extend:DF
4439               (match_dup 1)))
4440           (match_dup 0)
4441           (const_int 1)))]
4443   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4444   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4447 (define_expand "extend<mode>xf2"
4448   [(set (match_operand:XF 0 "nonimmediate_operand")
4449         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4450   "TARGET_80387"
4452   /* ??? Needed for compress_float_constant since all fp constants
4453      are TARGET_LEGITIMATE_CONSTANT_P.  */
4454   if (CONST_DOUBLE_P (operands[1]))
4455     {
4456       if (standard_80387_constant_p (operands[1]) > 0)
4457         {
4458           operands[1] = simplify_const_unary_operation
4459             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4460           emit_move_insn_1 (operands[0], operands[1]);
4461           DONE;
4462         }
4463       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4464     }
4467 (define_insn "*extend<mode>xf2_i387"
4468   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4469         (float_extend:XF
4470           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4471   "TARGET_80387"
4472   "* return output_387_reg_move (insn, operands);"
4473   [(set_attr "type" "fmov")
4474    (set_attr "mode" "<MODE>,XF")])
4476 ;; %%% This seems like bad news.
4477 ;; This cannot output into an f-reg because there is no way to be sure
4478 ;; of truncating in that case.  Otherwise this is just like a simple move
4479 ;; insn.  So we pretend we can output to a reg in order to get better
4480 ;; register preferencing, but we really use a stack slot.
4482 ;; Conversion from DFmode to SFmode.
4484 (define_insn "truncdfsf2"
4485   [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v")
4486         (float_truncate:SF
4487           (match_operand:DF 1 "register_ssemem_operand" "f,f,vm")))]
4488   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4490   switch (which_alternative)
4491     {
4492     case 0:
4493     case 1:
4494       return output_387_reg_move (insn, operands);
4496     case 2:
4497       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4499     default:
4500       gcc_unreachable ();
4501     }
4503   [(set_attr "type" "fmov,fmov,ssecvt")
4504    (set_attr "mode" "SF")
4505    (set (attr "enabled")
4506      (if_then_else
4507        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4508        (cond [(eq_attr "alternative" "0")
4509                 (symbol_ref "TARGET_MIX_SSE_I387")
4510               (eq_attr "alternative" "1")
4511                 (symbol_ref "TARGET_MIX_SSE_I387
4512                              && flag_unsafe_math_optimizations")
4513            ]
4514            (symbol_ref "true"))
4515        (cond [(eq_attr "alternative" "0")
4516                 (symbol_ref "true")
4517               (eq_attr "alternative" "1")
4518                 (symbol_ref "flag_unsafe_math_optimizations")
4519            ]
4520            (symbol_ref "false"))))])
4522 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4523    cvtsd2ss:
4524       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4525       cvtpd2ps xmm2,xmm1
4526    We do the conversion post reload to avoid producing of 128bit spills
4527    that might lead to ICE on 32bit target.  The sequence unlikely combine
4528    anyway.  */
4529 (define_split
4530   [(set (match_operand:SF 0 "sse_reg_operand")
4531         (float_truncate:SF
4532           (match_operand:DF 1 "nonimmediate_operand")))]
4533   "TARGET_USE_VECTOR_FP_CONVERTS
4534    && optimize_insn_for_speed_p ()
4535    && reload_completed
4536    && (!EXT_REX_SSE_REG_P (operands[0])
4537        || TARGET_AVX512VL)"
4538    [(set (match_dup 2)
4539          (vec_concat:V4SF
4540            (float_truncate:V2SF
4541              (match_dup 4))
4542            (match_dup 3)))]
4544   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4545   operands[3] = CONST0_RTX (V2SFmode);
4546   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4547   /* Use movsd for loading from memory, unpcklpd for registers.
4548      Try to avoid move when unpacking can be done in source, or SSE3
4549      movddup is available.  */
4550   if (REG_P (operands[1]))
4551     {
4552       if (!TARGET_SSE3
4553           && REGNO (operands[0]) != REGNO (operands[1]))
4554         {
4555           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4556           emit_move_insn (tmp, operands[1]);
4557           operands[1] = tmp;
4558         }
4559       else if (!TARGET_SSE3)
4560         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4561       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4562     }
4563   else
4564     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4565                                    CONST0_RTX (DFmode)));
4568 ;; It's more profitable to split and then truncate in the same register.
4569 (define_peephole2
4570   [(set (match_operand:SF 0 "sse_reg_operand")
4571         (float_truncate:SF
4572           (match_operand:DF 1 "memory_operand")))]
4573   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4574    && optimize_insn_for_speed_p ()"
4575   [(set (match_dup 2) (match_dup 1))
4576    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4577   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4579 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
4580 ;; late in the pass sequence (after register rename pass),
4581 ;; so allocated registers won't change anymore.
4583 (define_split
4584   [(set (match_operand:SF 0 "sse_reg_operand")
4585         (float_truncate:SF
4586           (match_operand:DF 1 "nonimmediate_operand")))]
4587   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4588    && optimize_function_for_speed_p (cfun)
4589    && (!REG_P (operands[1])
4590        || REGNO (operands[0]) != REGNO (operands[1]))
4591    && (!EXT_REX_SSE_REG_P (operands[0])
4592        || TARGET_AVX512VL)"
4593   [(set (match_dup 0)
4594         (vec_merge:V4SF
4595           (vec_duplicate:V4SF
4596             (float_truncate:SF
4597               (match_dup 1)))
4598           (match_dup 0)
4599           (const_int 1)))]
4601   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4602   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4605 ;; Conversion from XFmode to {SF,DF}mode
4607 (define_insn "truncxf<mode>2"
4608   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4609         (float_truncate:MODEF
4610           (match_operand:XF 1 "register_operand" "f,f")))]
4611   "TARGET_80387"
4612   "* return output_387_reg_move (insn, operands);"
4613   [(set_attr "type" "fmov")
4614    (set_attr "mode" "<MODE>")
4615    (set (attr "enabled")
4616      (cond [(eq_attr "alternative" "1")
4617               (symbol_ref "flag_unsafe_math_optimizations")
4618            ]
4619            (symbol_ref "true")))])
4621 ;; Signed conversion to DImode.
4623 (define_expand "fix_truncxfdi2"
4624   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4625                    (fix:DI (match_operand:XF 1 "register_operand")))
4626               (clobber (reg:CC FLAGS_REG))])]
4627   "TARGET_80387"
4629   if (TARGET_FISTTP)
4630    {
4631      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4632      DONE;
4633    }
4636 (define_expand "fix_trunc<mode>di2"
4637   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4638                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4639               (clobber (reg:CC FLAGS_REG))])]
4640   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4642   if (TARGET_FISTTP
4643       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4644    {
4645      emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4646      DONE;
4647    }
4648   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4649    {
4650      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4651      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4652      if (out != operands[0])
4653         emit_move_insn (operands[0], out);
4654      DONE;
4655    }
4658 ;; Signed conversion to SImode.
4660 (define_expand "fix_truncxfsi2"
4661   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4662                    (fix:SI (match_operand:XF 1 "register_operand")))
4663               (clobber (reg:CC FLAGS_REG))])]
4664   "TARGET_80387"
4666   if (TARGET_FISTTP)
4667    {
4668      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4669      DONE;
4670    }
4673 (define_expand "fix_trunc<mode>si2"
4674   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4675                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4676               (clobber (reg:CC FLAGS_REG))])]
4677   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4679   if (TARGET_FISTTP
4680       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4681    {
4682      emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4683      DONE;
4684    }
4685   if (SSE_FLOAT_MODE_P (<MODE>mode))
4686    {
4687      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4688      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4689      if (out != operands[0])
4690         emit_move_insn (operands[0], out);
4691      DONE;
4692    }
4695 ;; Signed conversion to HImode.
4697 (define_expand "fix_trunc<mode>hi2"
4698   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4699                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4700               (clobber (reg:CC FLAGS_REG))])]
4701   "TARGET_80387
4702    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4704   if (TARGET_FISTTP)
4705    {
4706      emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4707      DONE;
4708    }
4711 ;; Unsigned conversion to DImode
4713 (define_insn "fixuns_trunc<mode>di2"
4714   [(set (match_operand:DI 0 "register_operand" "=r")
4715         (unsigned_fix:DI
4716           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4717   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4718   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4719   [(set_attr "type" "sseicvt")
4720    (set_attr "prefix" "evex")
4721    (set_attr "mode" "DI")])
4723 ;; Unsigned conversion to SImode.
4725 (define_expand "fixuns_trunc<mode>si2"
4726   [(parallel
4727     [(set (match_operand:SI 0 "register_operand")
4728           (unsigned_fix:SI
4729             (match_operand:MODEF 1 "nonimmediate_operand")))
4730      (use (match_dup 2))
4731      (clobber (match_scratch:<ssevecmode> 3))
4732      (clobber (match_scratch:<ssevecmode> 4))])]
4733   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4735   machine_mode mode = <MODE>mode;
4736   machine_mode vecmode = <ssevecmode>mode;
4737   REAL_VALUE_TYPE TWO31r;
4738   rtx two31;
4740   if (TARGET_AVX512F)
4741     {
4742       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4743       DONE;
4744     }
4746   if (optimize_insn_for_size_p ())
4747     FAIL;
4749   real_ldexp (&TWO31r, &dconst1, 31);
4750   two31 = const_double_from_real_value (TWO31r, mode);
4751   two31 = ix86_build_const_vector (vecmode, true, two31);
4752   operands[2] = force_reg (vecmode, two31);
4755 (define_insn "fixuns_trunc<mode>si2_avx512f"
4756   [(set (match_operand:SI 0 "register_operand" "=r")
4757         (unsigned_fix:SI
4758           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4759   "TARGET_AVX512F && TARGET_SSE_MATH"
4760   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4761   [(set_attr "type" "sseicvt")
4762    (set_attr "prefix" "evex")
4763    (set_attr "mode" "SI")])
4765 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4766   [(set (match_operand:DI 0 "register_operand" "=r")
4767         (zero_extend:DI
4768           (unsigned_fix:SI
4769             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4770   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4771   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4772   [(set_attr "type" "sseicvt")
4773    (set_attr "prefix" "evex")
4774    (set_attr "mode" "SI")])
4776 (define_insn_and_split "*fixuns_trunc<mode>_1"
4777   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4778         (unsigned_fix:SI
4779           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4780    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4781    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4782    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4783   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4784    && optimize_function_for_speed_p (cfun)"
4785   "#"
4786   "&& reload_completed"
4787   [(const_int 0)]
4789   ix86_split_convert_uns_si_sse (operands);
4790   DONE;
4793 ;; Unsigned conversion to HImode.
4794 ;; Without these patterns, we'll try the unsigned SI conversion which
4795 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4797 (define_expand "fixuns_trunc<mode>hi2"
4798   [(set (match_dup 2)
4799         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4800    (set (match_operand:HI 0 "nonimmediate_operand")
4801         (subreg:HI (match_dup 2) 0))]
4802   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4803   "operands[2] = gen_reg_rtx (SImode);")
4805 ;; When SSE is available, it is always faster to use it!
4806 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4807   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4808         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4809   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4810    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4811   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4812   [(set_attr "type" "sseicvt")
4813    (set_attr "prefix" "maybe_vex")
4814    (set (attr "prefix_rex")
4815         (if_then_else
4816           (match_test "<SWI48:MODE>mode == DImode")
4817           (const_string "1")
4818           (const_string "*")))
4819    (set_attr "mode" "<MODEF:MODE>")
4820    (set_attr "athlon_decode" "double,vector")
4821    (set_attr "amdfam10_decode" "double,double")
4822    (set_attr "bdver1_decode" "double,double")])
4824 ;; Avoid vector decoded forms of the instruction.
4825 (define_peephole2
4826   [(match_scratch:MODEF 2 "x")
4827    (set (match_operand:SWI48 0 "register_operand")
4828         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4829   "TARGET_AVOID_VECTOR_DECODE
4830    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4831    && optimize_insn_for_speed_p ()"
4832   [(set (match_dup 2) (match_dup 1))
4833    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4835 (define_insn "fix_trunc<mode>_i387_fisttp"
4836   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4837         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4838    (clobber (match_scratch:XF 2 "=&f"))]
4839   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4840    && TARGET_FISTTP
4841    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4842          && (TARGET_64BIT || <MODE>mode != DImode))
4843         && TARGET_SSE_MATH)"
4844   "* return output_fix_trunc (insn, operands, true);"
4845   [(set_attr "type" "fisttp")
4846    (set_attr "mode" "<MODE>")])
4848 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4849 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4850 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4851 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4852 ;; function in i386.c.
4853 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4854   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4855         (fix:SWI248x (match_operand 1 "register_operand")))
4856    (clobber (reg:CC FLAGS_REG))]
4857   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4858    && !TARGET_FISTTP
4859    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4860          && (TARGET_64BIT || <MODE>mode != DImode))
4861    && can_create_pseudo_p ()"
4862   "#"
4863   "&& 1"
4864   [(const_int 0)]
4866   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4868   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4869   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4871   emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4872                                        operands[2], operands[3]));
4873   DONE;
4875   [(set_attr "type" "fistp")
4876    (set_attr "i387_cw" "trunc")
4877    (set_attr "mode" "<MODE>")])
4879 (define_insn "fix_truncdi_i387"
4880   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4881         (fix:DI (match_operand 1 "register_operand" "f")))
4882    (use (match_operand:HI 2 "memory_operand" "m"))
4883    (use (match_operand:HI 3 "memory_operand" "m"))
4884    (clobber (match_scratch:XF 4 "=&f"))]
4885   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4886    && !TARGET_FISTTP
4887    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4888   "* return output_fix_trunc (insn, operands, false);"
4889   [(set_attr "type" "fistp")
4890    (set_attr "i387_cw" "trunc")
4891    (set_attr "mode" "DI")])
4893 (define_insn "fix_trunc<mode>_i387"
4894   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4895         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4896    (use (match_operand:HI 2 "memory_operand" "m"))
4897    (use (match_operand:HI 3 "memory_operand" "m"))]
4898   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4899    && !TARGET_FISTTP
4900    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4901   "* return output_fix_trunc (insn, operands, false);"
4902   [(set_attr "type" "fistp")
4903    (set_attr "i387_cw" "trunc")
4904    (set_attr "mode" "<MODE>")])
4906 (define_insn "x86_fnstcw_1"
4907   [(set (match_operand:HI 0 "memory_operand" "=m")
4908         (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4909   "TARGET_80387"
4910   "fnstcw\t%0"
4911   [(set (attr "length")
4912         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4913    (set_attr "mode" "HI")
4914    (set_attr "unit" "i387")
4915    (set_attr "bdver1_decode" "vector")])
4917 ;; Conversion between fixed point and floating point.
4919 ;; Even though we only accept memory inputs, the backend _really_
4920 ;; wants to be able to do this between registers.  Thankfully, LRA
4921 ;; will fix this up for us during register allocation.
4923 (define_insn "floathi<mode>2"
4924   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4925         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4926   "TARGET_80387
4927    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4928        || TARGET_MIX_SSE_I387)"
4929   "fild%Z1\t%1"
4930   [(set_attr "type" "fmov")
4931    (set_attr "mode" "<MODE>")
4932    (set_attr "znver1_decode" "double")
4933    (set_attr "fp_int_src" "true")])
4935 (define_insn "float<SWI48x:mode>xf2"
4936   [(set (match_operand:XF 0 "register_operand" "=f")
4937         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4938   "TARGET_80387"
4939   "fild%Z1\t%1"
4940   [(set_attr "type" "fmov")
4941    (set_attr "mode" "XF")
4942    (set_attr "znver1_decode" "double")
4943    (set_attr "fp_int_src" "true")])
4945 (define_expand "float<SWI48x:mode><MODEF:mode>2"
4946   [(set (match_operand:MODEF 0 "register_operand")
4947         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4948   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4949    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4950        && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4952 (define_insn "*float<SWI48:mode><MODEF:mode>2"
4953   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4954         (float:MODEF
4955           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4956   "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4957    || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4958   "@
4959    fild%Z1\t%1
4960    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4961    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4962   [(set_attr "type" "fmov,sseicvt,sseicvt")
4963    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4964    (set_attr "mode" "<MODEF:MODE>")
4965    (set (attr "prefix_rex")
4966      (if_then_else
4967        (and (eq_attr "prefix" "maybe_vex")
4968             (match_test "<SWI48:MODE>mode == DImode"))
4969        (const_string "1")
4970        (const_string "*")))
4971    (set_attr "unit" "i387,*,*")
4972    (set_attr "athlon_decode" "*,double,direct")
4973    (set_attr "amdfam10_decode" "*,vector,double")
4974    (set_attr "bdver1_decode" "*,double,direct")
4975    (set_attr "znver1_decode" "double,*,*")
4976    (set_attr "fp_int_src" "true")
4977    (set (attr "enabled")
4978      (if_then_else
4979        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4980        (if_then_else
4981          (eq_attr "alternative" "0")
4982          (symbol_ref "TARGET_MIX_SSE_I387
4983                       && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4984                                            <SWI48:MODE>mode)")
4985          (symbol_ref "true"))
4986        (if_then_else
4987          (eq_attr "alternative" "0")
4988          (symbol_ref "true")
4989          (symbol_ref "false"))))
4990    (set (attr "preferred_for_speed")
4991      (cond [(eq_attr "alternative" "1")
4992               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4993            (symbol_ref "true")))])
4995 (define_insn "*floatdi<MODEF:mode>2_i387"
4996   [(set (match_operand:MODEF 0 "register_operand" "=f")
4997         (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4998   "!TARGET_64BIT
4999    && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5000   "fild%Z1\t%1"
5001   [(set_attr "type" "fmov")
5002    (set_attr "mode" "<MODEF:MODE>")
5003    (set_attr "znver1_decode" "double")
5004    (set_attr "fp_int_src" "true")])
5006 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5007 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5008 ;; alternative in sse2_loadld.
5009 (define_split
5010   [(set (match_operand:MODEF 0 "sse_reg_operand")
5011         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5012   "TARGET_SSE2
5013    && TARGET_USE_VECTOR_CONVERTS
5014    && optimize_function_for_speed_p (cfun)
5015    && reload_completed
5016    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5017    && (!EXT_REX_SSE_REG_P (operands[0])
5018        || TARGET_AVX512VL)"
5019   [(const_int 0)]
5021   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5022   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5024   emit_insn (gen_sse2_loadld (operands[4],
5025                               CONST0_RTX (V4SImode), operands[1]));
5027   if (<ssevecmode>mode == V4SFmode)
5028     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5029   else
5030     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5031   DONE;
5034 ;; Avoid store forwarding (partial memory) stall penalty
5035 ;; by passing DImode value through XMM registers.  */
5037 (define_split
5038   [(set (match_operand:X87MODEF 0 "register_operand")
5039         (float:X87MODEF
5040           (match_operand:DI 1 "register_operand")))]
5041   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5042    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5043    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5044    && can_create_pseudo_p ()"
5045   [(const_int 0)]
5047   emit_insn (gen_floatdi<mode>2_i387_with_xmm
5048              (operands[0], operands[1],
5049               assign_386_stack_local (DImode, SLOT_TEMP)));
5050   DONE;
5053 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5054   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5055         (float:X87MODEF
5056           (match_operand:DI 1 "register_operand" "r")))
5057    (clobber (match_scratch:V4SI 3 "=x"))
5058    (clobber (match_scratch:V4SI 4 "=x"))
5059    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5060   "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5061    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5062    && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5063   "#"
5064   "&& reload_completed"
5065   [(set (match_dup 2) (match_dup 3))
5066    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5068   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5069      Assemble the 64-bit DImode value in an xmm register.  */
5070   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5071                               gen_lowpart (SImode, operands[1])));
5072   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5073                               gen_highpart (SImode, operands[1])));
5074   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5075                                          operands[4]));
5077   operands[3] = gen_lowpart (DImode, operands[3]);
5079   [(set_attr "type" "multi")
5080    (set_attr "mode" "<X87MODEF:MODE>")
5081    (set_attr "unit" "i387")
5082    (set_attr "fp_int_src" "true")])
5084 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5085 ;; late in the pass sequence (after register rename pass), so allocated
5086 ;; registers won't change anymore
5088 (define_split
5089   [(set (match_operand:MODEF 0 "sse_reg_operand")
5090         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5091   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5092    && optimize_function_for_speed_p (cfun)
5093    && (!EXT_REX_SSE_REG_P (operands[0])
5094        || TARGET_AVX512VL)"
5095   [(set (match_dup 0)
5096         (vec_merge:<MODEF:ssevecmode>
5097           (vec_duplicate:<MODEF:ssevecmode>
5098             (float:MODEF
5099               (match_dup 1)))
5100           (match_dup 0)
5101           (const_int 1)))]
5103   const machine_mode vmode = <MODEF:ssevecmode>mode;
5105   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5106   emit_move_insn (operands[0], CONST0_RTX (vmode));
5109 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5110   [(set (match_operand:MODEF 0 "register_operand")
5111         (unsigned_float:MODEF
5112           (match_operand:SWI12 1 "nonimmediate_operand")))]
5113   "!TARGET_64BIT
5114    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5116   operands[1] = convert_to_mode (SImode, operands[1], 1);
5117   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5118   DONE;
5121 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5122   [(set (match_operand:MODEF 0 "register_operand" "=v")
5123         (unsigned_float:MODEF
5124           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5125   "TARGET_AVX512F && TARGET_SSE_MATH"
5126   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5127   [(set_attr "type" "sseicvt")
5128    (set_attr "prefix" "evex")
5129    (set_attr "mode" "<MODEF:MODE>")])
5131 ;; Avoid store forwarding (partial memory) stall penalty by extending
5132 ;; SImode value to DImode through XMM register instead of pushing two
5133 ;; SImode values to stack. Also note that fild loads from memory only.
5135 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5136   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5137         (unsigned_float:X87MODEF
5138           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5139    (clobber (match_operand:DI 2 "memory_operand" "=m"))
5140    (clobber (match_scratch:DI 3 "=x"))]
5141   "!TARGET_64BIT
5142    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5143    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5144   "#"
5145   "&& reload_completed"
5146   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5147    (set (match_dup 2) (match_dup 3))
5148    (set (match_dup 0)
5149         (float:X87MODEF (match_dup 2)))]
5150   ""
5151   [(set_attr "type" "multi")
5152    (set_attr "mode" "<MODE>")])
5154 (define_expand "floatunssi<mode>2"
5155   [(set (match_operand:X87MODEF 0 "register_operand")
5156         (unsigned_float:X87MODEF
5157           (match_operand:SI 1 "nonimmediate_operand")))]
5158   "(!TARGET_64BIT
5159     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5160     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5161    || ((!TARGET_64BIT || TARGET_AVX512F)
5162        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5164   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5165     {
5166       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5167                   (operands[0], operands[1],
5168                    assign_386_stack_local (DImode, SLOT_TEMP)));
5169       DONE;
5170     }
5171   if (!TARGET_AVX512F)
5172     {
5173       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5174       DONE;
5175     }
5178 (define_expand "floatunsdisf2"
5179   [(set (match_operand:SF 0 "register_operand")
5180         (unsigned_float:SF
5181           (match_operand:DI 1 "nonimmediate_operand")))]
5182   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5184   if (!TARGET_AVX512F)
5185     {
5186       x86_emit_floatuns (operands);
5187       DONE;
5188     }
5191 (define_expand "floatunsdidf2"
5192   [(set (match_operand:DF 0 "register_operand")
5193         (unsigned_float:DF
5194           (match_operand:DI 1 "nonimmediate_operand")))]
5195   "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5196    && TARGET_SSE2 && TARGET_SSE_MATH"
5198   if (!TARGET_64BIT)
5199     {
5200       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5201       DONE;
5202     }
5203   if (!TARGET_AVX512F)
5204     {
5205       x86_emit_floatuns (operands);
5206       DONE;
5207     }
5210 ;; Load effective address instructions
5212 (define_insn_and_split "*lea<mode>"
5213   [(set (match_operand:SWI48 0 "register_operand" "=r")
5214         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5215   ""
5217   if (SImode_address_operand (operands[1], VOIDmode))
5218     {
5219       gcc_assert (TARGET_64BIT);
5220       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5221     }
5222   else 
5223     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5225   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5226   [(const_int 0)]
5228   machine_mode mode = <MODE>mode;
5229   rtx pat;
5231   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5232      change operands[] array behind our back.  */
5233   pat = PATTERN (curr_insn);
5235   operands[0] = SET_DEST (pat);
5236   operands[1] = SET_SRC (pat);
5238   /* Emit all operations in SImode for zero-extended addresses.  */
5239   if (SImode_address_operand (operands[1], VOIDmode))
5240     mode = SImode;
5242   ix86_split_lea_for_addr (curr_insn, operands, mode);
5244   /* Zero-extend return register to DImode for zero-extended addresses.  */
5245   if (mode != <MODE>mode)
5246     emit_insn (gen_zero_extendsidi2
5247                (operands[0], gen_lowpart (mode, operands[0])));
5249   DONE;
5251   [(set_attr "type" "lea")
5252    (set (attr "mode")
5253      (if_then_else
5254        (match_operand 1 "SImode_address_operand")
5255        (const_string "SI")
5256        (const_string "<MODE>")))])
5258 ;; Add instructions
5260 (define_expand "add<mode>3"
5261   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5262         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5263                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5264   ""
5265   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5267 (define_insn_and_split "*add<dwi>3_doubleword"
5268   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5269         (plus:<DWI>
5270           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5271           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5272                                                         "ro<di>,r<di>")))
5273    (clobber (reg:CC FLAGS_REG))]
5274   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5275   "#"
5276   "reload_completed"
5277   [(parallel [(set (reg:CCC FLAGS_REG)
5278                    (compare:CCC
5279                      (plus:DWIH (match_dup 1) (match_dup 2))
5280                      (match_dup 1)))
5281               (set (match_dup 0)
5282                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5283    (parallel [(set (match_dup 3)
5284                    (plus:DWIH
5285                      (plus:DWIH
5286                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5287                        (match_dup 4))
5288                      (match_dup 5)))
5289               (clobber (reg:CC FLAGS_REG))])]
5291   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5292   if (operands[2] == const0_rtx)
5293     {
5294       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5295       DONE;
5296     }
5299 (define_insn "*add<mode>_1"
5300   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5301         (plus:SWI48
5302           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5303           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5304    (clobber (reg:CC FLAGS_REG))]
5305   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5307   switch (get_attr_type (insn))
5308     {
5309     case TYPE_LEA:
5310       return "#";
5312     case TYPE_INCDEC:
5313       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314       if (operands[2] == const1_rtx)
5315         return "inc{<imodesuffix>}\t%0";
5316       else
5317         {
5318           gcc_assert (operands[2] == constm1_rtx);
5319           return "dec{<imodesuffix>}\t%0";
5320         }
5322     default:
5323       /* For most processors, ADD is faster than LEA.  This alternative
5324          was added to use ADD as much as possible.  */
5325       if (which_alternative == 2)
5326         std::swap (operands[1], operands[2]);
5327         
5328       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5329       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5330         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5332       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5333     }
5335   [(set (attr "type")
5336      (cond [(eq_attr "alternative" "3")
5337               (const_string "lea")
5338             (match_operand:SWI48 2 "incdec_operand")
5339               (const_string "incdec")
5340            ]
5341            (const_string "alu")))
5342    (set (attr "length_immediate")
5343       (if_then_else
5344         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5345         (const_string "1")
5346         (const_string "*")))
5347    (set_attr "mode" "<MODE>")])
5349 ;; It may seem that nonimmediate operand is proper one for operand 1.
5350 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5351 ;; we take care in ix86_binary_operator_ok to not allow two memory
5352 ;; operands so proper swapping will be done in reload.  This allow
5353 ;; patterns constructed from addsi_1 to match.
5355 (define_insn "addsi_1_zext"
5356   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5357         (zero_extend:DI
5358           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5359                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5360    (clobber (reg:CC FLAGS_REG))]
5361   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5363   switch (get_attr_type (insn))
5364     {
5365     case TYPE_LEA:
5366       return "#";
5368     case TYPE_INCDEC:
5369       if (operands[2] == const1_rtx)
5370         return "inc{l}\t%k0";
5371       else
5372         {
5373           gcc_assert (operands[2] == constm1_rtx);
5374           return "dec{l}\t%k0";
5375         }
5377     default:
5378       /* For most processors, ADD is faster than LEA.  This alternative
5379          was added to use ADD as much as possible.  */
5380       if (which_alternative == 1)
5381         std::swap (operands[1], operands[2]);
5383       if (x86_maybe_negate_const_int (&operands[2], SImode))
5384         return "sub{l}\t{%2, %k0|%k0, %2}";
5386       return "add{l}\t{%2, %k0|%k0, %2}";
5387     }
5389   [(set (attr "type")
5390      (cond [(eq_attr "alternative" "2")
5391               (const_string "lea")
5392             (match_operand:SI 2 "incdec_operand")
5393               (const_string "incdec")
5394            ]
5395            (const_string "alu")))
5396    (set (attr "length_immediate")
5397       (if_then_else
5398         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5399         (const_string "1")
5400         (const_string "*")))
5401    (set_attr "mode" "SI")])
5403 (define_insn "*addhi_1"
5404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5405         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5406                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5407    (clobber (reg:CC FLAGS_REG))]
5408   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5410   switch (get_attr_type (insn))
5411     {
5412     case TYPE_LEA:
5413       return "#";
5415     case TYPE_INCDEC:
5416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417       if (operands[2] == const1_rtx)
5418         return "inc{w}\t%0";
5419       else
5420         {
5421           gcc_assert (operands[2] == constm1_rtx);
5422           return "dec{w}\t%0";
5423         }
5425     default:
5426       /* For most processors, ADD is faster than LEA.  This alternative
5427          was added to use ADD as much as possible.  */
5428       if (which_alternative == 2)
5429         std::swap (operands[1], operands[2]);
5431       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432       if (x86_maybe_negate_const_int (&operands[2], HImode))
5433         return "sub{w}\t{%2, %0|%0, %2}";
5435       return "add{w}\t{%2, %0|%0, %2}";
5436     }
5438   [(set (attr "type")
5439      (cond [(eq_attr "alternative" "3")
5440               (const_string "lea")
5441             (match_operand:HI 2 "incdec_operand")
5442               (const_string "incdec")
5443            ]
5444            (const_string "alu")))
5445    (set (attr "length_immediate")
5446       (if_then_else
5447         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5448         (const_string "1")
5449         (const_string "*")))
5450    (set_attr "mode" "HI,HI,HI,SI")])
5452 (define_insn "*addqi_1"
5453   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5454         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5455                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5456    (clobber (reg:CC FLAGS_REG))]
5457   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5459   bool widen = (get_attr_mode (insn) != MODE_QI);
5461   switch (get_attr_type (insn))
5462     {
5463     case TYPE_LEA:
5464       return "#";
5466     case TYPE_INCDEC:
5467       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5468       if (operands[2] == const1_rtx)
5469         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5470       else
5471         {
5472           gcc_assert (operands[2] == constm1_rtx);
5473           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5474         }
5476     default:
5477       /* For most processors, ADD is faster than LEA.  These alternatives
5478          were added to use ADD as much as possible.  */
5479       if (which_alternative == 2 || which_alternative == 4)
5480         std::swap (operands[1], operands[2]);
5482       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5483       if (x86_maybe_negate_const_int (&operands[2], QImode))
5484         {
5485           if (widen)
5486             return "sub{l}\t{%2, %k0|%k0, %2}";
5487           else
5488             return "sub{b}\t{%2, %0|%0, %2}";
5489         }
5490       if (widen)
5491         return "add{l}\t{%k2, %k0|%k0, %k2}";
5492       else
5493         return "add{b}\t{%2, %0|%0, %2}";
5494     }
5496   [(set (attr "type")
5497      (cond [(eq_attr "alternative" "5")
5498               (const_string "lea")
5499             (match_operand:QI 2 "incdec_operand")
5500               (const_string "incdec")
5501            ]
5502            (const_string "alu")))
5503    (set (attr "length_immediate")
5504       (if_then_else
5505         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5506         (const_string "1")
5507         (const_string "*")))
5508    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5509    ;; Potential partial reg stall on alternatives 3 and 4.
5510    (set (attr "preferred_for_speed")
5511      (cond [(eq_attr "alternative" "3,4")
5512               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5513            (symbol_ref "true")))])
5515 (define_insn "*addqi_1_slp"
5516   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5517         (plus:QI (match_dup 0)
5518                  (match_operand:QI 1 "general_operand" "qn,qm")))
5519    (clobber (reg:CC FLAGS_REG))]
5520   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5521    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_INCDEC:
5526       if (operands[1] == const1_rtx)
5527         return "inc{b}\t%0";
5528       else
5529         {
5530           gcc_assert (operands[1] == constm1_rtx);
5531           return "dec{b}\t%0";
5532         }
5534     default:
5535       if (x86_maybe_negate_const_int (&operands[1], QImode))
5536         return "sub{b}\t{%1, %0|%0, %1}";
5538       return "add{b}\t{%1, %0|%0, %1}";
5539     }
5541   [(set (attr "type")
5542      (if_then_else (match_operand:QI 1 "incdec_operand")
5543         (const_string "incdec")
5544         (const_string "alu1")))
5545    (set (attr "memory")
5546      (if_then_else (match_operand 1 "memory_operand")
5547         (const_string "load")
5548         (const_string "none")))
5549    (set_attr "mode" "QI")])
5551 ;; Split non destructive adds if we cannot use lea.
5552 (define_split
5553   [(set (match_operand:SWI48 0 "register_operand")
5554         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5555                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5556    (clobber (reg:CC FLAGS_REG))]
5557   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5558   [(set (match_dup 0) (match_dup 1))
5559    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5560               (clobber (reg:CC FLAGS_REG))])])
5562 ;; Split non destructive adds if we cannot use lea.
5563 (define_split
5564   [(set (match_operand:DI 0 "register_operand")
5565         (zero_extend:DI
5566           (plus:SI (match_operand:SI 1 "register_operand")
5567                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5568    (clobber (reg:CC FLAGS_REG))]
5569   "TARGET_64BIT
5570    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5571   [(set (match_dup 3) (match_dup 1))
5572    (parallel [(set (match_dup 0)
5573                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5574               (clobber (reg:CC FLAGS_REG))])]
5575   "operands[3] = gen_lowpart (SImode, operands[0]);")
5577 ;; Convert add to the lea pattern to avoid flags dependency.
5578 (define_split
5579   [(set (match_operand:SWI 0 "register_operand")
5580         (plus:SWI (match_operand:SWI 1 "register_operand")
5581                   (match_operand:SWI 2 "<nonmemory_operand>")))
5582    (clobber (reg:CC FLAGS_REG))]
5583   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5584   [(set (match_dup 0)
5585         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5587   if (<MODE>mode != <LEAMODE>mode)
5588     {
5589       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5590       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5591       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5592     }
5595 ;; Convert add to the lea pattern to avoid flags dependency.
5596 (define_split
5597   [(set (match_operand:DI 0 "register_operand")
5598         (zero_extend:DI
5599           (plus:SI (match_operand:SI 1 "register_operand")
5600                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5601    (clobber (reg:CC FLAGS_REG))]
5602   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5603   [(set (match_dup 0)
5604         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5606 (define_insn "*add<mode>_2"
5607   [(set (reg FLAGS_REG)
5608         (compare
5609           (plus:SWI
5610             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5611             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5612           (const_int 0)))
5613    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5614         (plus:SWI (match_dup 1) (match_dup 2)))]
5615   "ix86_match_ccmode (insn, CCGOCmode)
5616    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5618   switch (get_attr_type (insn))
5619     {
5620     case TYPE_INCDEC:
5621       if (operands[2] == const1_rtx)
5622         return "inc{<imodesuffix>}\t%0";
5623       else
5624         {
5625           gcc_assert (operands[2] == constm1_rtx);
5626           return "dec{<imodesuffix>}\t%0";
5627         }
5629     default:
5630       if (which_alternative == 2)
5631         std::swap (operands[1], operands[2]);
5632         
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5635         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5637       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5638     }
5640   [(set (attr "type")
5641      (if_then_else (match_operand:SWI 2 "incdec_operand")
5642         (const_string "incdec")
5643         (const_string "alu")))
5644    (set (attr "length_immediate")
5645       (if_then_else
5646         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5647         (const_string "1")
5648         (const_string "*")))
5649    (set_attr "mode" "<MODE>")])
5651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5652 (define_insn "*addsi_2_zext"
5653   [(set (reg FLAGS_REG)
5654         (compare
5655           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5656                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5657           (const_int 0)))
5658    (set (match_operand:DI 0 "register_operand" "=r,r")
5659         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5660   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5661    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5663   switch (get_attr_type (insn))
5664     {
5665     case TYPE_INCDEC:
5666       if (operands[2] == const1_rtx)
5667         return "inc{l}\t%k0";
5668       else
5669         {
5670           gcc_assert (operands[2] == constm1_rtx);
5671           return "dec{l}\t%k0";
5672         }
5674     default:
5675       if (which_alternative == 1)
5676         std::swap (operands[1], operands[2]);
5678       if (x86_maybe_negate_const_int (&operands[2], SImode))
5679         return "sub{l}\t{%2, %k0|%k0, %2}";
5681       return "add{l}\t{%2, %k0|%k0, %2}";
5682     }
5684   [(set (attr "type")
5685      (if_then_else (match_operand:SI 2 "incdec_operand")
5686         (const_string "incdec")
5687         (const_string "alu")))
5688    (set (attr "length_immediate")
5689       (if_then_else
5690         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5691         (const_string "1")
5692         (const_string "*")))
5693    (set_attr "mode" "SI")])
5695 (define_insn "*add<mode>_3"
5696   [(set (reg FLAGS_REG)
5697         (compare
5698           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5699           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5700    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5701   "ix86_match_ccmode (insn, CCZmode)
5702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5704   switch (get_attr_type (insn))
5705     {
5706     case TYPE_INCDEC:
5707       if (operands[2] == const1_rtx)
5708         return "inc{<imodesuffix>}\t%0";
5709       else
5710         {
5711           gcc_assert (operands[2] == constm1_rtx);
5712           return "dec{<imodesuffix>}\t%0";
5713         }
5715     default:
5716       if (which_alternative == 1)
5717         std::swap (operands[1], operands[2]);
5719       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5721         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5723       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5724     }
5726   [(set (attr "type")
5727      (if_then_else (match_operand:SWI 2 "incdec_operand")
5728         (const_string "incdec")
5729         (const_string "alu")))
5730    (set (attr "length_immediate")
5731       (if_then_else
5732         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5733         (const_string "1")
5734         (const_string "*")))
5735    (set_attr "mode" "<MODE>")])
5737 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5738 (define_insn "*addsi_3_zext"
5739   [(set (reg FLAGS_REG)
5740         (compare
5741           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5742           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5743    (set (match_operand:DI 0 "register_operand" "=r,r")
5744         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5745   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5746    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5748   switch (get_attr_type (insn))
5749     {
5750     case TYPE_INCDEC:
5751       if (operands[2] == const1_rtx)
5752         return "inc{l}\t%k0";
5753       else
5754         {
5755           gcc_assert (operands[2] == constm1_rtx);
5756           return "dec{l}\t%k0";
5757         }
5759     default:
5760       if (which_alternative == 1)
5761         std::swap (operands[1], operands[2]);
5763       if (x86_maybe_negate_const_int (&operands[2], SImode))
5764         return "sub{l}\t{%2, %k0|%k0, %2}";
5766       return "add{l}\t{%2, %k0|%k0, %2}";
5767     }
5769   [(set (attr "type")
5770      (if_then_else (match_operand:SI 2 "incdec_operand")
5771         (const_string "incdec")
5772         (const_string "alu")))
5773    (set (attr "length_immediate")
5774       (if_then_else
5775         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5776         (const_string "1")
5777         (const_string "*")))
5778    (set_attr "mode" "SI")])
5780 ; For comparisons against 1, -1 and 128, we may generate better code
5781 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5782 ; is matched then.  We can't accept general immediate, because for
5783 ; case of overflows,  the result is messed up.
5784 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5785 ; only for comparisons not depending on it.
5787 (define_insn "*adddi_4"
5788   [(set (reg FLAGS_REG)
5789         (compare
5790           (match_operand:DI 1 "nonimmediate_operand" "0")
5791           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5792    (clobber (match_scratch:DI 0 "=rm"))]
5793   "TARGET_64BIT
5794    && ix86_match_ccmode (insn, CCGCmode)"
5796   switch (get_attr_type (insn))
5797     {
5798     case TYPE_INCDEC:
5799       if (operands[2] == constm1_rtx)
5800         return "inc{q}\t%0";
5801       else
5802         {
5803           gcc_assert (operands[2] == const1_rtx);
5804           return "dec{q}\t%0";
5805         }
5807     default:
5808       if (x86_maybe_negate_const_int (&operands[2], DImode))
5809         return "add{q}\t{%2, %0|%0, %2}";
5811       return "sub{q}\t{%2, %0|%0, %2}";
5812     }
5814   [(set (attr "type")
5815      (if_then_else (match_operand:DI 2 "incdec_operand")
5816         (const_string "incdec")
5817         (const_string "alu")))
5818    (set (attr "length_immediate")
5819       (if_then_else
5820         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5821         (const_string "1")
5822         (const_string "*")))
5823    (set_attr "mode" "DI")])
5825 ; For comparisons against 1, -1 and 128, we may generate better code
5826 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5827 ; is matched then.  We can't accept general immediate, because for
5828 ; case of overflows,  the result is messed up.
5829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5830 ; only for comparisons not depending on it.
5832 (define_insn "*add<mode>_4"
5833   [(set (reg FLAGS_REG)
5834         (compare
5835           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5836           (match_operand:SWI124 2 "const_int_operand" "n")))
5837    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5838   "ix86_match_ccmode (insn, CCGCmode)"
5840   switch (get_attr_type (insn))
5841     {
5842     case TYPE_INCDEC:
5843       if (operands[2] == constm1_rtx)
5844         return "inc{<imodesuffix>}\t%0";
5845       else
5846         {
5847           gcc_assert (operands[2] == const1_rtx);
5848           return "dec{<imodesuffix>}\t%0";
5849         }
5851     default:
5852       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5855       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5856     }
5858   [(set (attr "type")
5859      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5860         (const_string "incdec")
5861         (const_string "alu")))
5862    (set (attr "length_immediate")
5863       (if_then_else
5864         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5865         (const_string "1")
5866         (const_string "*")))
5867    (set_attr "mode" "<MODE>")])
5869 (define_insn "*add<mode>_5"
5870   [(set (reg FLAGS_REG)
5871         (compare
5872           (plus:SWI
5873             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5874             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5875           (const_int 0)))
5876    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5877   "ix86_match_ccmode (insn, CCGOCmode)
5878    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5880   switch (get_attr_type (insn))
5881     {
5882     case TYPE_INCDEC:
5883       if (operands[2] == const1_rtx)
5884         return "inc{<imodesuffix>}\t%0";
5885       else
5886         {
5887           gcc_assert (operands[2] == constm1_rtx);
5888           return "dec{<imodesuffix>}\t%0";
5889         }
5891     default:
5892       if (which_alternative == 1)
5893         std::swap (operands[1], operands[2]);
5895       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5896       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5897         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5899       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5900     }
5902   [(set (attr "type")
5903      (if_then_else (match_operand:SWI 2 "incdec_operand")
5904         (const_string "incdec")
5905         (const_string "alu")))
5906    (set (attr "length_immediate")
5907       (if_then_else
5908         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5909         (const_string "1")
5910         (const_string "*")))
5911    (set_attr "mode" "<MODE>")])
5913 (define_insn "addqi_ext_1"
5914   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5915                          (const_int 8)
5916                          (const_int 8))
5917         (subreg:SI
5918           (plus:QI
5919             (subreg:QI
5920               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
5921                                (const_int 8)
5922                                (const_int 8)) 0)
5923             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5924    (clobber (reg:CC FLAGS_REG))]
5925   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
5926    rtx_equal_p (operands[0], operands[1])"
5928   switch (get_attr_type (insn))
5929     {
5930     case TYPE_INCDEC:
5931       if (operands[2] == const1_rtx)
5932         return "inc{b}\t%h0";
5933       else
5934         {
5935           gcc_assert (operands[2] == constm1_rtx);
5936           return "dec{b}\t%h0";
5937         }
5939     default:
5940       return "add{b}\t{%2, %h0|%h0, %2}";
5941     }
5943   [(set_attr "isa" "*,nox64")
5944    (set (attr "type")
5945      (if_then_else (match_operand:QI 2 "incdec_operand")
5946         (const_string "incdec")
5947         (const_string "alu")))
5948    (set_attr "mode" "QI")])
5950 (define_insn "*addqi_ext_2"
5951   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
5952                          (const_int 8)
5953                          (const_int 8))
5954         (subreg:SI
5955           (plus:QI
5956             (subreg:QI
5957               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
5958                                (const_int 8)
5959                                (const_int 8)) 0)
5960             (subreg:QI
5961               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
5962                                (const_int 8)
5963                                (const_int 8)) 0)) 0))
5964   (clobber (reg:CC FLAGS_REG))]
5965   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
5966    rtx_equal_p (operands[0], operands[1])
5967    || rtx_equal_p (operands[0], operands[2])"
5968   "add{b}\t{%h2, %h0|%h0, %h2}"
5969   [(set_attr "type" "alu")
5970    (set_attr "mode" "QI")])
5972 ;; Add with jump on overflow.
5973 (define_expand "addv<mode>4"
5974   [(parallel [(set (reg:CCO FLAGS_REG)
5975                    (eq:CCO (plus:<DWI>
5976                               (sign_extend:<DWI>
5977                                  (match_operand:SWI 1 "nonimmediate_operand"))
5978                               (match_dup 4))
5979                            (sign_extend:<DWI>
5980                               (plus:SWI (match_dup 1)
5981                                         (match_operand:SWI 2
5982                                            "<general_operand>")))))
5983               (set (match_operand:SWI 0 "register_operand")
5984                    (plus:SWI (match_dup 1) (match_dup 2)))])
5985    (set (pc) (if_then_else
5986                (eq (reg:CCO FLAGS_REG) (const_int 0))
5987                (label_ref (match_operand 3))
5988                (pc)))]
5989   ""
5991   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5992   if (CONST_INT_P (operands[2]))
5993     operands[4] = operands[2];
5994   else
5995     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5998 (define_insn "*addv<mode>4"
5999   [(set (reg:CCO FLAGS_REG)
6000         (eq:CCO (plus:<DWI>
6001                    (sign_extend:<DWI>
6002                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6003                    (sign_extend:<DWI>
6004                       (match_operand:SWI 2 "<general_sext_operand>"
6005                                            "<r>mWe,<r>We")))
6006                 (sign_extend:<DWI>
6007                    (plus:SWI (match_dup 1) (match_dup 2)))))
6008    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6009         (plus:SWI (match_dup 1) (match_dup 2)))]
6010   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6011   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6012   [(set_attr "type" "alu")
6013    (set_attr "mode" "<MODE>")])
6015 (define_insn "*addv<mode>4_1"
6016   [(set (reg:CCO FLAGS_REG)
6017         (eq:CCO (plus:<DWI>
6018                    (sign_extend:<DWI>
6019                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6020                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6021                 (sign_extend:<DWI>
6022                    (plus:SWI (match_dup 1)
6023                              (match_operand:SWI 2 "x86_64_immediate_operand"
6024                                                   "<i>")))))
6025    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6026         (plus:SWI (match_dup 1) (match_dup 2)))]
6027   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6028    && CONST_INT_P (operands[2])
6029    && INTVAL (operands[2]) == INTVAL (operands[3])"
6030   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6031   [(set_attr "type" "alu")
6032    (set_attr "mode" "<MODE>")
6033    (set (attr "length_immediate")
6034         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6035                   (const_string "1")
6036                (match_test "<MODE_SIZE> == 8")
6037                   (const_string "4")]
6038               (const_string "<MODE_SIZE>")))])
6040 (define_expand "uaddv<mode>4"
6041   [(parallel [(set (reg:CCC FLAGS_REG)
6042                    (compare:CCC
6043                      (plus:SWI
6044                        (match_operand:SWI 1 "nonimmediate_operand")
6045                        (match_operand:SWI 2 "<general_operand>"))
6046                      (match_dup 1)))
6047               (set (match_operand:SWI 0 "register_operand")
6048                    (plus:SWI (match_dup 1) (match_dup 2)))])
6049    (set (pc) (if_then_else
6050                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6051                (label_ref (match_operand 3))
6052                (pc)))]
6053   ""
6054   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6056 ;; The lea patterns for modes less than 32 bits need to be matched by
6057 ;; several insns converted to real lea by splitters.
6059 (define_insn_and_split "*lea<mode>_general_1"
6060   [(set (match_operand:SWI12 0 "register_operand" "=r")
6061         (plus:SWI12
6062           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6063                       (match_operand:SWI12 2 "register_operand" "r"))
6064           (match_operand:SWI12 3 "immediate_operand" "i")))]
6065   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6066   "#"
6067   "&& reload_completed"
6068   [(set (match_dup 0)
6069         (plus:SI
6070           (plus:SI (match_dup 1) (match_dup 2))
6071           (match_dup 3)))]
6073   operands[0] = gen_lowpart (SImode, operands[0]);
6074   operands[1] = gen_lowpart (SImode, operands[1]);
6075   operands[2] = gen_lowpart (SImode, operands[2]);
6076   operands[3] = gen_lowpart (SImode, operands[3]);
6078   [(set_attr "type" "lea")
6079    (set_attr "mode" "SI")])
6081 (define_insn_and_split "*lea<mode>_general_2"
6082   [(set (match_operand:SWI12 0 "register_operand" "=r")
6083         (plus:SWI12
6084           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6085                       (match_operand 2 "const248_operand" "n"))
6086           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6087   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6088   "#"
6089   "&& reload_completed"
6090   [(set (match_dup 0)
6091         (plus:SI
6092           (mult:SI (match_dup 1) (match_dup 2))
6093           (match_dup 3)))]
6095   operands[0] = gen_lowpart (SImode, operands[0]);
6096   operands[1] = gen_lowpart (SImode, operands[1]);
6097   operands[3] = gen_lowpart (SImode, operands[3]);
6099   [(set_attr "type" "lea")
6100    (set_attr "mode" "SI")])
6102 (define_insn_and_split "*lea<mode>_general_2b"
6103   [(set (match_operand:SWI12 0 "register_operand" "=r")
6104         (plus:SWI12
6105           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6106                         (match_operand 2 "const123_operand" "n"))
6107           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6108   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6109   "#"
6110   "&& reload_completed"
6111   [(set (match_dup 0)
6112         (plus:SI
6113           (ashift:SI (match_dup 1) (match_dup 2))
6114           (match_dup 3)))]
6116   operands[0] = gen_lowpart (SImode, operands[0]);
6117   operands[1] = gen_lowpart (SImode, operands[1]);
6118   operands[3] = gen_lowpart (SImode, operands[3]);
6120   [(set_attr "type" "lea")
6121    (set_attr "mode" "SI")])
6123 (define_insn_and_split "*lea<mode>_general_3"
6124   [(set (match_operand:SWI12 0 "register_operand" "=r")
6125         (plus:SWI12
6126           (plus:SWI12
6127             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6128                         (match_operand 2 "const248_operand" "n"))
6129             (match_operand:SWI12 3 "register_operand" "r"))
6130           (match_operand:SWI12 4 "immediate_operand" "i")))]
6131   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6132   "#"
6133   "&& reload_completed"
6134   [(set (match_dup 0)
6135         (plus:SI
6136           (plus:SI
6137             (mult:SI (match_dup 1) (match_dup 2))
6138             (match_dup 3))
6139           (match_dup 4)))]
6141   operands[0] = gen_lowpart (SImode, operands[0]);
6142   operands[1] = gen_lowpart (SImode, operands[1]);
6143   operands[3] = gen_lowpart (SImode, operands[3]);
6144   operands[4] = gen_lowpart (SImode, operands[4]);
6146   [(set_attr "type" "lea")
6147    (set_attr "mode" "SI")])
6149 (define_insn_and_split "*lea<mode>_general_3b"
6150   [(set (match_operand:SWI12 0 "register_operand" "=r")
6151         (plus:SWI12
6152           (plus:SWI12
6153             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6154                           (match_operand 2 "const123_operand" "n"))
6155             (match_operand:SWI12 3 "register_operand" "r"))
6156           (match_operand:SWI12 4 "immediate_operand" "i")))]
6157   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6158   "#"
6159   "&& reload_completed"
6160   [(set (match_dup 0)
6161         (plus:SI
6162           (plus:SI
6163             (ashift:SI (match_dup 1) (match_dup 2))
6164             (match_dup 3))
6165           (match_dup 4)))]
6167   operands[0] = gen_lowpart (SImode, operands[0]);
6168   operands[1] = gen_lowpart (SImode, operands[1]);
6169   operands[3] = gen_lowpart (SImode, operands[3]);
6170   operands[4] = gen_lowpart (SImode, operands[4]);
6172   [(set_attr "type" "lea")
6173    (set_attr "mode" "SI")])
6175 (define_insn_and_split "*lea<mode>_general_4"
6176   [(set (match_operand:SWI12 0 "register_operand" "=r")
6177         (any_or:SWI12
6178           (ashift:SWI12
6179             (match_operand:SWI12 1 "index_register_operand" "l")
6180             (match_operand 2 "const_0_to_3_operand" "n"))
6181           (match_operand 3 "const_int_operand" "n")))]
6182   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6183    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6184        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6185   "#"
6186   "&& reload_completed"
6187   [(set (match_dup 0)
6188         (plus:SI
6189           (mult:SI (match_dup 1) (match_dup 2))
6190           (match_dup 3)))]
6192   operands[0] = gen_lowpart (SImode, operands[0]);
6193   operands[1] = gen_lowpart (SImode, operands[1]);
6194   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6196   [(set_attr "type" "lea")
6197    (set_attr "mode" "SI")])
6199 (define_insn_and_split "*lea<mode>_general_4"
6200   [(set (match_operand:SWI48 0 "register_operand" "=r")
6201         (any_or:SWI48
6202           (ashift:SWI48
6203             (match_operand:SWI48 1 "index_register_operand" "l")
6204             (match_operand 2 "const_0_to_3_operand" "n"))
6205           (match_operand 3 "const_int_operand" "n")))]
6206   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6207    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6208   "#"
6209   "&& reload_completed"
6210   [(set (match_dup 0)
6211         (plus:SWI48
6212           (mult:SWI48 (match_dup 1) (match_dup 2))
6213           (match_dup 3)))]
6214   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6215   [(set_attr "type" "lea")
6216    (set_attr "mode" "<MODE>")])
6218 ;; Subtract instructions
6220 (define_expand "sub<mode>3"
6221   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6222         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6223                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6224   ""
6225   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6227 (define_insn_and_split "*sub<dwi>3_doubleword"
6228   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6229         (minus:<DWI>
6230           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6231           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6232                                                         "ro<di>,r<di>")))
6233    (clobber (reg:CC FLAGS_REG))]
6234   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6235   "#"
6236   "reload_completed"
6237   [(parallel [(set (reg:CC FLAGS_REG)
6238                    (compare:CC (match_dup 1) (match_dup 2)))
6239               (set (match_dup 0)
6240                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6241    (parallel [(set (match_dup 3)
6242                    (minus:DWIH
6243                      (minus:DWIH
6244                        (match_dup 4)
6245                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6246                      (match_dup 5)))
6247               (clobber (reg:CC FLAGS_REG))])]
6249   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6250   if (operands[2] == const0_rtx)
6251     {
6252       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6253       DONE;
6254     }
6257 (define_insn "*sub<mode>_1"
6258   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6259         (minus:SWI
6260           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6261           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6262    (clobber (reg:CC FLAGS_REG))]
6263   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6264   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6265   [(set_attr "type" "alu")
6266    (set_attr "mode" "<MODE>")])
6268 (define_insn "*subsi_1_zext"
6269   [(set (match_operand:DI 0 "register_operand" "=r")
6270         (zero_extend:DI
6271           (minus:SI (match_operand:SI 1 "register_operand" "0")
6272                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6273    (clobber (reg:CC FLAGS_REG))]
6274   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6275   "sub{l}\t{%2, %k0|%k0, %2}"
6276   [(set_attr "type" "alu")
6277    (set_attr "mode" "SI")])
6279 (define_insn "*subqi_1_slp"
6280   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6281         (minus:QI (match_dup 0)
6282                   (match_operand:QI 1 "general_operand" "qn,qm")))
6283    (clobber (reg:CC FLAGS_REG))]
6284   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6285    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6286   "sub{b}\t{%1, %0|%0, %1}"
6287   [(set_attr "type" "alu1")
6288    (set_attr "mode" "QI")])
6290 (define_insn "*sub<mode>_2"
6291   [(set (reg FLAGS_REG)
6292         (compare
6293           (minus:SWI
6294             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6295             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6296           (const_int 0)))
6297    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6298         (minus:SWI (match_dup 1) (match_dup 2)))]
6299   "ix86_match_ccmode (insn, CCGOCmode)
6300    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6301   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6302   [(set_attr "type" "alu")
6303    (set_attr "mode" "<MODE>")])
6305 (define_insn "*subsi_2_zext"
6306   [(set (reg FLAGS_REG)
6307         (compare
6308           (minus:SI (match_operand:SI 1 "register_operand" "0")
6309                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6310           (const_int 0)))
6311    (set (match_operand:DI 0 "register_operand" "=r")
6312         (zero_extend:DI
6313           (minus:SI (match_dup 1)
6314                     (match_dup 2))))]
6315   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6316    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6317   "sub{l}\t{%2, %k0|%k0, %2}"
6318   [(set_attr "type" "alu")
6319    (set_attr "mode" "SI")])
6321 ;; Subtract with jump on overflow.
6322 (define_expand "subv<mode>4"
6323   [(parallel [(set (reg:CCO FLAGS_REG)
6324                    (eq:CCO (minus:<DWI>
6325                               (sign_extend:<DWI>
6326                                  (match_operand:SWI 1 "nonimmediate_operand"))
6327                               (match_dup 4))
6328                            (sign_extend:<DWI>
6329                               (minus:SWI (match_dup 1)
6330                                          (match_operand:SWI 2
6331                                             "<general_operand>")))))
6332               (set (match_operand:SWI 0 "register_operand")
6333                    (minus:SWI (match_dup 1) (match_dup 2)))])
6334    (set (pc) (if_then_else
6335                (eq (reg:CCO FLAGS_REG) (const_int 0))
6336                (label_ref (match_operand 3))
6337                (pc)))]
6338   ""
6340   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6341   if (CONST_INT_P (operands[2]))
6342     operands[4] = operands[2];
6343   else
6344     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6347 (define_insn "*subv<mode>4"
6348   [(set (reg:CCO FLAGS_REG)
6349         (eq:CCO (minus:<DWI>
6350                    (sign_extend:<DWI>
6351                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6352                    (sign_extend:<DWI>
6353                       (match_operand:SWI 2 "<general_sext_operand>"
6354                                            "<r>We,<r>m")))
6355                 (sign_extend:<DWI>
6356                    (minus:SWI (match_dup 1) (match_dup 2)))))
6357    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6358         (minus:SWI (match_dup 1) (match_dup 2)))]
6359   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6360   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6361   [(set_attr "type" "alu")
6362    (set_attr "mode" "<MODE>")])
6364 (define_insn "*subv<mode>4_1"
6365   [(set (reg:CCO FLAGS_REG)
6366         (eq:CCO (minus:<DWI>
6367                    (sign_extend:<DWI>
6368                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6369                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6370                 (sign_extend:<DWI>
6371                    (minus:SWI (match_dup 1)
6372                               (match_operand:SWI 2 "x86_64_immediate_operand"
6373                                                    "<i>")))))
6374    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6375         (minus:SWI (match_dup 1) (match_dup 2)))]
6376   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6377    && CONST_INT_P (operands[2])
6378    && INTVAL (operands[2]) == INTVAL (operands[3])"
6379   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6380   [(set_attr "type" "alu")
6381    (set_attr "mode" "<MODE>")
6382    (set (attr "length_immediate")
6383         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6384                   (const_string "1")
6385                (match_test "<MODE_SIZE> == 8")
6386                   (const_string "4")]
6387               (const_string "<MODE_SIZE>")))])
6389 (define_expand "usubv<mode>4"
6390   [(parallel [(set (reg:CC FLAGS_REG)
6391                    (compare:CC
6392                      (match_operand:SWI 1 "nonimmediate_operand")
6393                      (match_operand:SWI 2 "<general_operand>")))
6394               (set (match_operand:SWI 0 "register_operand")
6395                    (minus:SWI (match_dup 1) (match_dup 2)))])
6396    (set (pc) (if_then_else
6397                (ltu (reg:CC FLAGS_REG) (const_int 0))
6398                (label_ref (match_operand 3))
6399                (pc)))]
6400   ""
6401   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6403 (define_insn "*sub<mode>_3"
6404   [(set (reg FLAGS_REG)
6405         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6406                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6407    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6408         (minus:SWI (match_dup 1) (match_dup 2)))]
6409   "ix86_match_ccmode (insn, CCmode)
6410    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6411   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6412   [(set_attr "type" "alu")
6413    (set_attr "mode" "<MODE>")])
6415 (define_peephole2
6416   [(parallel
6417      [(set (reg:CC FLAGS_REG)
6418            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6419                        (match_operand:SWI 1 "general_gr_operand")))
6420       (set (match_dup 0)
6421            (minus:SWI (match_dup 0) (match_dup 1)))])]
6422   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6423   [(set (reg:CC FLAGS_REG)
6424         (compare:CC (match_dup 0) (match_dup 1)))])
6426 (define_insn "*subsi_3_zext"
6427   [(set (reg FLAGS_REG)
6428         (compare (match_operand:SI 1 "register_operand" "0")
6429                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6430    (set (match_operand:DI 0 "register_operand" "=r")
6431         (zero_extend:DI
6432           (minus:SI (match_dup 1)
6433                     (match_dup 2))))]
6434   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6435    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6436   "sub{l}\t{%2, %1|%1, %2}"
6437   [(set_attr "type" "alu")
6438    (set_attr "mode" "SI")])
6440 ;; Add with carry and subtract with borrow
6442 (define_insn "add<mode>3_carry"
6443   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6444         (plus:SWI
6445           (plus:SWI
6446             (match_operator:SWI 4 "ix86_carry_flag_operator"
6447              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6448             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6449           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6450    (clobber (reg:CC FLAGS_REG))]
6451   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6452   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6453   [(set_attr "type" "alu")
6454    (set_attr "use_carry" "1")
6455    (set_attr "pent_pair" "pu")
6456    (set_attr "mode" "<MODE>")])
6458 (define_insn "*add<mode>3_carry_0"
6459   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6460         (plus:SWI
6461           (match_operator:SWI 3 "ix86_carry_flag_operator"
6462             [(match_operand 2 "flags_reg_operand") (const_int 0)])
6463           (match_operand:SWI 1 "nonimmediate_operand" "0")))
6464    (clobber (reg:CC FLAGS_REG))]
6465   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6466   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6467   [(set_attr "type" "alu")
6468    (set_attr "use_carry" "1")
6469    (set_attr "pent_pair" "pu")
6470    (set_attr "mode" "<MODE>")])
6472 (define_insn "*addsi3_carry_zext"
6473   [(set (match_operand:DI 0 "register_operand" "=r")
6474         (zero_extend:DI
6475           (plus:SI
6476             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6477                       [(reg FLAGS_REG) (const_int 0)])
6478                      (match_operand:SI 1 "register_operand" "%0"))
6479             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6480    (clobber (reg:CC FLAGS_REG))]
6481   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6482   "adc{l}\t{%2, %k0|%k0, %2}"
6483   [(set_attr "type" "alu")
6484    (set_attr "use_carry" "1")
6485    (set_attr "pent_pair" "pu")
6486    (set_attr "mode" "SI")])
6488 (define_insn "*addsi3_carry_zext_0"
6489   [(set (match_operand:DI 0 "register_operand" "=r")
6490         (zero_extend:DI
6491           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6492                     [(reg FLAGS_REG) (const_int 0)])
6493                    (match_operand:SI 1 "register_operand" "0"))))
6494    (clobber (reg:CC FLAGS_REG))]
6495   "TARGET_64BIT"
6496   "adc{l}\t{$0, %k0|%k0, 0}"
6497   [(set_attr "type" "alu")
6498    (set_attr "use_carry" "1")
6499    (set_attr "pent_pair" "pu")
6500    (set_attr "mode" "SI")])
6502 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6504 (define_insn "addcarry<mode>"
6505   [(set (reg:CCC FLAGS_REG)
6506         (compare:CCC
6507           (zero_extend:<DWI>
6508             (plus:SWI48
6509               (plus:SWI48
6510                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6511                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
6512                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6513               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6514           (plus:<DWI>
6515             (zero_extend:<DWI> (match_dup 2))
6516             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6517               [(match_dup 3) (const_int 0)]))))
6518    (set (match_operand:SWI48 0 "register_operand" "=r")
6519         (plus:SWI48 (plus:SWI48 (match_op_dup 5
6520                                  [(match_dup 3) (const_int 0)])
6521                                 (match_dup 1))
6522                     (match_dup 2)))]
6523   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6524   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6525   [(set_attr "type" "alu")
6526    (set_attr "use_carry" "1")
6527    (set_attr "pent_pair" "pu")
6528    (set_attr "mode" "<MODE>")])
6530 (define_expand "addcarry<mode>_0"
6531   [(parallel
6532      [(set (reg:CCC FLAGS_REG)
6533            (compare:CCC
6534              (plus:SWI48
6535                (match_operand:SWI48 1 "nonimmediate_operand")
6536                (match_operand:SWI48 2 "x86_64_general_operand"))
6537              (match_dup 1)))
6538       (set (match_operand:SWI48 0 "register_operand")
6539            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6540   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6542 (define_insn "sub<mode>3_carry"
6543   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6544         (minus:SWI
6545           (minus:SWI
6546             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6547             (match_operator:SWI 4 "ix86_carry_flag_operator"
6548              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6549           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6550    (clobber (reg:CC FLAGS_REG))]
6551   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6552   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6553   [(set_attr "type" "alu")
6554    (set_attr "use_carry" "1")
6555    (set_attr "pent_pair" "pu")
6556    (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>3_carry_0"
6559   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6560         (minus:SWI
6561           (match_operand:SWI 1 "nonimmediate_operand" "0")
6562           (match_operator:SWI 3 "ix86_carry_flag_operator"
6563             [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6564    (clobber (reg:CC FLAGS_REG))]
6565   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6566   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6567   [(set_attr "type" "alu")
6568    (set_attr "use_carry" "1")
6569    (set_attr "pent_pair" "pu")
6570    (set_attr "mode" "<MODE>")])
6572 (define_insn "*subsi3_carry_zext"
6573   [(set (match_operand:DI 0 "register_operand" "=r")
6574         (zero_extend:DI
6575           (minus:SI
6576             (minus:SI
6577               (match_operand:SI 1 "register_operand" "0")
6578               (match_operator:SI 3 "ix86_carry_flag_operator"
6579                [(reg FLAGS_REG) (const_int 0)]))
6580             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6581    (clobber (reg:CC FLAGS_REG))]
6582   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6583   "sbb{l}\t{%2, %k0|%k0, %2}"
6584   [(set_attr "type" "alu")
6585    (set_attr "use_carry" "1")
6586    (set_attr "pent_pair" "pu")
6587    (set_attr "mode" "SI")])
6589 (define_insn "*subsi3_carry_zext_0"
6590   [(set (match_operand:DI 0 "register_operand" "=r")
6591         (zero_extend:DI
6592           (minus:SI
6593             (match_operand:SI 1 "register_operand" "0")
6594             (match_operator:SI 2 "ix86_carry_flag_operator"
6595               [(reg FLAGS_REG) (const_int 0)]))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "TARGET_64BIT"
6598   "sbb{l}\t{$0, %k0|%k0, 0}"
6599   [(set_attr "type" "alu")
6600    (set_attr "use_carry" "1")
6601    (set_attr "pent_pair" "pu")
6602    (set_attr "mode" "SI")])
6604 (define_insn "sub<mode>3_carry_ccc"
6605   [(set (reg:CCC FLAGS_REG)
6606         (compare:CCC
6607           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6608           (plus:<DWI>
6609             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6610             (zero_extend:<DWI>
6611               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6612    (clobber (match_scratch:DWIH 0 "=r"))]
6613   ""
6614   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6615   [(set_attr "type" "alu")
6616    (set_attr "mode" "<MODE>")])
6618 (define_insn "*sub<mode>3_carry_ccc_1"
6619   [(set (reg:CCC FLAGS_REG)
6620         (compare:CCC
6621           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6622           (plus:<DWI>
6623             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6624             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6625    (clobber (match_scratch:DWIH 0 "=r"))]
6626   ""
6628   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6629   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "<MODE>")])
6634 ;; The sign flag is set from the
6635 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6636 ;; result, the overflow flag likewise, but the overflow flag is also
6637 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6638 (define_insn "sub<mode>3_carry_ccgz"
6639   [(set (reg:CCGZ FLAGS_REG)
6640         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6641                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6642                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6643                      UNSPEC_SBB))
6644    (clobber (match_scratch:DWIH 0 "=r"))]
6645   ""
6646   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "<MODE>")])
6650 (define_insn "subborrow<mode>"
6651   [(set (reg:CCC FLAGS_REG)
6652         (compare:CCC
6653           (zero_extend:<DWI>
6654             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6655           (plus:<DWI>
6656             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6657               [(match_operand 3 "flags_reg_operand") (const_int 0)])
6658             (zero_extend:<DWI>
6659               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6660    (set (match_operand:SWI48 0 "register_operand" "=r")
6661         (minus:SWI48 (minus:SWI48
6662                        (match_dup 1)
6663                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
6664                          [(match_dup 3) (const_int 0)]))
6665                      (match_dup 2)))]
6666   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6667   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6668   [(set_attr "type" "alu")
6669    (set_attr "use_carry" "1")
6670    (set_attr "pent_pair" "pu")
6671    (set_attr "mode" "<MODE>")])
6673 (define_expand "subborrow<mode>_0"
6674   [(parallel
6675      [(set (reg:CC FLAGS_REG)
6676            (compare:CC
6677              (match_operand:SWI48 1 "nonimmediate_operand")
6678              (match_operand:SWI48 2 "<general_operand>")))
6679       (set (match_operand:SWI48 0 "register_operand")
6680            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6681   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6683 ;; Overflow setting add instructions
6685 (define_expand "addqi3_cconly_overflow"
6686   [(parallel
6687      [(set (reg:CCC FLAGS_REG)
6688            (compare:CCC
6689              (plus:QI
6690                (match_operand:QI 0 "nonimmediate_operand")
6691                (match_operand:QI 1 "general_operand"))
6692              (match_dup 0)))
6693       (clobber (match_scratch:QI 2))])]
6694   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6696 (define_insn "*add<mode>3_cconly_overflow_1"
6697   [(set (reg:CCC FLAGS_REG)
6698         (compare:CCC
6699           (plus:SWI
6700             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6701             (match_operand:SWI 2 "<general_operand>" "<g>"))
6702           (match_dup 1)))
6703    (clobber (match_scratch:SWI 0 "=<r>"))]
6704   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6706   [(set_attr "type" "alu")
6707    (set_attr "mode" "<MODE>")])
6709 (define_insn "*add<mode>3_cc_overflow_1"
6710   [(set (reg:CCC FLAGS_REG)
6711         (compare:CCC
6712             (plus:SWI
6713                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6714                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6715             (match_dup 1)))
6716    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6717         (plus:SWI (match_dup 1) (match_dup 2)))]
6718   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6719   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6720   [(set_attr "type" "alu")
6721    (set_attr "mode" "<MODE>")])
6723 (define_insn "*addsi3_zext_cc_overflow_1"
6724   [(set (reg:CCC FLAGS_REG)
6725         (compare:CCC
6726           (plus:SI
6727             (match_operand:SI 1 "nonimmediate_operand" "%0")
6728             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6729           (match_dup 1)))
6730    (set (match_operand:DI 0 "register_operand" "=r")
6731         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6732   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6733   "add{l}\t{%2, %k0|%k0, %2}"
6734   [(set_attr "type" "alu")
6735    (set_attr "mode" "SI")])
6737 (define_insn "*add<mode>3_cconly_overflow_2"
6738   [(set (reg:CCC FLAGS_REG)
6739         (compare:CCC
6740           (plus:SWI
6741             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6742             (match_operand:SWI 2 "<general_operand>" "<g>"))
6743           (match_dup 2)))
6744    (clobber (match_scratch:SWI 0 "=<r>"))]
6745   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6746   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6747   [(set_attr "type" "alu")
6748    (set_attr "mode" "<MODE>")])
6750 (define_insn "*add<mode>3_cc_overflow_2"
6751   [(set (reg:CCC FLAGS_REG)
6752         (compare:CCC
6753             (plus:SWI
6754                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6755                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6756             (match_dup 2)))
6757    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6758         (plus:SWI (match_dup 1) (match_dup 2)))]
6759   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6760   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "<MODE>")])
6764 (define_insn "*addsi3_zext_cc_overflow_2"
6765   [(set (reg:CCC FLAGS_REG)
6766         (compare:CCC
6767           (plus:SI
6768             (match_operand:SI 1 "nonimmediate_operand" "%0")
6769             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6770           (match_dup 2)))
6771    (set (match_operand:DI 0 "register_operand" "=r")
6772         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6773   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6774   "add{l}\t{%2, %k0|%k0, %2}"
6775   [(set_attr "type" "alu")
6776    (set_attr "mode" "SI")])
6778 ;; The patterns that match these are at the end of this file.
6780 (define_expand "<plusminus_insn>xf3"
6781   [(set (match_operand:XF 0 "register_operand")
6782         (plusminus:XF
6783           (match_operand:XF 1 "register_operand")
6784           (match_operand:XF 2 "register_operand")))]
6785   "TARGET_80387")
6787 (define_expand "<plusminus_insn><mode>3"
6788   [(set (match_operand:MODEF 0 "register_operand")
6789         (plusminus:MODEF
6790           (match_operand:MODEF 1 "register_operand")
6791           (match_operand:MODEF 2 "nonimmediate_operand")))]
6792   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6793     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6795 ;; Multiply instructions
6797 (define_expand "mul<mode>3"
6798   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6799                    (mult:SWIM248
6800                      (match_operand:SWIM248 1 "register_operand")
6801                      (match_operand:SWIM248 2 "<general_operand>")))
6802               (clobber (reg:CC FLAGS_REG))])])
6804 (define_expand "mulqi3"
6805   [(parallel [(set (match_operand:QI 0 "register_operand")
6806                    (mult:QI
6807                      (match_operand:QI 1 "register_operand")
6808                      (match_operand:QI 2 "nonimmediate_operand")))
6809               (clobber (reg:CC FLAGS_REG))])]
6810   "TARGET_QIMODE_MATH")
6812 ;; On AMDFAM10
6813 ;; IMUL reg32/64, reg32/64, imm8        Direct
6814 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6815 ;; IMUL reg32/64, reg32/64, imm32       Direct
6816 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6817 ;; IMUL reg32/64, reg32/64              Direct
6818 ;; IMUL reg32/64, mem32/64              Direct
6820 ;; On BDVER1, all above IMULs use DirectPath
6822 ;; On AMDFAM10
6823 ;; IMUL reg16, reg16, imm8      VectorPath
6824 ;; IMUL reg16, mem16, imm8      VectorPath
6825 ;; IMUL reg16, reg16, imm16     VectorPath
6826 ;; IMUL reg16, mem16, imm16     VectorPath
6827 ;; IMUL reg16, reg16            Direct
6828 ;; IMUL reg16, mem16            Direct
6830 ;; On BDVER1, all HI MULs use DoublePath
6832 (define_insn "*mul<mode>3_1"
6833   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6834         (mult:SWIM248
6835           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6836           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6837    (clobber (reg:CC FLAGS_REG))]
6838   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6839   "@
6840    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6841    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6842    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6843   [(set_attr "type" "imul")
6844    (set_attr "prefix_0f" "0,0,1")
6845    (set (attr "athlon_decode")
6846         (cond [(eq_attr "cpu" "athlon")
6847                   (const_string "vector")
6848                (eq_attr "alternative" "1")
6849                   (const_string "vector")
6850                (and (eq_attr "alternative" "2")
6851                     (ior (match_test "<MODE>mode == HImode")
6852                          (match_operand 1 "memory_operand")))
6853                   (const_string "vector")]
6854               (const_string "direct")))
6855    (set (attr "amdfam10_decode")
6856         (cond [(and (eq_attr "alternative" "0,1")
6857                     (ior (match_test "<MODE>mode == HImode")
6858                          (match_operand 1 "memory_operand")))
6859                   (const_string "vector")]
6860               (const_string "direct")))
6861    (set (attr "bdver1_decode")
6862         (if_then_else
6863           (match_test "<MODE>mode == HImode")
6864             (const_string "double")
6865             (const_string "direct")))
6866    (set_attr "mode" "<MODE>")])
6868 (define_insn "*mulsi3_1_zext"
6869   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6870         (zero_extend:DI
6871           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6872                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6873    (clobber (reg:CC FLAGS_REG))]
6874   "TARGET_64BIT
6875    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6876   "@
6877    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6878    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6879    imul{l}\t{%2, %k0|%k0, %2}"
6880   [(set_attr "type" "imul")
6881    (set_attr "prefix_0f" "0,0,1")
6882    (set (attr "athlon_decode")
6883         (cond [(eq_attr "cpu" "athlon")
6884                   (const_string "vector")
6885                (eq_attr "alternative" "1")
6886                   (const_string "vector")
6887                (and (eq_attr "alternative" "2")
6888                     (match_operand 1 "memory_operand"))
6889                   (const_string "vector")]
6890               (const_string "direct")))
6891    (set (attr "amdfam10_decode")
6892         (cond [(and (eq_attr "alternative" "0,1")
6893                     (match_operand 1 "memory_operand"))
6894                   (const_string "vector")]
6895               (const_string "direct")))
6896    (set_attr "bdver1_decode" "direct")
6897    (set_attr "mode" "SI")])
6899 ;;On AMDFAM10 and BDVER1
6900 ;; MUL reg8     Direct
6901 ;; MUL mem8     Direct
6903 (define_insn "*mulqi3_1"
6904   [(set (match_operand:QI 0 "register_operand" "=a")
6905         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6906                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6907    (clobber (reg:CC FLAGS_REG))]
6908   "TARGET_QIMODE_MATH
6909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6910   "mul{b}\t%2"
6911   [(set_attr "type" "imul")
6912    (set_attr "length_immediate" "0")
6913    (set (attr "athlon_decode")
6914      (if_then_else (eq_attr "cpu" "athlon")
6915         (const_string "vector")
6916         (const_string "direct")))
6917    (set_attr "amdfam10_decode" "direct")
6918    (set_attr "bdver1_decode" "direct")
6919    (set_attr "mode" "QI")])
6921 ;; Multiply with jump on overflow.
6922 (define_expand "mulv<mode>4"
6923   [(parallel [(set (reg:CCO FLAGS_REG)
6924                    (eq:CCO (mult:<DWI>
6925                               (sign_extend:<DWI>
6926                                  (match_operand:SWI248 1 "register_operand"))
6927                               (match_dup 4))
6928                            (sign_extend:<DWI>
6929                               (mult:SWI248 (match_dup 1)
6930                                            (match_operand:SWI248 2
6931                                               "<general_operand>")))))
6932               (set (match_operand:SWI248 0 "register_operand")
6933                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6934    (set (pc) (if_then_else
6935                (eq (reg:CCO FLAGS_REG) (const_int 0))
6936                (label_ref (match_operand 3))
6937                (pc)))]
6938   ""
6940   if (CONST_INT_P (operands[2]))
6941     operands[4] = operands[2];
6942   else
6943     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6946 (define_insn "*mulv<mode>4"
6947   [(set (reg:CCO FLAGS_REG)
6948         (eq:CCO (mult:<DWI>
6949                    (sign_extend:<DWI>
6950                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6951                    (sign_extend:<DWI>
6952                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6953                 (sign_extend:<DWI>
6954                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6955    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6956         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6957   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6958   "@
6959    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6960    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6961   [(set_attr "type" "imul")
6962    (set_attr "prefix_0f" "0,1")
6963    (set (attr "athlon_decode")
6964         (cond [(eq_attr "cpu" "athlon")
6965                   (const_string "vector")
6966                (eq_attr "alternative" "0")
6967                   (const_string "vector")
6968                (and (eq_attr "alternative" "1")
6969                     (match_operand 1 "memory_operand"))
6970                   (const_string "vector")]
6971               (const_string "direct")))
6972    (set (attr "amdfam10_decode")
6973         (cond [(and (eq_attr "alternative" "1")
6974                     (match_operand 1 "memory_operand"))
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set_attr "bdver1_decode" "direct")
6978    (set_attr "mode" "<MODE>")])
6980 (define_insn "*mulvhi4"
6981   [(set (reg:CCO FLAGS_REG)
6982         (eq:CCO (mult:SI
6983                    (sign_extend:SI
6984                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6985                    (sign_extend:SI
6986                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6987                 (sign_extend:SI
6988                    (mult:HI (match_dup 1) (match_dup 2)))))
6989    (set (match_operand:HI 0 "register_operand" "=r")
6990         (mult:HI (match_dup 1) (match_dup 2)))]
6991   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992   "imul{w}\t{%2, %0|%0, %2}"
6993   [(set_attr "type" "imul")
6994    (set_attr "prefix_0f" "1")
6995    (set_attr "athlon_decode" "vector")
6996    (set_attr "amdfam10_decode" "direct")
6997    (set_attr "bdver1_decode" "double")
6998    (set_attr "mode" "HI")])
7000 (define_insn "*mulv<mode>4_1"
7001   [(set (reg:CCO FLAGS_REG)
7002         (eq:CCO (mult:<DWI>
7003                    (sign_extend:<DWI>
7004                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7005                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7006                 (sign_extend:<DWI>
7007                    (mult:SWI248 (match_dup 1)
7008                                 (match_operand:SWI248 2
7009                                    "<immediate_operand>" "K,<i>")))))
7010    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7011         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7012   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7013    && CONST_INT_P (operands[2])
7014    && INTVAL (operands[2]) == INTVAL (operands[3])"
7015   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7016   [(set_attr "type" "imul")
7017    (set (attr "prefix_0f")
7018         (if_then_else
7019           (match_test "<MODE>mode == HImode")
7020             (const_string "0")
7021             (const_string "*")))
7022    (set (attr "athlon_decode")
7023         (cond [(eq_attr "cpu" "athlon")
7024                   (const_string "vector")
7025                (eq_attr "alternative" "1")
7026                   (const_string "vector")]
7027               (const_string "direct")))
7028    (set (attr "amdfam10_decode")
7029         (cond [(ior (match_test "<MODE>mode == HImode")
7030                     (match_operand 1 "memory_operand"))
7031                   (const_string "vector")]
7032               (const_string "direct")))
7033    (set (attr "bdver1_decode")
7034         (if_then_else
7035           (match_test "<MODE>mode == HImode")
7036             (const_string "double")
7037             (const_string "direct")))
7038    (set_attr "mode" "<MODE>")
7039    (set (attr "length_immediate")
7040         (cond [(eq_attr "alternative" "0")
7041                   (const_string "1")
7042                (match_test "<MODE_SIZE> == 8")
7043                   (const_string "4")]
7044               (const_string "<MODE_SIZE>")))])
7046 (define_expand "umulv<mode>4"
7047   [(parallel [(set (reg:CCO FLAGS_REG)
7048                    (eq:CCO (mult:<DWI>
7049                               (zero_extend:<DWI>
7050                                  (match_operand:SWI248 1
7051                                                       "nonimmediate_operand"))
7052                               (zero_extend:<DWI>
7053                                  (match_operand:SWI248 2
7054                                                       "nonimmediate_operand")))
7055                            (zero_extend:<DWI>
7056                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7057               (set (match_operand:SWI248 0 "register_operand")
7058                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7059               (clobber (match_scratch:SWI248 4))])
7060    (set (pc) (if_then_else
7061                (eq (reg:CCO FLAGS_REG) (const_int 0))
7062                (label_ref (match_operand 3))
7063                (pc)))]
7064   ""
7066   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7067     operands[1] = force_reg (<MODE>mode, operands[1]);
7070 (define_insn "*umulv<mode>4"
7071   [(set (reg:CCO FLAGS_REG)
7072         (eq:CCO (mult:<DWI>
7073                    (zero_extend:<DWI>
7074                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7075                    (zero_extend:<DWI>
7076                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7077                 (zero_extend:<DWI>
7078                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7079    (set (match_operand:SWI248 0 "register_operand" "=a")
7080         (mult:SWI248 (match_dup 1) (match_dup 2)))
7081    (clobber (match_scratch:SWI248 3 "=d"))]
7082   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7083   "mul{<imodesuffix>}\t%2"
7084   [(set_attr "type" "imul")
7085    (set_attr "length_immediate" "0")
7086    (set (attr "athlon_decode")
7087      (if_then_else (eq_attr "cpu" "athlon")
7088        (const_string "vector")
7089        (const_string "double")))
7090    (set_attr "amdfam10_decode" "double")
7091    (set_attr "bdver1_decode" "direct")
7092    (set_attr "mode" "<MODE>")])
7094 (define_expand "<u>mulvqi4"
7095   [(parallel [(set (reg:CCO FLAGS_REG)
7096                    (eq:CCO (mult:HI
7097                               (any_extend:HI
7098                                  (match_operand:QI 1 "nonimmediate_operand"))
7099                               (any_extend:HI
7100                                  (match_operand:QI 2 "nonimmediate_operand")))
7101                            (any_extend:HI
7102                               (mult:QI (match_dup 1) (match_dup 2)))))
7103               (set (match_operand:QI 0 "register_operand")
7104                    (mult:QI (match_dup 1) (match_dup 2)))])
7105    (set (pc) (if_then_else
7106                (eq (reg:CCO FLAGS_REG) (const_int 0))
7107                (label_ref (match_operand 3))
7108                (pc)))]
7109   "TARGET_QIMODE_MATH"
7111   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7112     operands[1] = force_reg (QImode, operands[1]);
7115 (define_insn "*<u>mulvqi4"
7116   [(set (reg:CCO FLAGS_REG)
7117         (eq:CCO (mult:HI
7118                    (any_extend:HI
7119                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7120                    (any_extend:HI
7121                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7122                 (any_extend:HI
7123                    (mult:QI (match_dup 1) (match_dup 2)))))
7124    (set (match_operand:QI 0 "register_operand" "=a")
7125         (mult:QI (match_dup 1) (match_dup 2)))]
7126   "TARGET_QIMODE_MATH
7127    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7128   "<sgnprefix>mul{b}\t%2"
7129   [(set_attr "type" "imul")
7130    (set_attr "length_immediate" "0")
7131    (set (attr "athlon_decode")
7132      (if_then_else (eq_attr "cpu" "athlon")
7133         (const_string "vector")
7134         (const_string "direct")))
7135    (set_attr "amdfam10_decode" "direct")
7136    (set_attr "bdver1_decode" "direct")
7137    (set_attr "mode" "QI")])
7139 (define_expand "<u>mul<mode><dwi>3"
7140   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7141                    (mult:<DWI>
7142                      (any_extend:<DWI>
7143                        (match_operand:DWIH 1 "nonimmediate_operand"))
7144                      (any_extend:<DWI>
7145                        (match_operand:DWIH 2 "register_operand"))))
7146               (clobber (reg:CC FLAGS_REG))])])
7148 (define_expand "<u>mulqihi3"
7149   [(parallel [(set (match_operand:HI 0 "register_operand")
7150                    (mult:HI
7151                      (any_extend:HI
7152                        (match_operand:QI 1 "nonimmediate_operand"))
7153                      (any_extend:HI
7154                        (match_operand:QI 2 "register_operand"))))
7155               (clobber (reg:CC FLAGS_REG))])]
7156   "TARGET_QIMODE_MATH")
7158 (define_insn "*bmi2_umul<mode><dwi>3_1"
7159   [(set (match_operand:DWIH 0 "register_operand" "=r")
7160         (mult:DWIH
7161           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7162           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7163    (set (match_operand:DWIH 1 "register_operand" "=r")
7164         (truncate:DWIH
7165           (lshiftrt:<DWI>
7166             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7167                         (zero_extend:<DWI> (match_dup 3)))
7168             (match_operand:QI 4 "const_int_operand" "n"))))]
7169   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7171   "mulx\t{%3, %0, %1|%1, %0, %3}"
7172   [(set_attr "type" "imulx")
7173    (set_attr "prefix" "vex")
7174    (set_attr "mode" "<MODE>")])
7176 (define_insn "*umul<mode><dwi>3_1"
7177   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7178         (mult:<DWI>
7179           (zero_extend:<DWI>
7180             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7181           (zero_extend:<DWI>
7182             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185   "@
7186    #
7187    mul{<imodesuffix>}\t%2"
7188   [(set_attr "isa" "bmi2,*")
7189    (set_attr "type" "imulx,imul")
7190    (set_attr "length_immediate" "*,0")
7191    (set (attr "athlon_decode")
7192         (cond [(eq_attr "alternative" "1")
7193                  (if_then_else (eq_attr "cpu" "athlon")
7194                    (const_string "vector")
7195                    (const_string "double"))]
7196               (const_string "*")))
7197    (set_attr "amdfam10_decode" "*,double")
7198    (set_attr "bdver1_decode" "*,direct")
7199    (set_attr "prefix" "vex,orig")
7200    (set_attr "mode" "<MODE>")])
7202 ;; Convert mul to the mulx pattern to avoid flags dependency.
7203 (define_split
7204  [(set (match_operand:<DWI> 0 "register_operand")
7205        (mult:<DWI>
7206          (zero_extend:<DWI>
7207            (match_operand:DWIH 1 "register_operand"))
7208          (zero_extend:<DWI>
7209            (match_operand:DWIH 2 "nonimmediate_operand"))))
7210   (clobber (reg:CC FLAGS_REG))]
7211  "TARGET_BMI2 && reload_completed
7212   && REGNO (operands[1]) == DX_REG"
7213   [(parallel [(set (match_dup 3)
7214                    (mult:DWIH (match_dup 1) (match_dup 2)))
7215               (set (match_dup 4)
7216                    (truncate:DWIH
7217                      (lshiftrt:<DWI>
7218                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7219                                    (zero_extend:<DWI> (match_dup 2)))
7220                        (match_dup 5))))])]
7222   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7224   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7227 (define_insn "*mul<mode><dwi>3_1"
7228   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7229         (mult:<DWI>
7230           (sign_extend:<DWI>
7231             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7232           (sign_extend:<DWI>
7233             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7234    (clobber (reg:CC FLAGS_REG))]
7235   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7236   "imul{<imodesuffix>}\t%2"
7237   [(set_attr "type" "imul")
7238    (set_attr "length_immediate" "0")
7239    (set (attr "athlon_decode")
7240      (if_then_else (eq_attr "cpu" "athlon")
7241         (const_string "vector")
7242         (const_string "double")))
7243    (set_attr "amdfam10_decode" "double")
7244    (set_attr "bdver1_decode" "direct")
7245    (set_attr "mode" "<MODE>")])
7247 (define_insn "*<u>mulqihi3_1"
7248   [(set (match_operand:HI 0 "register_operand" "=a")
7249         (mult:HI
7250           (any_extend:HI
7251             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7252           (any_extend:HI
7253             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7254    (clobber (reg:CC FLAGS_REG))]
7255   "TARGET_QIMODE_MATH
7256    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7257   "<sgnprefix>mul{b}\t%2"
7258   [(set_attr "type" "imul")
7259    (set_attr "length_immediate" "0")
7260    (set (attr "athlon_decode")
7261      (if_then_else (eq_attr "cpu" "athlon")
7262         (const_string "vector")
7263         (const_string "direct")))
7264    (set_attr "amdfam10_decode" "direct")
7265    (set_attr "bdver1_decode" "direct")
7266    (set_attr "mode" "QI")])
7268 (define_expand "<s>mul<mode>3_highpart"
7269   [(parallel [(set (match_operand:DWIH 0 "register_operand")
7270                    (truncate:DWIH
7271                      (lshiftrt:<DWI>
7272                        (mult:<DWI>
7273                          (any_extend:<DWI>
7274                            (match_operand:DWIH 1 "nonimmediate_operand"))
7275                          (any_extend:<DWI>
7276                            (match_operand:DWIH 2 "register_operand")))
7277                        (match_dup 3))))
7278               (clobber (match_scratch:DWIH 4))
7279               (clobber (reg:CC FLAGS_REG))])]
7280   ""
7281   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7283 (define_insn "*<s>muldi3_highpart_1"
7284   [(set (match_operand:DI 0 "register_operand" "=d")
7285         (truncate:DI
7286           (lshiftrt:TI
7287             (mult:TI
7288               (any_extend:TI
7289                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7290               (any_extend:TI
7291                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7292             (const_int 64))))
7293    (clobber (match_scratch:DI 3 "=1"))
7294    (clobber (reg:CC FLAGS_REG))]
7295   "TARGET_64BIT
7296    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7297   "<sgnprefix>mul{q}\t%2"
7298   [(set_attr "type" "imul")
7299    (set_attr "length_immediate" "0")
7300    (set (attr "athlon_decode")
7301      (if_then_else (eq_attr "cpu" "athlon")
7302         (const_string "vector")
7303         (const_string "double")))
7304    (set_attr "amdfam10_decode" "double")
7305    (set_attr "bdver1_decode" "direct")
7306    (set_attr "mode" "DI")])
7308 (define_insn "*<s>mulsi3_highpart_zext"
7309   [(set (match_operand:DI 0 "register_operand" "=d")
7310         (zero_extend:DI (truncate:SI
7311           (lshiftrt:DI
7312             (mult:DI (any_extend:DI
7313                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7314                      (any_extend:DI
7315                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7316             (const_int 32)))))
7317    (clobber (match_scratch:SI 3 "=1"))
7318    (clobber (reg:CC FLAGS_REG))]
7319   "TARGET_64BIT
7320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7321   "<sgnprefix>mul{l}\t%2"
7322   [(set_attr "type" "imul")
7323    (set_attr "length_immediate" "0")
7324    (set (attr "athlon_decode")
7325      (if_then_else (eq_attr "cpu" "athlon")
7326         (const_string "vector")
7327         (const_string "double")))
7328    (set_attr "amdfam10_decode" "double")
7329    (set_attr "bdver1_decode" "direct")
7330    (set_attr "mode" "SI")])
7332 (define_insn "*<s>mulsi3_highpart_1"
7333   [(set (match_operand:SI 0 "register_operand" "=d")
7334         (truncate:SI
7335           (lshiftrt:DI
7336             (mult:DI
7337               (any_extend:DI
7338                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7339               (any_extend:DI
7340                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7341             (const_int 32))))
7342    (clobber (match_scratch:SI 3 "=1"))
7343    (clobber (reg:CC FLAGS_REG))]
7344   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7345   "<sgnprefix>mul{l}\t%2"
7346   [(set_attr "type" "imul")
7347    (set_attr "length_immediate" "0")
7348    (set (attr "athlon_decode")
7349      (if_then_else (eq_attr "cpu" "athlon")
7350         (const_string "vector")
7351         (const_string "double")))
7352    (set_attr "amdfam10_decode" "double")
7353    (set_attr "bdver1_decode" "direct")
7354    (set_attr "mode" "SI")])
7356 ;; The patterns that match these are at the end of this file.
7358 (define_expand "mulxf3"
7359   [(set (match_operand:XF 0 "register_operand")
7360         (mult:XF (match_operand:XF 1 "register_operand")
7361                  (match_operand:XF 2 "register_operand")))]
7362   "TARGET_80387")
7364 (define_expand "mul<mode>3"
7365   [(set (match_operand:MODEF 0 "register_operand")
7366         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7367                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7368   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7369     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7371 ;; Divide instructions
7373 ;; The patterns that match these are at the end of this file.
7375 (define_expand "divxf3"
7376   [(set (match_operand:XF 0 "register_operand")
7377         (div:XF (match_operand:XF 1 "register_operand")
7378                 (match_operand:XF 2 "register_operand")))]
7379   "TARGET_80387")
7381 (define_expand "div<mode>3"
7382   [(set (match_operand:MODEF 0 "register_operand")
7383         (div:MODEF (match_operand:MODEF 1 "register_operand")
7384                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7385   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7386     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7388   if (<MODE>mode == SFmode
7389       && TARGET_SSE && TARGET_SSE_MATH
7390       && TARGET_RECIP_DIV
7391       && optimize_insn_for_speed_p ()
7392       && flag_finite_math_only && !flag_trapping_math
7393       && flag_unsafe_math_optimizations)
7394     {
7395       ix86_emit_swdivsf (operands[0], operands[1],
7396                          operands[2], SFmode);
7397       DONE;
7398     }
7401 ;; Divmod instructions.
7403 (define_expand "divmod<mode>4"
7404   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7405                    (div:SWIM248
7406                      (match_operand:SWIM248 1 "register_operand")
7407                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7408               (set (match_operand:SWIM248 3 "register_operand")
7409                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7410               (clobber (reg:CC FLAGS_REG))])])
7412 ;; Split with 8bit unsigned divide:
7413 ;;      if (dividend an divisor are in [0-255])
7414 ;;         use 8bit unsigned integer divide
7415 ;;       else
7416 ;;         use original integer divide
7417 (define_split
7418   [(set (match_operand:SWI48 0 "register_operand")
7419         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7420                     (match_operand:SWI48 3 "nonimmediate_operand")))
7421    (set (match_operand:SWI48 1 "register_operand")
7422         (mod:SWI48 (match_dup 2) (match_dup 3)))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "TARGET_USE_8BIT_IDIV
7425    && TARGET_QIMODE_MATH
7426    && can_create_pseudo_p ()
7427    && !optimize_insn_for_size_p ()"
7428   [(const_int 0)]
7429   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7431 (define_split
7432   [(set (match_operand:DI 0 "register_operand")
7433         (zero_extend:DI
7434           (div:SI (match_operand:SI 2 "register_operand")
7435                   (match_operand:SI 3 "nonimmediate_operand"))))
7436    (set (match_operand:SI 1 "register_operand")
7437         (mod:SI (match_dup 2) (match_dup 3)))
7438    (clobber (reg:CC FLAGS_REG))]
7439   "TARGET_USE_8BIT_IDIV
7440    && TARGET_QIMODE_MATH
7441    && can_create_pseudo_p ()
7442    && !optimize_insn_for_size_p ()"
7443   [(const_int 0)]
7444   "ix86_split_idivmod (SImode, operands, true); DONE;")
7446 (define_split
7447   [(set (match_operand:DI 1 "register_operand")
7448         (zero_extend:DI
7449           (mod:SI (match_operand:SI 2 "register_operand")
7450                   (match_operand:SI 3 "nonimmediate_operand"))))
7451    (set (match_operand:SI 0 "register_operand")
7452         (div:SI  (match_dup 2) (match_dup 3)))
7453    (clobber (reg:CC FLAGS_REG))]
7454   "TARGET_USE_8BIT_IDIV
7455    && TARGET_QIMODE_MATH
7456    && can_create_pseudo_p ()
7457    && !optimize_insn_for_size_p ()"
7458   [(const_int 0)]
7459   "ix86_split_idivmod (SImode, operands, true); DONE;")
7461 (define_insn_and_split "divmod<mode>4_1"
7462   [(set (match_operand:SWI48 0 "register_operand" "=a")
7463         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7464                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7465    (set (match_operand:SWI48 1 "register_operand" "=&d")
7466         (mod:SWI48 (match_dup 2) (match_dup 3)))
7467    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7468    (clobber (reg:CC FLAGS_REG))]
7469   ""
7470   "#"
7471   "reload_completed"
7472   [(parallel [(set (match_dup 1)
7473                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7474               (clobber (reg:CC FLAGS_REG))])
7475    (parallel [(set (match_dup 0)
7476                    (div:SWI48 (match_dup 2) (match_dup 3)))
7477               (set (match_dup 1)
7478                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7479               (use (match_dup 1))
7480               (clobber (reg:CC FLAGS_REG))])]
7482   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7484   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7485     operands[4] = operands[2];
7486   else
7487     {
7488       /* Avoid use of cltd in favor of a mov+shift.  */
7489       emit_move_insn (operands[1], operands[2]);
7490       operands[4] = operands[1];
7491     }
7493   [(set_attr "type" "multi")
7494    (set_attr "mode" "<MODE>")])
7496 (define_insn_and_split "divmodsi4_zext_1"
7497   [(set (match_operand:DI 0 "register_operand" "=a")
7498         (zero_extend:DI
7499           (div:SI (match_operand:SI 2 "register_operand" "0")
7500                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7501    (set (match_operand:SI 1 "register_operand" "=&d")
7502         (mod:SI (match_dup 2) (match_dup 3)))
7503    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7504    (clobber (reg:CC FLAGS_REG))]
7505   "TARGET_64BIT"
7506   "#"
7507   "reload_completed"
7508   [(parallel [(set (match_dup 1)
7509                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7510               (clobber (reg:CC FLAGS_REG))])
7511    (parallel [(set (match_dup 0)
7512                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7513               (set (match_dup 1)
7514                    (mod:SI (match_dup 2) (match_dup 3)))
7515               (use (match_dup 1))
7516               (clobber (reg:CC FLAGS_REG))])]
7518   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7520   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7521     operands[4] = operands[2];
7522   else
7523     {
7524       /* Avoid use of cltd in favor of a mov+shift.  */
7525       emit_move_insn (operands[1], operands[2]);
7526       operands[4] = operands[1];
7527     }
7529   [(set_attr "type" "multi")
7530    (set_attr "mode" "SI")])
7532 (define_insn_and_split "divmodsi4_zext_2"
7533   [(set (match_operand:DI 1 "register_operand" "=&d")
7534         (zero_extend:DI
7535           (mod:SI (match_operand:SI 2 "register_operand" "0")
7536                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7537    (set (match_operand:SI 0 "register_operand" "=a")
7538         (div:SI (match_dup 2) (match_dup 3)))
7539    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7540    (clobber (reg:CC FLAGS_REG))]
7541   "TARGET_64BIT"
7542   "#"
7543   "reload_completed"
7544   [(parallel [(set (match_dup 6)
7545                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7546               (clobber (reg:CC FLAGS_REG))])
7547    (parallel [(set (match_dup 1)
7548                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7549               (set (match_dup 0)
7550                    (div:SI (match_dup 2) (match_dup 3)))
7551               (use (match_dup 6))
7552               (clobber (reg:CC FLAGS_REG))])]
7554   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7555   operands[6] = gen_lowpart (SImode, operands[1]);
7557   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7558     operands[4] = operands[2];
7559   else
7560     {
7561       /* Avoid use of cltd in favor of a mov+shift.  */
7562       emit_move_insn (operands[6], operands[2]);
7563       operands[4] = operands[6];
7564     }
7566   [(set_attr "type" "multi")
7567    (set_attr "mode" "SI")])
7569 (define_insn_and_split "*divmod<mode>4"
7570   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7571         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7572                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7573    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7574         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7575    (clobber (reg:CC FLAGS_REG))]
7576   ""
7577   "#"
7578   "reload_completed"
7579   [(parallel [(set (match_dup 1)
7580                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7581               (clobber (reg:CC FLAGS_REG))])
7582    (parallel [(set (match_dup 0)
7583                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7584               (set (match_dup 1)
7585                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7586               (use (match_dup 1))
7587               (clobber (reg:CC FLAGS_REG))])]
7589   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7591   if (<MODE>mode != HImode
7592       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7593     operands[4] = operands[2];
7594   else
7595     {
7596       /* Avoid use of cltd in favor of a mov+shift.  */
7597       emit_move_insn (operands[1], operands[2]);
7598       operands[4] = operands[1];
7599     }
7601   [(set_attr "type" "multi")
7602    (set_attr "mode" "<MODE>")])
7604 (define_insn_and_split "*divmodsi4_zext_1"
7605   [(set (match_operand:DI 0 "register_operand" "=a")
7606         (zero_extend:DI
7607           (div:SI (match_operand:SI 2 "register_operand" "0")
7608                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7609    (set (match_operand:SI 1 "register_operand" "=&d")
7610         (mod:SI (match_dup 2) (match_dup 3)))
7611    (clobber (reg:CC FLAGS_REG))]
7612   "TARGET_64BIT"
7613   "#"
7614   "reload_completed"
7615   [(parallel [(set (match_dup 1)
7616                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7617               (clobber (reg:CC FLAGS_REG))])
7618    (parallel [(set (match_dup 0)
7619                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7620               (set (match_dup 1)
7621                    (mod:SI (match_dup 2) (match_dup 3)))
7622               (use (match_dup 1))
7623               (clobber (reg:CC FLAGS_REG))])]
7625   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7627   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7628     operands[4] = operands[2];
7629   else
7630     {
7631       /* Avoid use of cltd in favor of a mov+shift.  */
7632       emit_move_insn (operands[1], operands[2]);
7633       operands[4] = operands[1];
7634     }
7636   [(set_attr "type" "multi")
7637    (set_attr "mode" "SI")])
7639 (define_insn_and_split "*divmodsi4_zext_2"
7640   [(set (match_operand:DI 1 "register_operand" "=&d")
7641         (zero_extend:DI
7642           (mod:SI (match_operand:SI 2 "register_operand" "0")
7643                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7644    (set (match_operand:SI 0 "register_operand" "=a")
7645         (div:SI (match_dup 2) (match_dup 3)))
7646    (clobber (reg:CC FLAGS_REG))]
7647   "TARGET_64BIT"
7648   "#"
7649   "reload_completed"
7650   [(parallel [(set (match_dup 6)
7651                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7652               (clobber (reg:CC FLAGS_REG))])
7653    (parallel [(set (match_dup 1)
7654                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7655               (set (match_dup 0)
7656                    (div:SI (match_dup 2) (match_dup 3)))
7657               (use (match_dup 6))
7658               (clobber (reg:CC FLAGS_REG))])]
7660   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7661   operands[6] = gen_lowpart (SImode, operands[1]);
7663   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7664     operands[4] = operands[2];
7665   else
7666     {
7667       /* Avoid use of cltd in favor of a mov+shift.  */
7668       emit_move_insn (operands[6], operands[2]);
7669       operands[4] = operands[6];
7670     }
7672   [(set_attr "type" "multi")
7673    (set_attr "mode" "SI")])
7675 (define_insn "*divmod<mode>4_noext"
7676   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7677         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7678                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7679    (set (match_operand:SWIM248 1 "register_operand" "=d")
7680         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7681    (use (match_operand:SWIM248 4 "register_operand" "1"))
7682    (clobber (reg:CC FLAGS_REG))]
7683   ""
7684   "idiv{<imodesuffix>}\t%3"
7685   [(set_attr "type" "idiv")
7686    (set_attr "mode" "<MODE>")])
7688 (define_insn "*divmodsi4_noext_zext_1"
7689   [(set (match_operand:DI 0 "register_operand" "=a")
7690         (zero_extend:DI
7691           (div:SI (match_operand:SI 2 "register_operand" "0")
7692                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7693    (set (match_operand:SI 1 "register_operand" "=d")
7694         (mod:SI (match_dup 2) (match_dup 3)))
7695    (use (match_operand:SI 4 "register_operand" "1"))
7696    (clobber (reg:CC FLAGS_REG))]
7697   "TARGET_64BIT"
7698   "idiv{l}\t%3"
7699   [(set_attr "type" "idiv")
7700    (set_attr "mode" "SI")])
7702 (define_insn "*divmodsi4_noext_zext_2"
7703   [(set (match_operand:DI 1 "register_operand" "=d")
7704         (zero_extend:DI
7705           (mod:SI (match_operand:SI 2 "register_operand" "0")
7706                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7707    (set (match_operand:SI 0 "register_operand" "=a")
7708         (div:SI (match_dup 2) (match_dup 3)))
7709    (use (match_operand:SI 4 "register_operand" "1"))
7710    (clobber (reg:CC FLAGS_REG))]
7711   "TARGET_64BIT"
7712   "idiv{l}\t%3"
7713   [(set_attr "type" "idiv")
7714    (set_attr "mode" "SI")])
7716 (define_expand "divmodqi4"
7717   [(parallel [(set (match_operand:QI 0 "register_operand")
7718                    (div:QI
7719                      (match_operand:QI 1 "register_operand")
7720                      (match_operand:QI 2 "nonimmediate_operand")))
7721               (set (match_operand:QI 3 "register_operand")
7722                    (mod:QI (match_dup 1) (match_dup 2)))
7723               (clobber (reg:CC FLAGS_REG))])]
7724   "TARGET_QIMODE_MATH"
7726   rtx div, mod;
7727   rtx tmp0, tmp1;
7728   
7729   tmp0 = gen_reg_rtx (HImode);
7730   tmp1 = gen_reg_rtx (HImode);
7732   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
7733   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7734   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7736   /* Extract remainder from AH.  */
7737   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7738   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7739   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7741   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7742   set_unique_reg_note (insn, REG_EQUAL, mod);
7744   /* Extract quotient from AL.  */
7745   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7747   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7748   set_unique_reg_note (insn, REG_EQUAL, div);
7750   DONE;
7753 ;; Divide AX by r/m8, with result stored in
7754 ;; AL <- Quotient
7755 ;; AH <- Remainder
7756 ;; Change div/mod to HImode and extend the second argument to HImode
7757 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7758 ;; combine may fail.
7759 (define_insn "divmodhiqi3"
7760   [(set (match_operand:HI 0 "register_operand" "=a")
7761         (ior:HI
7762           (ashift:HI
7763             (zero_extend:HI
7764               (truncate:QI
7765                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7766                         (sign_extend:HI
7767                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7768             (const_int 8))
7769           (zero_extend:HI
7770             (truncate:QI
7771               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_QIMODE_MATH"
7774   "idiv{b}\t%2"
7775   [(set_attr "type" "idiv")
7776    (set_attr "mode" "QI")])
7778 (define_expand "udivmod<mode>4"
7779   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7780                    (udiv:SWIM248
7781                      (match_operand:SWIM248 1 "register_operand")
7782                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7783               (set (match_operand:SWIM248 3 "register_operand")
7784                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7785               (clobber (reg:CC FLAGS_REG))])])
7787 ;; Split with 8bit unsigned divide:
7788 ;;      if (dividend an divisor are in [0-255])
7789 ;;         use 8bit unsigned integer divide
7790 ;;       else
7791 ;;         use original integer divide
7792 (define_split
7793   [(set (match_operand:SWI48 0 "register_operand")
7794         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7795                     (match_operand:SWI48 3 "nonimmediate_operand")))
7796    (set (match_operand:SWI48 1 "register_operand")
7797         (umod:SWI48 (match_dup 2) (match_dup 3)))
7798    (clobber (reg:CC FLAGS_REG))]
7799   "TARGET_USE_8BIT_IDIV
7800    && TARGET_QIMODE_MATH
7801    && can_create_pseudo_p ()
7802    && !optimize_insn_for_size_p ()"
7803   [(const_int 0)]
7804   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7806 (define_split
7807   [(set (match_operand:DI 0 "register_operand")
7808         (zero_extend:DI
7809           (udiv:SI (match_operand:SI 2 "register_operand")
7810                    (match_operand:SI 3 "nonimmediate_operand"))))
7811    (set (match_operand:SI 1 "register_operand")
7812         (umod:SI (match_dup 2) (match_dup 3)))
7813    (clobber (reg:CC FLAGS_REG))]
7814   "TARGET_64BIT
7815    && TARGET_USE_8BIT_IDIV
7816    && TARGET_QIMODE_MATH
7817    && can_create_pseudo_p ()
7818    && !optimize_insn_for_size_p ()"
7819   [(const_int 0)]
7820   "ix86_split_idivmod (SImode, operands, false); DONE;")
7822 (define_split
7823   [(set (match_operand:DI 1 "register_operand")
7824         (zero_extend:DI
7825           (umod:SI (match_operand:SI 2 "register_operand")
7826                    (match_operand:SI 3 "nonimmediate_operand"))))
7827    (set (match_operand:SI 0 "register_operand")
7828         (udiv:SI (match_dup 2) (match_dup 3)))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "TARGET_64BIT
7831    && TARGET_USE_8BIT_IDIV
7832    && TARGET_QIMODE_MATH
7833    && can_create_pseudo_p ()
7834    && !optimize_insn_for_size_p ()"
7835   [(const_int 0)]
7836   "ix86_split_idivmod (SImode, operands, false); DONE;")
7838 (define_insn_and_split "udivmod<mode>4_1"
7839   [(set (match_operand:SWI48 0 "register_operand" "=a")
7840         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7841                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7842    (set (match_operand:SWI48 1 "register_operand" "=&d")
7843         (umod:SWI48 (match_dup 2) (match_dup 3)))
7844    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7845    (clobber (reg:CC FLAGS_REG))]
7846   ""
7847   "#"
7848   "reload_completed"
7849   [(set (match_dup 1) (const_int 0))
7850    (parallel [(set (match_dup 0)
7851                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7852               (set (match_dup 1)
7853                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7854               (use (match_dup 1))
7855               (clobber (reg:CC FLAGS_REG))])]
7856   ""
7857   [(set_attr "type" "multi")
7858    (set_attr "mode" "<MODE>")])
7860 (define_insn_and_split "udivmodsi4_zext_1"
7861   [(set (match_operand:DI 0 "register_operand" "=a")
7862         (zero_extend:DI
7863           (udiv:SI (match_operand:SI 2 "register_operand" "0")
7864                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7865    (set (match_operand:SI 1 "register_operand" "=&d")
7866         (umod:SI (match_dup 2) (match_dup 3)))
7867    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7868    (clobber (reg:CC FLAGS_REG))]
7869   "TARGET_64BIT"
7870   "#"
7871   "reload_completed"
7872   [(set (match_dup 1) (const_int 0))
7873    (parallel [(set (match_dup 0)
7874                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7875               (set (match_dup 1)
7876                    (umod:SI (match_dup 2) (match_dup 3)))
7877               (use (match_dup 1))
7878               (clobber (reg:CC FLAGS_REG))])]
7879   ""
7880   [(set_attr "type" "multi")
7881    (set_attr "mode" "SI")])
7883 (define_insn_and_split "udivmodsi4_zext_2"
7884   [(set (match_operand:DI 1 "register_operand" "=&d")
7885         (zero_extend:DI
7886           (umod:SI (match_operand:SI 2 "register_operand" "0")
7887                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7888    (set (match_operand:SI 0 "register_operand" "=a")
7889         (udiv:SI (match_dup 2) (match_dup 3)))
7890    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7891    (clobber (reg:CC FLAGS_REG))]
7892   "TARGET_64BIT"
7893   "#"
7894   "reload_completed"
7895   [(set (match_dup 4) (const_int 0))
7896    (parallel [(set (match_dup 1)
7897                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7898               (set (match_dup 0)
7899                    (udiv:SI (match_dup 2) (match_dup 3)))
7900               (use (match_dup 4))
7901               (clobber (reg:CC FLAGS_REG))])]
7902   "operands[4] = gen_lowpart (SImode, operands[1]);"
7903   [(set_attr "type" "multi")
7904    (set_attr "mode" "SI")])
7906 (define_insn_and_split "*udivmod<mode>4"
7907   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7908         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7909                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7910    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7911         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7912    (clobber (reg:CC FLAGS_REG))]
7913   ""
7914   "#"
7915   "reload_completed"
7916   [(set (match_dup 1) (const_int 0))
7917    (parallel [(set (match_dup 0)
7918                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7919               (set (match_dup 1)
7920                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7921               (use (match_dup 1))
7922               (clobber (reg:CC FLAGS_REG))])]
7923   ""
7924   [(set_attr "type" "multi")
7925    (set_attr "mode" "<MODE>")])
7927 (define_insn_and_split "*udivmodsi4_zext_1"
7928   [(set (match_operand:DI 0 "register_operand" "=a")
7929         (zero_extend:DI
7930           (udiv:SI (match_operand:SI 2 "register_operand" "0")
7931                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7932    (set (match_operand:SI 1 "register_operand" "=&d")
7933         (umod:SI (match_dup 2) (match_dup 3)))
7934    (clobber (reg:CC FLAGS_REG))]
7935   "TARGET_64BIT"
7936   "#"
7937   "reload_completed"
7938   [(set (match_dup 1) (const_int 0))
7939    (parallel [(set (match_dup 0)
7940                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7941               (set (match_dup 1)
7942                    (umod:SI (match_dup 2) (match_dup 3)))
7943               (use (match_dup 1))
7944               (clobber (reg:CC FLAGS_REG))])]
7945   ""
7946   [(set_attr "type" "multi")
7947    (set_attr "mode" "SI")])
7949 (define_insn_and_split "*udivmodsi4_zext_2"
7950   [(set (match_operand:DI 1 "register_operand" "=&d")
7951         (zero_extend:DI
7952           (umod:SI (match_operand:SI 2 "register_operand" "0")
7953                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7954    (set (match_operand:SI 0 "register_operand" "=a")
7955         (udiv:SI (match_dup 2) (match_dup 3)))
7956    (clobber (reg:CC FLAGS_REG))]
7957   "TARGET_64BIT"
7958   "#"
7959   "reload_completed"
7960   [(set (match_dup 4) (const_int 0))
7961    (parallel [(set (match_dup 1)
7962                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7963               (set (match_dup 0)
7964                    (udiv:SI (match_dup 2) (match_dup 3)))
7965               (use (match_dup 4))
7966               (clobber (reg:CC FLAGS_REG))])]
7967   "operands[4] = gen_lowpart (SImode, operands[1]);"
7968   [(set_attr "type" "multi")
7969    (set_attr "mode" "SI")])
7971 ;; Optimize division or modulo by constant power of 2, if the constant
7972 ;; materializes only after expansion.
7973 (define_insn_and_split "*udivmod<mode>4_pow2"
7974   [(set (match_operand:SWI48 0 "register_operand" "=r")
7975         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7976                     (match_operand:SWI48 3 "const_int_operand" "n")))
7977    (set (match_operand:SWI48 1 "register_operand" "=r")
7978         (umod:SWI48 (match_dup 2) (match_dup 3)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7981    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7982   "#"
7983   "&& 1"
7984   [(set (match_dup 1) (match_dup 2))
7985    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7986               (clobber (reg:CC FLAGS_REG))])
7987    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7988               (clobber (reg:CC FLAGS_REG))])]
7990   int v = exact_log2 (UINTVAL (operands[3]));
7991   operands[4] = GEN_INT (v);
7992   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7994   [(set_attr "type" "multi")
7995    (set_attr "mode" "<MODE>")])
7997 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7998   [(set (match_operand:DI 0 "register_operand" "=r")
7999         (zero_extend:DI
8000           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8001                    (match_operand:SI 3 "const_int_operand" "n"))))
8002    (set (match_operand:SI 1 "register_operand" "=r")
8003         (umod:SI (match_dup 2) (match_dup 3)))
8004    (clobber (reg:CC FLAGS_REG))]
8005   "TARGET_64BIT
8006    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8007    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8008   "#"
8009   "&& 1"
8010   [(set (match_dup 1) (match_dup 2))
8011    (parallel [(set (match_dup 0)
8012                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8013               (clobber (reg:CC FLAGS_REG))])
8014    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8015               (clobber (reg:CC FLAGS_REG))])]
8017   int v = exact_log2 (UINTVAL (operands[3]));
8018   operands[4] = GEN_INT (v);
8019   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8021   [(set_attr "type" "multi")
8022    (set_attr "mode" "SI")])
8024 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8025   [(set (match_operand:DI 1 "register_operand" "=r")
8026         (zero_extend:DI
8027           (umod:SI (match_operand:SI 2 "register_operand" "0")
8028                    (match_operand:SI 3 "const_int_operand" "n"))))
8029    (set (match_operand:SI 0 "register_operand" "=r")
8030         (umod:SI (match_dup 2) (match_dup 3)))
8031    (clobber (reg:CC FLAGS_REG))]
8032   "TARGET_64BIT
8033    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8034    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8035   "#"
8036   "&& 1"
8037   [(set (match_dup 1) (match_dup 2))
8038    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8039               (clobber (reg:CC FLAGS_REG))])
8040    (parallel [(set (match_dup 1)
8041                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8042               (clobber (reg:CC FLAGS_REG))])]
8044   int v = exact_log2 (UINTVAL (operands[3]));
8045   operands[4] = GEN_INT (v);
8046   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8048   [(set_attr "type" "multi")
8049    (set_attr "mode" "SI")])
8051 (define_insn "*udivmod<mode>4_noext"
8052   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8053         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8054                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8055    (set (match_operand:SWIM248 1 "register_operand" "=d")
8056         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8057    (use (match_operand:SWIM248 4 "register_operand" "1"))
8058    (clobber (reg:CC FLAGS_REG))]
8059   ""
8060   "div{<imodesuffix>}\t%3"
8061   [(set_attr "type" "idiv")
8062    (set_attr "mode" "<MODE>")])
8064 (define_insn "*udivmodsi4_noext_zext_1"
8065   [(set (match_operand:DI 0 "register_operand" "=a")
8066         (zero_extend:DI
8067           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8068                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8069    (set (match_operand:SI 1 "register_operand" "=d")
8070         (umod:SI (match_dup 2) (match_dup 3)))
8071    (use (match_operand:SI 4 "register_operand" "1"))
8072    (clobber (reg:CC FLAGS_REG))]
8073   "TARGET_64BIT"
8074   "div{l}\t%3"
8075   [(set_attr "type" "idiv")
8076    (set_attr "mode" "SI")])
8078 (define_insn "*udivmodsi4_noext_zext_2"
8079   [(set (match_operand:DI 1 "register_operand" "=d")
8080         (zero_extend:DI
8081           (umod:SI (match_operand:SI 2 "register_operand" "0")
8082                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8083    (set (match_operand:SI 0 "register_operand" "=a")
8084         (udiv:SI (match_dup 2) (match_dup 3)))
8085    (use (match_operand:SI 4 "register_operand" "1"))
8086    (clobber (reg:CC FLAGS_REG))]
8087   "TARGET_64BIT"
8088   "div{l}\t%3"
8089   [(set_attr "type" "idiv")
8090    (set_attr "mode" "SI")])
8092 (define_expand "udivmodqi4"
8093   [(parallel [(set (match_operand:QI 0 "register_operand")
8094                    (udiv:QI
8095                      (match_operand:QI 1 "register_operand")
8096                      (match_operand:QI 2 "nonimmediate_operand")))
8097               (set (match_operand:QI 3 "register_operand")
8098                    (umod:QI (match_dup 1) (match_dup 2)))
8099               (clobber (reg:CC FLAGS_REG))])]
8100   "TARGET_QIMODE_MATH"
8102   rtx div, mod;
8103   rtx tmp0, tmp1;
8104   
8105   tmp0 = gen_reg_rtx (HImode);
8106   tmp1 = gen_reg_rtx (HImode);
8108   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8109   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8110   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8112   /* Extract remainder from AH.  */
8113   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8114   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8115   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8117   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8118   set_unique_reg_note (insn, REG_EQUAL, mod);
8120   /* Extract quotient from AL.  */
8121   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8123   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8124   set_unique_reg_note (insn, REG_EQUAL, div);
8126   DONE;
8129 (define_insn "udivmodhiqi3"
8130   [(set (match_operand:HI 0 "register_operand" "=a")
8131         (ior:HI
8132           (ashift:HI
8133             (zero_extend:HI
8134               (truncate:QI
8135                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8136                         (zero_extend:HI
8137                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8138             (const_int 8))
8139           (zero_extend:HI
8140             (truncate:QI
8141               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8142    (clobber (reg:CC FLAGS_REG))]
8143   "TARGET_QIMODE_MATH"
8144   "div{b}\t%2"
8145   [(set_attr "type" "idiv")
8146    (set_attr "mode" "QI")])
8148 ;; We cannot use div/idiv for double division, because it causes
8149 ;; "division by zero" on the overflow and that's not what we expect
8150 ;; from truncate.  Because true (non truncating) double division is
8151 ;; never generated, we can't create this insn anyway.
8153 ;(define_insn ""
8154 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8155 ;       (truncate:SI
8156 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8157 ;                  (zero_extend:DI
8158 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8159 ;   (set (match_operand:SI 3 "register_operand" "=d")
8160 ;       (truncate:SI
8161 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8162 ;   (clobber (reg:CC FLAGS_REG))]
8163 ;  ""
8164 ;  "div{l}\t{%2, %0|%0, %2}"
8165 ;  [(set_attr "type" "idiv")])
8167 ;;- Logical AND instructions
8169 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8170 ;; Note that this excludes ah.
8172 (define_expand "testsi_ccno_1"
8173   [(set (reg:CCNO FLAGS_REG)
8174         (compare:CCNO
8175           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8176                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8177           (const_int 0)))])
8179 (define_expand "testqi_ccz_1"
8180   [(set (reg:CCZ FLAGS_REG)
8181         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8182                              (match_operand:QI 1 "nonmemory_operand"))
8183                  (const_int 0)))])
8185 (define_expand "testdi_ccno_1"
8186   [(set (reg:CCNO FLAGS_REG)
8187         (compare:CCNO
8188           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8189                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8190           (const_int 0)))]
8191   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8193 (define_insn "*testdi_1"
8194   [(set (reg FLAGS_REG)
8195         (compare
8196          (and:DI
8197           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8198           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8199          (const_int 0)))]
8200   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8202   "@
8203    test{l}\t{%k1, %k0|%k0, %k1}
8204    test{l}\t{%k1, %k0|%k0, %k1}
8205    test{q}\t{%1, %0|%0, %1}
8206    test{q}\t{%1, %0|%0, %1}
8207    test{q}\t{%1, %0|%0, %1}"
8208   [(set_attr "type" "test")
8209    (set_attr "modrm" "0,1,0,1,1")
8210    (set_attr "mode" "SI,SI,DI,DI,DI")])
8212 (define_insn "*testqi_1_maybe_si"
8213   [(set (reg FLAGS_REG)
8214         (compare
8215           (and:QI
8216             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8217             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8218           (const_int 0)))]
8219    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8220     && ix86_match_ccmode (insn,
8221                          CONST_INT_P (operands[1])
8222                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8224   if (which_alternative == 3)
8225     {
8226       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8227         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8228       return "test{l}\t{%1, %k0|%k0, %1}";
8229     }
8230   return "test{b}\t{%1, %0|%0, %1}";
8232   [(set_attr "type" "test")
8233    (set_attr "modrm" "0,1,1,1")
8234    (set_attr "mode" "QI,QI,QI,SI")
8235    (set_attr "pent_pair" "uv,np,uv,np")])
8237 (define_insn "*test<mode>_1"
8238   [(set (reg FLAGS_REG)
8239         (compare
8240          (and:SWI124
8241           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8242           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8243          (const_int 0)))]
8244   "ix86_match_ccmode (insn, CCNOmode)
8245    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8246   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8247   [(set_attr "type" "test")
8248    (set_attr "modrm" "0,1,1")
8249    (set_attr "mode" "<MODE>")
8250    (set_attr "pent_pair" "uv,np,uv")])
8252 (define_expand "testqi_ext_1_ccno"
8253   [(set (reg:CCNO FLAGS_REG)
8254         (compare:CCNO
8255           (and:QI
8256             (subreg:QI
8257               (zero_extract:SI (match_operand 0 "ext_register_operand")
8258                                (const_int 8)
8259                                (const_int 8)) 0)
8260               (match_operand 1 "const_int_operand"))
8261           (const_int 0)))])
8263 (define_insn "*testqi_ext_1"
8264   [(set (reg FLAGS_REG)
8265         (compare
8266           (and:QI
8267             (subreg:QI
8268               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8269                                (const_int 8)
8270                                (const_int 8)) 0)
8271             (match_operand:QI 1 "general_operand" "QnBc,m"))
8272           (const_int 0)))]
8273   "ix86_match_ccmode (insn, CCNOmode)"
8274   "test{b}\t{%1, %h0|%h0, %1}"
8275   [(set_attr "isa" "*,nox64")
8276    (set_attr "type" "test")
8277    (set_attr "mode" "QI")])
8279 (define_insn "*testqi_ext_2"
8280   [(set (reg FLAGS_REG)
8281         (compare
8282           (and:QI
8283             (subreg:QI
8284               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8285                                (const_int 8)
8286                                (const_int 8)) 0)
8287             (subreg:QI
8288               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8289                                (const_int 8)
8290                                (const_int 8)) 0))
8291           (const_int 0)))]
8292   "ix86_match_ccmode (insn, CCNOmode)"
8293   "test{b}\t{%h1, %h0|%h0, %h1}"
8294   [(set_attr "type" "test")
8295    (set_attr "mode" "QI")])
8297 ;; Combine likes to form bit extractions for some tests.  Humor it.
8298 (define_insn_and_split "*testqi_ext_3"
8299   [(set (match_operand 0 "flags_reg_operand")
8300         (match_operator 1 "compare_operator"
8301           [(zero_extract:SWI248
8302              (match_operand 2 "nonimmediate_operand" "rm")
8303              (match_operand 3 "const_int_operand" "n")
8304              (match_operand 4 "const_int_operand" "n"))
8305            (const_int 0)]))]
8306   "ix86_match_ccmode (insn, CCNOmode)
8307    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8308        || GET_MODE (operands[2]) == SImode
8309        || GET_MODE (operands[2]) == HImode
8310        || GET_MODE (operands[2]) == QImode)
8311    /* Ensure that resulting mask is zero or sign extended operand.  */
8312    && INTVAL (operands[4]) >= 0
8313    && ((INTVAL (operands[3]) > 0
8314         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8315        || (<MODE>mode == DImode
8316            && INTVAL (operands[3]) > 32
8317            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8318   "#"
8319   "&& 1"
8320   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8322   rtx val = operands[2];
8323   HOST_WIDE_INT len = INTVAL (operands[3]);
8324   HOST_WIDE_INT pos = INTVAL (operands[4]);
8325   machine_mode mode = GET_MODE (val);
8327   if (SUBREG_P (val))
8328     {
8329       machine_mode submode = GET_MODE (SUBREG_REG (val));
8331       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8332       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8333           && GET_MODE_CLASS (submode) == MODE_INT)
8334         {
8335           val = SUBREG_REG (val);
8336           mode = submode;
8337         }
8338     }
8340   /* Small HImode tests can be converted to QImode.  */
8341   if (register_operand (val, HImode) && pos + len <= 8)
8342     {
8343       val = gen_lowpart (QImode, val);
8344       mode = QImode;
8345     }
8347   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8349   wide_int mask
8350     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8352   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8355 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8356 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8357 ;; this is relatively important trick.
8358 ;; Do the conversion only post-reload to avoid limiting of the register class
8359 ;; to QI regs.
8360 (define_split
8361   [(set (match_operand 0 "flags_reg_operand")
8362         (match_operator 1 "compare_operator"
8363           [(and (match_operand 2 "QIreg_operand")
8364                 (match_operand 3 "const_int_operand"))
8365            (const_int 0)]))]
8366    "reload_completed
8367     && GET_MODE (operands[2]) != QImode
8368     && ((ix86_match_ccmode (insn, CCZmode)
8369          && !(INTVAL (operands[3]) & ~(255 << 8)))
8370         || (ix86_match_ccmode (insn, CCNOmode)
8371             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8372   [(set (match_dup 0)
8373         (match_op_dup 1
8374           [(and:QI
8375              (subreg:QI
8376                (zero_extract:SI (match_dup 2)
8377                                 (const_int 8)
8378                                 (const_int 8)) 0)
8379              (match_dup 3))
8380            (const_int 0)]))]
8382   operands[2] = gen_lowpart (SImode, operands[2]);
8383   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8386 (define_split
8387   [(set (match_operand 0 "flags_reg_operand")
8388         (match_operator 1 "compare_operator"
8389           [(and (match_operand 2 "nonimmediate_operand")
8390                 (match_operand 3 "const_int_operand"))
8391            (const_int 0)]))]
8392    "reload_completed
8393     && GET_MODE (operands[2]) != QImode
8394     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8395     && ((ix86_match_ccmode (insn, CCZmode)
8396          && !(INTVAL (operands[3]) & ~255))
8397         || (ix86_match_ccmode (insn, CCNOmode)
8398             && !(INTVAL (operands[3]) & ~127)))"
8399   [(set (match_dup 0)
8400         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8401                          (const_int 0)]))]
8403   operands[2] = gen_lowpart (QImode, operands[2]);
8404   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8407 ;; %%% This used to optimize known byte-wide and operations to memory,
8408 ;; and sometimes to QImode registers.  If this is considered useful,
8409 ;; it should be done with splitters.
8411 (define_expand "and<mode>3"
8412   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8413         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8414                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8415   ""
8417   machine_mode mode = <MODE>mode;
8418   rtx (*insn) (rtx, rtx);
8420   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8421     {
8422       HOST_WIDE_INT ival = INTVAL (operands[2]);
8424       if (ival == (HOST_WIDE_INT) 0xffffffff)
8425         mode = SImode;
8426       else if (ival == 0xffff)
8427         mode = HImode;
8428       else if (ival == 0xff)
8429         mode = QImode;
8430       }
8432   if (mode == <MODE>mode)
8433     {
8434       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8435       DONE;
8436     }
8438   if (<MODE>mode == DImode)
8439     insn = (mode == SImode)
8440            ? gen_zero_extendsidi2
8441            : (mode == HImode)
8442            ? gen_zero_extendhidi2
8443            : gen_zero_extendqidi2;
8444   else if (<MODE>mode == SImode)
8445     insn = (mode == HImode)
8446            ? gen_zero_extendhisi2
8447            : gen_zero_extendqisi2;
8448   else if (<MODE>mode == HImode)
8449     insn = gen_zero_extendqihi2;
8450   else
8451     gcc_unreachable ();
8453   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8454   DONE;
8457 (define_insn_and_split "*anddi3_doubleword"
8458   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8459         (and:DI
8460          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8461          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8462    (clobber (reg:CC FLAGS_REG))]
8463   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8464    && ix86_binary_operator_ok (AND, DImode, operands)"
8465   "#"
8466   "&& reload_completed"
8467   [(const_int 0)]
8469   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8470   if (operands[2] == const0_rtx)
8471     {
8472       operands[1] = const0_rtx;
8473       ix86_expand_move (SImode, &operands[0]);
8474     }
8475   else if (operands[2] != constm1_rtx)
8476     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8477   else if (operands[5] == constm1_rtx)
8478     emit_note (NOTE_INSN_DELETED);
8479   if (operands[5] == const0_rtx)
8480     {
8481       operands[4] = const0_rtx;
8482       ix86_expand_move (SImode, &operands[3]);
8483     }
8484   else if (operands[5] != constm1_rtx)
8485     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8486   DONE;
8489 (define_insn "*anddi_1"
8490   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8491         (and:DI
8492          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8493          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8494    (clobber (reg:CC FLAGS_REG))]
8495   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8496   "@
8497    and{l}\t{%k2, %k0|%k0, %k2}
8498    and{q}\t{%2, %0|%0, %2}
8499    and{q}\t{%2, %0|%0, %2}
8500    #"
8501   [(set_attr "type" "alu,alu,alu,imovx")
8502    (set_attr "length_immediate" "*,*,*,0")
8503    (set (attr "prefix_rex")
8504      (if_then_else
8505        (and (eq_attr "type" "imovx")
8506             (and (match_test "INTVAL (operands[2]) == 0xff")
8507                  (match_operand 1 "ext_QIreg_operand")))
8508        (const_string "1")
8509        (const_string "*")))
8510    (set_attr "mode" "SI,DI,DI,SI")])
8512 (define_insn_and_split "*anddi_1_btr"
8513   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8514         (and:DI
8515          (match_operand:DI 1 "nonimmediate_operand" "%0")
8516          (match_operand:DI 2 "const_int_operand" "n")))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "TARGET_64BIT && TARGET_USE_BT
8519    && ix86_binary_operator_ok (AND, DImode, operands)
8520    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8521   "#"
8522   "&& reload_completed"
8523   [(parallel [(set (zero_extract:DI (match_dup 0)
8524                                     (const_int 1)
8525                                     (match_dup 3))
8526                    (const_int 0))
8527               (clobber (reg:CC FLAGS_REG))])]
8528   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8529   [(set_attr "type" "alu1")
8530    (set_attr "prefix_0f" "1")
8531    (set_attr "znver1_decode" "double")
8532    (set_attr "mode" "DI")])
8534 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8535 (define_split
8536   [(set (match_operand:DI 0 "register_operand")
8537         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8538                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8539    (clobber (reg:CC FLAGS_REG))]
8540   "TARGET_64BIT"
8541   [(parallel [(set (match_dup 0)
8542                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8543               (clobber (reg:CC FLAGS_REG))])]
8544   "operands[2] = gen_lowpart (SImode, operands[2]);")
8546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8547 (define_insn "*andsi_1_zext"
8548   [(set (match_operand:DI 0 "register_operand" "=r")
8549         (zero_extend:DI
8550           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8551                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8552    (clobber (reg:CC FLAGS_REG))]
8553   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8554   "and{l}\t{%2, %k0|%k0, %2}"
8555   [(set_attr "type" "alu")
8556    (set_attr "mode" "SI")])
8558 (define_insn "*and<mode>_1"
8559   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8560         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8561                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8562    (clobber (reg:CC FLAGS_REG))]
8563   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8564   "@
8565    and{<imodesuffix>}\t{%2, %0|%0, %2}
8566    and{<imodesuffix>}\t{%2, %0|%0, %2}
8567    #"
8568   [(set_attr "type" "alu,alu,imovx")
8569    (set_attr "length_immediate" "*,*,0")
8570    (set (attr "prefix_rex")
8571      (if_then_else
8572        (and (eq_attr "type" "imovx")
8573             (and (match_test "INTVAL (operands[2]) == 0xff")
8574                  (match_operand 1 "ext_QIreg_operand")))
8575        (const_string "1")
8576        (const_string "*")))
8577    (set_attr "mode" "<MODE>,<MODE>,SI")])
8579 (define_insn "*andqi_1"
8580   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8581         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8582                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8583    (clobber (reg:CC FLAGS_REG))]
8584   "ix86_binary_operator_ok (AND, QImode, operands)"
8585   "@
8586    and{b}\t{%2, %0|%0, %2}
8587    and{b}\t{%2, %0|%0, %2}
8588    and{l}\t{%k2, %k0|%k0, %k2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "QI,QI,SI")
8591    ;; Potential partial reg stall on alternative 2.
8592    (set (attr "preferred_for_speed")
8593      (cond [(eq_attr "alternative" "2")
8594               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8595            (symbol_ref "true")))])
8597 (define_insn "*andqi_1_slp"
8598   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8599         (and:QI (match_dup 0)
8600                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8601    (clobber (reg:CC FLAGS_REG))]
8602   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8603    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8604   "and{b}\t{%1, %0|%0, %1}"
8605   [(set_attr "type" "alu1")
8606    (set_attr "mode" "QI")])
8608 (define_split
8609   [(set (match_operand:SWI248 0 "register_operand")
8610         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8611                     (match_operand:SWI248 2 "const_int_operand")))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "reload_completed
8614    && (!REG_P (operands[1])
8615        || REGNO (operands[0]) != REGNO (operands[1]))"
8616   [(const_int 0)]
8618   HOST_WIDE_INT ival = INTVAL (operands[2]);
8619   machine_mode mode;
8620   rtx (*insn) (rtx, rtx);
8622   if (ival == (HOST_WIDE_INT) 0xffffffff)
8623     mode = SImode;
8624   else if (ival == 0xffff)
8625     mode = HImode;
8626   else
8627     {
8628       gcc_assert (ival == 0xff);
8629       mode = QImode;
8630     }
8632   if (<MODE>mode == DImode)
8633     insn = (mode == SImode)
8634            ? gen_zero_extendsidi2
8635            : (mode == HImode)
8636            ? gen_zero_extendhidi2
8637            : gen_zero_extendqidi2;
8638   else
8639     {
8640       if (<MODE>mode != SImode)
8641         /* Zero extend to SImode to avoid partial register stalls.  */
8642         operands[0] = gen_lowpart (SImode, operands[0]);
8644       insn = (mode == HImode)
8645              ? gen_zero_extendhisi2
8646              : gen_zero_extendqisi2;
8647     }
8648   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8649   DONE;
8652 (define_split
8653   [(set (match_operand:SWI48 0 "register_operand")
8654         (and:SWI48 (match_dup 0)
8655                    (const_int -65536)))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8658     || optimize_function_for_size_p (cfun)"
8659   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8660   "operands[1] = gen_lowpart (HImode, operands[0]);")
8662 (define_split
8663   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8664         (and:SWI248 (match_dup 0)
8665                     (const_int -256)))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8668    && reload_completed"
8669   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8670   "operands[1] = gen_lowpart (QImode, operands[0]);")
8672 (define_split
8673   [(set (match_operand:SWI248 0 "QIreg_operand")
8674         (and:SWI248 (match_dup 0)
8675                     (const_int -65281)))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8678    && reload_completed"
8679   [(parallel
8680      [(set (zero_extract:SI (match_dup 0)
8681                             (const_int 8)
8682                             (const_int 8))
8683            (subreg:SI
8684              (xor:QI
8685                (subreg:QI
8686                  (zero_extract:SI (match_dup 0)
8687                                   (const_int 8)
8688                                   (const_int 8)) 0)
8689                (subreg:QI
8690                  (zero_extract:SI (match_dup 0)
8691                                   (const_int 8)
8692                                   (const_int 8)) 0)) 0))
8693       (clobber (reg:CC FLAGS_REG))])]
8694   "operands[0] = gen_lowpart (SImode, operands[0]);")
8696 (define_insn "*anddi_2"
8697   [(set (reg FLAGS_REG)
8698         (compare
8699          (and:DI
8700           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8701           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8702          (const_int 0)))
8703    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8704         (and:DI (match_dup 1) (match_dup 2)))]
8705   "TARGET_64BIT
8706    && ix86_match_ccmode
8707         (insn,
8708          /* If we are going to emit andl instead of andq, and the operands[2]
8709             constant might have the SImode sign bit set, make sure the sign
8710             flag isn't tested, because the instruction will set the sign flag
8711             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8712             conservatively assume it might have bit 31 set.  */
8713          (satisfies_constraint_Z (operands[2])
8714           && (!CONST_INT_P (operands[2])
8715               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8716          ? CCZmode : CCNOmode)
8717    && ix86_binary_operator_ok (AND, DImode, operands)"
8718   "@
8719    and{l}\t{%k2, %k0|%k0, %k2}
8720    and{q}\t{%2, %0|%0, %2}
8721    and{q}\t{%2, %0|%0, %2}"
8722   [(set_attr "type" "alu")
8723    (set_attr "mode" "SI,DI,DI")])
8725 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8726 (define_insn "*andsi_2_zext"
8727   [(set (reg FLAGS_REG)
8728         (compare (and:SI
8729                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8730                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8731                  (const_int 0)))
8732    (set (match_operand:DI 0 "register_operand" "=r")
8733         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8734   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8735    && ix86_binary_operator_ok (AND, SImode, operands)"
8736   "and{l}\t{%2, %k0|%k0, %2}"
8737   [(set_attr "type" "alu")
8738    (set_attr "mode" "SI")])
8740 (define_insn "*andqi_2_maybe_si"
8741   [(set (reg FLAGS_REG)
8742         (compare (and:QI
8743                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8744                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8745                  (const_int 0)))
8746    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8747         (and:QI (match_dup 1) (match_dup 2)))]
8748   "ix86_binary_operator_ok (AND, QImode, operands)
8749    && ix86_match_ccmode (insn,
8750                          CONST_INT_P (operands[2])
8751                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8753   if (which_alternative == 2)
8754     {
8755       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8756         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8757       return "and{l}\t{%2, %k0|%k0, %2}";
8758     }
8759   return "and{b}\t{%2, %0|%0, %2}";
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "QI,QI,SI")])
8764 (define_insn "*and<mode>_2"
8765   [(set (reg FLAGS_REG)
8766         (compare (and:SWI124
8767                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8768                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8769                  (const_int 0)))
8770    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8771         (and:SWI124 (match_dup 1) (match_dup 2)))]
8772   "ix86_match_ccmode (insn, CCNOmode)
8773    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8774   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "<MODE>")])
8778 (define_insn "*andqi_2_slp"
8779   [(set (reg FLAGS_REG)
8780         (compare (and:QI
8781                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8782                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8783                  (const_int 0)))
8784    (set (strict_low_part (match_dup 0))
8785         (and:QI (match_dup 0) (match_dup 1)))]
8786   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8787    && ix86_match_ccmode (insn, CCNOmode)
8788    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8789   "and{b}\t{%1, %0|%0, %1}"
8790   [(set_attr "type" "alu1")
8791    (set_attr "mode" "QI")])
8793 (define_insn "andqi_ext_1"
8794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8795                          (const_int 8)
8796                          (const_int 8))
8797         (subreg:SI
8798           (and:QI
8799             (subreg:QI
8800               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8801                                (const_int 8)
8802                                (const_int 8)) 0)
8803             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8806    rtx_equal_p (operands[0], operands[1])"
8807   "and{b}\t{%2, %h0|%h0, %2}"
8808   [(set_attr "isa" "*,nox64")
8809    (set_attr "type" "alu")
8810    (set_attr "mode" "QI")])
8812 ;; Generated by peephole translating test to and.  This shows up
8813 ;; often in fp comparisons.
8814 (define_insn "*andqi_ext_1_cc"
8815   [(set (reg FLAGS_REG)
8816         (compare
8817           (and:QI
8818             (subreg:QI
8819               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8820                                (const_int 8)
8821                                (const_int 8)) 0)
8822             (match_operand:QI 2 "general_operand" "QnBc,m"))
8823           (const_int 0)))
8824    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8825                          (const_int 8)
8826                          (const_int 8))
8827         (subreg:SI
8828           (and:QI
8829             (subreg:QI
8830               (zero_extract:SI (match_dup 1)
8831                                (const_int 8)
8832                                (const_int 8)) 0)
8833             (match_dup 2)) 0))]
8834   "ix86_match_ccmode (insn, CCNOmode)
8835    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8836    && rtx_equal_p (operands[0], operands[1])"
8837   "and{b}\t{%2, %h0|%h0, %2}"
8838   [(set_attr "isa" "*,nox64")
8839    (set_attr "type" "alu")
8840    (set_attr "mode" "QI")])
8842 (define_insn "*andqi_ext_2"
8843   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8844                          (const_int 8)
8845                          (const_int 8))
8846         (subreg:SI
8847           (and:QI
8848             (subreg:QI
8849               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8850                                (const_int 8)
8851                                (const_int 8)) 0)
8852             (subreg:QI
8853               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8854                                (const_int 8)
8855                                (const_int 8)) 0)) 0))
8856    (clobber (reg:CC FLAGS_REG))]
8857   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
8858    rtx_equal_p (operands[0], operands[1])
8859    || rtx_equal_p (operands[0], operands[2])"
8860   "and{b}\t{%h2, %h0|%h0, %h2}"
8861   [(set_attr "type" "alu")
8862    (set_attr "mode" "QI")])
8864 ;; Convert wide AND instructions with immediate operand to shorter QImode
8865 ;; equivalents when possible.
8866 ;; Don't do the splitting with memory operands, since it introduces risk
8867 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8868 ;; for size, but that can (should?) be handled by generic code instead.
8869 (define_split
8870   [(set (match_operand:SWI248 0 "QIreg_operand")
8871         (and:SWI248 (match_operand:SWI248 1 "register_operand")
8872                     (match_operand:SWI248 2 "const_int_operand")))
8873    (clobber (reg:CC FLAGS_REG))]
8874    "reload_completed
8875     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876     && !(~INTVAL (operands[2]) & ~(255 << 8))"
8877   [(parallel
8878      [(set (zero_extract:SI (match_dup 0)
8879                             (const_int 8)
8880                             (const_int 8))
8881            (subreg:SI
8882              (and:QI
8883                (subreg:QI
8884                  (zero_extract:SI (match_dup 1)
8885                                   (const_int 8)
8886                                   (const_int 8)) 0)
8887                (match_dup 2)) 0))
8888       (clobber (reg:CC FLAGS_REG))])]
8890   operands[0] = gen_lowpart (SImode, operands[0]);
8891   operands[1] = gen_lowpart (SImode, operands[1]);
8892   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8895 ;; Since AND can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is not set.
8897 (define_split
8898   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8899         (and:SWI248 (match_operand:SWI248 1 "general_operand")
8900                     (match_operand:SWI248 2 "const_int_operand")))
8901    (clobber (reg:CC FLAGS_REG))]
8902    "reload_completed
8903     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8904     && !(~INTVAL (operands[2]) & ~255)
8905     && !(INTVAL (operands[2]) & 128)"
8906   [(parallel [(set (strict_low_part (match_dup 0))
8907                    (and:QI (match_dup 1)
8908                            (match_dup 2)))
8909               (clobber (reg:CC FLAGS_REG))])]
8911   operands[0] = gen_lowpart (QImode, operands[0]);
8912   operands[1] = gen_lowpart (QImode, operands[1]);
8913   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8916 (define_insn "*andndi3_doubleword"
8917   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
8918         (and:DI
8919           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
8920           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
8921    (clobber (reg:CC FLAGS_REG))]
8922   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8923   "#"
8924   [(set_attr "isa" "bmi,bmi,bmi,*")])
8926 (define_split
8927   [(set (match_operand:DI 0 "register_operand")
8928         (and:DI
8929           (not:DI (match_operand:DI 1 "register_operand"))
8930           (match_operand:DI 2 "nonimmediate_operand")))
8931    (clobber (reg:CC FLAGS_REG))]
8932   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8933    && reload_completed"
8934   [(parallel [(set (match_dup 0)
8935                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8936               (clobber (reg:CC FLAGS_REG))])
8937    (parallel [(set (match_dup 3)
8938                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8939               (clobber (reg:CC FLAGS_REG))])]
8940   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8942 (define_split
8943   [(set (match_operand:DI 0 "register_operand")
8944         (and:DI
8945           (not:DI (match_dup 0))
8946           (match_operand:DI 1 "nonimmediate_operand")))
8947    (clobber (reg:CC FLAGS_REG))]
8948   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8949    && reload_completed"
8950   [(set (match_dup 0) (not:SI (match_dup 0)))
8951    (parallel [(set (match_dup 0)
8952                    (and:SI (match_dup 0) (match_dup 1)))
8953               (clobber (reg:CC FLAGS_REG))])
8954    (set (match_dup 2) (not:SI (match_dup 2)))
8955    (parallel [(set (match_dup 2)
8956                    (and:SI (match_dup 2) (match_dup 3)))
8957               (clobber (reg:CC FLAGS_REG))])]
8958   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8960 (define_insn "*andn<mode>_1"
8961   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8962         (and:SWI48
8963           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8964           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8965    (clobber (reg:CC FLAGS_REG))]
8966   "TARGET_BMI"
8967   "andn\t{%2, %1, %0|%0, %1, %2}"
8968   [(set_attr "type" "bitmanip")
8969    (set_attr "btver2_decode" "direct, double")
8970    (set_attr "mode" "<MODE>")])
8972 (define_insn "*andn<mode>_1"
8973   [(set (match_operand:SWI12 0 "register_operand" "=r")
8974         (and:SWI12
8975           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8976           (match_operand:SWI12 2 "register_operand" "r")))
8977    (clobber (reg:CC FLAGS_REG))]
8978   "TARGET_BMI"
8979   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8980   [(set_attr "type" "bitmanip")
8981    (set_attr "btver2_decode" "direct")
8982    (set_attr "mode" "SI")])
8984 (define_insn "*andn_<mode>_ccno"
8985   [(set (reg FLAGS_REG)
8986         (compare
8987           (and:SWI48
8988             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8989             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8990           (const_int 0)))
8991    (clobber (match_scratch:SWI48 0 "=r,r"))]
8992   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8993   "andn\t{%2, %1, %0|%0, %1, %2}"
8994   [(set_attr "type" "bitmanip")
8995    (set_attr "btver2_decode" "direct, double")
8996    (set_attr "mode" "<MODE>")])
8998 ;; Logical inclusive and exclusive OR instructions
9000 ;; %%% This used to optimize known byte-wide and operations to memory.
9001 ;; If this is considered useful, it should be done with splitters.
9003 (define_expand "<code><mode>3"
9004   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9005         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9006                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9007   ""
9008   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9010 (define_insn_and_split "*<code>di3_doubleword"
9011   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9012         (any_or:DI
9013          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9014          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9015    (clobber (reg:CC FLAGS_REG))]
9016   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9017    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9018   "#"
9019   "&& reload_completed"
9020   [(const_int 0)]
9022   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9023   if (operands[2] == constm1_rtx)
9024     {
9025       if (<CODE> == IOR)
9026         {
9027           operands[1] = constm1_rtx;
9028           ix86_expand_move (SImode, &operands[0]);
9029         }
9030       else
9031         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9032     }
9033   else if (operands[2] != const0_rtx)
9034     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9035   else if (operands[5] == const0_rtx)
9036     emit_note (NOTE_INSN_DELETED);
9037   if (operands[5] == constm1_rtx)
9038     {
9039       if (<CODE> == IOR)
9040         {
9041           operands[4] = constm1_rtx;
9042           ix86_expand_move (SImode, &operands[3]);
9043         }
9044       else
9045         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9046     }
9047   else if (operands[5] != const0_rtx)
9048     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9049   DONE;
9052 (define_insn "*<code><mode>_1"
9053   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9054         (any_or:SWI248
9055          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9056          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9057    (clobber (reg:CC FLAGS_REG))]
9058   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9059   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9060   [(set_attr "type" "alu")
9061    (set_attr "mode" "<MODE>")])
9063 (define_insn_and_split "*iordi_1_bts"
9064   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9065         (ior:DI
9066          (match_operand:DI 1 "nonimmediate_operand" "%0")
9067          (match_operand:DI 2 "const_int_operand" "n")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "TARGET_64BIT && TARGET_USE_BT
9070    && ix86_binary_operator_ok (IOR, DImode, operands)
9071    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9072   "#"
9073   "&& reload_completed"
9074   [(parallel [(set (zero_extract:DI (match_dup 0)
9075                                     (const_int 1)
9076                                     (match_dup 3))
9077                    (const_int 1))
9078               (clobber (reg:CC FLAGS_REG))])]
9079   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9080   [(set_attr "type" "alu1")
9081    (set_attr "prefix_0f" "1")
9082    (set_attr "znver1_decode" "double")
9083    (set_attr "mode" "DI")])
9085 (define_insn_and_split "*xordi_1_btc"
9086   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9087         (xor:DI
9088          (match_operand:DI 1 "nonimmediate_operand" "%0")
9089          (match_operand:DI 2 "const_int_operand" "n")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "TARGET_64BIT && TARGET_USE_BT
9092    && ix86_binary_operator_ok (XOR, DImode, operands)
9093    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9094   "#"
9095   "&& reload_completed"
9096   [(parallel [(set (zero_extract:DI (match_dup 0)
9097                                     (const_int 1)
9098                                     (match_dup 3))
9099                    (not:DI (zero_extract:DI (match_dup 0)
9100                                             (const_int 1)
9101                                             (match_dup 3))))
9102               (clobber (reg:CC FLAGS_REG))])]
9103   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9104   [(set_attr "type" "alu1")
9105    (set_attr "prefix_0f" "1")
9106    (set_attr "znver1_decode" "double")
9107    (set_attr "mode" "DI")])
9109 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9110 (define_insn "*<code>si_1_zext"
9111   [(set (match_operand:DI 0 "register_operand" "=r")
9112         (zero_extend:DI
9113          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9114                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9115    (clobber (reg:CC FLAGS_REG))]
9116   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9117   "<logic>{l}\t{%2, %k0|%k0, %2}"
9118   [(set_attr "type" "alu")
9119    (set_attr "mode" "SI")])
9121 (define_insn "*<code>si_1_zext_imm"
9122   [(set (match_operand:DI 0 "register_operand" "=r")
9123         (any_or:DI
9124          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9125          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9128   "<logic>{l}\t{%2, %k0|%k0, %2}"
9129   [(set_attr "type" "alu")
9130    (set_attr "mode" "SI")])
9132 (define_insn "*<code>qi_1"
9133   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9134         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9135                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9138   "@
9139    <logic>{b}\t{%2, %0|%0, %2}
9140    <logic>{b}\t{%2, %0|%0, %2}
9141    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9142   [(set_attr "type" "alu")
9143    (set_attr "mode" "QI,QI,SI")
9144    ;; Potential partial reg stall on alternative 2.
9145    (set (attr "preferred_for_speed")
9146      (cond [(eq_attr "alternative" "2")
9147               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9148            (symbol_ref "true")))])
9150 (define_insn "*<code>qi_1_slp"
9151   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9152         (any_or:QI (match_dup 0)
9153                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9156    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9157   "<logic>{b}\t{%1, %0|%0, %1}"
9158   [(set_attr "type" "alu1")
9159    (set_attr "mode" "QI")])
9161 (define_insn "*<code><mode>_2"
9162   [(set (reg FLAGS_REG)
9163         (compare (any_or:SWI
9164                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9165                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9166                  (const_int 0)))
9167    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9168         (any_or:SWI (match_dup 1) (match_dup 2)))]
9169   "ix86_match_ccmode (insn, CCNOmode)
9170    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9171   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "<MODE>")])
9175 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9176 ;; ??? Special case for immediate operand is missing - it is tricky.
9177 (define_insn "*<code>si_2_zext"
9178   [(set (reg FLAGS_REG)
9179         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9180                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9181                  (const_int 0)))
9182    (set (match_operand:DI 0 "register_operand" "=r")
9183         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9184   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9185    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9186   "<logic>{l}\t{%2, %k0|%k0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "mode" "SI")])
9190 (define_insn "*<code>si_2_zext_imm"
9191   [(set (reg FLAGS_REG)
9192         (compare (any_or:SI
9193                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9194                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9195                  (const_int 0)))
9196    (set (match_operand:DI 0 "register_operand" "=r")
9197         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9198   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9199    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9200   "<logic>{l}\t{%2, %k0|%k0, %2}"
9201   [(set_attr "type" "alu")
9202    (set_attr "mode" "SI")])
9204 (define_insn "*<code>qi_2_slp"
9205   [(set (reg FLAGS_REG)
9206         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9208                  (const_int 0)))
9209    (set (strict_low_part (match_dup 0))
9210         (any_or:QI (match_dup 0) (match_dup 1)))]
9211   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9212    && ix86_match_ccmode (insn, CCNOmode)
9213    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9214   "<logic>{b}\t{%1, %0|%0, %1}"
9215   [(set_attr "type" "alu1")
9216    (set_attr "mode" "QI")])
9218 (define_insn "*<code><mode>_3"
9219   [(set (reg FLAGS_REG)
9220         (compare (any_or:SWI
9221                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9222                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9223                  (const_int 0)))
9224    (clobber (match_scratch:SWI 0 "=<r>"))]
9225   "ix86_match_ccmode (insn, CCNOmode)
9226    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9227   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9228   [(set_attr "type" "alu")
9229    (set_attr "mode" "<MODE>")])
9231 (define_insn "*<code>qi_ext_1"
9232   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9233                          (const_int 8)
9234                          (const_int 8))
9235         (subreg:SI
9236           (any_or:QI
9237             (subreg:QI
9238               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9239                                (const_int 8)
9240                                (const_int 8)) 0)
9241             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9242    (clobber (reg:CC FLAGS_REG))]
9243   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9244    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9245    && rtx_equal_p (operands[0], operands[1])"
9246   "<logic>{b}\t{%2, %h0|%h0, %2}"
9247   [(set_attr "isa" "*,nox64")
9248    (set_attr "type" "alu")
9249    (set_attr "mode" "QI")])
9251 (define_insn "*<code>qi_ext_2"
9252   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9253                          (const_int 8)
9254                          (const_int 8))
9255         (subreg:SI
9256           (any_or:QI
9257             (subreg:QI
9258               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9259                                (const_int 8)
9260                                (const_int 8)) 0)
9261             (subreg:QI
9262               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9263                                (const_int 8)
9264                                (const_int 8)) 0)) 0))
9265    (clobber (reg:CC FLAGS_REG))]
9266   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9267    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9268    && (rtx_equal_p (operands[0], operands[1])
9269        || rtx_equal_p (operands[0], operands[2]))"
9270   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9271   [(set_attr "type" "alu")
9272    (set_attr "mode" "QI")])
9274 ;; Convert wide OR instructions with immediate operand to shorter QImode
9275 ;; equivalents when possible.
9276 ;; Don't do the splitting with memory operands, since it introduces risk
9277 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9278 ;; for size, but that can (should?) be handled by generic code instead.
9279 (define_split
9280   [(set (match_operand:SWI248 0 "QIreg_operand")
9281         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9282                        (match_operand:SWI248 2 "const_int_operand")))
9283    (clobber (reg:CC FLAGS_REG))]
9284    "reload_completed
9285     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9286     && !(INTVAL (operands[2]) & ~(255 << 8))"
9287   [(parallel
9288      [(set (zero_extract:SI (match_dup 0)
9289                             (const_int 8)
9290                             (const_int 8))
9291            (subreg:SI
9292              (any_or:QI
9293                (subreg:QI
9294                  (zero_extract:SI (match_dup 1)
9295                                   (const_int 8)
9296                                   (const_int 8)) 0)
9297                (match_dup 2)) 0))
9298       (clobber (reg:CC FLAGS_REG))])]
9300   operands[0] = gen_lowpart (SImode, operands[0]);
9301   operands[1] = gen_lowpart (SImode, operands[1]);
9302   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9305 ;; Since OR can be encoded with sign extended immediate, this is only
9306 ;; profitable when 7th bit is set.
9307 (define_split
9308   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9309         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9310                        (match_operand:SWI248 2 "const_int_operand")))
9311    (clobber (reg:CC FLAGS_REG))]
9312    "reload_completed
9313     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9314     && !(INTVAL (operands[2]) & ~255)
9315     && (INTVAL (operands[2]) & 128)"
9316   [(parallel [(set (strict_low_part (match_dup 0))
9317                    (any_or:QI (match_dup 1)
9318                               (match_dup 2)))
9319               (clobber (reg:CC FLAGS_REG))])]
9321   operands[0] = gen_lowpart (QImode, operands[0]);
9322   operands[1] = gen_lowpart (QImode, operands[1]);
9323   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9326 (define_expand "xorqi_ext_1_cc"
9327   [(parallel [
9328      (set (reg:CCNO FLAGS_REG)
9329           (compare:CCNO
9330             (xor:QI
9331               (subreg:QI
9332                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9333                                  (const_int 8)
9334                                  (const_int 8)) 0)
9335               (match_operand 2 "const_int_operand"))
9336             (const_int 0)))
9337      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9338                            (const_int 8)
9339                            (const_int 8))
9340           (subreg:SI
9341             (xor:QI
9342               (subreg:QI
9343                 (zero_extract:SI (match_dup 1)
9344                                  (const_int 8)
9345                                  (const_int 8)) 0)
9346             (match_dup 2)) 0))])])
9348 (define_insn "*xorqi_ext_1_cc"
9349   [(set (reg FLAGS_REG)
9350         (compare
9351           (xor:QI
9352             (subreg:QI
9353               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9354                                (const_int 8)
9355                                (const_int 8)) 0)
9356             (match_operand:QI 2 "general_operand" "QnBc,m"))
9357           (const_int 0)))
9358    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9359                          (const_int 8)
9360                          (const_int 8))
9361         (subreg:SI
9362           (xor:QI
9363             (subreg:QI
9364               (zero_extract:SI (match_dup 1)
9365                                (const_int 8)
9366                                (const_int 8)) 0)
9367           (match_dup 2)) 0))]
9368   "ix86_match_ccmode (insn, CCNOmode)
9369    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9370    && rtx_equal_p (operands[0], operands[1])"
9371   "xor{b}\t{%2, %h0|%h0, %2}"
9372   [(set_attr "isa" "*,nox64")
9373    (set_attr "type" "alu")
9374    (set_attr "mode" "QI")])
9376 ;; Negation instructions
9378 (define_expand "neg<mode>2"
9379   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9380         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9381   ""
9382   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9384 (define_insn_and_split "*neg<dwi>2_doubleword"
9385   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9386         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9387    (clobber (reg:CC FLAGS_REG))]
9388   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9389   "#"
9390   "reload_completed"
9391   [(parallel
9392     [(set (reg:CCZ FLAGS_REG)
9393           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9394      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9395    (parallel
9396     [(set (match_dup 2)
9397           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9398                                 (match_dup 3))
9399                      (const_int 0)))
9400      (clobber (reg:CC FLAGS_REG))])
9401    (parallel
9402     [(set (match_dup 2)
9403           (neg:DWIH (match_dup 2)))
9404      (clobber (reg:CC FLAGS_REG))])]
9405   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9407 (define_insn "*neg<mode>2_1"
9408   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9409         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9412   "neg{<imodesuffix>}\t%0"
9413   [(set_attr "type" "negnot")
9414    (set_attr "mode" "<MODE>")])
9416 ;; Combine is quite creative about this pattern.
9417 (define_insn "*negsi2_1_zext"
9418   [(set (match_operand:DI 0 "register_operand" "=r")
9419         (lshiftrt:DI
9420           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9421                              (const_int 32)))
9422         (const_int 32)))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9425   "neg{l}\t%k0"
9426   [(set_attr "type" "negnot")
9427    (set_attr "mode" "SI")])
9429 ;; The problem with neg is that it does not perform (compare x 0),
9430 ;; it really performs (compare 0 x), which leaves us with the zero
9431 ;; flag being the only useful item.
9433 (define_insn "*neg<mode>2_cmpz"
9434   [(set (reg:CCZ FLAGS_REG)
9435         (compare:CCZ
9436           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9437                    (const_int 0)))
9438    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9439         (neg:SWI (match_dup 1)))]
9440   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9441   "neg{<imodesuffix>}\t%0"
9442   [(set_attr "type" "negnot")
9443    (set_attr "mode" "<MODE>")])
9445 (define_insn "*negsi2_cmpz_zext"
9446   [(set (reg:CCZ FLAGS_REG)
9447         (compare:CCZ
9448           (lshiftrt:DI
9449             (neg:DI (ashift:DI
9450                       (match_operand:DI 1 "register_operand" "0")
9451                       (const_int 32)))
9452             (const_int 32))
9453           (const_int 0)))
9454    (set (match_operand:DI 0 "register_operand" "=r")
9455         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9456                                         (const_int 32)))
9457                      (const_int 32)))]
9458   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9459   "neg{l}\t%k0"
9460   [(set_attr "type" "negnot")
9461    (set_attr "mode" "SI")])
9463 ;; Negate with jump on overflow.
9464 (define_expand "negv<mode>3"
9465   [(parallel [(set (reg:CCO FLAGS_REG)
9466                    (ne:CCO (match_operand:SWI 1 "register_operand")
9467                            (match_dup 3)))
9468               (set (match_operand:SWI 0 "register_operand")
9469                    (neg:SWI (match_dup 1)))])
9470    (set (pc) (if_then_else
9471                (eq (reg:CCO FLAGS_REG) (const_int 0))
9472                (label_ref (match_operand 2))
9473                (pc)))]
9474   ""
9476   operands[3]
9477     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9478                     <MODE>mode);
9481 (define_insn "*negv<mode>3"
9482   [(set (reg:CCO FLAGS_REG)
9483         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9484                 (match_operand:SWI 2 "const_int_operand")))
9485    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9486         (neg:SWI (match_dup 1)))]
9487   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9488    && mode_signbit_p (<MODE>mode, operands[2])"
9489   "neg{<imodesuffix>}\t%0"
9490   [(set_attr "type" "negnot")
9491    (set_attr "mode" "<MODE>")])
9493 ;; Changing of sign for FP values is doable using integer unit too.
9495 (define_expand "<code><mode>2"
9496   [(set (match_operand:X87MODEF 0 "register_operand")
9497         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9498   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9499   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9501 (define_insn "*absneg<mode>2"
9502   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9503         (match_operator:MODEF 3 "absneg_operator"
9504           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9505    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9506    (clobber (reg:CC FLAGS_REG))]
9507   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9508   "#"
9509   [(set (attr "enabled")
9510      (if_then_else
9511        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9512        (if_then_else
9513          (eq_attr "alternative" "2")
9514          (symbol_ref "TARGET_MIX_SSE_I387")
9515          (symbol_ref "true"))
9516        (if_then_else
9517          (eq_attr "alternative" "2,3")
9518          (symbol_ref "true")
9519          (symbol_ref "false"))))])
9521 (define_insn "*absnegxf2_i387"
9522   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9523         (match_operator:XF 3 "absneg_operator"
9524           [(match_operand:XF 1 "register_operand" "0,0")]))
9525    (use (match_operand 2))
9526    (clobber (reg:CC FLAGS_REG))]
9527   "TARGET_80387"
9528   "#")
9530 (define_expand "<code>tf2"
9531   [(set (match_operand:TF 0 "register_operand")
9532         (absneg:TF (match_operand:TF 1 "register_operand")))]
9533   "TARGET_SSE"
9534   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9536 (define_insn "*absnegtf2_sse"
9537   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9538         (match_operator:TF 3 "absneg_operator"
9539           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9540    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "TARGET_SSE"
9543   "#")
9545 ;; Splitters for fp abs and neg.
9547 (define_split
9548   [(set (match_operand 0 "fp_register_operand")
9549         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9550    (use (match_operand 2))
9551    (clobber (reg:CC FLAGS_REG))]
9552   "reload_completed"
9553   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9555 (define_split
9556   [(set (match_operand 0 "sse_reg_operand")
9557         (match_operator 3 "absneg_operator"
9558           [(match_operand 1 "register_operand")]))
9559    (use (match_operand 2 "nonimmediate_operand"))
9560    (clobber (reg:CC FLAGS_REG))]
9561   "reload_completed"
9562   [(set (match_dup 0) (match_dup 3))]
9564   machine_mode mode = GET_MODE (operands[0]);
9565   machine_mode vmode = GET_MODE (operands[2]);
9566   rtx tmp;
9568   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9569   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9570   if (operands_match_p (operands[0], operands[2]))
9571     std::swap (operands[1], operands[2]);
9572   if (GET_CODE (operands[3]) == ABS)
9573     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9574   else
9575     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9576   operands[3] = tmp;
9579 (define_split
9580   [(set (match_operand:SF 0 "general_reg_operand")
9581         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9582    (use (match_operand:V4SF 2))
9583    (clobber (reg:CC FLAGS_REG))]
9584   "reload_completed"
9585   [(parallel [(set (match_dup 0) (match_dup 1))
9586               (clobber (reg:CC FLAGS_REG))])]
9588   rtx tmp;
9589   operands[0] = gen_lowpart (SImode, operands[0]);
9590   if (GET_CODE (operands[1]) == ABS)
9591     {
9592       tmp = gen_int_mode (0x7fffffff, SImode);
9593       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9594     }
9595   else
9596     {
9597       tmp = gen_int_mode (0x80000000, SImode);
9598       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9599     }
9600   operands[1] = tmp;
9603 (define_split
9604   [(set (match_operand:DF 0 "general_reg_operand")
9605         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9606    (use (match_operand 2))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "reload_completed"
9609   [(parallel [(set (match_dup 0) (match_dup 1))
9610               (clobber (reg:CC FLAGS_REG))])]
9612   rtx tmp;
9613   if (TARGET_64BIT)
9614     {
9615       tmp = gen_lowpart (DImode, operands[0]);
9616       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9617       operands[0] = tmp;
9619       if (GET_CODE (operands[1]) == ABS)
9620         tmp = const0_rtx;
9621       else
9622         tmp = gen_rtx_NOT (DImode, tmp);
9623     }
9624   else
9625     {
9626       operands[0] = gen_highpart (SImode, operands[0]);
9627       if (GET_CODE (operands[1]) == ABS)
9628         {
9629           tmp = gen_int_mode (0x7fffffff, SImode);
9630           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9631         }
9632       else
9633         {
9634           tmp = gen_int_mode (0x80000000, SImode);
9635           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9636         }
9637     }
9638   operands[1] = tmp;
9641 (define_split
9642   [(set (match_operand:XF 0 "general_reg_operand")
9643         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9644    (use (match_operand 2))
9645    (clobber (reg:CC FLAGS_REG))]
9646   "reload_completed"
9647   [(parallel [(set (match_dup 0) (match_dup 1))
9648               (clobber (reg:CC FLAGS_REG))])]
9650   rtx tmp;
9651   operands[0] = gen_rtx_REG (SImode,
9652                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9653   if (GET_CODE (operands[1]) == ABS)
9654     {
9655       tmp = GEN_INT (0x7fff);
9656       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9657     }
9658   else
9659     {
9660       tmp = GEN_INT (0x8000);
9661       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9662     }
9663   operands[1] = tmp;
9666 ;; Conditionalize these after reload. If they match before reload, we
9667 ;; lose the clobber and ability to use integer instructions.
9669 (define_insn "*<code><mode>2_1"
9670   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9671         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9672   "TARGET_80387
9673    && (reload_completed
9674        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9675   "<absneg_mnemonic>"
9676   [(set_attr "type" "fsgn")
9677    (set_attr "mode" "<MODE>")])
9679 ;; Copysign instructions
9681 (define_mode_iterator CSGNMODE [SF DF TF])
9682 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9684 (define_expand "copysign<mode>3"
9685   [(match_operand:CSGNMODE 0 "register_operand")
9686    (match_operand:CSGNMODE 1 "nonmemory_operand")
9687    (match_operand:CSGNMODE 2 "register_operand")]
9688   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9689    || (TARGET_SSE && (<MODE>mode == TFmode))"
9690   "ix86_expand_copysign (operands); DONE;")
9692 (define_insn_and_split "copysign<mode>3_const"
9693   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9694         (unspec:CSGNMODE
9695           [(match_operand:<CSGNVMODE> 1 "nonimm_or_0_operand" "YvmC")
9696            (match_operand:CSGNMODE 2 "register_operand" "0")
9697            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9698           UNSPEC_COPYSIGN))]
9699   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9700    || (TARGET_SSE && (<MODE>mode == TFmode))"
9701   "#"
9702   "&& reload_completed"
9703   [(const_int 0)]
9704   "ix86_split_copysign_const (operands); DONE;")
9706 (define_insn "copysign<mode>3_var"
9707   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9708         (unspec:CSGNMODE
9709           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9710            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9711            (match_operand:<CSGNVMODE> 4
9712              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9713            (match_operand:<CSGNVMODE> 5
9714              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9715           UNSPEC_COPYSIGN))
9716    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9717   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9718    || (TARGET_SSE && (<MODE>mode == TFmode))"
9719   "#")
9721 (define_split
9722   [(set (match_operand:CSGNMODE 0 "register_operand")
9723         (unspec:CSGNMODE
9724           [(match_operand:CSGNMODE 2 "register_operand")
9725            (match_operand:CSGNMODE 3 "register_operand")
9726            (match_operand:<CSGNVMODE> 4)
9727            (match_operand:<CSGNVMODE> 5)]
9728           UNSPEC_COPYSIGN))
9729    (clobber (match_scratch:<CSGNVMODE> 1))]
9730   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9731     || (TARGET_SSE && (<MODE>mode == TFmode)))
9732    && reload_completed"
9733   [(const_int 0)]
9734   "ix86_split_copysign_var (operands); DONE;")
9736 ;; One complement instructions
9738 (define_expand "one_cmpl<mode>2"
9739   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9740         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9741   ""
9742   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9744 (define_insn_and_split "*one_cmpldi2_doubleword"
9745   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9746         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9747   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9748    && ix86_unary_operator_ok (NOT, DImode, operands)"
9749   "#"
9750   "&& reload_completed"
9751   [(set (match_dup 0)
9752         (not:SI (match_dup 1)))
9753    (set (match_dup 2)
9754         (not:SI (match_dup 3)))]
9755   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9757 (define_insn "*one_cmpl<mode>2_1"
9758   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9759         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9760   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9761   "not{<imodesuffix>}\t%0"
9762   [(set_attr "type" "negnot")
9763    (set_attr "mode" "<MODE>")])
9765 ;; ??? Currently never generated - xor is used instead.
9766 (define_insn "*one_cmplsi2_1_zext"
9767   [(set (match_operand:DI 0 "register_operand" "=r")
9768         (zero_extend:DI
9769           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9770   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9771   "not{l}\t%k0"
9772   [(set_attr "type" "negnot")
9773    (set_attr "mode" "SI")])
9775 (define_insn "*one_cmplqi2_1"
9776   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9777         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9778   "ix86_unary_operator_ok (NOT, QImode, operands)"
9779   "@
9780    not{b}\t%0
9781    not{l}\t%k0"
9782   [(set_attr "type" "negnot")
9783    (set_attr "mode" "QI,SI")
9784    ;; Potential partial reg stall on alternative 1.
9785    (set (attr "preferred_for_speed")
9786      (cond [(eq_attr "alternative" "1")
9787               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9788            (symbol_ref "true")))])
9790 (define_insn "*one_cmpl<mode>2_2"
9791   [(set (reg FLAGS_REG)
9792         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9793                  (const_int 0)))
9794    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9795         (not:SWI (match_dup 1)))]
9796   "ix86_match_ccmode (insn, CCNOmode)
9797    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9798   "#"
9799   [(set_attr "type" "alu1")
9800    (set_attr "mode" "<MODE>")])
9802 (define_split
9803   [(set (match_operand 0 "flags_reg_operand")
9804         (match_operator 2 "compare_operator"
9805           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9806            (const_int 0)]))
9807    (set (match_operand:SWI 1 "nonimmediate_operand")
9808         (not:SWI (match_dup 3)))]
9809   "ix86_match_ccmode (insn, CCNOmode)"
9810   [(parallel [(set (match_dup 0)
9811                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9812                                     (const_int 0)]))
9813               (set (match_dup 1)
9814                    (xor:SWI (match_dup 3) (const_int -1)))])])
9816 ;; ??? Currently never generated - xor is used instead.
9817 (define_insn "*one_cmplsi2_2_zext"
9818   [(set (reg FLAGS_REG)
9819         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9820                  (const_int 0)))
9821    (set (match_operand:DI 0 "register_operand" "=r")
9822         (zero_extend:DI (not:SI (match_dup 1))))]
9823   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9824    && ix86_unary_operator_ok (NOT, SImode, operands)"
9825   "#"
9826   [(set_attr "type" "alu1")
9827    (set_attr "mode" "SI")])
9829 (define_split
9830   [(set (match_operand 0 "flags_reg_operand")
9831         (match_operator 2 "compare_operator"
9832           [(not:SI (match_operand:SI 3 "register_operand"))
9833            (const_int 0)]))
9834    (set (match_operand:DI 1 "register_operand")
9835         (zero_extend:DI (not:SI (match_dup 3))))]
9836   "ix86_match_ccmode (insn, CCNOmode)"
9837   [(parallel [(set (match_dup 0)
9838                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9839                                     (const_int 0)]))
9840               (set (match_dup 1)
9841                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9843 ;; Shift instructions
9845 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9846 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9847 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9848 ;; from the assembler input.
9850 ;; This instruction shifts the target reg/mem as usual, but instead of
9851 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9852 ;; is a left shift double, bits are taken from the high order bits of
9853 ;; reg, else if the insn is a shift right double, bits are taken from the
9854 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9855 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9857 ;; Since sh[lr]d does not change the `reg' operand, that is done
9858 ;; separately, making all shifts emit pairs of shift double and normal
9859 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9860 ;; support a 63 bit shift, each shift where the count is in a reg expands
9861 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9863 ;; If the shift count is a constant, we need never emit more than one
9864 ;; shift pair, instead using moves and sign extension for counts greater
9865 ;; than 31.
9867 (define_expand "ashl<mode>3"
9868   [(set (match_operand:SDWIM 0 "<shift_operand>")
9869         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9870                       (match_operand:QI 2 "nonmemory_operand")))]
9871   ""
9872   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9874 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9875   [(set (match_operand:<DWI> 0 "register_operand")
9876         (ashift:<DWI>
9877           (match_operand:<DWI> 1 "register_operand")
9878           (subreg:QI
9879             (and:SI
9880               (match_operand:SI 2 "register_operand" "c")
9881               (match_operand:SI 3 "const_int_operand")) 0)))
9882    (clobber (reg:CC FLAGS_REG))]
9883   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9884    && can_create_pseudo_p ()"
9885   "#"
9886   "&& 1"
9887   [(parallel
9888      [(set (match_dup 6)
9889            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9890                      (lshiftrt:DWIH (match_dup 5)
9891                        (minus:QI (match_dup 8) (match_dup 2)))))
9892       (clobber (reg:CC FLAGS_REG))])
9893    (parallel
9894      [(set (match_dup 4)
9895            (ashift:DWIH (match_dup 5) (match_dup 2)))
9896       (clobber (reg:CC FLAGS_REG))])]
9898   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9900   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9902   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9903       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9904     {
9905       rtx tem = gen_reg_rtx (SImode);
9906       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9907       operands[2] = tem;
9908     }
9910   operands[2] = gen_lowpart (QImode, operands[2]);
9912   if (!rtx_equal_p (operands[6], operands[7]))
9913     emit_move_insn (operands[6], operands[7]);
9916 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9917   [(set (match_operand:<DWI> 0 "register_operand")
9918         (ashift:<DWI>
9919           (match_operand:<DWI> 1 "register_operand")
9920           (and:QI
9921             (match_operand:QI 2 "register_operand" "c")
9922             (match_operand:QI 3 "const_int_operand"))))
9923    (clobber (reg:CC FLAGS_REG))]
9924   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9925    && can_create_pseudo_p ()"
9926   "#"
9927   "&& 1"
9928   [(parallel
9929      [(set (match_dup 6)
9930            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9931                      (lshiftrt:DWIH (match_dup 5)
9932                        (minus:QI (match_dup 8) (match_dup 2)))))
9933       (clobber (reg:CC FLAGS_REG))])
9934    (parallel
9935      [(set (match_dup 4)
9936            (ashift:DWIH (match_dup 5) (match_dup 2)))
9937       (clobber (reg:CC FLAGS_REG))])]
9939   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9941   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9943   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9944       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9945     {
9946       rtx tem = gen_reg_rtx (QImode);
9947       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9948       operands[2] = tem;
9949     }
9951   if (!rtx_equal_p (operands[6], operands[7]))
9952     emit_move_insn (operands[6], operands[7]);
9955 (define_insn "*ashl<mode>3_doubleword"
9956   [(set (match_operand:DWI 0 "register_operand" "=&r")
9957         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9958                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9959    (clobber (reg:CC FLAGS_REG))]
9960   ""
9961   "#"
9962   [(set_attr "type" "multi")])
9964 (define_split
9965   [(set (match_operand:DWI 0 "register_operand")
9966         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9967                     (match_operand:QI 2 "nonmemory_operand")))
9968    (clobber (reg:CC FLAGS_REG))]
9969   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9970   [(const_int 0)]
9971   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9973 ;; By default we don't ask for a scratch register, because when DWImode
9974 ;; values are manipulated, registers are already at a premium.  But if
9975 ;; we have one handy, we won't turn it away.
9977 (define_peephole2
9978   [(match_scratch:DWIH 3 "r")
9979    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9980                    (ashift:<DWI>
9981                      (match_operand:<DWI> 1 "nonmemory_operand")
9982                      (match_operand:QI 2 "nonmemory_operand")))
9983               (clobber (reg:CC FLAGS_REG))])
9984    (match_dup 3)]
9985   "TARGET_CMOVE"
9986   [(const_int 0)]
9987   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9989 (define_insn "x86_64_shld"
9990   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9991         (ior:DI (ashift:DI (match_dup 0)
9992                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9993                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9994                   (minus:QI (const_int 64) (match_dup 2)))))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "TARGET_64BIT"
9997   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9998   [(set_attr "type" "ishift")
9999    (set_attr "prefix_0f" "1")
10000    (set_attr "mode" "DI")
10001    (set_attr "athlon_decode" "vector")
10002    (set_attr "amdfam10_decode" "vector")
10003    (set_attr "bdver1_decode" "vector")])
10005 (define_insn "x86_shld"
10006   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10007         (ior:SI (ashift:SI (match_dup 0)
10008                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10009                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10010                   (minus:QI (const_int 32) (match_dup 2)))))
10011    (clobber (reg:CC FLAGS_REG))]
10012   ""
10013   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10014   [(set_attr "type" "ishift")
10015    (set_attr "prefix_0f" "1")
10016    (set_attr "mode" "SI")
10017    (set_attr "pent_pair" "np")
10018    (set_attr "athlon_decode" "vector")
10019    (set_attr "amdfam10_decode" "vector")
10020    (set_attr "bdver1_decode" "vector")])
10022 (define_expand "x86_shift<mode>_adj_1"
10023   [(set (reg:CCZ FLAGS_REG)
10024         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10025                              (match_dup 4))
10026                      (const_int 0)))
10027    (set (match_operand:SWI48 0 "register_operand")
10028         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10029                             (match_operand:SWI48 1 "register_operand")
10030                             (match_dup 0)))
10031    (set (match_dup 1)
10032         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10033                             (match_operand:SWI48 3 "register_operand")
10034                             (match_dup 1)))]
10035   "TARGET_CMOVE"
10036   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10038 (define_expand "x86_shift<mode>_adj_2"
10039   [(use (match_operand:SWI48 0 "register_operand"))
10040    (use (match_operand:SWI48 1 "register_operand"))
10041    (use (match_operand:QI 2 "register_operand"))]
10042   ""
10044   rtx_code_label *label = gen_label_rtx ();
10045   rtx tmp;
10047   emit_insn (gen_testqi_ccz_1 (operands[2],
10048                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10050   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10051   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10052   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10053                               gen_rtx_LABEL_REF (VOIDmode, label),
10054                               pc_rtx);
10055   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10056   JUMP_LABEL (tmp) = label;
10058   emit_move_insn (operands[0], operands[1]);
10059   ix86_expand_clear (operands[1]);
10061   emit_label (label);
10062   LABEL_NUSES (label) = 1;
10064   DONE;
10067 ;; Avoid useless masking of count operand.
10068 (define_insn_and_split "*ashl<mode>3_mask"
10069   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10070         (ashift:SWI48
10071           (match_operand:SWI48 1 "nonimmediate_operand")
10072           (subreg:QI
10073             (and:SI
10074               (match_operand:SI 2 "register_operand" "c,r")
10075               (match_operand:SI 3 "const_int_operand")) 0)))
10076    (clobber (reg:CC FLAGS_REG))]
10077   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10078    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10079       == GET_MODE_BITSIZE (<MODE>mode)-1
10080    && can_create_pseudo_p ()"
10081   "#"
10082   "&& 1"
10083   [(parallel
10084      [(set (match_dup 0)
10085            (ashift:SWI48 (match_dup 1)
10086                          (match_dup 2)))
10087       (clobber (reg:CC FLAGS_REG))])]
10088   "operands[2] = gen_lowpart (QImode, operands[2]);"
10089   [(set_attr "isa" "*,bmi2")])
10091 (define_insn_and_split "*ashl<mode>3_mask_1"
10092   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10093         (ashift:SWI48
10094           (match_operand:SWI48 1 "nonimmediate_operand")
10095           (and:QI
10096             (match_operand:QI 2 "register_operand" "c,r")
10097             (match_operand:QI 3 "const_int_operand"))))
10098    (clobber (reg:CC FLAGS_REG))]
10099   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10100    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10101       == GET_MODE_BITSIZE (<MODE>mode)-1
10102    && can_create_pseudo_p ()"
10103   "#"
10104   "&& 1"
10105   [(parallel
10106      [(set (match_dup 0)
10107            (ashift:SWI48 (match_dup 1)
10108                          (match_dup 2)))
10109       (clobber (reg:CC FLAGS_REG))])]
10110   ""
10111   [(set_attr "isa" "*,bmi2")])
10113 (define_insn "*bmi2_ashl<mode>3_1"
10114   [(set (match_operand:SWI48 0 "register_operand" "=r")
10115         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10116                       (match_operand:SWI48 2 "register_operand" "r")))]
10117   "TARGET_BMI2"
10118   "shlx\t{%2, %1, %0|%0, %1, %2}"
10119   [(set_attr "type" "ishiftx")
10120    (set_attr "mode" "<MODE>")])
10122 (define_insn "*ashl<mode>3_1"
10123   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10124         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10125                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10126    (clobber (reg:CC FLAGS_REG))]
10127   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10129   switch (get_attr_type (insn))
10130     {
10131     case TYPE_LEA:
10132     case TYPE_ISHIFTX:
10133       return "#";
10135     case TYPE_ALU:
10136       gcc_assert (operands[2] == const1_rtx);
10137       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10138       return "add{<imodesuffix>}\t%0, %0";
10140     default:
10141       if (operands[2] == const1_rtx
10142           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10143         return "sal{<imodesuffix>}\t%0";
10144       else
10145         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10146     }
10148   [(set_attr "isa" "*,*,bmi2")
10149    (set (attr "type")
10150      (cond [(eq_attr "alternative" "1")
10151               (const_string "lea")
10152             (eq_attr "alternative" "2")
10153               (const_string "ishiftx")
10154             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10155                       (match_operand 0 "register_operand"))
10156                  (match_operand 2 "const1_operand"))
10157               (const_string "alu")
10158            ]
10159            (const_string "ishift")))
10160    (set (attr "length_immediate")
10161      (if_then_else
10162        (ior (eq_attr "type" "alu")
10163             (and (eq_attr "type" "ishift")
10164                  (and (match_operand 2 "const1_operand")
10165                       (ior (match_test "TARGET_SHIFT1")
10166                            (match_test "optimize_function_for_size_p (cfun)")))))
10167        (const_string "0")
10168        (const_string "*")))
10169    (set_attr "mode" "<MODE>")])
10171 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10172 (define_split
10173   [(set (match_operand:SWI48 0 "register_operand")
10174         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10175                       (match_operand:QI 2 "register_operand")))
10176    (clobber (reg:CC FLAGS_REG))]
10177   "TARGET_BMI2 && reload_completed"
10178   [(set (match_dup 0)
10179         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10180   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10182 (define_insn "*bmi2_ashlsi3_1_zext"
10183   [(set (match_operand:DI 0 "register_operand" "=r")
10184         (zero_extend:DI
10185           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10186                      (match_operand:SI 2 "register_operand" "r"))))]
10187   "TARGET_64BIT && TARGET_BMI2"
10188   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10189   [(set_attr "type" "ishiftx")
10190    (set_attr "mode" "SI")])
10192 (define_insn "*ashlsi3_1_zext"
10193   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10194         (zero_extend:DI
10195           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10196                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10197    (clobber (reg:CC FLAGS_REG))]
10198   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10200   switch (get_attr_type (insn))
10201     {
10202     case TYPE_LEA:
10203     case TYPE_ISHIFTX:
10204       return "#";
10206     case TYPE_ALU:
10207       gcc_assert (operands[2] == const1_rtx);
10208       return "add{l}\t%k0, %k0";
10210     default:
10211       if (operands[2] == const1_rtx
10212           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10213         return "sal{l}\t%k0";
10214       else
10215         return "sal{l}\t{%2, %k0|%k0, %2}";
10216     }
10218   [(set_attr "isa" "*,*,bmi2")
10219    (set (attr "type")
10220      (cond [(eq_attr "alternative" "1")
10221               (const_string "lea")
10222             (eq_attr "alternative" "2")
10223               (const_string "ishiftx")
10224             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10225                  (match_operand 2 "const1_operand"))
10226               (const_string "alu")
10227            ]
10228            (const_string "ishift")))
10229    (set (attr "length_immediate")
10230      (if_then_else
10231        (ior (eq_attr "type" "alu")
10232             (and (eq_attr "type" "ishift")
10233                  (and (match_operand 2 "const1_operand")
10234                       (ior (match_test "TARGET_SHIFT1")
10235                            (match_test "optimize_function_for_size_p (cfun)")))))
10236        (const_string "0")
10237        (const_string "*")))
10238    (set_attr "mode" "SI")])
10240 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10241 (define_split
10242   [(set (match_operand:DI 0 "register_operand")
10243         (zero_extend:DI
10244           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10245                      (match_operand:QI 2 "register_operand"))))
10246    (clobber (reg:CC FLAGS_REG))]
10247   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10248   [(set (match_dup 0)
10249         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10250   "operands[2] = gen_lowpart (SImode, operands[2]);")
10252 (define_insn "*ashlhi3_1"
10253   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10254         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10255                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10256    (clobber (reg:CC FLAGS_REG))]
10257   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10259   switch (get_attr_type (insn))
10260     {
10261     case TYPE_LEA:
10262       return "#";
10264     case TYPE_ALU:
10265       gcc_assert (operands[2] == const1_rtx);
10266       return "add{w}\t%0, %0";
10268     default:
10269       if (operands[2] == const1_rtx
10270           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10271         return "sal{w}\t%0";
10272       else
10273         return "sal{w}\t{%2, %0|%0, %2}";
10274     }
10276   [(set (attr "type")
10277      (cond [(eq_attr "alternative" "1")
10278               (const_string "lea")
10279             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10280                       (match_operand 0 "register_operand"))
10281                  (match_operand 2 "const1_operand"))
10282               (const_string "alu")
10283            ]
10284            (const_string "ishift")))
10285    (set (attr "length_immediate")
10286      (if_then_else
10287        (ior (eq_attr "type" "alu")
10288             (and (eq_attr "type" "ishift")
10289                  (and (match_operand 2 "const1_operand")
10290                       (ior (match_test "TARGET_SHIFT1")
10291                            (match_test "optimize_function_for_size_p (cfun)")))))
10292        (const_string "0")
10293        (const_string "*")))
10294    (set_attr "mode" "HI,SI")])
10296 (define_insn "*ashlqi3_1"
10297   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10298         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10299                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10300    (clobber (reg:CC FLAGS_REG))]
10301   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10303   switch (get_attr_type (insn))
10304     {
10305     case TYPE_LEA:
10306       return "#";
10308     case TYPE_ALU:
10309       gcc_assert (operands[2] == const1_rtx);
10310       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10311         return "add{l}\t%k0, %k0";
10312       else
10313         return "add{b}\t%0, %0";
10315     default:
10316       if (operands[2] == const1_rtx
10317           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10318         {
10319           if (get_attr_mode (insn) == MODE_SI)
10320             return "sal{l}\t%k0";
10321           else
10322             return "sal{b}\t%0";
10323         }
10324       else
10325         {
10326           if (get_attr_mode (insn) == MODE_SI)
10327             return "sal{l}\t{%2, %k0|%k0, %2}";
10328           else
10329             return "sal{b}\t{%2, %0|%0, %2}";
10330         }
10331     }
10333   [(set (attr "type")
10334      (cond [(eq_attr "alternative" "2")
10335               (const_string "lea")
10336             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10337                       (match_operand 0 "register_operand"))
10338                  (match_operand 2 "const1_operand"))
10339               (const_string "alu")
10340            ]
10341            (const_string "ishift")))
10342    (set (attr "length_immediate")
10343      (if_then_else
10344        (ior (eq_attr "type" "alu")
10345             (and (eq_attr "type" "ishift")
10346                  (and (match_operand 2 "const1_operand")
10347                       (ior (match_test "TARGET_SHIFT1")
10348                            (match_test "optimize_function_for_size_p (cfun)")))))
10349        (const_string "0")
10350        (const_string "*")))
10351    (set_attr "mode" "QI,SI,SI")
10352    ;; Potential partial reg stall on alternative 1.
10353    (set (attr "preferred_for_speed")
10354      (cond [(eq_attr "alternative" "1")
10355               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10356            (symbol_ref "true")))])
10358 (define_insn "*ashlqi3_1_slp"
10359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10360         (ashift:QI (match_dup 0)
10361                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10362    (clobber (reg:CC FLAGS_REG))]
10363   "(optimize_function_for_size_p (cfun)
10364     || !TARGET_PARTIAL_FLAG_REG_STALL
10365     || (operands[1] == const1_rtx
10366         && (TARGET_SHIFT1
10367             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10369   switch (get_attr_type (insn))
10370     {
10371     case TYPE_ALU1:
10372       gcc_assert (operands[1] == const1_rtx);
10373       return "add{b}\t%0, %0";
10375     default:
10376       if (operands[1] == const1_rtx
10377           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10378         return "sal{b}\t%0";
10379       else
10380         return "sal{b}\t{%1, %0|%0, %1}";
10381     }
10383   [(set (attr "type")
10384      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10385                       (match_operand 0 "register_operand"))
10386                  (match_operand 1 "const1_operand"))
10387               (const_string "alu1")
10388            ]
10389            (const_string "ishift1")))
10390    (set (attr "length_immediate")
10391      (if_then_else
10392        (ior (eq_attr "type" "alu1")
10393             (and (eq_attr "type" "ishift1")
10394                  (and (match_operand 1 "const1_operand")
10395                       (ior (match_test "TARGET_SHIFT1")
10396                            (match_test "optimize_function_for_size_p (cfun)")))))
10397        (const_string "0")
10398        (const_string "*")))
10399    (set_attr "mode" "QI")])
10401 ;; Convert ashift to the lea pattern to avoid flags dependency.
10402 (define_split
10403   [(set (match_operand:SWI 0 "register_operand")
10404         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10405                     (match_operand 2 "const_0_to_3_operand")))
10406    (clobber (reg:CC FLAGS_REG))]
10407   "reload_completed
10408    && REGNO (operands[0]) != REGNO (operands[1])"
10409   [(set (match_dup 0)
10410         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10412   if (<MODE>mode != <LEAMODE>mode)
10413     {
10414       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10415       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10416     }
10417   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10420 ;; Convert ashift to the lea pattern to avoid flags dependency.
10421 (define_split
10422   [(set (match_operand:DI 0 "register_operand")
10423         (zero_extend:DI
10424           (ashift:SI (match_operand:SI 1 "index_register_operand")
10425                      (match_operand 2 "const_0_to_3_operand"))))
10426    (clobber (reg:CC FLAGS_REG))]
10427   "TARGET_64BIT && reload_completed
10428    && REGNO (operands[0]) != REGNO (operands[1])"
10429   [(set (match_dup 0)
10430         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10432   operands[1] = gen_lowpart (SImode, operands[1]);
10433   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10436 ;; This pattern can't accept a variable shift count, since shifts by
10437 ;; zero don't affect the flags.  We assume that shifts by constant
10438 ;; zero are optimized away.
10439 (define_insn "*ashl<mode>3_cmp"
10440   [(set (reg FLAGS_REG)
10441         (compare
10442           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10443                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10444           (const_int 0)))
10445    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10446         (ashift:SWI (match_dup 1) (match_dup 2)))]
10447   "(optimize_function_for_size_p (cfun)
10448     || !TARGET_PARTIAL_FLAG_REG_STALL
10449     || (operands[2] == const1_rtx
10450         && (TARGET_SHIFT1
10451             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10452    && ix86_match_ccmode (insn, CCGOCmode)
10453    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10455   switch (get_attr_type (insn))
10456     {
10457     case TYPE_ALU:
10458       gcc_assert (operands[2] == const1_rtx);
10459       return "add{<imodesuffix>}\t%0, %0";
10461     default:
10462       if (operands[2] == const1_rtx
10463           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464         return "sal{<imodesuffix>}\t%0";
10465       else
10466         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10467     }
10469   [(set (attr "type")
10470      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10471                       (match_operand 0 "register_operand"))
10472                  (match_operand 2 "const1_operand"))
10473               (const_string "alu")
10474            ]
10475            (const_string "ishift")))
10476    (set (attr "length_immediate")
10477      (if_then_else
10478        (ior (eq_attr "type" "alu")
10479             (and (eq_attr "type" "ishift")
10480                  (and (match_operand 2 "const1_operand")
10481                       (ior (match_test "TARGET_SHIFT1")
10482                            (match_test "optimize_function_for_size_p (cfun)")))))
10483        (const_string "0")
10484        (const_string "*")))
10485    (set_attr "mode" "<MODE>")])
10487 (define_insn "*ashlsi3_cmp_zext"
10488   [(set (reg FLAGS_REG)
10489         (compare
10490           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10491                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10492           (const_int 0)))
10493    (set (match_operand:DI 0 "register_operand" "=r")
10494         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10495   "TARGET_64BIT
10496    && (optimize_function_for_size_p (cfun)
10497        || !TARGET_PARTIAL_FLAG_REG_STALL
10498        || (operands[2] == const1_rtx
10499            && (TARGET_SHIFT1
10500                || TARGET_DOUBLE_WITH_ADD)))
10501    && ix86_match_ccmode (insn, CCGOCmode)
10502    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10504   switch (get_attr_type (insn))
10505     {
10506     case TYPE_ALU:
10507       gcc_assert (operands[2] == const1_rtx);
10508       return "add{l}\t%k0, %k0";
10510     default:
10511       if (operands[2] == const1_rtx
10512           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10513         return "sal{l}\t%k0";
10514       else
10515         return "sal{l}\t{%2, %k0|%k0, %2}";
10516     }
10518   [(set (attr "type")
10519      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10520                  (match_operand 2 "const1_operand"))
10521               (const_string "alu")
10522            ]
10523            (const_string "ishift")))
10524    (set (attr "length_immediate")
10525      (if_then_else
10526        (ior (eq_attr "type" "alu")
10527             (and (eq_attr "type" "ishift")
10528                  (and (match_operand 2 "const1_operand")
10529                       (ior (match_test "TARGET_SHIFT1")
10530                            (match_test "optimize_function_for_size_p (cfun)")))))
10531        (const_string "0")
10532        (const_string "*")))
10533    (set_attr "mode" "SI")])
10535 (define_insn "*ashl<mode>3_cconly"
10536   [(set (reg FLAGS_REG)
10537         (compare
10538           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10539                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10540           (const_int 0)))
10541    (clobber (match_scratch:SWI 0 "=<r>"))]
10542   "(optimize_function_for_size_p (cfun)
10543     || !TARGET_PARTIAL_FLAG_REG_STALL
10544     || (operands[2] == const1_rtx
10545         && (TARGET_SHIFT1
10546             || TARGET_DOUBLE_WITH_ADD)))
10547    && ix86_match_ccmode (insn, CCGOCmode)"
10549   switch (get_attr_type (insn))
10550     {
10551     case TYPE_ALU:
10552       gcc_assert (operands[2] == const1_rtx);
10553       return "add{<imodesuffix>}\t%0, %0";
10555     default:
10556       if (operands[2] == const1_rtx
10557           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10558         return "sal{<imodesuffix>}\t%0";
10559       else
10560         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10561     }
10563   [(set (attr "type")
10564      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10565                       (match_operand 0 "register_operand"))
10566                  (match_operand 2 "const1_operand"))
10567               (const_string "alu")
10568            ]
10569            (const_string "ishift")))
10570    (set (attr "length_immediate")
10571      (if_then_else
10572        (ior (eq_attr "type" "alu")
10573             (and (eq_attr "type" "ishift")
10574                  (and (match_operand 2 "const1_operand")
10575                       (ior (match_test "TARGET_SHIFT1")
10576                            (match_test "optimize_function_for_size_p (cfun)")))))
10577        (const_string "0")
10578        (const_string "*")))
10579    (set_attr "mode" "<MODE>")])
10581 ;; See comment above `ashl<mode>3' about how this works.
10583 (define_expand "<shift_insn><mode>3"
10584   [(set (match_operand:SDWIM 0 "<shift_operand>")
10585         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10586                            (match_operand:QI 2 "nonmemory_operand")))]
10587   ""
10588   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10590 ;; Avoid useless masking of count operand.
10591 (define_insn_and_split "*<shift_insn><mode>3_mask"
10592   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10593         (any_shiftrt:SWI48
10594           (match_operand:SWI48 1 "nonimmediate_operand")
10595           (subreg:QI
10596             (and:SI
10597               (match_operand:SI 2 "register_operand" "c,r")
10598               (match_operand:SI 3 "const_int_operand")) 0)))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10601    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10602       == GET_MODE_BITSIZE (<MODE>mode)-1
10603    && can_create_pseudo_p ()"
10604   "#"
10605   "&& 1"
10606   [(parallel
10607      [(set (match_dup 0)
10608            (any_shiftrt:SWI48 (match_dup 1)
10609                               (match_dup 2)))
10610       (clobber (reg:CC FLAGS_REG))])]
10611   "operands[2] = gen_lowpart (QImode, operands[2]);"
10612   [(set_attr "isa" "*,bmi2")])
10614 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10615   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10616         (any_shiftrt:SWI48
10617           (match_operand:SWI48 1 "nonimmediate_operand")
10618           (and:QI
10619             (match_operand:QI 2 "register_operand" "c,r")
10620             (match_operand:QI 3 "const_int_operand"))))
10621    (clobber (reg:CC FLAGS_REG))]
10622   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10623    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10624       == GET_MODE_BITSIZE (<MODE>mode)-1
10625    && can_create_pseudo_p ()"
10626   "#"
10627   "&& 1"
10628   [(parallel
10629      [(set (match_dup 0)
10630            (any_shiftrt:SWI48 (match_dup 1)
10631                               (match_dup 2)))
10632       (clobber (reg:CC FLAGS_REG))])]
10633   ""
10634   [(set_attr "isa" "*,bmi2")])
10636 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10637   [(set (match_operand:<DWI> 0 "register_operand")
10638         (any_shiftrt:<DWI>
10639           (match_operand:<DWI> 1 "register_operand")
10640           (subreg:QI
10641             (and:SI
10642               (match_operand:SI 2 "register_operand" "c")
10643               (match_operand:SI 3 "const_int_operand")) 0)))
10644    (clobber (reg:CC FLAGS_REG))]
10645   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10646    && can_create_pseudo_p ()"
10647   "#"
10648   "&& 1"
10649   [(parallel
10650      [(set (match_dup 4)
10651            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10652                      (ashift:DWIH (match_dup 7)
10653                        (minus:QI (match_dup 8) (match_dup 2)))))
10654       (clobber (reg:CC FLAGS_REG))])
10655    (parallel
10656      [(set (match_dup 6)
10657            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10658       (clobber (reg:CC FLAGS_REG))])]
10660   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10662   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10664   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10665       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10666     {
10667       rtx tem = gen_reg_rtx (SImode);
10668       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10669       operands[2] = tem;
10670     }
10672   operands[2] = gen_lowpart (QImode, operands[2]);
10674   if (!rtx_equal_p (operands[4], operands[5]))
10675     emit_move_insn (operands[4], operands[5]);
10678 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10679   [(set (match_operand:<DWI> 0 "register_operand")
10680         (any_shiftrt:<DWI>
10681           (match_operand:<DWI> 1 "register_operand")
10682           (and:QI
10683             (match_operand:QI 2 "register_operand" "c")
10684             (match_operand:QI 3 "const_int_operand"))))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10687    && can_create_pseudo_p ()"
10688   "#"
10689   "&& 1"
10690   [(parallel
10691      [(set (match_dup 4)
10692            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10693                      (ashift:DWIH (match_dup 7)
10694                        (minus:QI (match_dup 8) (match_dup 2)))))
10695       (clobber (reg:CC FLAGS_REG))])
10696    (parallel
10697      [(set (match_dup 6)
10698            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10699       (clobber (reg:CC FLAGS_REG))])]
10701   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10703   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10705   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10706       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10707     {
10708       rtx tem = gen_reg_rtx (QImode);
10709       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10710       operands[2] = tem;
10711     }
10713   if (!rtx_equal_p (operands[4], operands[5]))
10714     emit_move_insn (operands[4], operands[5]);
10717 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10718   [(set (match_operand:DWI 0 "register_operand" "=&r")
10719         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10720                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   ""
10723   "#"
10724   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10725   [(const_int 0)]
10726   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10727   [(set_attr "type" "multi")])
10729 ;; By default we don't ask for a scratch register, because when DWImode
10730 ;; values are manipulated, registers are already at a premium.  But if
10731 ;; we have one handy, we won't turn it away.
10733 (define_peephole2
10734   [(match_scratch:DWIH 3 "r")
10735    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10736                    (any_shiftrt:<DWI>
10737                      (match_operand:<DWI> 1 "register_operand")
10738                      (match_operand:QI 2 "nonmemory_operand")))
10739               (clobber (reg:CC FLAGS_REG))])
10740    (match_dup 3)]
10741   "TARGET_CMOVE"
10742   [(const_int 0)]
10743   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10745 (define_insn "x86_64_shrd"
10746   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10747         (ior:DI (lshiftrt:DI (match_dup 0)
10748                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10749                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10750                   (minus:QI (const_int 64) (match_dup 2)))))
10751    (clobber (reg:CC FLAGS_REG))]
10752   "TARGET_64BIT"
10753   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10754   [(set_attr "type" "ishift")
10755    (set_attr "prefix_0f" "1")
10756    (set_attr "mode" "DI")
10757    (set_attr "athlon_decode" "vector")
10758    (set_attr "amdfam10_decode" "vector")
10759    (set_attr "bdver1_decode" "vector")])
10761 (define_insn "x86_shrd"
10762   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10763         (ior:SI (lshiftrt:SI (match_dup 0)
10764                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10765                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10766                   (minus:QI (const_int 32) (match_dup 2)))))
10767    (clobber (reg:CC FLAGS_REG))]
10768   ""
10769   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10770   [(set_attr "type" "ishift")
10771    (set_attr "prefix_0f" "1")
10772    (set_attr "mode" "SI")
10773    (set_attr "pent_pair" "np")
10774    (set_attr "athlon_decode" "vector")
10775    (set_attr "amdfam10_decode" "vector")
10776    (set_attr "bdver1_decode" "vector")])
10778 (define_insn "ashrdi3_cvt"
10779   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10780         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10781                      (match_operand:QI 2 "const_int_operand")))
10782    (clobber (reg:CC FLAGS_REG))]
10783   "TARGET_64BIT && INTVAL (operands[2]) == 63
10784    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10785    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10786   "@
10787    {cqto|cqo}
10788    sar{q}\t{%2, %0|%0, %2}"
10789   [(set_attr "type" "imovx,ishift")
10790    (set_attr "prefix_0f" "0,*")
10791    (set_attr "length_immediate" "0,*")
10792    (set_attr "modrm" "0,1")
10793    (set_attr "mode" "DI")])
10795 (define_insn "*ashrsi3_cvt_zext"
10796   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10797         (zero_extend:DI
10798           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10799                        (match_operand:QI 2 "const_int_operand"))))
10800    (clobber (reg:CC FLAGS_REG))]
10801   "TARGET_64BIT && INTVAL (operands[2]) == 31
10802    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10803    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10804   "@
10805    {cltd|cdq}
10806    sar{l}\t{%2, %k0|%k0, %2}"
10807   [(set_attr "type" "imovx,ishift")
10808    (set_attr "prefix_0f" "0,*")
10809    (set_attr "length_immediate" "0,*")
10810    (set_attr "modrm" "0,1")
10811    (set_attr "mode" "SI")])
10813 (define_insn "ashrsi3_cvt"
10814   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10815         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10816                      (match_operand:QI 2 "const_int_operand")))
10817    (clobber (reg:CC FLAGS_REG))]
10818   "INTVAL (operands[2]) == 31
10819    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10820    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10821   "@
10822    {cltd|cdq}
10823    sar{l}\t{%2, %0|%0, %2}"
10824   [(set_attr "type" "imovx,ishift")
10825    (set_attr "prefix_0f" "0,*")
10826    (set_attr "length_immediate" "0,*")
10827    (set_attr "modrm" "0,1")
10828    (set_attr "mode" "SI")])
10830 (define_expand "x86_shift<mode>_adj_3"
10831   [(use (match_operand:SWI48 0 "register_operand"))
10832    (use (match_operand:SWI48 1 "register_operand"))
10833    (use (match_operand:QI 2 "register_operand"))]
10834   ""
10836   rtx_code_label *label = gen_label_rtx ();
10837   rtx tmp;
10839   emit_insn (gen_testqi_ccz_1 (operands[2],
10840                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10842   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10843   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10844   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10845                               gen_rtx_LABEL_REF (VOIDmode, label),
10846                               pc_rtx);
10847   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10848   JUMP_LABEL (tmp) = label;
10850   emit_move_insn (operands[0], operands[1]);
10851   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10852                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10853   emit_label (label);
10854   LABEL_NUSES (label) = 1;
10856   DONE;
10859 (define_insn "*bmi2_<shift_insn><mode>3_1"
10860   [(set (match_operand:SWI48 0 "register_operand" "=r")
10861         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10862                            (match_operand:SWI48 2 "register_operand" "r")))]
10863   "TARGET_BMI2"
10864   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10865   [(set_attr "type" "ishiftx")
10866    (set_attr "mode" "<MODE>")])
10868 (define_insn "*<shift_insn><mode>3_1"
10869   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10870         (any_shiftrt:SWI48
10871           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10872           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10876   switch (get_attr_type (insn))
10877     {
10878     case TYPE_ISHIFTX:
10879       return "#";
10881     default:
10882       if (operands[2] == const1_rtx
10883           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10884         return "<shift>{<imodesuffix>}\t%0";
10885       else
10886         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10887     }
10889   [(set_attr "isa" "*,bmi2")
10890    (set_attr "type" "ishift,ishiftx")
10891    (set (attr "length_immediate")
10892      (if_then_else
10893        (and (match_operand 2 "const1_operand")
10894             (ior (match_test "TARGET_SHIFT1")
10895                  (match_test "optimize_function_for_size_p (cfun)")))
10896        (const_string "0")
10897        (const_string "*")))
10898    (set_attr "mode" "<MODE>")])
10900 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10901 (define_split
10902   [(set (match_operand:SWI48 0 "register_operand")
10903         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10904                            (match_operand:QI 2 "register_operand")))
10905    (clobber (reg:CC FLAGS_REG))]
10906   "TARGET_BMI2 && reload_completed"
10907   [(set (match_dup 0)
10908         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10909   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10911 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10912   [(set (match_operand:DI 0 "register_operand" "=r")
10913         (zero_extend:DI
10914           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10915                           (match_operand:SI 2 "register_operand" "r"))))]
10916   "TARGET_64BIT && TARGET_BMI2"
10917   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10918   [(set_attr "type" "ishiftx")
10919    (set_attr "mode" "SI")])
10921 (define_insn "*<shift_insn>si3_1_zext"
10922   [(set (match_operand:DI 0 "register_operand" "=r,r")
10923         (zero_extend:DI
10924           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10925                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10929   switch (get_attr_type (insn))
10930     {
10931     case TYPE_ISHIFTX:
10932       return "#";
10934     default:
10935       if (operands[2] == const1_rtx
10936           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10937         return "<shift>{l}\t%k0";
10938       else
10939         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10940     }
10942   [(set_attr "isa" "*,bmi2")
10943    (set_attr "type" "ishift,ishiftx")
10944    (set (attr "length_immediate")
10945      (if_then_else
10946        (and (match_operand 2 "const1_operand")
10947             (ior (match_test "TARGET_SHIFT1")
10948                  (match_test "optimize_function_for_size_p (cfun)")))
10949        (const_string "0")
10950        (const_string "*")))
10951    (set_attr "mode" "SI")])
10953 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10954 (define_split
10955   [(set (match_operand:DI 0 "register_operand")
10956         (zero_extend:DI
10957           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10958                           (match_operand:QI 2 "register_operand"))))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10961   [(set (match_dup 0)
10962         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10963   "operands[2] = gen_lowpart (SImode, operands[2]);")
10965 (define_insn "*<shift_insn><mode>3_1"
10966   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10967         (any_shiftrt:SWI12
10968           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10969           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10973   if (operands[2] == const1_rtx
10974       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10975     return "<shift>{<imodesuffix>}\t%0";
10976   else
10977     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10979   [(set_attr "type" "ishift")
10980    (set (attr "length_immediate")
10981      (if_then_else
10982        (and (match_operand 2 "const1_operand")
10983             (ior (match_test "TARGET_SHIFT1")
10984                  (match_test "optimize_function_for_size_p (cfun)")))
10985        (const_string "0")
10986        (const_string "*")))
10987    (set_attr "mode" "<MODE>")])
10989 (define_insn "*<shift_insn>qi3_1_slp"
10990   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10991         (any_shiftrt:QI (match_dup 0)
10992                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "(optimize_function_for_size_p (cfun)
10995     || !TARGET_PARTIAL_REG_STALL
10996     || (operands[1] == const1_rtx
10997         && TARGET_SHIFT1))"
10999   if (operands[1] == const1_rtx
11000       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11001     return "<shift>{b}\t%0";
11002   else
11003     return "<shift>{b}\t{%1, %0|%0, %1}";
11005   [(set_attr "type" "ishift1")
11006    (set (attr "length_immediate")
11007      (if_then_else
11008        (and (match_operand 1 "const1_operand")
11009             (ior (match_test "TARGET_SHIFT1")
11010                  (match_test "optimize_function_for_size_p (cfun)")))
11011        (const_string "0")
11012        (const_string "*")))
11013    (set_attr "mode" "QI")])
11015 ;; This pattern can't accept a variable shift count, since shifts by
11016 ;; zero don't affect the flags.  We assume that shifts by constant
11017 ;; zero are optimized away.
11018 (define_insn "*<shift_insn><mode>3_cmp"
11019   [(set (reg FLAGS_REG)
11020         (compare
11021           (any_shiftrt:SWI
11022             (match_operand:SWI 1 "nonimmediate_operand" "0")
11023             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11024           (const_int 0)))
11025    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11026         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11027   "(optimize_function_for_size_p (cfun)
11028     || !TARGET_PARTIAL_FLAG_REG_STALL
11029     || (operands[2] == const1_rtx
11030         && TARGET_SHIFT1))
11031    && ix86_match_ccmode (insn, CCGOCmode)
11032    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11034   if (operands[2] == const1_rtx
11035       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11036     return "<shift>{<imodesuffix>}\t%0";
11037   else
11038     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11040   [(set_attr "type" "ishift")
11041    (set (attr "length_immediate")
11042      (if_then_else
11043        (and (match_operand 2 "const1_operand")
11044             (ior (match_test "TARGET_SHIFT1")
11045                  (match_test "optimize_function_for_size_p (cfun)")))
11046        (const_string "0")
11047        (const_string "*")))
11048    (set_attr "mode" "<MODE>")])
11050 (define_insn "*<shift_insn>si3_cmp_zext"
11051   [(set (reg FLAGS_REG)
11052         (compare
11053           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11054                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11055           (const_int 0)))
11056    (set (match_operand:DI 0 "register_operand" "=r")
11057         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11058   "TARGET_64BIT
11059    && (optimize_function_for_size_p (cfun)
11060        || !TARGET_PARTIAL_FLAG_REG_STALL
11061        || (operands[2] == const1_rtx
11062            && TARGET_SHIFT1))
11063    && ix86_match_ccmode (insn, CCGOCmode)
11064    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11066   if (operands[2] == const1_rtx
11067       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11068     return "<shift>{l}\t%k0";
11069   else
11070     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11072   [(set_attr "type" "ishift")
11073    (set (attr "length_immediate")
11074      (if_then_else
11075        (and (match_operand 2 "const1_operand")
11076             (ior (match_test "TARGET_SHIFT1")
11077                  (match_test "optimize_function_for_size_p (cfun)")))
11078        (const_string "0")
11079        (const_string "*")))
11080    (set_attr "mode" "SI")])
11082 (define_insn "*<shift_insn><mode>3_cconly"
11083   [(set (reg FLAGS_REG)
11084         (compare
11085           (any_shiftrt:SWI
11086             (match_operand:SWI 1 "register_operand" "0")
11087             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11088           (const_int 0)))
11089    (clobber (match_scratch:SWI 0 "=<r>"))]
11090   "(optimize_function_for_size_p (cfun)
11091     || !TARGET_PARTIAL_FLAG_REG_STALL
11092     || (operands[2] == const1_rtx
11093         && TARGET_SHIFT1))
11094    && ix86_match_ccmode (insn, CCGOCmode)"
11096   if (operands[2] == const1_rtx
11097       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11098     return "<shift>{<imodesuffix>}\t%0";
11099   else
11100     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11102   [(set_attr "type" "ishift")
11103    (set (attr "length_immediate")
11104      (if_then_else
11105        (and (match_operand 2 "const1_operand")
11106             (ior (match_test "TARGET_SHIFT1")
11107                  (match_test "optimize_function_for_size_p (cfun)")))
11108        (const_string "0")
11109        (const_string "*")))
11110    (set_attr "mode" "<MODE>")])
11112 ;; Rotate instructions
11114 (define_expand "<rotate_insn>ti3"
11115   [(set (match_operand:TI 0 "register_operand")
11116         (any_rotate:TI (match_operand:TI 1 "register_operand")
11117                        (match_operand:QI 2 "nonmemory_operand")))]
11118   "TARGET_64BIT"
11120   if (const_1_to_63_operand (operands[2], VOIDmode))
11121     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11122                 (operands[0], operands[1], operands[2]));
11123   else
11124     FAIL;
11126   DONE;
11129 (define_expand "<rotate_insn>di3"
11130   [(set (match_operand:DI 0 "shiftdi_operand")
11131         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11132                        (match_operand:QI 2 "nonmemory_operand")))]
11133  ""
11135   if (TARGET_64BIT)
11136     ix86_expand_binary_operator (<CODE>, DImode, operands);
11137   else if (const_1_to_31_operand (operands[2], VOIDmode))
11138     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11139                 (operands[0], operands[1], operands[2]));
11140   else
11141     FAIL;
11143   DONE;
11146 (define_expand "<rotate_insn><mode>3"
11147   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11148         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11149                             (match_operand:QI 2 "nonmemory_operand")))]
11150   ""
11151   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11153 ;; Avoid useless masking of count operand.
11154 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11155   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11156         (any_rotate:SWI48
11157           (match_operand:SWI48 1 "nonimmediate_operand")
11158           (subreg:QI
11159             (and:SI
11160               (match_operand:SI 2 "register_operand" "c")
11161               (match_operand:SI 3 "const_int_operand")) 0)))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11164    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11165       == GET_MODE_BITSIZE (<MODE>mode)-1
11166    && can_create_pseudo_p ()"
11167   "#"
11168   "&& 1"
11169   [(parallel
11170      [(set (match_dup 0)
11171            (any_rotate:SWI48 (match_dup 1)
11172                              (match_dup 2)))
11173       (clobber (reg:CC FLAGS_REG))])]
11174   "operands[2] = gen_lowpart (QImode, operands[2]);")
11176 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11177   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11178         (any_rotate:SWI48
11179           (match_operand:SWI48 1 "nonimmediate_operand")
11180           (and:QI
11181             (match_operand:QI 2 "register_operand" "c")
11182             (match_operand:QI 3 "const_int_operand"))))
11183    (clobber (reg:CC FLAGS_REG))]
11184   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11185    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11186       == GET_MODE_BITSIZE (<MODE>mode)-1
11187    && can_create_pseudo_p ()"
11188   "#"
11189   "&& 1"
11190   [(parallel
11191      [(set (match_dup 0)
11192            (any_rotate:SWI48 (match_dup 1)
11193                              (match_dup 2)))
11194       (clobber (reg:CC FLAGS_REG))])])
11196 ;; Implement rotation using two double-precision
11197 ;; shift instructions and a scratch register.
11199 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11200  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11201        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11202                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11203   (clobber (reg:CC FLAGS_REG))
11204   (clobber (match_scratch:DWIH 3 "=&r"))]
11205  ""
11206  "#"
11207  "reload_completed"
11208  [(set (match_dup 3) (match_dup 4))
11209   (parallel
11210    [(set (match_dup 4)
11211          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11212                    (lshiftrt:DWIH (match_dup 5)
11213                                   (minus:QI (match_dup 6) (match_dup 2)))))
11214     (clobber (reg:CC FLAGS_REG))])
11215   (parallel
11216    [(set (match_dup 5)
11217          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11218                    (lshiftrt:DWIH (match_dup 3)
11219                                   (minus:QI (match_dup 6) (match_dup 2)))))
11220     (clobber (reg:CC FLAGS_REG))])]
11222   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11224   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11227 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11228  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11229        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11230                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11231   (clobber (reg:CC FLAGS_REG))
11232   (clobber (match_scratch:DWIH 3 "=&r"))]
11233  ""
11234  "#"
11235  "reload_completed"
11236  [(set (match_dup 3) (match_dup 4))
11237   (parallel
11238    [(set (match_dup 4)
11239          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11240                    (ashift:DWIH (match_dup 5)
11241                                 (minus:QI (match_dup 6) (match_dup 2)))))
11242     (clobber (reg:CC FLAGS_REG))])
11243   (parallel
11244    [(set (match_dup 5)
11245          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11246                    (ashift:DWIH (match_dup 3)
11247                                 (minus:QI (match_dup 6) (match_dup 2)))))
11248     (clobber (reg:CC FLAGS_REG))])]
11250   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11252   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11255 (define_mode_attr rorx_immediate_operand
11256         [(SI "const_0_to_31_operand")
11257          (DI "const_0_to_63_operand")])
11259 (define_insn "*bmi2_rorx<mode>3_1"
11260   [(set (match_operand:SWI48 0 "register_operand" "=r")
11261         (rotatert:SWI48
11262           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11263           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11264   "TARGET_BMI2"
11265   "rorx\t{%2, %1, %0|%0, %1, %2}"
11266   [(set_attr "type" "rotatex")
11267    (set_attr "mode" "<MODE>")])
11269 (define_insn "*<rotate_insn><mode>3_1"
11270   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11271         (any_rotate:SWI48
11272           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11273           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11274    (clobber (reg:CC FLAGS_REG))]
11275   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11277   switch (get_attr_type (insn))
11278     {
11279     case TYPE_ROTATEX:
11280       return "#";
11282     default:
11283       if (operands[2] == const1_rtx
11284           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11285         return "<rotate>{<imodesuffix>}\t%0";
11286       else
11287         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11288     }
11290   [(set_attr "isa" "*,bmi2")
11291    (set_attr "type" "rotate,rotatex")
11292    (set (attr "length_immediate")
11293      (if_then_else
11294        (and (eq_attr "type" "rotate")
11295             (and (match_operand 2 "const1_operand")
11296                  (ior (match_test "TARGET_SHIFT1")
11297                       (match_test "optimize_function_for_size_p (cfun)"))))
11298        (const_string "0")
11299        (const_string "*")))
11300    (set_attr "mode" "<MODE>")])
11302 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11303 (define_split
11304   [(set (match_operand:SWI48 0 "register_operand")
11305         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11306                       (match_operand:QI 2 "const_int_operand")))
11307    (clobber (reg:CC FLAGS_REG))]
11308   "TARGET_BMI2 && reload_completed"
11309   [(set (match_dup 0)
11310         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11312   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11314   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11317 (define_split
11318   [(set (match_operand:SWI48 0 "register_operand")
11319         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11320                         (match_operand:QI 2 "const_int_operand")))
11321    (clobber (reg:CC FLAGS_REG))]
11322   "TARGET_BMI2 && reload_completed"
11323   [(set (match_dup 0)
11324         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11326 (define_insn "*bmi2_rorxsi3_1_zext"
11327   [(set (match_operand:DI 0 "register_operand" "=r")
11328         (zero_extend:DI
11329           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11330                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11331   "TARGET_64BIT && TARGET_BMI2"
11332   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11333   [(set_attr "type" "rotatex")
11334    (set_attr "mode" "SI")])
11336 (define_insn "*<rotate_insn>si3_1_zext"
11337   [(set (match_operand:DI 0 "register_operand" "=r,r")
11338         (zero_extend:DI
11339           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11340                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11344   switch (get_attr_type (insn))
11345     {
11346     case TYPE_ROTATEX:
11347       return "#";
11349     default:
11350       if (operands[2] == const1_rtx
11351           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11352         return "<rotate>{l}\t%k0";
11353       else
11354         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11355     }
11357   [(set_attr "isa" "*,bmi2")
11358    (set_attr "type" "rotate,rotatex")
11359    (set (attr "length_immediate")
11360      (if_then_else
11361        (and (eq_attr "type" "rotate")
11362             (and (match_operand 2 "const1_operand")
11363                  (ior (match_test "TARGET_SHIFT1")
11364                       (match_test "optimize_function_for_size_p (cfun)"))))
11365        (const_string "0")
11366        (const_string "*")))
11367    (set_attr "mode" "SI")])
11369 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11370 (define_split
11371   [(set (match_operand:DI 0 "register_operand")
11372         (zero_extend:DI
11373           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11374                      (match_operand:QI 2 "const_int_operand"))))
11375    (clobber (reg:CC FLAGS_REG))]
11376   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11377   [(set (match_dup 0)
11378         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11380   int bitsize = GET_MODE_BITSIZE (SImode);
11382   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11385 (define_split
11386   [(set (match_operand:DI 0 "register_operand")
11387         (zero_extend:DI
11388           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11389                        (match_operand:QI 2 "const_int_operand"))))
11390    (clobber (reg:CC FLAGS_REG))]
11391   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11392   [(set (match_dup 0)
11393         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11395 (define_insn "*<rotate_insn><mode>3_1"
11396   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11397         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11398                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11399    (clobber (reg:CC FLAGS_REG))]
11400   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11402   if (operands[2] == const1_rtx
11403       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11404     return "<rotate>{<imodesuffix>}\t%0";
11405   else
11406     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11408   [(set_attr "type" "rotate")
11409    (set (attr "length_immediate")
11410      (if_then_else
11411        (and (match_operand 2 "const1_operand")
11412             (ior (match_test "TARGET_SHIFT1")
11413                  (match_test "optimize_function_for_size_p (cfun)")))
11414        (const_string "0")
11415        (const_string "*")))
11416    (set_attr "mode" "<MODE>")])
11418 (define_insn "*<rotate_insn>qi3_1_slp"
11419   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11420         (any_rotate:QI (match_dup 0)
11421                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11422    (clobber (reg:CC FLAGS_REG))]
11423   "(optimize_function_for_size_p (cfun)
11424     || !TARGET_PARTIAL_REG_STALL
11425     || (operands[1] == const1_rtx
11426         && TARGET_SHIFT1))"
11428   if (operands[1] == const1_rtx
11429       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11430     return "<rotate>{b}\t%0";
11431   else
11432     return "<rotate>{b}\t{%1, %0|%0, %1}";
11434   [(set_attr "type" "rotate1")
11435    (set (attr "length_immediate")
11436      (if_then_else
11437        (and (match_operand 1 "const1_operand")
11438             (ior (match_test "TARGET_SHIFT1")
11439                  (match_test "optimize_function_for_size_p (cfun)")))
11440        (const_string "0")
11441        (const_string "*")))
11442    (set_attr "mode" "QI")])
11444 (define_split
11445  [(set (match_operand:HI 0 "QIreg_operand")
11446        (any_rotate:HI (match_dup 0) (const_int 8)))
11447   (clobber (reg:CC FLAGS_REG))]
11448  "reload_completed
11449   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11450  [(parallel [(set (strict_low_part (match_dup 0))
11451                   (bswap:HI (match_dup 0)))
11452              (clobber (reg:CC FLAGS_REG))])])
11454 ;; Bit set / bit test instructions
11456 ;; %%% bts, btr, btc
11458 ;; These instructions are *slow* when applied to memory.
11460 (define_code_attr btsc [(ior "bts") (xor "btc")])
11462 (define_insn "*<btsc><mode>"
11463   [(set (match_operand:SWI48 0 "register_operand" "=r")
11464         (any_or:SWI48
11465           (ashift:SWI48 (const_int 1)
11466                         (match_operand:QI 2 "register_operand" "r"))
11467           (match_operand:SWI48 1 "register_operand" "0")))
11468    (clobber (reg:CC FLAGS_REG))]
11469   "TARGET_USE_BT"
11470   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11471   [(set_attr "type" "alu1")
11472    (set_attr "prefix_0f" "1")
11473    (set_attr "znver1_decode" "double")
11474    (set_attr "mode" "<MODE>")])
11476 ;; Avoid useless masking of count operand.
11477 (define_insn_and_split "*<btsc><mode>_mask"
11478   [(set (match_operand:SWI48 0 "register_operand")
11479         (any_or:SWI48
11480           (ashift:SWI48
11481             (const_int 1)
11482             (subreg:QI
11483               (and:SI
11484                 (match_operand:SI 1 "register_operand")
11485                 (match_operand:SI 2 "const_int_operand")) 0))
11486           (match_operand:SWI48 3 "register_operand")))
11487    (clobber (reg:CC FLAGS_REG))]
11488   "TARGET_USE_BT
11489    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11490       == GET_MODE_BITSIZE (<MODE>mode)-1
11491    && can_create_pseudo_p ()"
11492   "#"
11493   "&& 1"
11494   [(parallel
11495      [(set (match_dup 0)
11496            (any_or:SWI48
11497              (ashift:SWI48 (const_int 1)
11498                            (match_dup 1))
11499              (match_dup 3)))
11500       (clobber (reg:CC FLAGS_REG))])]
11501   "operands[1] = gen_lowpart (QImode, operands[1]);")
11503 (define_insn_and_split "*<btsc><mode>_mask_1"
11504   [(set (match_operand:SWI48 0 "register_operand")
11505         (any_or:SWI48
11506           (ashift:SWI48
11507             (const_int 1)
11508             (and:QI
11509               (match_operand:QI 1 "register_operand")
11510               (match_operand:QI 2 "const_int_operand")))
11511           (match_operand:SWI48 3 "register_operand")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "TARGET_USE_BT
11514    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11515       == GET_MODE_BITSIZE (<MODE>mode)-1
11516    && can_create_pseudo_p ()"
11517   "#"
11518   "&& 1"
11519   [(parallel
11520      [(set (match_dup 0)
11521            (any_or:SWI48
11522              (ashift:SWI48 (const_int 1)
11523                            (match_dup 1))
11524              (match_dup 3)))
11525       (clobber (reg:CC FLAGS_REG))])])
11527 (define_insn "*btr<mode>"
11528   [(set (match_operand:SWI48 0 "register_operand" "=r")
11529         (and:SWI48
11530           (rotate:SWI48 (const_int -2)
11531                         (match_operand:QI 2 "register_operand" "r"))
11532         (match_operand:SWI48 1 "register_operand" "0")))
11533    (clobber (reg:CC FLAGS_REG))]
11534   "TARGET_USE_BT"
11535   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11536   [(set_attr "type" "alu1")
11537    (set_attr "prefix_0f" "1")
11538    (set_attr "znver1_decode" "double")
11539    (set_attr "mode" "<MODE>")])
11541 ;; Avoid useless masking of count operand.
11542 (define_insn_and_split "*btr<mode>_mask"
11543   [(set (match_operand:SWI48 0 "register_operand")
11544         (and:SWI48
11545           (rotate:SWI48
11546             (const_int -2)
11547             (subreg:QI
11548               (and:SI
11549                 (match_operand:SI 1 "register_operand")
11550                 (match_operand:SI 2 "const_int_operand")) 0))
11551           (match_operand:SWI48 3 "register_operand")))
11552    (clobber (reg:CC FLAGS_REG))]
11553   "TARGET_USE_BT
11554    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11555       == GET_MODE_BITSIZE (<MODE>mode)-1
11556    && can_create_pseudo_p ()"
11557   "#"
11558   "&& 1"
11559   [(parallel
11560      [(set (match_dup 0)
11561            (and:SWI48
11562              (rotate:SWI48 (const_int -2)
11563                            (match_dup 1))
11564              (match_dup 3)))
11565       (clobber (reg:CC FLAGS_REG))])]
11566   "operands[1] = gen_lowpart (QImode, operands[1]);")
11568 (define_insn_and_split "*btr<mode>_mask_1"
11569   [(set (match_operand:SWI48 0 "register_operand")
11570         (and:SWI48
11571           (rotate:SWI48
11572             (const_int -2)
11573             (and:QI
11574               (match_operand:QI 1 "register_operand")
11575               (match_operand:QI 2 "const_int_operand")))
11576           (match_operand:SWI48 3 "register_operand")))
11577    (clobber (reg:CC FLAGS_REG))]
11578   "TARGET_USE_BT
11579    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11580       == GET_MODE_BITSIZE (<MODE>mode)-1
11581    && can_create_pseudo_p ()"
11582   "#"
11583   "&& 1"
11584   [(parallel
11585      [(set (match_dup 0)
11586            (and:SWI48
11587              (rotate:SWI48 (const_int -2)
11588                            (match_dup 1))
11589              (match_dup 3)))
11590       (clobber (reg:CC FLAGS_REG))])])
11592 ;; These instructions are never faster than the corresponding
11593 ;; and/ior/xor operations when using immediate operand, so with
11594 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11595 ;; relevant immediates within the instruction itself, so operating
11596 ;; on bits in the high 32-bits of a register becomes easier.
11598 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11599 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11600 ;; negdf respectively, so they can never be disabled entirely.
11602 (define_insn "*btsq_imm"
11603   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11604                          (const_int 1)
11605                          (match_operand 1 "const_0_to_63_operand" "J"))
11606         (const_int 1))
11607    (clobber (reg:CC FLAGS_REG))]
11608   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11609   "bts{q}\t{%1, %0|%0, %1}"
11610   [(set_attr "type" "alu1")
11611    (set_attr "prefix_0f" "1")
11612    (set_attr "znver1_decode" "double")
11613    (set_attr "mode" "DI")])
11615 (define_insn "*btrq_imm"
11616   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11617                          (const_int 1)
11618                          (match_operand 1 "const_0_to_63_operand" "J"))
11619         (const_int 0))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11622   "btr{q}\t{%1, %0|%0, %1}"
11623   [(set_attr "type" "alu1")
11624    (set_attr "prefix_0f" "1")
11625    (set_attr "znver1_decode" "double")
11626    (set_attr "mode" "DI")])
11628 (define_insn "*btcq_imm"
11629   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11630                          (const_int 1)
11631                          (match_operand 1 "const_0_to_63_operand" "J"))
11632         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11633    (clobber (reg:CC FLAGS_REG))]
11634   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11635   "btc{q}\t{%1, %0|%0, %1}"
11636   [(set_attr "type" "alu1")
11637    (set_attr "prefix_0f" "1")
11638    (set_attr "znver1_decode" "double")
11639    (set_attr "mode" "DI")])
11641 ;; Allow Nocona to avoid these instructions if a register is available.
11643 (define_peephole2
11644   [(match_scratch:DI 2 "r")
11645    (parallel [(set (zero_extract:DI
11646                      (match_operand:DI 0 "nonimmediate_operand")
11647                      (const_int 1)
11648                      (match_operand 1 "const_0_to_63_operand"))
11649                    (const_int 1))
11650               (clobber (reg:CC FLAGS_REG))])]
11651   "TARGET_64BIT && !TARGET_USE_BT"
11652   [(parallel [(set (match_dup 0)
11653                    (ior:DI (match_dup 0) (match_dup 3)))
11654               (clobber (reg:CC FLAGS_REG))])]
11656   int i = INTVAL (operands[1]);
11658   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11660   if (!x86_64_immediate_operand (operands[3], DImode))
11661     {
11662       emit_move_insn (operands[2], operands[3]);
11663       operands[3] = operands[2];
11664     }
11667 (define_peephole2
11668   [(match_scratch:DI 2 "r")
11669    (parallel [(set (zero_extract:DI
11670                      (match_operand:DI 0 "nonimmediate_operand")
11671                      (const_int 1)
11672                      (match_operand 1 "const_0_to_63_operand"))
11673                    (const_int 0))
11674               (clobber (reg:CC FLAGS_REG))])]
11675   "TARGET_64BIT && !TARGET_USE_BT"
11676   [(parallel [(set (match_dup 0)
11677                    (and:DI (match_dup 0) (match_dup 3)))
11678               (clobber (reg:CC FLAGS_REG))])]
11680   int i = INTVAL (operands[1]);
11682   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11684   if (!x86_64_immediate_operand (operands[3], DImode))
11685     {
11686       emit_move_insn (operands[2], operands[3]);
11687       operands[3] = operands[2];
11688     }
11691 (define_peephole2
11692   [(match_scratch:DI 2 "r")
11693    (parallel [(set (zero_extract:DI
11694                      (match_operand:DI 0 "nonimmediate_operand")
11695                      (const_int 1)
11696                      (match_operand 1 "const_0_to_63_operand"))
11697               (not:DI (zero_extract:DI
11698                         (match_dup 0) (const_int 1) (match_dup 1))))
11699               (clobber (reg:CC FLAGS_REG))])]
11700   "TARGET_64BIT && !TARGET_USE_BT"
11701   [(parallel [(set (match_dup 0)
11702                    (xor:DI (match_dup 0) (match_dup 3)))
11703               (clobber (reg:CC FLAGS_REG))])]
11705   int i = INTVAL (operands[1]);
11707   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11709   if (!x86_64_immediate_operand (operands[3], DImode))
11710     {
11711       emit_move_insn (operands[2], operands[3]);
11712       operands[3] = operands[2];
11713     }
11716 ;; %%% bt
11718 (define_insn "*bt<mode>"
11719   [(set (reg:CCC FLAGS_REG)
11720         (compare:CCC
11721           (zero_extract:SWI48
11722             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11723             (const_int 1)
11724             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11725           (const_int 0)))]
11726   ""
11728   switch (get_attr_mode (insn))
11729     {
11730     case MODE_SI:
11731       return "bt{l}\t{%1, %k0|%k0, %1}";
11733     case MODE_DI:
11734       return "bt{q}\t{%q1, %0|%0, %q1}";
11736     default:
11737       gcc_unreachable ();
11738     }
11740   [(set_attr "type" "alu1")
11741    (set_attr "prefix_0f" "1")
11742    (set (attr "mode")
11743         (if_then_else
11744           (and (match_test "CONST_INT_P (operands[1])")
11745                (match_test "INTVAL (operands[1]) < 32"))
11746           (const_string "SI")
11747           (const_string "<MODE>")))])
11749 (define_insn_and_split "*jcc_bt<mode>"
11750   [(set (pc)
11751         (if_then_else (match_operator 0 "bt_comparison_operator"
11752                         [(zero_extract:SWI48
11753                            (match_operand:SWI48 1 "nonimmediate_operand")
11754                            (const_int 1)
11755                            (match_operand:SI 2 "nonmemory_operand"))
11756                          (const_int 0)])
11757                       (label_ref (match_operand 3))
11758                       (pc)))
11759    (clobber (reg:CC FLAGS_REG))]
11760   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11761    && (CONST_INT_P (operands[2])
11762        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11763           && INTVAL (operands[2])
11764                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11765        : !memory_operand (operands[1], <MODE>mode))
11766    && can_create_pseudo_p ()"
11767   "#"
11768   "&& 1"
11769   [(set (reg:CCC FLAGS_REG)
11770         (compare:CCC
11771           (zero_extract:SWI48
11772             (match_dup 1)
11773             (const_int 1)
11774             (match_dup 2))
11775           (const_int 0)))
11776    (set (pc)
11777         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11778                       (label_ref (match_dup 3))
11779                       (pc)))]
11781   operands[0] = shallow_copy_rtx (operands[0]);
11782   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11785 (define_insn_and_split "*jcc_bt<mode>_1"
11786   [(set (pc)
11787         (if_then_else (match_operator 0 "bt_comparison_operator"
11788                         [(zero_extract:SWI48
11789                            (match_operand:SWI48 1 "register_operand")
11790                            (const_int 1)
11791                            (zero_extend:SI
11792                              (match_operand:QI 2 "register_operand")))
11793                          (const_int 0)])
11794                       (label_ref (match_operand 3))
11795                       (pc)))
11796    (clobber (reg:CC FLAGS_REG))]
11797   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11798    && can_create_pseudo_p ()"
11799   "#"
11800   "&& 1"
11801   [(set (reg:CCC FLAGS_REG)
11802         (compare:CCC
11803           (zero_extract:SWI48
11804             (match_dup 1)
11805             (const_int 1)
11806             (match_dup 2))
11807           (const_int 0)))
11808    (set (pc)
11809         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11810                       (label_ref (match_dup 3))
11811                       (pc)))]
11813   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11814   operands[0] = shallow_copy_rtx (operands[0]);
11815   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11818 ;; Avoid useless masking of bit offset operand.
11819 (define_insn_and_split "*jcc_bt<mode>_mask"
11820   [(set (pc)
11821         (if_then_else (match_operator 0 "bt_comparison_operator"
11822                         [(zero_extract:SWI48
11823                            (match_operand:SWI48 1 "register_operand")
11824                            (const_int 1)
11825                            (and:SI
11826                              (match_operand:SI 2 "register_operand")
11827                              (match_operand 3 "const_int_operand")))])
11828                       (label_ref (match_operand 4))
11829                       (pc)))
11830    (clobber (reg:CC FLAGS_REG))]
11831   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11832    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11833       == GET_MODE_BITSIZE (<MODE>mode)-1
11834    && can_create_pseudo_p ()"
11835   "#"
11836   "&& 1"
11837   [(set (reg:CCC FLAGS_REG)
11838         (compare:CCC
11839           (zero_extract:SWI48
11840             (match_dup 1)
11841             (const_int 1)
11842             (match_dup 2))
11843           (const_int 0)))
11844    (set (pc)
11845         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11846                       (label_ref (match_dup 4))
11847                       (pc)))]
11849   operands[0] = shallow_copy_rtx (operands[0]);
11850   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11853 ;; Store-flag instructions.
11855 ;; For all sCOND expanders, also expand the compare or test insn that
11856 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11858 (define_insn_and_split "*setcc_di_1"
11859   [(set (match_operand:DI 0 "register_operand" "=q")
11860         (match_operator:DI 1 "ix86_comparison_operator"
11861           [(reg FLAGS_REG) (const_int 0)]))]
11862   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11863   "#"
11864   "&& reload_completed"
11865   [(set (match_dup 2) (match_dup 1))
11866    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11868   operands[1] = shallow_copy_rtx (operands[1]);
11869   PUT_MODE (operands[1], QImode);
11870   operands[2] = gen_lowpart (QImode, operands[0]);
11873 (define_insn_and_split "*setcc_si_1_and"
11874   [(set (match_operand:SI 0 "register_operand" "=q")
11875         (match_operator:SI 1 "ix86_comparison_operator"
11876           [(reg FLAGS_REG) (const_int 0)]))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "!TARGET_PARTIAL_REG_STALL
11879    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11880   "#"
11881   "&& reload_completed"
11882   [(set (match_dup 2) (match_dup 1))
11883    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11884               (clobber (reg:CC FLAGS_REG))])]
11886   operands[1] = shallow_copy_rtx (operands[1]);
11887   PUT_MODE (operands[1], QImode);
11888   operands[2] = gen_lowpart (QImode, operands[0]);
11891 (define_insn_and_split "*setcc_si_1_movzbl"
11892   [(set (match_operand:SI 0 "register_operand" "=q")
11893         (match_operator:SI 1 "ix86_comparison_operator"
11894           [(reg FLAGS_REG) (const_int 0)]))]
11895   "!TARGET_PARTIAL_REG_STALL
11896    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11897   "#"
11898   "&& reload_completed"
11899   [(set (match_dup 2) (match_dup 1))
11900    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11902   operands[1] = shallow_copy_rtx (operands[1]);
11903   PUT_MODE (operands[1], QImode);
11904   operands[2] = gen_lowpart (QImode, operands[0]);
11907 (define_insn "*setcc_qi"
11908   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11909         (match_operator:QI 1 "ix86_comparison_operator"
11910           [(reg FLAGS_REG) (const_int 0)]))]
11911   ""
11912   "set%C1\t%0"
11913   [(set_attr "type" "setcc")
11914    (set_attr "mode" "QI")])
11916 (define_insn "*setcc_qi_slp"
11917   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11918         (match_operator:QI 1 "ix86_comparison_operator"
11919           [(reg FLAGS_REG) (const_int 0)]))]
11920   ""
11921   "set%C1\t%0"
11922   [(set_attr "type" "setcc")
11923    (set_attr "mode" "QI")])
11925 ;; In general it is not safe to assume too much about CCmode registers,
11926 ;; so simplify-rtx stops when it sees a second one.  Under certain
11927 ;; conditions this is safe on x86, so help combine not create
11929 ;;      seta    %al
11930 ;;      testb   %al, %al
11931 ;;      sete    %al
11933 (define_split
11934   [(set (match_operand:QI 0 "nonimmediate_operand")
11935         (ne:QI (match_operator 1 "ix86_comparison_operator"
11936                  [(reg FLAGS_REG) (const_int 0)])
11937             (const_int 0)))]
11938   ""
11939   [(set (match_dup 0) (match_dup 1))]
11941   operands[1] = shallow_copy_rtx (operands[1]);
11942   PUT_MODE (operands[1], QImode);
11945 (define_split
11946   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11947         (ne:QI (match_operator 1 "ix86_comparison_operator"
11948                  [(reg FLAGS_REG) (const_int 0)])
11949             (const_int 0)))]
11950   ""
11951   [(set (match_dup 0) (match_dup 1))]
11953   operands[1] = shallow_copy_rtx (operands[1]);
11954   PUT_MODE (operands[1], QImode);
11957 (define_split
11958   [(set (match_operand:QI 0 "nonimmediate_operand")
11959         (eq:QI (match_operator 1 "ix86_comparison_operator"
11960                  [(reg FLAGS_REG) (const_int 0)])
11961             (const_int 0)))]
11962   ""
11963   [(set (match_dup 0) (match_dup 1))]
11965   operands[1] = shallow_copy_rtx (operands[1]);
11966   PUT_MODE (operands[1], QImode);
11967   PUT_CODE (operands[1],
11968             ix86_reverse_condition (GET_CODE (operands[1]),
11969                                     GET_MODE (XEXP (operands[1], 0))));
11971   /* Make sure that (a) the CCmode we have for the flags is strong
11972      enough for the reversed compare or (b) we have a valid FP compare.  */
11973   if (! ix86_comparison_operator (operands[1], VOIDmode))
11974     FAIL;
11977 (define_split
11978   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11979         (eq:QI (match_operator 1 "ix86_comparison_operator"
11980                  [(reg FLAGS_REG) (const_int 0)])
11981             (const_int 0)))]
11982   ""
11983   [(set (match_dup 0) (match_dup 1))]
11985   operands[1] = shallow_copy_rtx (operands[1]);
11986   PUT_MODE (operands[1], QImode);
11987   PUT_CODE (operands[1],
11988             ix86_reverse_condition (GET_CODE (operands[1]),
11989                                     GET_MODE (XEXP (operands[1], 0))));
11991   /* Make sure that (a) the CCmode we have for the flags is strong
11992      enough for the reversed compare or (b) we have a valid FP compare.  */
11993   if (! ix86_comparison_operator (operands[1], VOIDmode))
11994     FAIL;
11997 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11998 ;; subsequent logical operations are used to imitate conditional moves.
11999 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12000 ;; it directly.
12002 (define_insn "setcc_<mode>_sse"
12003   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12004         (match_operator:MODEF 3 "sse_comparison_operator"
12005           [(match_operand:MODEF 1 "register_operand" "0,x")
12006            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12007   "SSE_FLOAT_MODE_P (<MODE>mode)"
12008   "@
12009    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12010    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12011   [(set_attr "isa" "noavx,avx")
12012    (set_attr "type" "ssecmp")
12013    (set_attr "length_immediate" "1")
12014    (set_attr "prefix" "orig,vex")
12015    (set_attr "mode" "<MODE>")])
12017 ;; Basic conditional jump instructions.
12018 ;; We ignore the overflow flag for signed branch instructions.
12020 (define_insn "*jcc"
12021   [(set (pc)
12022         (if_then_else (match_operator 1 "ix86_comparison_operator"
12023                                       [(reg FLAGS_REG) (const_int 0)])
12024                       (label_ref (match_operand 0))
12025                       (pc)))]
12026   ""
12027   "%!%+j%C1\t%l0"
12028   [(set_attr "type" "ibr")
12029    (set_attr "modrm" "0")
12030    (set (attr "length")
12031         (if_then_else
12032           (and (ge (minus (match_dup 0) (pc))
12033                    (const_int -126))
12034                (lt (minus (match_dup 0) (pc))
12035                    (const_int 128)))
12036           (const_int 2)
12037           (const_int 6)))])
12039 ;; In general it is not safe to assume too much about CCmode registers,
12040 ;; so simplify-rtx stops when it sees a second one.  Under certain
12041 ;; conditions this is safe on x86, so help combine not create
12043 ;;      seta    %al
12044 ;;      testb   %al, %al
12045 ;;      je      Lfoo
12047 (define_split
12048   [(set (pc)
12049         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12050                                       [(reg FLAGS_REG) (const_int 0)])
12051                           (const_int 0))
12052                       (label_ref (match_operand 1))
12053                       (pc)))]
12054   ""
12055   [(set (pc)
12056         (if_then_else (match_dup 0)
12057                       (label_ref (match_dup 1))
12058                       (pc)))]
12060   operands[0] = shallow_copy_rtx (operands[0]);
12061   PUT_MODE (operands[0], VOIDmode);
12064 (define_split
12065   [(set (pc)
12066         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12067                                       [(reg FLAGS_REG) (const_int 0)])
12068                           (const_int 0))
12069                       (label_ref (match_operand 1))
12070                       (pc)))]
12071   ""
12072   [(set (pc)
12073         (if_then_else (match_dup 0)
12074                       (label_ref (match_dup 1))
12075                       (pc)))]
12077   operands[0] = shallow_copy_rtx (operands[0]);
12078   PUT_MODE (operands[0], VOIDmode);
12079   PUT_CODE (operands[0],
12080             ix86_reverse_condition (GET_CODE (operands[0]),
12081                                     GET_MODE (XEXP (operands[0], 0))));
12083   /* Make sure that (a) the CCmode we have for the flags is strong
12084      enough for the reversed compare or (b) we have a valid FP compare.  */
12085   if (! ix86_comparison_operator (operands[0], VOIDmode))
12086     FAIL;
12089 ;; Unconditional and other jump instructions
12091 (define_insn "jump"
12092   [(set (pc)
12093         (label_ref (match_operand 0)))]
12094   ""
12095   "%!jmp\t%l0"
12096   [(set_attr "type" "ibr")
12097    (set_attr "modrm" "0")
12098    (set (attr "length")
12099         (if_then_else
12100           (and (ge (minus (match_dup 0) (pc))
12101                    (const_int -126))
12102                (lt (minus (match_dup 0) (pc))
12103                    (const_int 128)))
12104           (const_int 2)
12105           (const_int 5)))])
12107 (define_expand "indirect_jump"
12108   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12109   ""
12111   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12112     operands[0] = convert_memory_address (word_mode, operands[0]);
12113   cfun->machine->has_local_indirect_jump = true;
12116 (define_insn "*indirect_jump"
12117   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12118   ""
12119   "* return ix86_output_indirect_jmp (operands[0]);"
12120   [(set (attr "type")
12121      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12122                                  != indirect_branch_keep)")
12123         (const_string "multi")
12124         (const_string "ibr")))
12125    (set_attr "length_immediate" "0")])
12127 (define_expand "tablejump"
12128   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12129               (use (label_ref (match_operand 1)))])]
12130   ""
12132   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12133      relative.  Convert the relative address to an absolute address.  */
12134   if (flag_pic)
12135     {
12136       rtx op0, op1;
12137       enum rtx_code code;
12139       /* We can't use @GOTOFF for text labels on VxWorks;
12140          see gotoff_operand.  */
12141       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12142         {
12143           code = PLUS;
12144           op0 = operands[0];
12145           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12146         }
12147       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12148         {
12149           code = PLUS;
12150           op0 = operands[0];
12151           op1 = pic_offset_table_rtx;
12152         }
12153       else
12154         {
12155           code = MINUS;
12156           op0 = pic_offset_table_rtx;
12157           op1 = operands[0];
12158         }
12160       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12161                                          OPTAB_DIRECT);
12162     }
12164   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12165     operands[0] = convert_memory_address (word_mode, operands[0]);
12166   cfun->machine->has_local_indirect_jump = true;
12169 (define_insn "*tablejump_1"
12170   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12171    (use (label_ref (match_operand 1)))]
12172   ""
12173   "* return ix86_output_indirect_jmp (operands[0]);"
12174   [(set (attr "type")
12175      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12176                                  != indirect_branch_keep)")
12177         (const_string "multi")
12178         (const_string "ibr")))
12179    (set_attr "length_immediate" "0")])
12181 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12183 (define_peephole2
12184   [(set (reg FLAGS_REG) (match_operand 0))
12185    (set (match_operand:QI 1 "register_operand")
12186         (match_operator:QI 2 "ix86_comparison_operator"
12187           [(reg FLAGS_REG) (const_int 0)]))
12188    (set (match_operand 3 "any_QIreg_operand")
12189         (zero_extend (match_dup 1)))]
12190   "(peep2_reg_dead_p (3, operands[1])
12191     || operands_match_p (operands[1], operands[3]))
12192    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12193    && peep2_regno_dead_p (0, FLAGS_REG)"
12194   [(set (match_dup 4) (match_dup 0))
12195    (set (strict_low_part (match_dup 5))
12196         (match_dup 2))]
12198   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12199   operands[5] = gen_lowpart (QImode, operands[3]);
12200   ix86_expand_clear (operands[3]);
12203 (define_peephole2
12204   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12205               (match_operand 4)])
12206    (set (match_operand:QI 1 "register_operand")
12207         (match_operator:QI 2 "ix86_comparison_operator"
12208           [(reg FLAGS_REG) (const_int 0)]))
12209    (set (match_operand 3 "any_QIreg_operand")
12210         (zero_extend (match_dup 1)))]
12211   "(peep2_reg_dead_p (3, operands[1])
12212     || operands_match_p (operands[1], operands[3]))
12213    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12214    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12215    && ! reg_set_p (operands[3], operands[4])
12216    && peep2_regno_dead_p (0, FLAGS_REG)"
12217   [(parallel [(set (match_dup 5) (match_dup 0))
12218               (match_dup 4)])
12219    (set (strict_low_part (match_dup 6))
12220         (match_dup 2))]
12222   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12223   operands[6] = gen_lowpart (QImode, operands[3]);
12224   ix86_expand_clear (operands[3]);
12227 (define_peephole2
12228   [(set (reg FLAGS_REG) (match_operand 0))
12229    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12230               (match_operand 5)])
12231    (set (match_operand:QI 2 "register_operand")
12232         (match_operator:QI 3 "ix86_comparison_operator"
12233           [(reg FLAGS_REG) (const_int 0)]))
12234    (set (match_operand 4 "any_QIreg_operand")
12235         (zero_extend (match_dup 2)))]
12236   "(peep2_reg_dead_p (4, operands[2])
12237     || operands_match_p (operands[2], operands[4]))
12238    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12239    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12240    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12241    && ! reg_set_p (operands[4], operands[5])
12242    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12243    && peep2_regno_dead_p (0, FLAGS_REG)"
12244   [(set (match_dup 6) (match_dup 0))
12245    (parallel [(set (match_dup 7) (match_dup 1))
12246               (match_dup 5)])
12247    (set (strict_low_part (match_dup 8))
12248         (match_dup 3))]
12250   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12251   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12252   operands[8] = gen_lowpart (QImode, operands[4]);
12253   ix86_expand_clear (operands[4]);
12256 ;; Similar, but match zero extend with andsi3.
12258 (define_peephole2
12259   [(set (reg FLAGS_REG) (match_operand 0))
12260    (set (match_operand:QI 1 "register_operand")
12261         (match_operator:QI 2 "ix86_comparison_operator"
12262           [(reg FLAGS_REG) (const_int 0)]))
12263    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12264                    (and:SI (match_dup 3) (const_int 255)))
12265               (clobber (reg:CC FLAGS_REG))])]
12266   "REGNO (operands[1]) == REGNO (operands[3])
12267    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12268    && peep2_regno_dead_p (0, FLAGS_REG)"
12269   [(set (match_dup 4) (match_dup 0))
12270    (set (strict_low_part (match_dup 5))
12271         (match_dup 2))]
12273   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12274   operands[5] = gen_lowpart (QImode, operands[3]);
12275   ix86_expand_clear (operands[3]);
12278 (define_peephole2
12279   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12280               (match_operand 4)])
12281    (set (match_operand:QI 1 "register_operand")
12282         (match_operator:QI 2 "ix86_comparison_operator"
12283           [(reg FLAGS_REG) (const_int 0)]))
12284    (parallel [(set (match_operand 3 "any_QIreg_operand")
12285                    (zero_extend (match_dup 1)))
12286               (clobber (reg:CC FLAGS_REG))])]
12287   "(peep2_reg_dead_p (3, operands[1])
12288     || operands_match_p (operands[1], operands[3]))
12289    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12290    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12291    && ! reg_set_p (operands[3], operands[4])
12292    && peep2_regno_dead_p (0, FLAGS_REG)"
12293   [(parallel [(set (match_dup 5) (match_dup 0))
12294               (match_dup 4)])
12295    (set (strict_low_part (match_dup 6))
12296         (match_dup 2))]
12298   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12299   operands[6] = gen_lowpart (QImode, operands[3]);
12300   ix86_expand_clear (operands[3]);
12303 (define_peephole2
12304   [(set (reg FLAGS_REG) (match_operand 0))
12305    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12306               (match_operand 5)])
12307    (set (match_operand:QI 2 "register_operand")
12308         (match_operator:QI 3 "ix86_comparison_operator"
12309           [(reg FLAGS_REG) (const_int 0)]))
12310    (parallel [(set (match_operand 4 "any_QIreg_operand")
12311                    (zero_extend (match_dup 2)))
12312               (clobber (reg:CC FLAGS_REG))])]
12313   "(peep2_reg_dead_p (4, operands[2])
12314     || operands_match_p (operands[2], operands[4]))
12315    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12316    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12317    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12318    && ! reg_set_p (operands[4], operands[5])
12319    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12320    && peep2_regno_dead_p (0, FLAGS_REG)"
12321   [(set (match_dup 6) (match_dup 0))
12322    (parallel [(set (match_dup 7) (match_dup 1))
12323               (match_dup 5)])
12324    (set (strict_low_part (match_dup 8))
12325         (match_dup 3))]
12327   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12328   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12329   operands[8] = gen_lowpart (QImode, operands[4]);
12330   ix86_expand_clear (operands[4]);
12333 ;; Call instructions.
12335 ;; The predicates normally associated with named expanders are not properly
12336 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12337 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12339 ;; P6 processors will jump to the address after the decrement when %esp
12340 ;; is used as a call operand, so they will execute return address as a code.
12341 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12343 ;; Register constraint for call instruction.
12344 (define_mode_attr c [(SI "l") (DI "r")])
12346 ;; Call subroutine returning no value.
12348 (define_expand "call"
12349   [(call (match_operand:QI 0)
12350          (match_operand 1))
12351    (use (match_operand 2))]
12352   ""
12354   ix86_expand_call (NULL, operands[0], operands[1],
12355                     operands[2], NULL, false);
12356   DONE;
12359 (define_expand "sibcall"
12360   [(call (match_operand:QI 0)
12361          (match_operand 1))
12362    (use (match_operand 2))]
12363   ""
12365   ix86_expand_call (NULL, operands[0], operands[1],
12366                     operands[2], NULL, true);
12367   DONE;
12370 (define_insn "*call"
12371   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12372          (match_operand 1))]
12373   "!SIBLING_CALL_P (insn)"
12374   "* return ix86_output_call_insn (insn, operands[0]);"
12375   [(set_attr "type" "call")])
12377 ;; This covers both call and sibcall since only GOT slot is allowed.
12378 (define_insn "*call_got_x32"
12379   [(call (mem:QI (zero_extend:DI
12380                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12381          (match_operand 1))]
12382   "TARGET_X32"
12384   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12385   return ix86_output_call_insn (insn, fnaddr);
12387   [(set_attr "type" "call")])
12389 ;; Since sibcall never returns, we can only use call-clobbered register
12390 ;; as GOT base.
12391 (define_insn "*sibcall_GOT_32"
12392   [(call (mem:QI
12393            (mem:SI (plus:SI
12394                      (match_operand:SI 0 "register_no_elim_operand" "U")
12395                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12396          (match_operand 2))]
12397   "!TARGET_MACHO
12398   && !TARGET_64BIT
12399   && !TARGET_INDIRECT_BRANCH_REGISTER
12400   && SIBLING_CALL_P (insn)"
12402   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12403   fnaddr = gen_const_mem (SImode, fnaddr);
12404   return ix86_output_call_insn (insn, fnaddr);
12406   [(set_attr "type" "call")])
12408 (define_insn "*sibcall"
12409   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12410          (match_operand 1))]
12411   "SIBLING_CALL_P (insn)"
12412   "* return ix86_output_call_insn (insn, operands[0]);"
12413   [(set_attr "type" "call")])
12415 (define_insn "*sibcall_memory"
12416   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12417          (match_operand 1))
12418    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12419   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12420   "* return ix86_output_call_insn (insn, operands[0]);"
12421   [(set_attr "type" "call")])
12423 (define_peephole2
12424   [(set (match_operand:W 0 "register_operand")
12425         (match_operand:W 1 "memory_operand"))
12426    (call (mem:QI (match_dup 0))
12427          (match_operand 3))]
12428   "!TARGET_X32
12429    && !TARGET_INDIRECT_BRANCH_REGISTER
12430    && SIBLING_CALL_P (peep2_next_insn (1))
12431    && !reg_mentioned_p (operands[0],
12432                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12433   [(parallel [(call (mem:QI (match_dup 1))
12434                     (match_dup 3))
12435               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12437 (define_peephole2
12438   [(set (match_operand:W 0 "register_operand")
12439         (match_operand:W 1 "memory_operand"))
12440    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12441    (call (mem:QI (match_dup 0))
12442          (match_operand 3))]
12443   "!TARGET_X32
12444    && !TARGET_INDIRECT_BRANCH_REGISTER
12445    && SIBLING_CALL_P (peep2_next_insn (2))
12446    && !reg_mentioned_p (operands[0],
12447                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12448   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12449    (parallel [(call (mem:QI (match_dup 1))
12450                     (match_dup 3))
12451               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12453 (define_expand "call_pop"
12454   [(parallel [(call (match_operand:QI 0)
12455                     (match_operand:SI 1))
12456               (set (reg:SI SP_REG)
12457                    (plus:SI (reg:SI SP_REG)
12458                             (match_operand:SI 3)))])]
12459   "!TARGET_64BIT"
12461   ix86_expand_call (NULL, operands[0], operands[1],
12462                     operands[2], operands[3], false);
12463   DONE;
12466 (define_insn "*call_pop"
12467   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12468          (match_operand 1))
12469    (set (reg:SI SP_REG)
12470         (plus:SI (reg:SI SP_REG)
12471                  (match_operand:SI 2 "immediate_operand" "i")))]
12472   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12473   "* return ix86_output_call_insn (insn, operands[0]);"
12474   [(set_attr "type" "call")])
12476 (define_insn "*sibcall_pop"
12477   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12478          (match_operand 1))
12479    (set (reg:SI SP_REG)
12480         (plus:SI (reg:SI SP_REG)
12481                  (match_operand:SI 2 "immediate_operand" "i")))]
12482   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12483   "* return ix86_output_call_insn (insn, operands[0]);"
12484   [(set_attr "type" "call")])
12486 (define_insn "*sibcall_pop_memory"
12487   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12488          (match_operand 1))
12489    (set (reg:SI SP_REG)
12490         (plus:SI (reg:SI SP_REG)
12491                  (match_operand:SI 2 "immediate_operand" "i")))
12492    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12493   "!TARGET_64BIT"
12494   "* return ix86_output_call_insn (insn, operands[0]);"
12495   [(set_attr "type" "call")])
12497 (define_peephole2
12498   [(set (match_operand:SI 0 "register_operand")
12499         (match_operand:SI 1 "memory_operand"))
12500    (parallel [(call (mem:QI (match_dup 0))
12501                     (match_operand 3))
12502               (set (reg:SI SP_REG)
12503                    (plus:SI (reg:SI SP_REG)
12504                             (match_operand:SI 4 "immediate_operand")))])]
12505   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12506    && !reg_mentioned_p (operands[0],
12507                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12508   [(parallel [(call (mem:QI (match_dup 1))
12509                     (match_dup 3))
12510               (set (reg:SI SP_REG)
12511                    (plus:SI (reg:SI SP_REG)
12512                             (match_dup 4)))
12513               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12515 (define_peephole2
12516   [(set (match_operand:SI 0 "register_operand")
12517         (match_operand:SI 1 "memory_operand"))
12518    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12519    (parallel [(call (mem:QI (match_dup 0))
12520                     (match_operand 3))
12521               (set (reg:SI SP_REG)
12522                    (plus:SI (reg:SI SP_REG)
12523                             (match_operand:SI 4 "immediate_operand")))])]
12524   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12525    && !reg_mentioned_p (operands[0],
12526                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12527   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12528    (parallel [(call (mem:QI (match_dup 1))
12529                     (match_dup 3))
12530               (set (reg:SI SP_REG)
12531                    (plus:SI (reg:SI SP_REG)
12532                             (match_dup 4)))
12533               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12535 ;; Combining simple memory jump instruction
12537 (define_peephole2
12538   [(set (match_operand:W 0 "register_operand")
12539         (match_operand:W 1 "memory_operand"))
12540    (set (pc) (match_dup 0))]
12541   "!TARGET_X32
12542    && !TARGET_INDIRECT_BRANCH_REGISTER
12543    && peep2_reg_dead_p (2, operands[0])"
12544   [(set (pc) (match_dup 1))])
12546 ;; Call subroutine, returning value in operand 0
12548 (define_expand "call_value"
12549   [(set (match_operand 0)
12550         (call (match_operand:QI 1)
12551               (match_operand 2)))
12552    (use (match_operand 3))]
12553   ""
12555   ix86_expand_call (operands[0], operands[1], operands[2],
12556                     operands[3], NULL, false);
12557   DONE;
12560 (define_expand "sibcall_value"
12561   [(set (match_operand 0)
12562         (call (match_operand:QI 1)
12563               (match_operand 2)))
12564    (use (match_operand 3))]
12565   ""
12567   ix86_expand_call (operands[0], operands[1], operands[2],
12568                     operands[3], NULL, true);
12569   DONE;
12572 (define_insn "*call_value"
12573   [(set (match_operand 0)
12574         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12575               (match_operand 2)))]
12576   "!SIBLING_CALL_P (insn)"
12577   "* return ix86_output_call_insn (insn, operands[1]);"
12578   [(set_attr "type" "callv")])
12580 ;; This covers both call and sibcall since only GOT slot is allowed.
12581 (define_insn "*call_value_got_x32"
12582   [(set (match_operand 0)
12583         (call (mem:QI
12584                 (zero_extend:DI
12585                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12586               (match_operand 2)))]
12587   "TARGET_X32"
12589   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12590   return ix86_output_call_insn (insn, fnaddr);
12592   [(set_attr "type" "callv")])
12594 ;; Since sibcall never returns, we can only use call-clobbered register
12595 ;; as GOT base.
12596 (define_insn "*sibcall_value_GOT_32"
12597   [(set (match_operand 0)
12598         (call (mem:QI
12599                 (mem:SI (plus:SI
12600                           (match_operand:SI 1 "register_no_elim_operand" "U")
12601                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12602          (match_operand 3)))]
12603   "!TARGET_MACHO
12604    && !TARGET_64BIT
12605    && !TARGET_INDIRECT_BRANCH_REGISTER
12606    && SIBLING_CALL_P (insn)"
12608   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12609   fnaddr = gen_const_mem (SImode, fnaddr);
12610   return ix86_output_call_insn (insn, fnaddr);
12612   [(set_attr "type" "callv")])
12614 (define_insn "*sibcall_value"
12615   [(set (match_operand 0)
12616         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12617               (match_operand 2)))]
12618   "SIBLING_CALL_P (insn)"
12619   "* return ix86_output_call_insn (insn, operands[1]);"
12620   [(set_attr "type" "callv")])
12622 (define_insn "*sibcall_value_memory"
12623   [(set (match_operand 0)
12624         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12625               (match_operand 2)))
12626    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12627   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12628   "* return ix86_output_call_insn (insn, operands[1]);"
12629   [(set_attr "type" "callv")])
12631 (define_peephole2
12632   [(set (match_operand:W 0 "register_operand")
12633         (match_operand:W 1 "memory_operand"))
12634    (set (match_operand 2)
12635    (call (mem:QI (match_dup 0))
12636                  (match_operand 3)))]
12637   "!TARGET_X32
12638    && !TARGET_INDIRECT_BRANCH_REGISTER
12639    && SIBLING_CALL_P (peep2_next_insn (1))
12640    && !reg_mentioned_p (operands[0],
12641                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12642   [(parallel [(set (match_dup 2)
12643                    (call (mem:QI (match_dup 1))
12644                          (match_dup 3)))
12645               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12647 (define_peephole2
12648   [(set (match_operand:W 0 "register_operand")
12649         (match_operand:W 1 "memory_operand"))
12650    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12651    (set (match_operand 2)
12652         (call (mem:QI (match_dup 0))
12653               (match_operand 3)))]
12654   "!TARGET_X32
12655    && !TARGET_INDIRECT_BRANCH_REGISTER
12656    && SIBLING_CALL_P (peep2_next_insn (2))
12657    && !reg_mentioned_p (operands[0],
12658                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12659   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12660    (parallel [(set (match_dup 2)
12661                    (call (mem:QI (match_dup 1))
12662                          (match_dup 3)))
12663               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12665 (define_expand "call_value_pop"
12666   [(parallel [(set (match_operand 0)
12667                    (call (match_operand:QI 1)
12668                          (match_operand:SI 2)))
12669               (set (reg:SI SP_REG)
12670                    (plus:SI (reg:SI SP_REG)
12671                             (match_operand:SI 4)))])]
12672   "!TARGET_64BIT"
12674   ix86_expand_call (operands[0], operands[1], operands[2],
12675                     operands[3], operands[4], false);
12676   DONE;
12679 (define_insn "*call_value_pop"
12680   [(set (match_operand 0)
12681         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12682               (match_operand 2)))
12683    (set (reg:SI SP_REG)
12684         (plus:SI (reg:SI SP_REG)
12685                  (match_operand:SI 3 "immediate_operand" "i")))]
12686   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12687   "* return ix86_output_call_insn (insn, operands[1]);"
12688   [(set_attr "type" "callv")])
12690 (define_insn "*sibcall_value_pop"
12691   [(set (match_operand 0)
12692         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12693               (match_operand 2)))
12694    (set (reg:SI SP_REG)
12695         (plus:SI (reg:SI SP_REG)
12696                  (match_operand:SI 3 "immediate_operand" "i")))]
12697   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12698   "* return ix86_output_call_insn (insn, operands[1]);"
12699   [(set_attr "type" "callv")])
12701 (define_insn "*sibcall_value_pop_memory"
12702   [(set (match_operand 0)
12703         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12704               (match_operand 2)))
12705    (set (reg:SI SP_REG)
12706         (plus:SI (reg:SI SP_REG)
12707                  (match_operand:SI 3 "immediate_operand" "i")))
12708    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12709   "!TARGET_64BIT"
12710   "* return ix86_output_call_insn (insn, operands[1]);"
12711   [(set_attr "type" "callv")])
12713 (define_peephole2
12714   [(set (match_operand:SI 0 "register_operand")
12715         (match_operand:SI 1 "memory_operand"))
12716    (parallel [(set (match_operand 2)
12717                    (call (mem:QI (match_dup 0))
12718                          (match_operand 3)))
12719               (set (reg:SI SP_REG)
12720                    (plus:SI (reg:SI SP_REG)
12721                             (match_operand:SI 4 "immediate_operand")))])]
12722   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12723    && !reg_mentioned_p (operands[0],
12724                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12725   [(parallel [(set (match_dup 2)
12726                    (call (mem:QI (match_dup 1))
12727                          (match_dup 3)))
12728               (set (reg:SI SP_REG)
12729                    (plus:SI (reg:SI SP_REG)
12730                             (match_dup 4)))
12731               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12733 (define_peephole2
12734   [(set (match_operand:SI 0 "register_operand")
12735         (match_operand:SI 1 "memory_operand"))
12736    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12737    (parallel [(set (match_operand 2)
12738                    (call (mem:QI (match_dup 0))
12739                          (match_operand 3)))
12740               (set (reg:SI SP_REG)
12741                    (plus:SI (reg:SI SP_REG)
12742                             (match_operand:SI 4 "immediate_operand")))])]
12743   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12744    && !reg_mentioned_p (operands[0],
12745                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12746   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12747    (parallel [(set (match_dup 2)
12748                    (call (mem:QI (match_dup 1))
12749                          (match_dup 3)))
12750               (set (reg:SI SP_REG)
12751                    (plus:SI (reg:SI SP_REG)
12752                             (match_dup 4)))
12753               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12755 ;; Call subroutine returning any type.
12757 (define_expand "untyped_call"
12758   [(parallel [(call (match_operand 0)
12759                     (const_int 0))
12760               (match_operand 1)
12761               (match_operand 2)])]
12762   ""
12764   int i;
12766   /* In order to give reg-stack an easier job in validating two
12767      coprocessor registers as containing a possible return value,
12768      simply pretend the untyped call returns a complex long double
12769      value. 
12771      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12772      and should have the default ABI.  */
12774   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12775                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12776                     operands[0], const0_rtx,
12777                     GEN_INT ((TARGET_64BIT
12778                               ? (ix86_abi == SYSV_ABI
12779                                  ? X86_64_SSE_REGPARM_MAX
12780                                  : X86_64_MS_SSE_REGPARM_MAX)
12781                               : X86_32_SSE_REGPARM_MAX)
12782                              - 1),
12783                     NULL, false);
12785   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12786     {
12787       rtx set = XVECEXP (operands[2], 0, i);
12788       emit_move_insn (SET_DEST (set), SET_SRC (set));
12789     }
12791   /* The optimizer does not know that the call sets the function value
12792      registers we stored in the result block.  We avoid problems by
12793      claiming that all hard registers are used and clobbered at this
12794      point.  */
12795   emit_insn (gen_blockage ());
12797   DONE;
12800 ;; Prologue and epilogue instructions
12802 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12803 ;; all of memory.  This blocks insns from being moved across this point.
12805 (define_insn "blockage"
12806   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12807   ""
12808   ""
12809   [(set_attr "length" "0")])
12811 ;; Do not schedule instructions accessing memory across this point.
12813 (define_expand "memory_blockage"
12814   [(set (match_dup 0)
12815         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12816   ""
12818   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12819   MEM_VOLATILE_P (operands[0]) = 1;
12822 (define_insn "*memory_blockage"
12823   [(set (match_operand:BLK 0)
12824         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12825   ""
12826   ""
12827   [(set_attr "length" "0")])
12829 ;; As USE insns aren't meaningful after reload, this is used instead
12830 ;; to prevent deleting instructions setting registers for PIC code
12831 (define_insn "prologue_use"
12832   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12833   ""
12834   ""
12835   [(set_attr "length" "0")])
12837 ;; Insn emitted into the body of a function to return from a function.
12838 ;; This is only done if the function's epilogue is known to be simple.
12839 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12841 (define_expand "return"
12842   [(simple_return)]
12843   "ix86_can_use_return_insn_p ()"
12845   if (crtl->args.pops_args)
12846     {
12847       rtx popc = GEN_INT (crtl->args.pops_args);
12848       emit_jump_insn (gen_simple_return_pop_internal (popc));
12849       DONE;
12850     }
12853 ;; We need to disable this for TARGET_SEH, as otherwise
12854 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12855 ;; the maximum size of prologue in unwind information.
12856 ;; Also disallow shrink-wrapping if using stack slot to pass the
12857 ;; static chain pointer - the first instruction has to be pushl %esi
12858 ;; and it can't be moved around, as we use alternate entry points
12859 ;; in that case.
12861 (define_expand "simple_return"
12862   [(simple_return)]
12863   "!TARGET_SEH && !ix86_static_chain_on_stack"
12865   if (crtl->args.pops_args)
12866     {
12867       rtx popc = GEN_INT (crtl->args.pops_args);
12868       emit_jump_insn (gen_simple_return_pop_internal (popc));
12869       DONE;
12870     }
12873 (define_insn "simple_return_internal"
12874   [(simple_return)]
12875   "reload_completed"
12876   "* return ix86_output_function_return (false);"
12877   [(set_attr "length" "1")
12878    (set_attr "atom_unit" "jeu")
12879    (set_attr "length_immediate" "0")
12880    (set_attr "modrm" "0")])
12882 (define_insn "interrupt_return"
12883   [(simple_return)
12884    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12885   "reload_completed"
12887   return TARGET_64BIT ? "iretq" : "iret";
12890 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12891 ;; instruction Athlon and K8 have.
12893 (define_insn "simple_return_internal_long"
12894   [(simple_return)
12895    (unspec [(const_int 0)] UNSPEC_REP)]
12896   "reload_completed"
12897   "* return ix86_output_function_return (true);"
12898   [(set_attr "length" "2")
12899    (set_attr "atom_unit" "jeu")
12900    (set_attr "length_immediate" "0")
12901    (set_attr "prefix_rep" "1")
12902    (set_attr "modrm" "0")])
12904 (define_insn_and_split "simple_return_pop_internal"
12905   [(simple_return)
12906    (use (match_operand:SI 0 "const_int_operand"))]
12907   "reload_completed"
12908   "%!ret\t%0"
12909   "&& cfun->machine->function_return_type != indirect_branch_keep"
12910   [(const_int 0)]
12911   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12912   [(set_attr "length" "3")
12913    (set_attr "atom_unit" "jeu")
12914    (set_attr "length_immediate" "2")
12915    (set_attr "modrm" "0")])
12917 (define_expand "simple_return_indirect_internal"
12918   [(parallel
12919      [(simple_return)
12920       (use (match_operand 0 "register_operand"))])])
12922 (define_insn "*simple_return_indirect_internal<mode>"
12923   [(simple_return)
12924    (use (match_operand:W 0 "register_operand" "r"))]
12925   "reload_completed"
12926   "* return ix86_output_indirect_function_return (operands[0]);"
12927   [(set (attr "type")
12928      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12929                                  != indirect_branch_keep)")
12930         (const_string "multi")
12931         (const_string "ibr")))
12932    (set_attr "length_immediate" "0")])
12934 (define_insn "nop"
12935   [(const_int 0)]
12936   ""
12937   "nop"
12938   [(set_attr "length" "1")
12939    (set_attr "length_immediate" "0")
12940    (set_attr "modrm" "0")])
12942 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12943 (define_insn "nops"
12944   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12945                     UNSPECV_NOPS)]
12946   "reload_completed"
12948   int num = INTVAL (operands[0]);
12950   gcc_assert (IN_RANGE (num, 1, 8));
12952   while (num--)
12953     fputs ("\tnop\n", asm_out_file);
12955   return "";
12957   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12958    (set_attr "length_immediate" "0")
12959    (set_attr "modrm" "0")])
12961 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12962 ;; branch prediction penalty for the third jump in a 16-byte
12963 ;; block on K8.
12965 (define_insn "pad"
12966   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12967   ""
12969 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12970   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12971 #else
12972   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12973      The align insn is used to avoid 3 jump instructions in the row to improve
12974      branch prediction and the benefits hardly outweigh the cost of extra 8
12975      nops on the average inserted by full alignment pseudo operation.  */
12976 #endif
12977   return "";
12979   [(set_attr "length" "16")])
12981 (define_expand "prologue"
12982   [(const_int 0)]
12983   ""
12984   "ix86_expand_prologue (); DONE;")
12986 (define_expand "set_got"
12987   [(parallel
12988      [(set (match_operand:SI 0 "register_operand")
12989            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12990       (clobber (reg:CC FLAGS_REG))])]
12991   "!TARGET_64BIT"
12993   if (flag_pic && !TARGET_VXWORKS_RTP)
12994     ix86_pc_thunk_call_expanded = true;
12997 (define_insn "*set_got"
12998   [(set (match_operand:SI 0 "register_operand" "=r")
12999         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13000    (clobber (reg:CC FLAGS_REG))]
13001   "!TARGET_64BIT"
13002   "* return output_set_got (operands[0], NULL_RTX);"
13003   [(set_attr "type" "multi")
13004    (set_attr "length" "12")])
13006 (define_expand "set_got_labelled"
13007   [(parallel
13008      [(set (match_operand:SI 0 "register_operand")
13009            (unspec:SI [(label_ref (match_operand 1))]
13010                       UNSPEC_SET_GOT))
13011       (clobber (reg:CC FLAGS_REG))])]
13012   "!TARGET_64BIT"
13014   if (flag_pic && !TARGET_VXWORKS_RTP)
13015     ix86_pc_thunk_call_expanded = true;
13018 (define_insn "*set_got_labelled"
13019   [(set (match_operand:SI 0 "register_operand" "=r")
13020         (unspec:SI [(label_ref (match_operand 1))]
13021          UNSPEC_SET_GOT))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "!TARGET_64BIT"
13024   "* return output_set_got (operands[0], operands[1]);"
13025   [(set_attr "type" "multi")
13026    (set_attr "length" "12")])
13028 (define_insn "set_got_rex64"
13029   [(set (match_operand:DI 0 "register_operand" "=r")
13030         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13031   "TARGET_64BIT"
13032   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13033   [(set_attr "type" "lea")
13034    (set_attr "length_address" "4")
13035    (set_attr "mode" "DI")])
13037 (define_insn "set_rip_rex64"
13038   [(set (match_operand:DI 0 "register_operand" "=r")
13039         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13040   "TARGET_64BIT"
13041   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13042   [(set_attr "type" "lea")
13043    (set_attr "length_address" "4")
13044    (set_attr "mode" "DI")])
13046 (define_insn "set_got_offset_rex64"
13047   [(set (match_operand:DI 0 "register_operand" "=r")
13048         (unspec:DI
13049           [(label_ref (match_operand 1))]
13050           UNSPEC_SET_GOT_OFFSET))]
13051   "TARGET_LP64"
13052   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13053   [(set_attr "type" "imov")
13054    (set_attr "length_immediate" "0")
13055    (set_attr "length_address" "8")
13056    (set_attr "mode" "DI")])
13058 (define_expand "epilogue"
13059   [(const_int 0)]
13060   ""
13061   "ix86_expand_epilogue (1); DONE;")
13063 (define_expand "sibcall_epilogue"
13064   [(const_int 0)]
13065   ""
13066   "ix86_expand_epilogue (0); DONE;")
13068 (define_expand "eh_return"
13069   [(use (match_operand 0 "register_operand"))]
13070   ""
13072   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13074   /* Tricky bit: we write the address of the handler to which we will
13075      be returning into someone else's stack frame, one word below the
13076      stack address we wish to restore.  */
13077   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13078   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13079   /* Return address is always in word_mode.  */
13080   tmp = gen_rtx_MEM (word_mode, tmp);
13081   if (GET_MODE (ra) != word_mode)
13082     ra = convert_to_mode (word_mode, ra, 1);
13083   emit_move_insn (tmp, ra);
13085   emit_jump_insn (gen_eh_return_internal ());
13086   emit_barrier ();
13087   DONE;
13090 (define_insn_and_split "eh_return_internal"
13091   [(eh_return)]
13092   ""
13093   "#"
13094   "epilogue_completed"
13095   [(const_int 0)]
13096   "ix86_expand_epilogue (2); DONE;")
13098 (define_insn "leave"
13099   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13100    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13101    (clobber (mem:BLK (scratch)))]
13102   "!TARGET_64BIT"
13103   "leave"
13104   [(set_attr "type" "leave")])
13106 (define_insn "leave_rex64"
13107   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13108    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13109    (clobber (mem:BLK (scratch)))]
13110   "TARGET_64BIT"
13111   "leave"
13112   [(set_attr "type" "leave")])
13114 ;; Handle -fsplit-stack.
13116 (define_expand "split_stack_prologue"
13117   [(const_int 0)]
13118   ""
13120   ix86_expand_split_stack_prologue ();
13121   DONE;
13124 ;; In order to support the call/return predictor, we use a return
13125 ;; instruction which the middle-end doesn't see.
13126 (define_insn "split_stack_return"
13127   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13128                      UNSPECV_SPLIT_STACK_RETURN)]
13129   ""
13131   if (operands[0] == const0_rtx)
13132     return "ret";
13133   else
13134     return "ret\t%0";
13136   [(set_attr "atom_unit" "jeu")
13137    (set_attr "modrm" "0")
13138    (set (attr "length")
13139         (if_then_else (match_operand:SI 0 "const0_operand")
13140                       (const_int 1)
13141                       (const_int 3)))
13142    (set (attr "length_immediate")
13143         (if_then_else (match_operand:SI 0 "const0_operand")
13144                       (const_int 0)
13145                       (const_int 2)))])
13147 ;; If there are operand 0 bytes available on the stack, jump to
13148 ;; operand 1.
13150 (define_expand "split_stack_space_check"
13151   [(set (pc) (if_then_else
13152               (ltu (minus (reg SP_REG)
13153                           (match_operand 0 "register_operand"))
13154                    (match_dup 2))
13155               (label_ref (match_operand 1))
13156               (pc)))]
13157   ""
13159   rtx reg = gen_reg_rtx (Pmode);
13161   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13163   operands[2] = ix86_split_stack_guard ();
13164   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13166   DONE;
13169 ;; Bit manipulation instructions.
13171 (define_expand "ffs<mode>2"
13172   [(set (match_dup 2) (const_int -1))
13173    (parallel [(set (match_dup 3) (match_dup 4))
13174               (set (match_operand:SWI48 0 "register_operand")
13175                    (ctz:SWI48
13176                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13177    (set (match_dup 0) (if_then_else:SWI48
13178                         (eq (match_dup 3) (const_int 0))
13179                         (match_dup 2)
13180                         (match_dup 0)))
13181    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13182               (clobber (reg:CC FLAGS_REG))])]
13183   ""
13185   machine_mode flags_mode;
13187   if (<MODE>mode == SImode && !TARGET_CMOVE)
13188     {
13189       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13190       DONE;
13191     }
13193   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13195   operands[2] = gen_reg_rtx (<MODE>mode);
13196   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13197   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13200 (define_insn_and_split "ffssi2_no_cmove"
13201   [(set (match_operand:SI 0 "register_operand" "=r")
13202         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13203    (clobber (match_scratch:SI 2 "=&q"))
13204    (clobber (reg:CC FLAGS_REG))]
13205   "!TARGET_CMOVE"
13206   "#"
13207   "&& reload_completed"
13208   [(parallel [(set (match_dup 4) (match_dup 5))
13209               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13210    (set (strict_low_part (match_dup 3))
13211         (eq:QI (match_dup 4) (const_int 0)))
13212    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13213               (clobber (reg:CC FLAGS_REG))])
13214    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13215               (clobber (reg:CC FLAGS_REG))])
13216    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13217               (clobber (reg:CC FLAGS_REG))])]
13219   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13221   operands[3] = gen_lowpart (QImode, operands[2]);
13222   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13223   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13225   ix86_expand_clear (operands[2]);
13228 (define_insn_and_split "*tzcnt<mode>_1"
13229   [(set (reg:CCC FLAGS_REG)
13230         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13231                      (const_int 0)))
13232    (set (match_operand:SWI48 0 "register_operand" "=r")
13233         (ctz:SWI48 (match_dup 1)))]
13234   "TARGET_BMI"
13235   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13236   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13237    && optimize_function_for_speed_p (cfun)
13238    && !reg_mentioned_p (operands[0], operands[1])"
13239   [(parallel
13240     [(set (reg:CCC FLAGS_REG)
13241           (compare:CCC (match_dup 1) (const_int 0)))
13242      (set (match_dup 0)
13243           (ctz:SWI48 (match_dup 1)))
13244      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13245   "ix86_expand_clear (operands[0]);"
13246   [(set_attr "type" "alu1")
13247    (set_attr "prefix_0f" "1")
13248    (set_attr "prefix_rep" "1")
13249    (set_attr "btver2_decode" "double")
13250    (set_attr "mode" "<MODE>")])
13252 ; False dependency happens when destination is only updated by tzcnt,
13253 ; lzcnt or popcnt.  There is no false dependency when destination is
13254 ; also used in source.
13255 (define_insn "*tzcnt<mode>_1_falsedep"
13256   [(set (reg:CCC FLAGS_REG)
13257         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13258                      (const_int 0)))
13259    (set (match_operand:SWI48 0 "register_operand" "=r")
13260         (ctz:SWI48 (match_dup 1)))
13261    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13262            UNSPEC_INSN_FALSE_DEP)]
13263   "TARGET_BMI"
13264   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13265   [(set_attr "type" "alu1")
13266    (set_attr "prefix_0f" "1")
13267    (set_attr "prefix_rep" "1")
13268    (set_attr "btver2_decode" "double")
13269    (set_attr "mode" "<MODE>")])
13271 (define_insn "*bsf<mode>_1"
13272   [(set (reg:CCZ FLAGS_REG)
13273         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13274                      (const_int 0)))
13275    (set (match_operand:SWI48 0 "register_operand" "=r")
13276         (ctz:SWI48 (match_dup 1)))]
13277   ""
13278   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13279   [(set_attr "type" "alu1")
13280    (set_attr "prefix_0f" "1")
13281    (set_attr "btver2_decode" "double")
13282    (set_attr "znver1_decode" "vector")
13283    (set_attr "mode" "<MODE>")])
13285 (define_insn_and_split "ctz<mode>2"
13286   [(set (match_operand:SWI48 0 "register_operand" "=r")
13287         (ctz:SWI48
13288           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13289    (clobber (reg:CC FLAGS_REG))]
13290   ""
13292   if (TARGET_BMI)
13293     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13294   else if (optimize_function_for_size_p (cfun))
13295     ;
13296   else if (TARGET_GENERIC)
13297     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13298     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13300   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13302   "(TARGET_BMI || TARGET_GENERIC)
13303    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13304    && optimize_function_for_speed_p (cfun)
13305    && !reg_mentioned_p (operands[0], operands[1])"
13306   [(parallel
13307     [(set (match_dup 0)
13308           (ctz:SWI48 (match_dup 1)))
13309      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13310      (clobber (reg:CC FLAGS_REG))])]
13311   "ix86_expand_clear (operands[0]);"
13312   [(set_attr "type" "alu1")
13313    (set_attr "prefix_0f" "1")
13314    (set (attr "prefix_rep")
13315      (if_then_else
13316        (ior (match_test "TARGET_BMI")
13317             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13318                  (match_test "TARGET_GENERIC")))
13319        (const_string "1")
13320        (const_string "0")))
13321    (set_attr "mode" "<MODE>")])
13323 ; False dependency happens when destination is only updated by tzcnt,
13324 ; lzcnt or popcnt.  There is no false dependency when destination is
13325 ; also used in source.
13326 (define_insn "*ctz<mode>2_falsedep"
13327   [(set (match_operand:SWI48 0 "register_operand" "=r")
13328         (ctz:SWI48
13329           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13330    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13331            UNSPEC_INSN_FALSE_DEP)
13332    (clobber (reg:CC FLAGS_REG))]
13333   ""
13335   if (TARGET_BMI)
13336     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13337   else if (TARGET_GENERIC)
13338     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13339     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13340   else
13341     gcc_unreachable ();
13343   [(set_attr "type" "alu1")
13344    (set_attr "prefix_0f" "1")
13345    (set_attr "prefix_rep" "1")
13346    (set_attr "mode" "<MODE>")])
13348 (define_insn "bsr_rex64"
13349   [(set (match_operand:DI 0 "register_operand" "=r")
13350         (minus:DI (const_int 63)
13351                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13352    (clobber (reg:CC FLAGS_REG))]
13353   "TARGET_64BIT"
13354   "bsr{q}\t{%1, %0|%0, %1}"
13355   [(set_attr "type" "alu1")
13356    (set_attr "prefix_0f" "1")
13357    (set_attr "znver1_decode" "vector")
13358    (set_attr "mode" "DI")])
13360 (define_insn "bsr"
13361   [(set (match_operand:SI 0 "register_operand" "=r")
13362         (minus:SI (const_int 31)
13363                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13364    (clobber (reg:CC FLAGS_REG))]
13365   ""
13366   "bsr{l}\t{%1, %0|%0, %1}"
13367   [(set_attr "type" "alu1")
13368    (set_attr "prefix_0f" "1")
13369    (set_attr "znver1_decode" "vector")
13370    (set_attr "mode" "SI")])
13372 (define_insn "*bsrhi"
13373   [(set (match_operand:HI 0 "register_operand" "=r")
13374         (minus:HI (const_int 15)
13375                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13376    (clobber (reg:CC FLAGS_REG))]
13377   ""
13378   "bsr{w}\t{%1, %0|%0, %1}"
13379   [(set_attr "type" "alu1")
13380    (set_attr "prefix_0f" "1")
13381    (set_attr "znver1_decode" "vector")
13382    (set_attr "mode" "HI")])
13384 (define_expand "clz<mode>2"
13385   [(parallel
13386      [(set (match_operand:SWI48 0 "register_operand")
13387            (minus:SWI48
13388              (match_dup 2)
13389              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13390       (clobber (reg:CC FLAGS_REG))])
13391    (parallel
13392      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13393       (clobber (reg:CC FLAGS_REG))])]
13394   ""
13396   if (TARGET_LZCNT)
13397     {
13398       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13399       DONE;
13400     }
13401   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13404 (define_insn_and_split "clz<mode>2_lzcnt"
13405   [(set (match_operand:SWI48 0 "register_operand" "=r")
13406         (clz:SWI48
13407           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13408    (clobber (reg:CC FLAGS_REG))]
13409   "TARGET_LZCNT"
13410   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13411   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13412    && optimize_function_for_speed_p (cfun)
13413    && !reg_mentioned_p (operands[0], operands[1])"
13414   [(parallel
13415     [(set (match_dup 0)
13416           (clz:SWI48 (match_dup 1)))
13417      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13418      (clobber (reg:CC FLAGS_REG))])]
13419   "ix86_expand_clear (operands[0]);"
13420   [(set_attr "prefix_rep" "1")
13421    (set_attr "type" "bitmanip")
13422    (set_attr "mode" "<MODE>")])
13424 ; False dependency happens when destination is only updated by tzcnt,
13425 ; lzcnt or popcnt.  There is no false dependency when destination is
13426 ; also used in source.
13427 (define_insn "*clz<mode>2_lzcnt_falsedep"
13428   [(set (match_operand:SWI48 0 "register_operand" "=r")
13429         (clz:SWI48
13430           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13431    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13432            UNSPEC_INSN_FALSE_DEP)
13433    (clobber (reg:CC FLAGS_REG))]
13434   "TARGET_LZCNT"
13435   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13436   [(set_attr "prefix_rep" "1")
13437    (set_attr "type" "bitmanip")
13438    (set_attr "mode" "<MODE>")])
13440 (define_int_iterator LT_ZCNT
13441         [(UNSPEC_TZCNT "TARGET_BMI")
13442          (UNSPEC_LZCNT "TARGET_LZCNT")])
13444 (define_int_attr lt_zcnt
13445         [(UNSPEC_TZCNT "tzcnt")
13446          (UNSPEC_LZCNT "lzcnt")])
13448 (define_int_attr lt_zcnt_type
13449         [(UNSPEC_TZCNT "alu1")
13450          (UNSPEC_LZCNT "bitmanip")])
13452 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13453 ;; provides operand size as output when source operand is zero. 
13455 (define_insn_and_split "<lt_zcnt>_<mode>"
13456   [(set (match_operand:SWI48 0 "register_operand" "=r")
13457         (unspec:SWI48
13458           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13459    (clobber (reg:CC FLAGS_REG))]
13460   ""
13461   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13462   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13463    && optimize_function_for_speed_p (cfun)
13464    && !reg_mentioned_p (operands[0], operands[1])"
13465   [(parallel
13466     [(set (match_dup 0)
13467           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13468      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13469      (clobber (reg:CC FLAGS_REG))])]
13470   "ix86_expand_clear (operands[0]);"
13471   [(set_attr "type" "<lt_zcnt_type>")
13472    (set_attr "prefix_0f" "1")
13473    (set_attr "prefix_rep" "1")
13474    (set_attr "mode" "<MODE>")])
13476 ; False dependency happens when destination is only updated by tzcnt,
13477 ; lzcnt or popcnt.  There is no false dependency when destination is
13478 ; also used in source.
13479 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13480   [(set (match_operand:SWI48 0 "register_operand" "=r")
13481         (unspec:SWI48
13482           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13483    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13484            UNSPEC_INSN_FALSE_DEP)
13485    (clobber (reg:CC FLAGS_REG))]
13486   ""
13487   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13488   [(set_attr "type" "<lt_zcnt_type>")
13489    (set_attr "prefix_0f" "1")
13490    (set_attr "prefix_rep" "1")
13491    (set_attr "mode" "<MODE>")])
13493 (define_insn "<lt_zcnt>_hi"
13494   [(set (match_operand:HI 0 "register_operand" "=r")
13495         (unspec:HI
13496           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13497    (clobber (reg:CC FLAGS_REG))]
13498   ""
13499   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13500   [(set_attr "type" "<lt_zcnt_type>")
13501    (set_attr "prefix_0f" "1")
13502    (set_attr "prefix_rep" "1")
13503    (set_attr "mode" "HI")])
13505 ;; BMI instructions.
13507 (define_insn "bmi_bextr_<mode>"
13508   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13509         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13510                        (match_operand:SWI48 2 "register_operand" "r,r")]
13511                       UNSPEC_BEXTR))
13512    (clobber (reg:CC FLAGS_REG))]
13513   "TARGET_BMI"
13514   "bextr\t{%2, %1, %0|%0, %1, %2}"
13515   [(set_attr "type" "bitmanip")
13516    (set_attr "btver2_decode" "direct, double")
13517    (set_attr "mode" "<MODE>")])
13519 (define_insn "*bmi_bextr_<mode>_ccz"
13520   [(set (reg:CCZ FLAGS_REG)
13521         (compare:CCZ
13522           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13523                          (match_operand:SWI48 2 "register_operand" "r,r")]
13524                         UNSPEC_BEXTR)
13525           (const_int 0)))
13526    (clobber (match_scratch:SWI48 0 "=r,r"))]
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_blsi_<mode>"
13534   [(set (match_operand:SWI48 0 "register_operand" "=r")
13535         (and:SWI48
13536           (neg:SWI48
13537             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13538           (match_dup 1)))
13539    (clobber (reg:CC FLAGS_REG))]
13540   "TARGET_BMI"
13541   "blsi\t{%1, %0|%0, %1}"
13542   [(set_attr "type" "bitmanip")
13543    (set_attr "btver2_decode" "double")
13544    (set_attr "mode" "<MODE>")])
13546 (define_insn "*bmi_blsmsk_<mode>"
13547   [(set (match_operand:SWI48 0 "register_operand" "=r")
13548         (xor:SWI48
13549           (plus:SWI48
13550             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13551             (const_int -1))
13552           (match_dup 1)))
13553    (clobber (reg:CC FLAGS_REG))]
13554   "TARGET_BMI"
13555   "blsmsk\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_blsr_<mode>"
13561   [(set (match_operand:SWI48 0 "register_operand" "=r")
13562         (and: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    "blsr\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>_cmp"
13575   [(set (reg:CCZ FLAGS_REG)
13576         (compare:CCZ
13577           (and:SWI48
13578             (plus:SWI48
13579               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13580               (const_int -1))
13581             (match_dup 1))
13582           (const_int 0)))
13583    (set (match_operand:SWI48 0 "register_operand" "=r")
13584         (and:SWI48
13585           (plus:SWI48
13586             (match_dup 1)
13587             (const_int -1))
13588           (match_dup 1)))]
13589    "TARGET_BMI"
13590    "blsr\t{%1, %0|%0, %1}"
13591   [(set_attr "type" "bitmanip")
13592    (set_attr "btver2_decode" "double")
13593    (set_attr "mode" "<MODE>")])
13595 (define_insn "*bmi_blsr_<mode>_ccz"
13596   [(set (reg:CCZ FLAGS_REG)
13597         (compare:CCZ
13598           (and:SWI48
13599             (plus:SWI48
13600               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13601               (const_int -1))
13602             (match_dup 1))
13603           (const_int 0)))
13604    (clobber (match_scratch:SWI48 0 "=r"))]
13605    "TARGET_BMI"
13606    "blsr\t{%1, %0|%0, %1}"
13607   [(set_attr "type" "bitmanip")
13608    (set_attr "btver2_decode" "double")
13609    (set_attr "mode" "<MODE>")])
13611 ;; BMI2 instructions.
13612 (define_expand "bmi2_bzhi_<mode>3"
13613   [(parallel
13614     [(set (match_operand:SWI48 0 "register_operand")
13615           (zero_extract:SWI48
13616             (match_operand:SWI48 1 "nonimmediate_operand")
13617             (umin:SWI48
13618               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13619                          (const_int 255))
13620               (match_dup 3))
13621             (const_int 0)))
13622      (clobber (reg:CC FLAGS_REG))])]
13623   "TARGET_BMI2"
13624   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13626 (define_insn "*bmi2_bzhi_<mode>3"
13627   [(set (match_operand:SWI48 0 "register_operand" "=r")
13628         (zero_extract:SWI48
13629           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13630           (umin:SWI48
13631             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13632                        (const_int 255))
13633             (match_operand:SWI48 3 "const_int_operand" "n"))
13634           (const_int 0)))
13635    (clobber (reg:CC FLAGS_REG))]
13636   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13637   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13638   [(set_attr "type" "bitmanip")
13639    (set_attr "prefix" "vex")
13640    (set_attr "mode" "<MODE>")])
13642 (define_insn "*bmi2_bzhi_<mode>3_1"
13643   [(set (match_operand:SWI48 0 "register_operand" "=r")
13644         (zero_extract:SWI48
13645           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13646           (umin:SWI48
13647             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13648             (match_operand:SWI48 3 "const_int_operand" "n"))
13649           (const_int 0)))
13650    (clobber (reg:CC FLAGS_REG))]
13651   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13652   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13653   [(set_attr "type" "bitmanip")
13654    (set_attr "prefix" "vex")
13655    (set_attr "mode" "<MODE>")])
13657 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13658   [(set (reg:CCZ FLAGS_REG)
13659         (compare:CCZ
13660           (zero_extract:SWI48
13661             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13662             (umin:SWI48
13663               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13664               (match_operand:SWI48 3 "const_int_operand" "n"))
13665             (const_int 0))
13666         (const_int 0)))
13667    (clobber (match_scratch:SWI48 0 "=r"))]
13668   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13669   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13670   [(set_attr "type" "bitmanip")
13671    (set_attr "prefix" "vex")
13672    (set_attr "mode" "<MODE>")])
13674 (define_insn "bmi2_pdep_<mode>3"
13675   [(set (match_operand:SWI48 0 "register_operand" "=r")
13676         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13677                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13678                        UNSPEC_PDEP))]
13679   "TARGET_BMI2"
13680   "pdep\t{%2, %1, %0|%0, %1, %2}"
13681   [(set_attr "type" "bitmanip")
13682    (set_attr "prefix" "vex")
13683    (set_attr "mode" "<MODE>")])
13685 (define_insn "bmi2_pext_<mode>3"
13686   [(set (match_operand:SWI48 0 "register_operand" "=r")
13687         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13688                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13689                        UNSPEC_PEXT))]
13690   "TARGET_BMI2"
13691   "pext\t{%2, %1, %0|%0, %1, %2}"
13692   [(set_attr "type" "bitmanip")
13693    (set_attr "prefix" "vex")
13694    (set_attr "mode" "<MODE>")])
13696 ;; TBM instructions.
13697 (define_insn "tbm_bextri_<mode>"
13698   [(set (match_operand:SWI48 0 "register_operand" "=r")
13699         (zero_extract:SWI48
13700           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13701           (match_operand 2 "const_0_to_255_operand" "N")
13702           (match_operand 3 "const_0_to_255_operand" "N")))
13703    (clobber (reg:CC FLAGS_REG))]
13704    "TARGET_TBM"
13706   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13707   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13709   [(set_attr "type" "bitmanip")
13710    (set_attr "mode" "<MODE>")])
13712 (define_insn "*tbm_blcfill_<mode>"
13713   [(set (match_operand:SWI48 0 "register_operand" "=r")
13714         (and:SWI48
13715           (plus:SWI48
13716             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13717             (const_int 1))
13718           (match_dup 1)))
13719    (clobber (reg:CC FLAGS_REG))]
13720    "TARGET_TBM"
13721    "blcfill\t{%1, %0|%0, %1}"
13722   [(set_attr "type" "bitmanip")
13723    (set_attr "mode" "<MODE>")])
13725 (define_insn "*tbm_blci_<mode>"
13726   [(set (match_operand:SWI48 0 "register_operand" "=r")
13727         (ior:SWI48
13728           (not:SWI48
13729             (plus:SWI48
13730               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13731               (const_int 1)))
13732           (match_dup 1)))
13733    (clobber (reg:CC FLAGS_REG))]
13734    "TARGET_TBM"
13735    "blci\t{%1, %0|%0, %1}"
13736   [(set_attr "type" "bitmanip")
13737    (set_attr "mode" "<MODE>")])
13739 (define_insn "*tbm_blcic_<mode>"
13740   [(set (match_operand:SWI48 0 "register_operand" "=r")
13741         (and:SWI48
13742           (plus:SWI48
13743             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13744             (const_int 1))
13745           (not:SWI48
13746             (match_dup 1))))
13747    (clobber (reg:CC FLAGS_REG))]
13748    "TARGET_TBM"
13749    "blcic\t{%1, %0|%0, %1}"
13750   [(set_attr "type" "bitmanip")
13751    (set_attr "mode" "<MODE>")])
13753 (define_insn "*tbm_blcmsk_<mode>"
13754   [(set (match_operand:SWI48 0 "register_operand" "=r")
13755         (xor:SWI48
13756           (plus:SWI48
13757             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13758             (const_int 1))
13759           (match_dup 1)))
13760    (clobber (reg:CC FLAGS_REG))]
13761    "TARGET_TBM"
13762    "blcmsk\t{%1, %0|%0, %1}"
13763   [(set_attr "type" "bitmanip")
13764    (set_attr "mode" "<MODE>")])
13766 (define_insn "*tbm_blcs_<mode>"
13767   [(set (match_operand:SWI48 0 "register_operand" "=r")
13768         (ior:SWI48
13769           (plus:SWI48
13770             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13771             (const_int 1))
13772           (match_dup 1)))
13773    (clobber (reg:CC FLAGS_REG))]
13774    "TARGET_TBM"
13775    "blcs\t{%1, %0|%0, %1}"
13776   [(set_attr "type" "bitmanip")
13777    (set_attr "mode" "<MODE>")])
13779 (define_insn "*tbm_blsfill_<mode>"
13780   [(set (match_operand:SWI48 0 "register_operand" "=r")
13781         (ior:SWI48
13782           (plus:SWI48
13783             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13784             (const_int -1))
13785           (match_dup 1)))
13786    (clobber (reg:CC FLAGS_REG))]
13787    "TARGET_TBM"
13788    "blsfill\t{%1, %0|%0, %1}"
13789   [(set_attr "type" "bitmanip")
13790    (set_attr "mode" "<MODE>")])
13792 (define_insn "*tbm_blsic_<mode>"
13793   [(set (match_operand:SWI48 0 "register_operand" "=r")
13794         (ior:SWI48
13795           (plus:SWI48
13796             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13797             (const_int -1))
13798           (not:SWI48
13799             (match_dup 1))))
13800    (clobber (reg:CC FLAGS_REG))]
13801    "TARGET_TBM"
13802    "blsic\t{%1, %0|%0, %1}"
13803   [(set_attr "type" "bitmanip")
13804    (set_attr "mode" "<MODE>")])
13806 (define_insn "*tbm_t1mskc_<mode>"
13807   [(set (match_operand:SWI48 0 "register_operand" "=r")
13808         (ior:SWI48
13809           (plus:SWI48
13810             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13811             (const_int 1))
13812           (not:SWI48
13813             (match_dup 1))))
13814    (clobber (reg:CC FLAGS_REG))]
13815    "TARGET_TBM"
13816    "t1mskc\t{%1, %0|%0, %1}"
13817   [(set_attr "type" "bitmanip")
13818    (set_attr "mode" "<MODE>")])
13820 (define_insn "*tbm_tzmsk_<mode>"
13821   [(set (match_operand:SWI48 0 "register_operand" "=r")
13822         (and:SWI48
13823           (plus:SWI48
13824             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13825             (const_int -1))
13826           (not:SWI48
13827             (match_dup 1))))
13828    (clobber (reg:CC FLAGS_REG))]
13829    "TARGET_TBM"
13830    "tzmsk\t{%1, %0|%0, %1}"
13831   [(set_attr "type" "bitmanip")
13832    (set_attr "mode" "<MODE>")])
13834 (define_insn_and_split "popcount<mode>2"
13835   [(set (match_operand:SWI48 0 "register_operand" "=r")
13836         (popcount:SWI48
13837           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13838    (clobber (reg:CC FLAGS_REG))]
13839   "TARGET_POPCNT"
13841 #if TARGET_MACHO
13842   return "popcnt\t{%1, %0|%0, %1}";
13843 #else
13844   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13845 #endif
13847   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13848    && optimize_function_for_speed_p (cfun)
13849    && !reg_mentioned_p (operands[0], operands[1])"
13850   [(parallel
13851     [(set (match_dup 0)
13852           (popcount:SWI48 (match_dup 1)))
13853      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13854      (clobber (reg:CC FLAGS_REG))])]
13855   "ix86_expand_clear (operands[0]);"
13856   [(set_attr "prefix_rep" "1")
13857    (set_attr "type" "bitmanip")
13858    (set_attr "mode" "<MODE>")])
13860 ; False dependency happens when destination is only updated by tzcnt,
13861 ; lzcnt or popcnt.  There is no false dependency when destination is
13862 ; also used in source.
13863 (define_insn "*popcount<mode>2_falsedep"
13864   [(set (match_operand:SWI48 0 "register_operand" "=r")
13865         (popcount:SWI48
13866           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13867    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13868            UNSPEC_INSN_FALSE_DEP)
13869    (clobber (reg:CC FLAGS_REG))]
13870   "TARGET_POPCNT"
13872 #if TARGET_MACHO
13873   return "popcnt\t{%1, %0|%0, %1}";
13874 #else
13875   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13876 #endif
13878   [(set_attr "prefix_rep" "1")
13879    (set_attr "type" "bitmanip")
13880    (set_attr "mode" "<MODE>")])
13882 (define_insn_and_split "*popcounthi2_1"
13883   [(set (match_operand:SI 0 "register_operand")
13884         (popcount:SI
13885           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13886    (clobber (reg:CC FLAGS_REG))]
13887   "TARGET_POPCNT
13888    && can_create_pseudo_p ()"
13889   "#"
13890   "&& 1"
13891   [(const_int 0)]
13893   rtx tmp = gen_reg_rtx (HImode);
13895   emit_insn (gen_popcounthi2 (tmp, operands[1]));
13896   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13897   DONE;
13900 (define_insn "popcounthi2"
13901   [(set (match_operand:HI 0 "register_operand" "=r")
13902         (popcount:HI
13903           (match_operand:HI 1 "nonimmediate_operand" "rm")))
13904    (clobber (reg:CC FLAGS_REG))]
13905   "TARGET_POPCNT"
13907 #if TARGET_MACHO
13908   return "popcnt\t{%1, %0|%0, %1}";
13909 #else
13910   return "popcnt{w}\t{%1, %0|%0, %1}";
13911 #endif
13913   [(set_attr "prefix_rep" "1")
13914    (set_attr "type" "bitmanip")
13915    (set_attr "mode" "HI")])
13917 (define_expand "bswapdi2"
13918   [(set (match_operand:DI 0 "register_operand")
13919         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13920   "TARGET_64BIT"
13922   if (!TARGET_MOVBE)
13923     operands[1] = force_reg (DImode, operands[1]);
13926 (define_expand "bswapsi2"
13927   [(set (match_operand:SI 0 "register_operand")
13928         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13929   ""
13931   if (TARGET_MOVBE)
13932     ;
13933   else if (TARGET_BSWAP)
13934     operands[1] = force_reg (SImode, operands[1]);
13935   else
13936     {
13937       rtx x = operands[0];
13939       emit_move_insn (x, operands[1]);
13940       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13941       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13942       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13943       DONE;
13944     }
13947 (define_insn "*bswap<mode>2_movbe"
13948   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13949         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13950   "TARGET_MOVBE
13951    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13952   "@
13953     bswap\t%0
13954     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
13955     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
13956   [(set_attr "type" "bitmanip,imov,imov")
13957    (set_attr "modrm" "0,1,1")
13958    (set_attr "prefix_0f" "*,1,1")
13959    (set_attr "prefix_extra" "*,1,1")
13960    (set_attr "mode" "<MODE>")])
13962 (define_insn "*bswap<mode>2"
13963   [(set (match_operand:SWI48 0 "register_operand" "=r")
13964         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13965   "TARGET_BSWAP"
13966   "bswap\t%0"
13967   [(set_attr "type" "bitmanip")
13968    (set_attr "modrm" "0")
13969    (set_attr "mode" "<MODE>")])
13971 (define_expand "bswaphi2"
13972   [(set (match_operand:HI 0 "register_operand")
13973         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
13974   "TARGET_MOVBE")
13976 (define_insn "*bswaphi2_movbe"
13977   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
13978         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
13979   "TARGET_MOVBE
13980    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13981   "@
13982     xchg{b}\t{%h0, %b0|%b0, %h0}
13983     movbe{w}\t{%1, %0|%0, %1}
13984     movbe{w}\t{%1, %0|%0, %1}"
13985   [(set_attr "type" "imov")
13986    (set_attr "modrm" "*,1,1")
13987    (set_attr "prefix_0f" "*,1,1")
13988    (set_attr "prefix_extra" "*,1,1")
13989    (set_attr "pent_pair" "np,*,*")
13990    (set_attr "athlon_decode" "vector,*,*")
13991    (set_attr "amdfam10_decode" "double,*,*")
13992    (set_attr "bdver1_decode" "double,*,*")
13993    (set_attr "mode" "QI,HI,HI")])
13995 (define_peephole2
13996   [(set (match_operand:HI 0 "general_reg_operand")
13997         (bswap:HI (match_dup 0)))]
13998   "TARGET_MOVBE
13999    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14000    && peep2_regno_dead_p (0, FLAGS_REG)"
14001   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14002               (clobber (reg:CC FLAGS_REG))])])
14004 (define_insn "bswaphi_lowpart"
14005   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14006         (bswap:HI (match_dup 0)))
14007    (clobber (reg:CC FLAGS_REG))]
14008   ""
14009   "@
14010     xchg{b}\t{%h0, %b0|%b0, %h0}
14011     rol{w}\t{$8, %0|%0, 8}"
14012   [(set (attr "preferred_for_size")
14013      (cond [(eq_attr "alternative" "0")
14014               (symbol_ref "true")]
14015            (symbol_ref "false")))
14016    (set (attr "preferred_for_speed")
14017      (cond [(eq_attr "alternative" "0")
14018               (symbol_ref "TARGET_USE_XCHGB")]
14019            (symbol_ref "!TARGET_USE_XCHGB")))
14020    (set_attr "length" "2,4")
14021    (set_attr "mode" "QI,HI")])
14023 (define_expand "paritydi2"
14024   [(set (match_operand:DI 0 "register_operand")
14025         (parity:DI (match_operand:DI 1 "register_operand")))]
14026   "! TARGET_POPCNT"
14028   rtx scratch = gen_reg_rtx (QImode);
14030   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14031                                 NULL_RTX, operands[1]));
14033   ix86_expand_setcc (scratch, ORDERED,
14034                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14036   if (TARGET_64BIT)
14037     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14038   else
14039     {
14040       rtx tmp = gen_reg_rtx (SImode);
14042       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14043       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14044     }
14045   DONE;
14048 (define_expand "paritysi2"
14049   [(set (match_operand:SI 0 "register_operand")
14050         (parity:SI (match_operand:SI 1 "register_operand")))]
14051   "! TARGET_POPCNT"
14053   rtx scratch = gen_reg_rtx (QImode);
14055   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14057   ix86_expand_setcc (scratch, ORDERED,
14058                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14060   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14061   DONE;
14064 (define_insn_and_split "paritydi2_cmp"
14065   [(set (reg:CC FLAGS_REG)
14066         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14067                    UNSPEC_PARITY))
14068    (clobber (match_scratch:DI 0 "=r"))
14069    (clobber (match_scratch:SI 1 "=&r"))
14070    (clobber (match_scratch:HI 2 "=Q"))]
14071   "! TARGET_POPCNT"
14072   "#"
14073   "&& reload_completed"
14074   [(parallel
14075      [(set (match_dup 1)
14076            (xor:SI (match_dup 1) (match_dup 4)))
14077       (clobber (reg:CC FLAGS_REG))])
14078    (parallel
14079      [(set (reg:CC FLAGS_REG)
14080            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14081       (clobber (match_dup 1))
14082       (clobber (match_dup 2))])]
14084   operands[4] = gen_lowpart (SImode, operands[3]);
14086   if (TARGET_64BIT)
14087     {
14088       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14089       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14090     }
14091   else
14092     operands[1] = gen_highpart (SImode, operands[3]);
14095 (define_insn_and_split "paritysi2_cmp"
14096   [(set (reg:CC FLAGS_REG)
14097         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14098                    UNSPEC_PARITY))
14099    (clobber (match_scratch:SI 0 "=r"))
14100    (clobber (match_scratch:HI 1 "=&Q"))]
14101   "! TARGET_POPCNT"
14102   "#"
14103   "&& reload_completed"
14104   [(parallel
14105      [(set (match_dup 1)
14106            (xor:HI (match_dup 1) (match_dup 3)))
14107       (clobber (reg:CC FLAGS_REG))])
14108    (parallel
14109      [(set (reg:CC FLAGS_REG)
14110            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14111       (clobber (match_dup 1))])]
14113   operands[3] = gen_lowpart (HImode, operands[2]);
14115   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14116   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14119 (define_insn "*parityhi2_cmp"
14120   [(set (reg:CC FLAGS_REG)
14121         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14122                    UNSPEC_PARITY))
14123    (clobber (match_scratch:HI 0 "=Q"))]
14124   "! TARGET_POPCNT"
14125   "xor{b}\t{%h0, %b0|%b0, %h0}"
14126   [(set_attr "length" "2")
14127    (set_attr "mode" "HI")])
14130 ;; Thread-local storage patterns for ELF.
14132 ;; Note that these code sequences must appear exactly as shown
14133 ;; in order to allow linker relaxation.
14135 (define_insn "*tls_global_dynamic_32_gnu"
14136   [(set (match_operand:SI 0 "register_operand" "=a")
14137         (unspec:SI
14138          [(match_operand:SI 1 "register_operand" "Yb")
14139           (match_operand 2 "tls_symbolic_operand")
14140           (match_operand 3 "constant_call_address_operand" "Bz")
14141           (reg:SI SP_REG)]
14142          UNSPEC_TLS_GD))
14143    (clobber (match_scratch:SI 4 "=d"))
14144    (clobber (match_scratch:SI 5 "=c"))
14145    (clobber (reg:CC FLAGS_REG))]
14146   "!TARGET_64BIT && TARGET_GNU_TLS"
14148   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14149     output_asm_insn
14150       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14151   else
14152     output_asm_insn
14153       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14154   if (TARGET_SUN_TLS)
14155 #ifdef HAVE_AS_IX86_TLSGDPLT
14156     return "call\t%a2@tlsgdplt";
14157 #else
14158     return "call\t%p3@plt";
14159 #endif
14160   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14161     return "call\t%P3";
14162   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14164   [(set_attr "type" "multi")
14165    (set_attr "length" "12")])
14167 (define_expand "tls_global_dynamic_32"
14168   [(parallel
14169     [(set (match_operand:SI 0 "register_operand")
14170           (unspec:SI [(match_operand:SI 2 "register_operand")
14171                       (match_operand 1 "tls_symbolic_operand")
14172                       (match_operand 3 "constant_call_address_operand")
14173                       (reg:SI SP_REG)]
14174                      UNSPEC_TLS_GD))
14175      (clobber (match_scratch:SI 4))
14176      (clobber (match_scratch:SI 5))
14177      (clobber (reg:CC FLAGS_REG))])]
14178   ""
14179   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14181 (define_insn "*tls_global_dynamic_64_<mode>"
14182   [(set (match_operand:P 0 "register_operand" "=a")
14183         (call:P
14184          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14185          (match_operand 3)))
14186    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14187               (reg:P SP_REG)]
14188              UNSPEC_TLS_GD)]
14189   "TARGET_64BIT"
14191   if (!TARGET_X32)
14192     /* The .loc directive has effect for 'the immediately following assembly
14193        instruction'.  So for a sequence:
14194          .loc f l
14195          .byte x
14196          insn1
14197        the 'immediately following assembly instruction' is insn1.
14198        We want to emit an insn prefix here, but if we use .byte (as shown in
14199        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14200        inside the insn sequence, rather than to the start.  After relaxation
14201        of the sequence by the linker, the .loc might point inside an insn.
14202        Use data16 prefix instead, which doesn't have this problem.  */
14203     fputs ("\tdata16", asm_out_file);
14204   output_asm_insn
14205     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14206   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14207     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14208   else
14209     fputs (ASM_BYTE "0x66\n", asm_out_file);
14210   fputs ("\trex64\n", asm_out_file);
14211   if (TARGET_SUN_TLS)
14212     return "call\t%p2@plt";
14213   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14214     return "call\t%P2";
14215   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14217   [(set_attr "type" "multi")
14218    (set (attr "length")
14219         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14221 (define_insn "*tls_global_dynamic_64_largepic"
14222   [(set (match_operand:DI 0 "register_operand" "=a")
14223         (call:DI
14224          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14225                           (match_operand:DI 3 "immediate_operand" "i")))
14226          (match_operand 4)))
14227    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14228                (reg:DI SP_REG)]
14229               UNSPEC_TLS_GD)]
14230   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14231    && GET_CODE (operands[3]) == CONST
14232    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14233    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14235   output_asm_insn
14236     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14237   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14238   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14239   return "call\t{*%%rax|rax}";
14241   [(set_attr "type" "multi")
14242    (set_attr "length" "22")])
14244 (define_expand "tls_global_dynamic_64_<mode>"
14245   [(parallel
14246     [(set (match_operand:P 0 "register_operand")
14247           (call:P
14248            (mem:QI (match_operand 2))
14249            (const_int 0)))
14250      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14251                 (reg:P SP_REG)]
14252                UNSPEC_TLS_GD)])]
14253   "TARGET_64BIT"
14254   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14256 (define_insn "*tls_local_dynamic_base_32_gnu"
14257   [(set (match_operand:SI 0 "register_operand" "=a")
14258         (unspec:SI
14259          [(match_operand:SI 1 "register_operand" "Yb")
14260           (match_operand 2 "constant_call_address_operand" "Bz")
14261           (reg:SI SP_REG)]
14262          UNSPEC_TLS_LD_BASE))
14263    (clobber (match_scratch:SI 3 "=d"))
14264    (clobber (match_scratch:SI 4 "=c"))
14265    (clobber (reg:CC FLAGS_REG))]
14266   "!TARGET_64BIT && TARGET_GNU_TLS"
14268   output_asm_insn
14269     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14270   if (TARGET_SUN_TLS)
14271     {
14272       if (HAVE_AS_IX86_TLSLDMPLT)
14273         return "call\t%&@tlsldmplt";
14274       else
14275         return "call\t%p2@plt";
14276     }
14277   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14278     return "call\t%P2";
14279   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14281   [(set_attr "type" "multi")
14282    (set_attr "length" "11")])
14284 (define_expand "tls_local_dynamic_base_32"
14285   [(parallel
14286      [(set (match_operand:SI 0 "register_operand")
14287            (unspec:SI
14288             [(match_operand:SI 1 "register_operand")
14289              (match_operand 2 "constant_call_address_operand")
14290              (reg:SI SP_REG)]
14291             UNSPEC_TLS_LD_BASE))
14292       (clobber (match_scratch:SI 3))
14293       (clobber (match_scratch:SI 4))
14294       (clobber (reg:CC FLAGS_REG))])]
14295   ""
14296   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14298 (define_insn "*tls_local_dynamic_base_64_<mode>"
14299   [(set (match_operand:P 0 "register_operand" "=a")
14300         (call:P
14301          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14302          (match_operand 2)))
14303    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14304   "TARGET_64BIT"
14306   output_asm_insn
14307     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14308   if (TARGET_SUN_TLS)
14309     return "call\t%p1@plt";
14310   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14311     return "call\t%P1";
14312   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14314   [(set_attr "type" "multi")
14315    (set_attr "length" "12")])
14317 (define_insn "*tls_local_dynamic_base_64_largepic"
14318   [(set (match_operand:DI 0 "register_operand" "=a")
14319         (call:DI
14320          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14321                           (match_operand:DI 2 "immediate_operand" "i")))
14322          (match_operand 3)))
14323    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14324   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14325    && GET_CODE (operands[2]) == CONST
14326    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14327    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14329   output_asm_insn
14330     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14331   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14332   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14333   return "call\t{*%%rax|rax}";
14335   [(set_attr "type" "multi")
14336    (set_attr "length" "22")])
14338 (define_expand "tls_local_dynamic_base_64_<mode>"
14339   [(parallel
14340      [(set (match_operand:P 0 "register_operand")
14341            (call:P
14342             (mem:QI (match_operand 1))
14343             (const_int 0)))
14344       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14345   "TARGET_64BIT"
14346   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14348 ;; Local dynamic of a single variable is a lose.  Show combine how
14349 ;; to convert that back to global dynamic.
14351 (define_insn_and_split "*tls_local_dynamic_32_once"
14352   [(set (match_operand:SI 0 "register_operand" "=a")
14353         (plus:SI
14354          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14355                      (match_operand 2 "constant_call_address_operand" "Bz")
14356                      (reg:SI SP_REG)]
14357                     UNSPEC_TLS_LD_BASE)
14358          (const:SI (unspec:SI
14359                     [(match_operand 3 "tls_symbolic_operand")]
14360                     UNSPEC_DTPOFF))))
14361    (clobber (match_scratch:SI 4 "=d"))
14362    (clobber (match_scratch:SI 5 "=c"))
14363    (clobber (reg:CC FLAGS_REG))]
14364   ""
14365   "#"
14366   ""
14367   [(parallel
14368      [(set (match_dup 0)
14369            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14370                        (reg:SI SP_REG)]
14371                       UNSPEC_TLS_GD))
14372       (clobber (match_dup 4))
14373       (clobber (match_dup 5))
14374       (clobber (reg:CC FLAGS_REG))])])
14376 ;; Load and add the thread base pointer from %<tp_seg>:0.
14377 (define_insn_and_split "*load_tp_<mode>"
14378   [(set (match_operand:PTR 0 "register_operand" "=r")
14379         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14380   ""
14381   "#"
14382   ""
14383   [(set (match_dup 0)
14384         (match_dup 1))]
14386   addr_space_t as = DEFAULT_TLS_SEG_REG;
14388   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14389   set_mem_addr_space (operands[1], as);
14392 (define_insn_and_split "*load_tp_x32_zext"
14393   [(set (match_operand:DI 0 "register_operand" "=r")
14394         (zero_extend:DI
14395           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14396   "TARGET_X32"
14397   "#"
14398   ""
14399   [(set (match_dup 0)
14400         (zero_extend:DI (match_dup 1)))]
14402   addr_space_t as = DEFAULT_TLS_SEG_REG;
14404   operands[1] = gen_const_mem (SImode, const0_rtx);
14405   set_mem_addr_space (operands[1], as);
14408 (define_insn_and_split "*add_tp_<mode>"
14409   [(set (match_operand:PTR 0 "register_operand" "=r")
14410         (plus:PTR
14411           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14412           (match_operand:PTR 1 "register_operand" "0")))
14413    (clobber (reg:CC FLAGS_REG))]
14414   ""
14415   "#"
14416   ""
14417   [(parallel
14418      [(set (match_dup 0)
14419            (plus:PTR (match_dup 1) (match_dup 2)))
14420       (clobber (reg:CC FLAGS_REG))])]
14422   addr_space_t as = DEFAULT_TLS_SEG_REG;
14424   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14425   set_mem_addr_space (operands[2], as);
14428 (define_insn_and_split "*add_tp_x32_zext"
14429   [(set (match_operand:DI 0 "register_operand" "=r")
14430         (zero_extend:DI
14431           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14432                    (match_operand:SI 1 "register_operand" "0"))))
14433    (clobber (reg:CC FLAGS_REG))]
14434   "TARGET_X32"
14435   "#"
14436   ""
14437   [(parallel
14438      [(set (match_dup 0)
14439            (zero_extend:DI
14440              (plus:SI (match_dup 1) (match_dup 2))))
14441       (clobber (reg:CC FLAGS_REG))])]
14443   addr_space_t as = DEFAULT_TLS_SEG_REG;
14445   operands[2] = gen_const_mem (SImode, const0_rtx);
14446   set_mem_addr_space (operands[2], as);
14449 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14450 ;; %rax as destination of the initial executable code sequence.
14451 (define_insn "tls_initial_exec_64_sun"
14452   [(set (match_operand:DI 0 "register_operand" "=a")
14453         (unspec:DI
14454          [(match_operand 1 "tls_symbolic_operand")]
14455          UNSPEC_TLS_IE_SUN))
14456    (clobber (reg:CC FLAGS_REG))]
14457   "TARGET_64BIT && TARGET_SUN_TLS"
14459   output_asm_insn
14460     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14461   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14463   [(set_attr "type" "multi")])
14465 ;; GNU2 TLS patterns can be split.
14467 (define_expand "tls_dynamic_gnu2_32"
14468   [(set (match_dup 3)
14469         (plus:SI (match_operand:SI 2 "register_operand")
14470                  (const:SI
14471                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14472                              UNSPEC_TLSDESC))))
14473    (parallel
14474     [(set (match_operand:SI 0 "register_operand")
14475           (unspec:SI [(match_dup 1) (match_dup 3)
14476                       (match_dup 2) (reg:SI SP_REG)]
14477                       UNSPEC_TLSDESC))
14478      (clobber (reg:CC FLAGS_REG))])]
14479   "!TARGET_64BIT && TARGET_GNU2_TLS"
14481   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14482   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14485 (define_insn "*tls_dynamic_gnu2_lea_32"
14486   [(set (match_operand:SI 0 "register_operand" "=r")
14487         (plus:SI (match_operand:SI 1 "register_operand" "b")
14488                  (const:SI
14489                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14490                               UNSPEC_TLSDESC))))]
14491   "!TARGET_64BIT && TARGET_GNU2_TLS"
14492   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14493   [(set_attr "type" "lea")
14494    (set_attr "mode" "SI")
14495    (set_attr "length" "6")
14496    (set_attr "length_address" "4")])
14498 (define_insn "*tls_dynamic_gnu2_call_32"
14499   [(set (match_operand:SI 0 "register_operand" "=a")
14500         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14501                     (match_operand:SI 2 "register_operand" "0")
14502                     ;; we have to make sure %ebx still points to the GOT
14503                     (match_operand:SI 3 "register_operand" "b")
14504                     (reg:SI SP_REG)]
14505                    UNSPEC_TLSDESC))
14506    (clobber (reg:CC FLAGS_REG))]
14507   "!TARGET_64BIT && TARGET_GNU2_TLS"
14508   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14509   [(set_attr "type" "call")
14510    (set_attr "length" "2")
14511    (set_attr "length_address" "0")])
14513 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14514   [(set (match_operand:SI 0 "register_operand" "=&a")
14515         (plus:SI
14516          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14517                      (match_operand:SI 4)
14518                      (match_operand:SI 2 "register_operand" "b")
14519                      (reg:SI SP_REG)]
14520                     UNSPEC_TLSDESC)
14521          (const:SI (unspec:SI
14522                     [(match_operand 1 "tls_symbolic_operand")]
14523                     UNSPEC_DTPOFF))))
14524    (clobber (reg:CC FLAGS_REG))]
14525   "!TARGET_64BIT && TARGET_GNU2_TLS"
14526   "#"
14527   ""
14528   [(set (match_dup 0) (match_dup 5))]
14530   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14531   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14534 (define_expand "tls_dynamic_gnu2_64"
14535   [(set (match_dup 2)
14536         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14537                    UNSPEC_TLSDESC))
14538    (parallel
14539     [(set (match_operand:DI 0 "register_operand")
14540           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14541                      UNSPEC_TLSDESC))
14542      (clobber (reg:CC FLAGS_REG))])]
14543   "TARGET_64BIT && TARGET_GNU2_TLS"
14545   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14546   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14549 (define_insn "*tls_dynamic_gnu2_lea_64"
14550   [(set (match_operand:DI 0 "register_operand" "=r")
14551         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14552                    UNSPEC_TLSDESC))]
14553   "TARGET_64BIT && TARGET_GNU2_TLS"
14554   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14555   [(set_attr "type" "lea")
14556    (set_attr "mode" "DI")
14557    (set_attr "length" "7")
14558    (set_attr "length_address" "4")])
14560 (define_insn "*tls_dynamic_gnu2_call_64"
14561   [(set (match_operand:DI 0 "register_operand" "=a")
14562         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14563                     (match_operand:DI 2 "register_operand" "0")
14564                     (reg:DI SP_REG)]
14565                    UNSPEC_TLSDESC))
14566    (clobber (reg:CC FLAGS_REG))]
14567   "TARGET_64BIT && TARGET_GNU2_TLS"
14568   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14569   [(set_attr "type" "call")
14570    (set_attr "length" "2")
14571    (set_attr "length_address" "0")])
14573 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14574   [(set (match_operand:DI 0 "register_operand" "=&a")
14575         (plus:DI
14576          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14577                      (match_operand:DI 3)
14578                      (reg:DI SP_REG)]
14579                     UNSPEC_TLSDESC)
14580          (const:DI (unspec:DI
14581                     [(match_operand 1 "tls_symbolic_operand")]
14582                     UNSPEC_DTPOFF))))
14583    (clobber (reg:CC FLAGS_REG))]
14584   "TARGET_64BIT && TARGET_GNU2_TLS"
14585   "#"
14586   ""
14587   [(set (match_dup 0) (match_dup 4))]
14589   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14590   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14593 (define_split
14594   [(match_operand 0 "tls_address_pattern")]
14595   "TARGET_TLS_DIRECT_SEG_REFS"
14596   [(match_dup 0)]
14597   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14600 ;; These patterns match the binary 387 instructions for addM3, subM3,
14601 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14602 ;; SFmode.  The first is the normal insn, the second the same insn but
14603 ;; with one operand a conversion, and the third the same insn but with
14604 ;; the other operand a conversion.  The conversion may be SFmode or
14605 ;; SImode if the target mode DFmode, but only SImode if the target mode
14606 ;; is SFmode.
14608 ;; Gcc is slightly more smart about handling normal two address instructions
14609 ;; so use special patterns for add and mull.
14611 (define_insn "*fop_xf_comm_i387"
14612   [(set (match_operand:XF 0 "register_operand" "=f")
14613         (match_operator:XF 3 "binary_fp_operator"
14614                         [(match_operand:XF 1 "register_operand" "%0")
14615                          (match_operand:XF 2 "register_operand" "f")]))]
14616   "TARGET_80387
14617    && COMMUTATIVE_ARITH_P (operands[3])"
14618   "* return output_387_binary_op (insn, operands);"
14619   [(set (attr "type")
14620         (if_then_else (match_operand:XF 3 "mult_operator")
14621            (const_string "fmul")
14622            (const_string "fop")))
14623    (set_attr "mode" "XF")])
14625 (define_insn "*fop_<mode>_comm"
14626   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14627         (match_operator:MODEF 3 "binary_fp_operator"
14628           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14629            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14630   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14631     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14632    && COMMUTATIVE_ARITH_P (operands[3])
14633    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14634   "* return output_387_binary_op (insn, operands);"
14635   [(set (attr "type")
14636         (if_then_else (eq_attr "alternative" "1,2")
14637            (if_then_else (match_operand:MODEF 3 "mult_operator")
14638               (const_string "ssemul")
14639               (const_string "sseadd"))
14640            (if_then_else (match_operand:MODEF 3 "mult_operator")
14641               (const_string "fmul")
14642               (const_string "fop"))))
14643    (set_attr "isa" "*,noavx,avx")
14644    (set_attr "prefix" "orig,orig,vex")
14645    (set_attr "mode" "<MODE>")
14646    (set (attr "enabled")
14647      (if_then_else
14648        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14649        (if_then_else
14650          (eq_attr "alternative" "0")
14651          (symbol_ref "TARGET_MIX_SSE_I387
14652                       && X87_ENABLE_ARITH (<MODE>mode)")
14653          (const_string "*"))
14654        (if_then_else
14655          (eq_attr "alternative" "0")
14656          (symbol_ref "true")
14657          (symbol_ref "false"))))])
14659 (define_insn "*rcpsf2_sse"
14660   [(set (match_operand:SF 0 "register_operand" "=x,x")
14661         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
14662                    UNSPEC_RCP))]
14663   "TARGET_SSE && TARGET_SSE_MATH"
14664   "@
14665    %vrcpss\t{%d1, %0|%0, %d1}
14666    %vrcpss\t{%1, %d0|%d0, %1}"
14667   [(set_attr "type" "sse")
14668    (set_attr "atom_sse_attr" "rcp")
14669    (set_attr "btver2_sse_attr" "rcp")
14670    (set_attr "prefix" "maybe_vex")
14671    (set_attr "mode" "SF")])
14673 (define_insn "*fop_xf_1_i387"
14674   [(set (match_operand:XF 0 "register_operand" "=f,f")
14675         (match_operator:XF 3 "binary_fp_operator"
14676                         [(match_operand:XF 1 "register_operand" "0,f")
14677                          (match_operand:XF 2 "register_operand" "f,0")]))]
14678   "TARGET_80387
14679    && !COMMUTATIVE_ARITH_P (operands[3])"
14680   "* return output_387_binary_op (insn, operands);"
14681   [(set (attr "type")
14682         (if_then_else (match_operand:XF 3 "div_operator")
14683            (const_string "fdiv")
14684            (const_string "fop")))
14685    (set_attr "mode" "XF")])
14687 (define_insn "*fop_<mode>_1"
14688   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14689         (match_operator:MODEF 3 "binary_fp_operator"
14690           [(match_operand:MODEF 1
14691              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14692            (match_operand:MODEF 2
14693              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14694   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14695     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14696    && !COMMUTATIVE_ARITH_P (operands[3])
14697    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14698   "* return output_387_binary_op (insn, operands);"
14699   [(set (attr "type")
14700         (if_then_else (eq_attr "alternative" "2,3")
14701            (if_then_else (match_operand:MODEF 3 "div_operator")
14702               (const_string "ssediv")
14703               (const_string "sseadd"))
14704            (if_then_else (match_operand:MODEF 3 "div_operator")
14705               (const_string "fdiv")
14706               (const_string "fop"))))
14707    (set_attr "isa" "*,*,noavx,avx")
14708    (set_attr "prefix" "orig,orig,orig,vex")
14709    (set_attr "mode" "<MODE>")
14710    (set (attr "enabled")
14711      (if_then_else
14712        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14713        (if_then_else
14714          (eq_attr "alternative" "0,1")
14715          (symbol_ref "TARGET_MIX_SSE_I387
14716                       && X87_ENABLE_ARITH (<MODE>mode)")
14717          (const_string "*"))
14718        (if_then_else
14719          (eq_attr "alternative" "0,1")
14720          (symbol_ref "true")
14721          (symbol_ref "false"))))])
14723 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14724   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14725         (match_operator:X87MODEF 3 "binary_fp_operator"
14726           [(float:X87MODEF
14727              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14728            (match_operand:X87MODEF 2 "register_operand" "0")]))]
14729   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14730    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14731    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14732        || optimize_function_for_size_p (cfun))"
14733   "* return output_387_binary_op (insn, operands);"
14734   [(set (attr "type")
14735         (cond [(match_operand:X87MODEF 3 "mult_operator")
14736                  (const_string "fmul")
14737                (match_operand:X87MODEF 3 "div_operator")
14738                  (const_string "fdiv")
14739               ]
14740               (const_string "fop")))
14741    (set_attr "fp_int_src" "true")
14742    (set_attr "mode" "<SWI24:MODE>")])
14744 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14745   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14746         (match_operator:X87MODEF 3 "binary_fp_operator"
14747           [(match_operand:X87MODEF 1 "register_operand" "0")
14748            (float:X87MODEF
14749              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14750   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14751    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14752    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14753        || optimize_function_for_size_p (cfun))"
14754   "* return output_387_binary_op (insn, operands);"
14755   [(set (attr "type")
14756         (cond [(match_operand:X87MODEF 3 "mult_operator")
14757                  (const_string "fmul")
14758                (match_operand:X87MODEF 3 "div_operator")
14759                  (const_string "fdiv")
14760               ]
14761               (const_string "fop")))
14762    (set_attr "fp_int_src" "true")
14763    (set_attr "mode" "<MODE>")])
14765 (define_insn "*fop_xf_4_i387"
14766   [(set (match_operand:XF 0 "register_operand" "=f,f")
14767         (match_operator:XF 3 "binary_fp_operator"
14768            [(float_extend:XF
14769               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14770             (match_operand:XF 2 "register_operand" "0,f")]))]
14771   "TARGET_80387"
14772   "* return output_387_binary_op (insn, operands);"
14773   [(set (attr "type")
14774         (cond [(match_operand:XF 3 "mult_operator")
14775                  (const_string "fmul")
14776                (match_operand:XF 3 "div_operator")
14777                  (const_string "fdiv")
14778               ]
14779               (const_string "fop")))
14780    (set_attr "mode" "<MODE>")])
14782 (define_insn "*fop_df_4_i387"
14783   [(set (match_operand:DF 0 "register_operand" "=f,f")
14784         (match_operator:DF 3 "binary_fp_operator"
14785            [(float_extend:DF
14786              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14787             (match_operand:DF 2 "register_operand" "0,f")]))]
14788   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14789    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14790   "* return output_387_binary_op (insn, operands);"
14791   [(set (attr "type")
14792         (cond [(match_operand:DF 3 "mult_operator")
14793                  (const_string "fmul")
14794                (match_operand:DF 3 "div_operator")
14795                  (const_string "fdiv")
14796               ]
14797               (const_string "fop")))
14798    (set_attr "mode" "SF")])
14800 (define_insn "*fop_xf_5_i387"
14801   [(set (match_operand:XF 0 "register_operand" "=f,f")
14802         (match_operator:XF 3 "binary_fp_operator"
14803           [(match_operand:XF 1 "register_operand" "0,f")
14804            (float_extend:XF
14805              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14806   "TARGET_80387"
14807   "* return output_387_binary_op (insn, operands);"
14808   [(set (attr "type")
14809         (cond [(match_operand:XF 3 "mult_operator")
14810                  (const_string "fmul")
14811                (match_operand:XF 3 "div_operator")
14812                  (const_string "fdiv")
14813               ]
14814               (const_string "fop")))
14815    (set_attr "mode" "<MODE>")])
14817 (define_insn "*fop_df_5_i387"
14818   [(set (match_operand:DF 0 "register_operand" "=f,f")
14819         (match_operator:DF 3 "binary_fp_operator"
14820           [(match_operand:DF 1 "register_operand" "0,f")
14821            (float_extend:DF
14822             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14823   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14824    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14825   "* return output_387_binary_op (insn, operands);"
14826   [(set (attr "type")
14827         (cond [(match_operand:DF 3 "mult_operator")
14828                  (const_string "fmul")
14829                (match_operand:DF 3 "div_operator")
14830                  (const_string "fdiv")
14831               ]
14832               (const_string "fop")))
14833    (set_attr "mode" "SF")])
14835 (define_insn "*fop_xf_6_i387"
14836   [(set (match_operand:XF 0 "register_operand" "=f,f")
14837         (match_operator:XF 3 "binary_fp_operator"
14838           [(float_extend:XF
14839              (match_operand:MODEF 1 "register_operand" "0,f"))
14840            (float_extend:XF
14841              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14842   "TARGET_80387"
14843   "* return output_387_binary_op (insn, operands);"
14844   [(set (attr "type")
14845         (cond [(match_operand:XF 3 "mult_operator")
14846                  (const_string "fmul")
14847                (match_operand:XF 3 "div_operator")
14848                  (const_string "fdiv")
14849               ]
14850               (const_string "fop")))
14851    (set_attr "mode" "<MODE>")])
14853 (define_insn "*fop_df_6_i387"
14854   [(set (match_operand:DF 0 "register_operand" "=f,f")
14855         (match_operator:DF 3 "binary_fp_operator"
14856           [(float_extend:DF
14857             (match_operand:SF 1 "register_operand" "0,f"))
14858            (float_extend:DF
14859             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14860   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14861    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14862   "* return output_387_binary_op (insn, operands);"
14863   [(set (attr "type")
14864         (cond [(match_operand:DF 3 "mult_operator")
14865                  (const_string "fmul")
14866                (match_operand:DF 3 "div_operator")
14867                  (const_string "fdiv")
14868               ]
14869               (const_string "fop")))
14870    (set_attr "mode" "SF")])
14872 ;; FPU special functions.
14874 ;; This pattern implements a no-op XFmode truncation for
14875 ;; all fancy i386 XFmode math functions.
14877 (define_insn "truncxf<mode>2_i387_noop_unspec"
14878   [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14879         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14880         UNSPEC_TRUNC_NOOP))]
14881   "TARGET_USE_FANCY_MATH_387"
14882   "* return output_387_reg_move (insn, operands);"
14883   [(set_attr "type" "fmov")
14884    (set_attr "mode" "<MODE>")])
14886 (define_insn "sqrtxf2"
14887   [(set (match_operand:XF 0 "register_operand" "=f")
14888         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14889   "TARGET_USE_FANCY_MATH_387"
14890   "fsqrt"
14891   [(set_attr "type" "fpspc")
14892    (set_attr "mode" "XF")
14893    (set_attr "athlon_decode" "direct")
14894    (set_attr "amdfam10_decode" "direct")
14895    (set_attr "bdver1_decode" "direct")])
14897 (define_insn "*rsqrtsf2_sse"
14898   [(set (match_operand:SF 0 "register_operand" "=x,x")
14899         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
14900                    UNSPEC_RSQRT))]
14901   "TARGET_SSE && TARGET_SSE_MATH"
14902   "@
14903    %vrsqrtss\t{%d1, %0|%0, %d1}
14904    %vrsqrtss\t{%1, %d0|%d0, %1}"
14905   [(set_attr "type" "sse")
14906    (set_attr "atom_sse_attr" "rcp")
14907    (set_attr "btver2_sse_attr" "rcp")
14908    (set_attr "prefix" "maybe_vex")
14909    (set_attr "mode" "SF")])
14911 (define_expand "rsqrtsf2"
14912   [(set (match_operand:SF 0 "register_operand")
14913         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14914                    UNSPEC_RSQRT))]
14915   "TARGET_SSE && TARGET_SSE_MATH"
14917   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14918   DONE;
14921 (define_insn "*sqrt<mode>2_sse"
14922   [(set (match_operand:MODEF 0 "register_operand" "=v,v")
14923         (sqrt:MODEF
14924           (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
14925   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14926   "@
14927    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14928    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14929   [(set_attr "type" "sse")
14930    (set_attr "atom_sse_attr" "sqrt")
14931    (set_attr "btver2_sse_attr" "sqrt")
14932    (set_attr "prefix" "maybe_vex")
14933    (set_attr "mode" "<MODE>")
14934    (set_attr "athlon_decode" "*")
14935    (set_attr "amdfam10_decode" "*")
14936    (set_attr "bdver1_decode" "*")])
14938 (define_expand "sqrt<mode>2"
14939   [(set (match_operand:MODEF 0 "register_operand")
14940         (sqrt:MODEF
14941           (match_operand:MODEF 1 "nonimmediate_operand")))]
14942   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14943    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14945   if (<MODE>mode == SFmode
14946       && TARGET_SSE && TARGET_SSE_MATH
14947       && TARGET_RECIP_SQRT
14948       && !optimize_function_for_size_p (cfun)
14949       && flag_finite_math_only && !flag_trapping_math
14950       && flag_unsafe_math_optimizations)
14951     {
14952       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14953       DONE;
14954     }
14956   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14957     {
14958       rtx op0 = gen_reg_rtx (XFmode);
14959       rtx op1 = gen_reg_rtx (XFmode);
14961       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14962       emit_insn (gen_sqrtxf2 (op0, op1));
14963       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14964       DONE;
14965    }
14968 (define_insn "x86_fnstsw_1"
14969   [(set (match_operand:HI 0 "register_operand" "=a")
14970         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
14971   "TARGET_80387"
14972   "fnstsw\t%0"
14973   [(set_attr "length" "2")
14974    (set_attr "mode" "SI")
14975    (set_attr "unit" "i387")])
14977 (define_insn "fpremxf4_i387"
14978   [(set (match_operand:XF 0 "register_operand" "=f")
14979         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14980                     (match_operand:XF 3 "register_operand" "1")]
14981                    UNSPEC_FPREM_F))
14982    (set (match_operand:XF 1 "register_operand" "=f")
14983         (unspec:XF [(match_dup 2) (match_dup 3)]
14984                    UNSPEC_FPREM_U))
14985    (set (reg:CCFP FPSR_REG)
14986         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14987                      UNSPEC_C2_FLAG))]
14988   "TARGET_USE_FANCY_MATH_387
14989    && flag_finite_math_only"
14990   "fprem"
14991   [(set_attr "type" "fpspc")
14992    (set_attr "znver1_decode" "vector")
14993    (set_attr "mode" "XF")])
14995 (define_expand "fmodxf3"
14996   [(use (match_operand:XF 0 "register_operand"))
14997    (use (match_operand:XF 1 "general_operand"))
14998    (use (match_operand:XF 2 "general_operand"))]
14999   "TARGET_USE_FANCY_MATH_387
15000    && flag_finite_math_only"
15002   rtx_code_label *label = gen_label_rtx ();
15004   rtx op1 = gen_reg_rtx (XFmode);
15005   rtx op2 = gen_reg_rtx (XFmode);
15007   emit_move_insn (op2, operands[2]);
15008   emit_move_insn (op1, operands[1]);
15010   emit_label (label);
15011   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15012   ix86_emit_fp_unordered_jump (label);
15013   LABEL_NUSES (label) = 1;
15015   emit_move_insn (operands[0], op1);
15016   DONE;
15019 (define_expand "fmod<mode>3"
15020   [(use (match_operand:MODEF 0 "register_operand"))
15021    (use (match_operand:MODEF 1 "general_operand"))
15022    (use (match_operand:MODEF 2 "general_operand"))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && flag_finite_math_only"
15026   rtx (*gen_truncxf) (rtx, rtx);
15028   rtx_code_label *label = gen_label_rtx ();
15030   rtx op1 = gen_reg_rtx (XFmode);
15031   rtx op2 = gen_reg_rtx (XFmode);
15033   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15034   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15036   emit_label (label);
15037   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15038   ix86_emit_fp_unordered_jump (label);
15039   LABEL_NUSES (label) = 1;
15041   /* Truncate the result properly for strict SSE math.  */
15042   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15043       && !TARGET_MIX_SSE_I387)
15044     gen_truncxf = gen_truncxf<mode>2;
15045   else
15046     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15048   emit_insn (gen_truncxf (operands[0], op1));
15049   DONE;
15052 (define_insn "fprem1xf4_i387"
15053   [(set (match_operand:XF 0 "register_operand" "=f")
15054         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15055                     (match_operand:XF 3 "register_operand" "1")]
15056                    UNSPEC_FPREM1_F))
15057    (set (match_operand:XF 1 "register_operand" "=f")
15058         (unspec:XF [(match_dup 2) (match_dup 3)]
15059                    UNSPEC_FPREM1_U))
15060    (set (reg:CCFP FPSR_REG)
15061         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15062                      UNSPEC_C2_FLAG))]
15063   "TARGET_USE_FANCY_MATH_387
15064    && flag_finite_math_only"
15065   "fprem1"
15066   [(set_attr "type" "fpspc")
15067    (set_attr "znver1_decode" "vector")
15068    (set_attr "mode" "XF")])
15070 (define_expand "remainderxf3"
15071   [(use (match_operand:XF 0 "register_operand"))
15072    (use (match_operand:XF 1 "general_operand"))
15073    (use (match_operand:XF 2 "general_operand"))]
15074   "TARGET_USE_FANCY_MATH_387
15075    && flag_finite_math_only"
15077   rtx_code_label *label = gen_label_rtx ();
15079   rtx op1 = gen_reg_rtx (XFmode);
15080   rtx op2 = gen_reg_rtx (XFmode);
15082   emit_move_insn (op2, operands[2]);
15083   emit_move_insn (op1, operands[1]);
15085   emit_label (label);
15086   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15087   ix86_emit_fp_unordered_jump (label);
15088   LABEL_NUSES (label) = 1;
15090   emit_move_insn (operands[0], op1);
15091   DONE;
15094 (define_expand "remainder<mode>3"
15095   [(use (match_operand:MODEF 0 "register_operand"))
15096    (use (match_operand:MODEF 1 "general_operand"))
15097    (use (match_operand:MODEF 2 "general_operand"))]
15098   "TARGET_USE_FANCY_MATH_387
15099    && flag_finite_math_only"
15101   rtx (*gen_truncxf) (rtx, rtx);
15103   rtx_code_label *label = gen_label_rtx ();
15105   rtx op1 = gen_reg_rtx (XFmode);
15106   rtx op2 = gen_reg_rtx (XFmode);
15108   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15109   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15111   emit_label (label);
15113   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15114   ix86_emit_fp_unordered_jump (label);
15115   LABEL_NUSES (label) = 1;
15117   /* Truncate the result properly for strict SSE math.  */
15118   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15119       && !TARGET_MIX_SSE_I387)
15120     gen_truncxf = gen_truncxf<mode>2;
15121   else
15122     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15124   emit_insn (gen_truncxf (operands[0], op1));
15125   DONE;
15128 (define_int_iterator SINCOS
15129         [UNSPEC_SIN
15130          UNSPEC_COS])
15132 (define_int_attr sincos
15133         [(UNSPEC_SIN "sin")
15134          (UNSPEC_COS "cos")])
15136 (define_insn "<sincos>xf2"
15137   [(set (match_operand:XF 0 "register_operand" "=f")
15138         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15139                    SINCOS))]
15140   "TARGET_USE_FANCY_MATH_387
15141    && flag_unsafe_math_optimizations"
15142   "f<sincos>"
15143   [(set_attr "type" "fpspc")
15144    (set_attr "znver1_decode" "vector")
15145    (set_attr "mode" "XF")])
15147 (define_expand "<sincos><mode>2"
15148   [(set (match_operand:MODEF 0 "register_operand")
15149         (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15150                       SINCOS))]
15151   "TARGET_USE_FANCY_MATH_387
15152    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15153        || TARGET_MIX_SSE_I387)
15154    && flag_unsafe_math_optimizations"
15156   rtx op0 = gen_reg_rtx (XFmode);
15157   rtx op1 = gen_reg_rtx (XFmode);
15159   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15160   emit_insn (gen_<sincos>xf2 (op0, op1));
15161   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15162   DONE;
15165 (define_insn "sincosxf3"
15166   [(set (match_operand:XF 0 "register_operand" "=f")
15167         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15168                    UNSPEC_SINCOS_COS))
15169    (set (match_operand:XF 1 "register_operand" "=f")
15170         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15171   "TARGET_USE_FANCY_MATH_387
15172    && flag_unsafe_math_optimizations"
15173   "fsincos"
15174   [(set_attr "type" "fpspc")
15175    (set_attr "znver1_decode" "vector")
15176    (set_attr "mode" "XF")])
15178 (define_expand "sincos<mode>3"
15179   [(use (match_operand:MODEF 0 "register_operand"))
15180    (use (match_operand:MODEF 1 "register_operand"))
15181    (use (match_operand:MODEF 2 "general_operand"))]
15182   "TARGET_USE_FANCY_MATH_387
15183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184        || TARGET_MIX_SSE_I387)
15185    && flag_unsafe_math_optimizations"
15187   rtx op0 = gen_reg_rtx (XFmode);
15188   rtx op1 = gen_reg_rtx (XFmode);
15189   rtx op2 = gen_reg_rtx (XFmode);
15191   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15192   emit_insn (gen_sincosxf3 (op0, op1, op2));
15193   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15194   emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15195   DONE;
15198 (define_insn "fptanxf4_i387"
15199   [(set (match_operand:SF 0 "register_operand" "=f")
15200         (match_operand:SF 3 "const1_operand"))
15201    (set (match_operand:XF 1 "register_operand" "=f")
15202         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15203                    UNSPEC_TAN))]
15204   "TARGET_USE_FANCY_MATH_387
15205    && flag_unsafe_math_optimizations"
15206   "fptan"
15207   [(set_attr "type" "fpspc")
15208    (set_attr "znver1_decode" "vector")
15209    (set_attr "mode" "XF")])
15211 (define_expand "tanxf2"
15212   [(use (match_operand:XF 0 "register_operand"))
15213    (use (match_operand:XF 1 "register_operand"))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && flag_unsafe_math_optimizations"
15217   rtx one = gen_reg_rtx (SFmode);
15218   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15219                                 CONST1_RTX (SFmode)));
15220   DONE;
15223 (define_expand "tan<mode>2"
15224   [(use (match_operand:MODEF 0 "register_operand"))
15225    (use (match_operand:MODEF 1 "general_operand"))]
15226   "TARGET_USE_FANCY_MATH_387
15227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15228        || TARGET_MIX_SSE_I387)
15229    && flag_unsafe_math_optimizations"
15231   rtx op0 = gen_reg_rtx (XFmode);
15232   rtx op1 = gen_reg_rtx (XFmode);
15234   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15235   emit_insn (gen_tanxf2 (op0, op1));
15236   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15237   DONE;
15240 (define_insn "atan2xf3"
15241   [(set (match_operand:XF 0 "register_operand" "=f")
15242         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15243                     (match_operand:XF 2 "register_operand" "f")]
15244                    UNSPEC_FPATAN))
15245    (clobber (match_scratch:XF 3 "=2"))]
15246   "TARGET_USE_FANCY_MATH_387
15247    && flag_unsafe_math_optimizations"
15248   "fpatan"
15249   [(set_attr "type" "fpspc")
15250    (set_attr "znver1_decode" "vector")
15251    (set_attr "mode" "XF")])
15253 (define_expand "atan2<mode>3"
15254   [(use (match_operand:MODEF 0 "register_operand"))
15255    (use (match_operand:MODEF 1 "general_operand"))
15256    (use (match_operand:MODEF 2 "general_operand"))]
15257   "TARGET_USE_FANCY_MATH_387
15258    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15259        || TARGET_MIX_SSE_I387)
15260    && flag_unsafe_math_optimizations"
15262   rtx op0 = gen_reg_rtx (XFmode);
15263   rtx op1 = gen_reg_rtx (XFmode);
15264   rtx op2 = gen_reg_rtx (XFmode);
15266   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15267   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15269   emit_insn (gen_atan2xf3 (op0, op2, op1));
15270   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15271   DONE;
15274 (define_expand "atanxf2"
15275   [(parallel [(set (match_operand:XF 0 "register_operand")
15276                    (unspec:XF [(match_dup 2)
15277                                (match_operand:XF 1 "register_operand")]
15278                               UNSPEC_FPATAN))
15279               (clobber (match_scratch:XF 3))])]
15280   "TARGET_USE_FANCY_MATH_387
15281    && flag_unsafe_math_optimizations"
15282   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15284 (define_expand "atan<mode>2"
15285   [(use (match_operand:MODEF 0 "register_operand"))
15286    (use (match_operand:MODEF 1 "general_operand"))]
15287   "TARGET_USE_FANCY_MATH_387
15288    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15289        || TARGET_MIX_SSE_I387)
15290    && flag_unsafe_math_optimizations"
15292   rtx op0 = gen_reg_rtx (XFmode);
15293   rtx op1 = gen_reg_rtx (XFmode);
15295   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15296   emit_insn (gen_atanxf2 (op0, op1));
15297   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15298   DONE;
15301 (define_expand "asinxf2"
15302   [(set (match_dup 2)
15303         (mult:XF (match_operand:XF 1 "register_operand")
15304                  (match_dup 1)))
15305    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15306    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15307    (parallel [(set (match_operand:XF 0 "register_operand")
15308                    (unspec:XF [(match_dup 5) (match_dup 1)]
15309                               UNSPEC_FPATAN))
15310               (clobber (match_scratch:XF 6))])]
15311   "TARGET_USE_FANCY_MATH_387
15312    && flag_unsafe_math_optimizations"
15314   int i;
15316   for (i = 2; i < 6; i++)
15317     operands[i] = gen_reg_rtx (XFmode);
15319   emit_move_insn (operands[3], CONST1_RTX (XFmode));
15322 (define_expand "asin<mode>2"
15323   [(use (match_operand:MODEF 0 "register_operand"))
15324    (use (match_operand:MODEF 1 "general_operand"))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15327        || TARGET_MIX_SSE_I387)
15328    && flag_unsafe_math_optimizations"
15330   rtx op0 = gen_reg_rtx (XFmode);
15331   rtx op1 = gen_reg_rtx (XFmode);
15333   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15334   emit_insn (gen_asinxf2 (op0, op1));
15335   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15336   DONE;
15339 (define_expand "acosxf2"
15340   [(set (match_dup 2)
15341         (mult:XF (match_operand:XF 1 "register_operand")
15342                  (match_dup 1)))
15343    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15344    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15345    (parallel [(set (match_operand:XF 0 "register_operand")
15346                    (unspec:XF [(match_dup 1) (match_dup 5)]
15347                               UNSPEC_FPATAN))
15348               (clobber (match_scratch:XF 6))])]
15349   "TARGET_USE_FANCY_MATH_387
15350    && flag_unsafe_math_optimizations"
15352   int i;
15354   for (i = 2; i < 6; i++)
15355     operands[i] = gen_reg_rtx (XFmode);
15357   emit_move_insn (operands[3], CONST1_RTX (XFmode));
15360 (define_expand "acos<mode>2"
15361   [(use (match_operand:MODEF 0 "register_operand"))
15362    (use (match_operand:MODEF 1 "general_operand"))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15365        || TARGET_MIX_SSE_I387)
15366    && flag_unsafe_math_optimizations"
15368   rtx op0 = gen_reg_rtx (XFmode);
15369   rtx op1 = gen_reg_rtx (XFmode);
15371   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15372   emit_insn (gen_acosxf2 (op0, op1));
15373   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15374   DONE;
15377 (define_insn "fyl2xxf3_i387"
15378   [(set (match_operand:XF 0 "register_operand" "=f")
15379         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15380                     (match_operand:XF 2 "register_operand" "f")]
15381                    UNSPEC_FYL2X))
15382    (clobber (match_scratch:XF 3 "=2"))]
15383   "TARGET_USE_FANCY_MATH_387
15384    && flag_unsafe_math_optimizations"
15385   "fyl2x"
15386   [(set_attr "type" "fpspc")
15387    (set_attr "znver1_decode" "vector")
15388    (set_attr "mode" "XF")])
15390 (define_expand "logxf2"
15391   [(parallel [(set (match_operand:XF 0 "register_operand")
15392                    (unspec:XF [(match_operand:XF 1 "register_operand")
15393                                (match_dup 2)] UNSPEC_FYL2X))
15394               (clobber (match_scratch:XF 3))])]
15395   "TARGET_USE_FANCY_MATH_387
15396    && flag_unsafe_math_optimizations"
15398   operands[2]
15399     = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15402 (define_expand "log<mode>2"
15403   [(use (match_operand:MODEF 0 "register_operand"))
15404    (use (match_operand:MODEF 1 "general_operand"))]
15405   "TARGET_USE_FANCY_MATH_387
15406    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15407        || TARGET_MIX_SSE_I387)
15408    && flag_unsafe_math_optimizations"
15410   rtx op0 = gen_reg_rtx (XFmode);
15411   rtx op1 = gen_reg_rtx (XFmode);
15413   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15414   emit_insn (gen_logxf2 (op0, op1));
15415   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15416   DONE;
15419 (define_expand "log10xf2"
15420   [(parallel [(set (match_operand:XF 0 "register_operand")
15421                    (unspec:XF [(match_operand:XF 1 "register_operand")
15422                                (match_dup 2)] UNSPEC_FYL2X))
15423               (clobber (match_scratch:XF 3))])]
15424   "TARGET_USE_FANCY_MATH_387
15425    && flag_unsafe_math_optimizations"
15427   operands[2]
15428     = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15431 (define_expand "log10<mode>2"
15432   [(use (match_operand:MODEF 0 "register_operand"))
15433    (use (match_operand:MODEF 1 "general_operand"))]
15434   "TARGET_USE_FANCY_MATH_387
15435    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15436        || TARGET_MIX_SSE_I387)
15437    && flag_unsafe_math_optimizations"
15439   rtx op0 = gen_reg_rtx (XFmode);
15440   rtx op1 = gen_reg_rtx (XFmode);
15442   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15443   emit_insn (gen_log10xf2 (op0, op1));
15444   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15445   DONE;
15448 (define_expand "log2xf2"
15449   [(parallel [(set (match_operand:XF 0 "register_operand")
15450                    (unspec:XF [(match_operand:XF 1 "register_operand")
15451                                (match_dup 2)] UNSPEC_FYL2X))
15452               (clobber (match_scratch:XF 3))])]
15453   "TARGET_USE_FANCY_MATH_387
15454    && flag_unsafe_math_optimizations"
15455   "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15457 (define_expand "log2<mode>2"
15458   [(use (match_operand:MODEF 0 "register_operand"))
15459    (use (match_operand:MODEF 1 "general_operand"))]
15460   "TARGET_USE_FANCY_MATH_387
15461    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15462        || TARGET_MIX_SSE_I387)
15463    && flag_unsafe_math_optimizations"
15465   rtx op0 = gen_reg_rtx (XFmode);
15466   rtx op1 = gen_reg_rtx (XFmode);
15468   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15469   emit_insn (gen_log2xf2 (op0, op1));
15470   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15471   DONE;
15474 (define_insn "fyl2xp1xf3_i387"
15475   [(set (match_operand:XF 0 "register_operand" "=f")
15476         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15477                     (match_operand:XF 2 "register_operand" "f")]
15478                    UNSPEC_FYL2XP1))
15479    (clobber (match_scratch:XF 3 "=2"))]
15480   "TARGET_USE_FANCY_MATH_387
15481    && flag_unsafe_math_optimizations"
15482   "fyl2xp1"
15483   [(set_attr "type" "fpspc")
15484    (set_attr "znver1_decode" "vector")
15485    (set_attr "mode" "XF")])
15487 (define_expand "log1pxf2"
15488   [(use (match_operand:XF 0 "register_operand"))
15489    (use (match_operand:XF 1 "register_operand"))]
15490   "TARGET_USE_FANCY_MATH_387
15491    && flag_unsafe_math_optimizations"
15493   ix86_emit_i387_log1p (operands[0], operands[1]);
15494   DONE;
15497 (define_expand "log1p<mode>2"
15498   [(use (match_operand:MODEF 0 "register_operand"))
15499    (use (match_operand:MODEF 1 "general_operand"))]
15500   "TARGET_USE_FANCY_MATH_387
15501    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15502        || TARGET_MIX_SSE_I387)
15503    && flag_unsafe_math_optimizations"
15505   rtx op0 = gen_reg_rtx (XFmode);
15506   rtx op1 = gen_reg_rtx (XFmode);
15508   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15509   emit_insn (gen_log1pxf2 (op0, op1));
15510   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15511   DONE;
15514 (define_insn "fxtractxf3_i387"
15515   [(set (match_operand:XF 0 "register_operand" "=f")
15516         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15517                    UNSPEC_XTRACT_FRACT))
15518    (set (match_operand:XF 1 "register_operand" "=f")
15519         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15520   "TARGET_USE_FANCY_MATH_387
15521    && flag_unsafe_math_optimizations"
15522   "fxtract"
15523   [(set_attr "type" "fpspc")
15524    (set_attr "znver1_decode" "vector")
15525    (set_attr "mode" "XF")])
15527 (define_expand "logbxf2"
15528   [(parallel [(set (match_dup 2)
15529                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15530                               UNSPEC_XTRACT_FRACT))
15531               (set (match_operand:XF 0 "register_operand")
15532                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15533   "TARGET_USE_FANCY_MATH_387
15534    && flag_unsafe_math_optimizations"
15535   "operands[2] = gen_reg_rtx (XFmode);")
15537 (define_expand "logb<mode>2"
15538   [(use (match_operand:MODEF 0 "register_operand"))
15539    (use (match_operand:MODEF 1 "general_operand"))]
15540   "TARGET_USE_FANCY_MATH_387
15541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15542        || TARGET_MIX_SSE_I387)
15543    && flag_unsafe_math_optimizations"
15545   rtx op0 = gen_reg_rtx (XFmode);
15546   rtx op1 = gen_reg_rtx (XFmode);
15548   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15549   emit_insn (gen_logbxf2 (op0, op1));
15550   emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15551   DONE;
15554 (define_expand "ilogbxf2"
15555   [(use (match_operand:SI 0 "register_operand"))
15556    (use (match_operand:XF 1 "register_operand"))]
15557   "TARGET_USE_FANCY_MATH_387
15558    && flag_unsafe_math_optimizations"
15560   rtx op0, op1;
15562   if (optimize_insn_for_size_p ())
15563     FAIL;
15565   op0 = gen_reg_rtx (XFmode);
15566   op1 = gen_reg_rtx (XFmode);
15568   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15569   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15570   DONE;
15573 (define_expand "ilogb<mode>2"
15574   [(use (match_operand:SI 0 "register_operand"))
15575    (use (match_operand:MODEF 1 "general_operand"))]
15576   "TARGET_USE_FANCY_MATH_387
15577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15578        || TARGET_MIX_SSE_I387)
15579    && flag_unsafe_math_optimizations"
15581   rtx op0, op1, op2;
15583   if (optimize_insn_for_size_p ())
15584     FAIL;
15586   op0 = gen_reg_rtx (XFmode);
15587   op1 = gen_reg_rtx (XFmode);
15588   op2 = gen_reg_rtx (XFmode);
15590   emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15591   emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15592   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15593   DONE;
15596 (define_insn "*f2xm1xf2_i387"
15597   [(set (match_operand:XF 0 "register_operand" "=f")
15598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15599                    UNSPEC_F2XM1))]
15600   "TARGET_USE_FANCY_MATH_387
15601    && flag_unsafe_math_optimizations"
15602   "f2xm1"
15603   [(set_attr "type" "fpspc")
15604    (set_attr "znver1_decode" "vector")
15605    (set_attr "mode" "XF")])
15607 (define_insn "fscalexf4_i387"
15608   [(set (match_operand:XF 0 "register_operand" "=f")
15609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610                     (match_operand:XF 3 "register_operand" "1")]
15611                    UNSPEC_FSCALE_FRACT))
15612    (set (match_operand:XF 1 "register_operand" "=f")
15613         (unspec:XF [(match_dup 2) (match_dup 3)]
15614                    UNSPEC_FSCALE_EXP))]
15615   "TARGET_USE_FANCY_MATH_387
15616    && flag_unsafe_math_optimizations"
15617   "fscale"
15618   [(set_attr "type" "fpspc")
15619    (set_attr "znver1_decode" "vector")
15620    (set_attr "mode" "XF")])
15622 (define_expand "expNcorexf3"
15623   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15624                                (match_operand:XF 2 "register_operand")))
15625    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15626    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15627    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15628    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15629    (parallel [(set (match_operand:XF 0 "register_operand")
15630                    (unspec:XF [(match_dup 8) (match_dup 4)]
15631                               UNSPEC_FSCALE_FRACT))
15632               (set (match_dup 9)
15633                    (unspec:XF [(match_dup 8) (match_dup 4)]
15634                               UNSPEC_FSCALE_EXP))])]
15635   "TARGET_USE_FANCY_MATH_387
15636    && flag_unsafe_math_optimizations"
15638   int i;
15640   for (i = 3; i < 10; i++)
15641     operands[i] = gen_reg_rtx (XFmode);
15643   emit_move_insn (operands[7], CONST1_RTX (XFmode));
15646 (define_expand "expxf2"
15647   [(use (match_operand:XF 0 "register_operand"))
15648    (use (match_operand:XF 1 "register_operand"))]
15649   "TARGET_USE_FANCY_MATH_387
15650    && flag_unsafe_math_optimizations"
15652   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15654   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15655   DONE;
15658 (define_expand "exp<mode>2"
15659   [(use (match_operand:MODEF 0 "register_operand"))
15660    (use (match_operand:MODEF 1 "general_operand"))]
15661   "TARGET_USE_FANCY_MATH_387
15662    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15663        || TARGET_MIX_SSE_I387)
15664    && flag_unsafe_math_optimizations"
15666   rtx op0 = gen_reg_rtx (XFmode);
15667   rtx op1 = gen_reg_rtx (XFmode);
15669   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15670   emit_insn (gen_expxf2 (op0, op1));
15671   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15672   DONE;
15675 (define_expand "exp10xf2"
15676   [(use (match_operand:XF 0 "register_operand"))
15677    (use (match_operand:XF 1 "register_operand"))]
15678   "TARGET_USE_FANCY_MATH_387
15679    && flag_unsafe_math_optimizations"
15681   rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15683   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15684   DONE;
15687 (define_expand "exp10<mode>2"
15688   [(use (match_operand:MODEF 0 "register_operand"))
15689    (use (match_operand:MODEF 1 "general_operand"))]
15690   "TARGET_USE_FANCY_MATH_387
15691    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15692        || TARGET_MIX_SSE_I387)
15693    && flag_unsafe_math_optimizations"
15695   rtx op0 = gen_reg_rtx (XFmode);
15696   rtx op1 = gen_reg_rtx (XFmode);
15698   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15699   emit_insn (gen_exp10xf2 (op0, op1));
15700   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15701   DONE;
15704 (define_expand "exp2xf2"
15705   [(use (match_operand:XF 0 "register_operand"))
15706    (use (match_operand:XF 1 "register_operand"))]
15707   "TARGET_USE_FANCY_MATH_387
15708    && flag_unsafe_math_optimizations"
15710   rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15712   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15713   DONE;
15716 (define_expand "exp2<mode>2"
15717   [(use (match_operand:MODEF 0 "register_operand"))
15718    (use (match_operand:MODEF 1 "general_operand"))]
15719   "TARGET_USE_FANCY_MATH_387
15720    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15721        || TARGET_MIX_SSE_I387)
15722    && flag_unsafe_math_optimizations"
15724   rtx op0 = gen_reg_rtx (XFmode);
15725   rtx op1 = gen_reg_rtx (XFmode);
15727   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15728   emit_insn (gen_exp2xf2 (op0, op1));
15729   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15730   DONE;
15733 (define_expand "expm1xf2"
15734   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15735                                (match_dup 2)))
15736    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15737    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15738    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15739    (parallel [(set (match_dup 7)
15740                    (unspec:XF [(match_dup 6) (match_dup 4)]
15741                               UNSPEC_FSCALE_FRACT))
15742               (set (match_dup 8)
15743                    (unspec:XF [(match_dup 6) (match_dup 4)]
15744                               UNSPEC_FSCALE_EXP))])
15745    (parallel [(set (match_dup 10)
15746                    (unspec:XF [(match_dup 9) (match_dup 8)]
15747                               UNSPEC_FSCALE_FRACT))
15748               (set (match_dup 11)
15749                    (unspec:XF [(match_dup 9) (match_dup 8)]
15750                               UNSPEC_FSCALE_EXP))])
15751    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15752    (set (match_operand:XF 0 "register_operand")
15753         (plus:XF (match_dup 12) (match_dup 7)))]
15754   "TARGET_USE_FANCY_MATH_387
15755    && flag_unsafe_math_optimizations"
15757   int i;
15759   for (i = 2; i < 13; i++)
15760     operands[i] = gen_reg_rtx (XFmode);
15762   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15763   emit_move_insn (operands[9], CONST1_RTX (XFmode));
15766 (define_expand "expm1<mode>2"
15767   [(use (match_operand:MODEF 0 "register_operand"))
15768    (use (match_operand:MODEF 1 "general_operand"))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15771        || TARGET_MIX_SSE_I387)
15772    && flag_unsafe_math_optimizations"
15774   rtx op0 = gen_reg_rtx (XFmode);
15775   rtx op1 = gen_reg_rtx (XFmode);
15777   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15778   emit_insn (gen_expm1xf2 (op0, op1));
15779   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15780   DONE;
15783 (define_expand "ldexpxf3"
15784   [(match_operand:XF 0 "register_operand")
15785    (match_operand:XF 1 "register_operand")
15786    (match_operand:SI 2 "register_operand")]
15787   "TARGET_USE_FANCY_MATH_387
15788    && flag_unsafe_math_optimizations"
15790   rtx tmp1 = gen_reg_rtx (XFmode);
15791   rtx tmp2 = gen_reg_rtx (XFmode);
15793   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15794   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15795                                  operands[1], tmp1));
15796   DONE;
15799 (define_expand "ldexp<mode>3"
15800   [(use (match_operand:MODEF 0 "register_operand"))
15801    (use (match_operand:MODEF 1 "general_operand"))
15802    (use (match_operand:SI 2 "register_operand"))]
15803   "TARGET_USE_FANCY_MATH_387
15804    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15805        || TARGET_MIX_SSE_I387)
15806    && flag_unsafe_math_optimizations"
15808   rtx op0 = gen_reg_rtx (XFmode);
15809   rtx op1 = gen_reg_rtx (XFmode);
15811   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15812   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15813   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15814   DONE;
15817 (define_expand "scalbxf3"
15818   [(parallel [(set (match_operand:XF 0 " register_operand")
15819                    (unspec:XF [(match_operand:XF 1 "register_operand")
15820                                (match_operand:XF 2 "register_operand")]
15821                               UNSPEC_FSCALE_FRACT))
15822               (set (match_dup 3)
15823                    (unspec:XF [(match_dup 1) (match_dup 2)]
15824                               UNSPEC_FSCALE_EXP))])]
15825   "TARGET_USE_FANCY_MATH_387
15826    && flag_unsafe_math_optimizations"
15827   "operands[3] = gen_reg_rtx (XFmode);")
15829 (define_expand "scalb<mode>3"
15830   [(use (match_operand:MODEF 0 "register_operand"))
15831    (use (match_operand:MODEF 1 "general_operand"))
15832    (use (match_operand:MODEF 2 "general_operand"))]
15833   "TARGET_USE_FANCY_MATH_387
15834    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15835        || TARGET_MIX_SSE_I387)
15836    && flag_unsafe_math_optimizations"
15838   rtx op0 = gen_reg_rtx (XFmode);
15839   rtx op1 = gen_reg_rtx (XFmode);
15840   rtx op2 = gen_reg_rtx (XFmode);
15842   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15843   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15844   emit_insn (gen_scalbxf3 (op0, op1, op2));
15845   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15846   DONE;
15849 (define_expand "significandxf2"
15850   [(parallel [(set (match_operand:XF 0 "register_operand")
15851                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15852                               UNSPEC_XTRACT_FRACT))
15853               (set (match_dup 2)
15854                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15855   "TARGET_USE_FANCY_MATH_387
15856    && flag_unsafe_math_optimizations"
15857   "operands[2] = gen_reg_rtx (XFmode);")
15859 (define_expand "significand<mode>2"
15860   [(use (match_operand:MODEF 0 "register_operand"))
15861    (use (match_operand:MODEF 1 "general_operand"))]
15862   "TARGET_USE_FANCY_MATH_387
15863    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15864        || TARGET_MIX_SSE_I387)
15865    && flag_unsafe_math_optimizations"
15867   rtx op0 = gen_reg_rtx (XFmode);
15868   rtx op1 = gen_reg_rtx (XFmode);
15870   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15871   emit_insn (gen_significandxf2 (op0, op1));
15872   emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15873   DONE;
15877 (define_insn "sse4_1_round<mode>2"
15878   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15879         (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
15880                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15881                       UNSPEC_ROUND))]
15882   "TARGET_SSE4_1"
15883   "@
15884    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15885    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15886   [(set_attr "type" "ssecvt")
15887    (set_attr "prefix_extra" "1,*")
15888    (set_attr "length_immediate" "*,1")
15889    (set_attr "prefix" "maybe_vex,evex")
15890    (set_attr "isa" "noavx512f,avx512f")
15891    (set_attr "mode" "<MODE>")])
15893 (define_insn "rintxf2"
15894   [(set (match_operand:XF 0 "register_operand" "=f")
15895         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15896                    UNSPEC_FRNDINT))]
15897   "TARGET_USE_FANCY_MATH_387"
15898   "frndint"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "znver1_decode" "vector")
15901    (set_attr "mode" "XF")])
15903 (define_expand "rint<mode>2"
15904   [(use (match_operand:MODEF 0 "register_operand"))
15905    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15906   "TARGET_USE_FANCY_MATH_387
15907    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15909   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15910     {
15911       if (TARGET_SSE4_1)
15912         emit_insn (gen_sse4_1_round<mode>2
15913                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15914       else
15915         ix86_expand_rint (operands[0], operands[1]);
15916     }
15917   else
15918     {
15919       rtx op0 = gen_reg_rtx (XFmode);
15920       rtx op1 = gen_reg_rtx (XFmode);
15922       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15923       emit_insn (gen_rintxf2 (op0, op1));
15924       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15925     }
15926   DONE;
15929 (define_expand "nearbyintxf2"
15930   [(set (match_operand:XF 0 "register_operand")
15931         (unspec:XF [(match_operand:XF 1 "register_operand")]
15932                    UNSPEC_FRNDINT))]
15933   "TARGET_USE_FANCY_MATH_387
15934    && !flag_trapping_math")
15936 (define_expand "nearbyint<mode>2"
15937   [(use (match_operand:MODEF 0 "register_operand"))
15938    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15939   "(TARGET_USE_FANCY_MATH_387
15940     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15941           || TARGET_MIX_SSE_I387)
15942     && !flag_trapping_math)
15943    || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
15945   if (TARGET_SSE4_1 && TARGET_SSE_MATH)
15946     emit_insn (gen_sse4_1_round<mode>2
15947                (operands[0], operands[1], GEN_INT (ROUND_MXCSR
15948                                                    | ROUND_NO_EXC)));
15949   else
15950     {
15951       rtx op0 = gen_reg_rtx (XFmode);
15952       rtx op1 = gen_reg_rtx (XFmode);
15954       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15955       emit_insn (gen_nearbyintxf2 (op0, op1));
15956       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15957     }
15958   DONE;
15961 (define_expand "round<mode>2"
15962   [(match_operand:X87MODEF 0 "register_operand")
15963    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15964   "(TARGET_USE_FANCY_MATH_387
15965     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15966         || TARGET_MIX_SSE_I387)
15967     && flag_unsafe_math_optimizations
15968     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15969    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15970        && !flag_trapping_math && !flag_rounding_math)"
15972   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15973       && !flag_trapping_math && !flag_rounding_math)
15974     {
15975       if (TARGET_SSE4_1)
15976         {
15977           operands[1] = force_reg (<MODE>mode, operands[1]);
15978           ix86_expand_round_sse4 (operands[0], operands[1]);
15979         }
15980       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15981         ix86_expand_round (operands[0], operands[1]);
15982       else
15983         ix86_expand_rounddf_32 (operands[0], operands[1]);
15984     }
15985   else
15986     {
15987       operands[1] = force_reg (<MODE>mode, operands[1]);
15988       ix86_emit_i387_round (operands[0], operands[1]);
15989     }
15990   DONE;
15993 (define_insn "lrintxfdi2"
15994   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
15995         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15996                    UNSPEC_FIST))
15997    (clobber (match_scratch:XF 2 "=&f"))]
15998   "TARGET_USE_FANCY_MATH_387"
15999   "* return output_fix_trunc (insn, operands, false);"
16000   [(set_attr "type" "fpspc")
16001    (set_attr "mode" "DI")])
16003 (define_insn "lrintxf<mode>2"
16004   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16005         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16006                       UNSPEC_FIST))]
16007   "TARGET_USE_FANCY_MATH_387"
16008   "* return output_fix_trunc (insn, operands, false);"
16009   [(set_attr "type" "fpspc")
16010    (set_attr "mode" "<MODE>")])
16012 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16013   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16014      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16015                    UNSPEC_FIX_NOTRUNC))]
16016   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16018 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16019   [(match_operand:SWI248x 0 "nonimmediate_operand")
16020    (match_operand:X87MODEF 1 "register_operand")]
16021   "(TARGET_USE_FANCY_MATH_387
16022     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16023         || TARGET_MIX_SSE_I387)
16024     && flag_unsafe_math_optimizations)
16025    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16026        && <SWI248x:MODE>mode != HImode 
16027        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16028        && !flag_trapping_math && !flag_rounding_math)"
16030   if (optimize_insn_for_size_p ())
16031     FAIL;
16033   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16034       && <SWI248x:MODE>mode != HImode
16035       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16036       && !flag_trapping_math && !flag_rounding_math)
16037     ix86_expand_lround (operands[0], operands[1]);
16038   else
16039     ix86_emit_i387_round (operands[0], operands[1]);
16040   DONE;
16043 (define_int_iterator FRNDINT_ROUNDING
16044         [UNSPEC_FRNDINT_FLOOR
16045          UNSPEC_FRNDINT_CEIL
16046          UNSPEC_FRNDINT_TRUNC])
16048 (define_int_iterator FIST_ROUNDING
16049         [UNSPEC_FIST_FLOOR
16050          UNSPEC_FIST_CEIL])
16052 ;; Base name for define_insn
16053 (define_int_attr rounding_insn
16054         [(UNSPEC_FRNDINT_FLOOR "floor")
16055          (UNSPEC_FRNDINT_CEIL "ceil")
16056          (UNSPEC_FRNDINT_TRUNC "btrunc")
16057          (UNSPEC_FIST_FLOOR "floor")
16058          (UNSPEC_FIST_CEIL "ceil")])
16060 (define_int_attr rounding
16061         [(UNSPEC_FRNDINT_FLOOR "floor")
16062          (UNSPEC_FRNDINT_CEIL "ceil")
16063          (UNSPEC_FRNDINT_TRUNC "trunc")
16064          (UNSPEC_FIST_FLOOR "floor")
16065          (UNSPEC_FIST_CEIL "ceil")])
16067 (define_int_attr ROUNDING
16068         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16069          (UNSPEC_FRNDINT_CEIL "CEIL")
16070          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16071          (UNSPEC_FIST_FLOOR "FLOOR")
16072          (UNSPEC_FIST_CEIL "CEIL")])
16074 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16075 (define_insn_and_split "frndintxf2_<rounding>"
16076   [(set (match_operand:XF 0 "register_operand")
16077         (unspec:XF [(match_operand:XF 1 "register_operand")]
16078                    FRNDINT_ROUNDING))
16079    (clobber (reg:CC FLAGS_REG))]
16080   "TARGET_USE_FANCY_MATH_387
16081    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16082    && can_create_pseudo_p ()"
16083   "#"
16084   "&& 1"
16085   [(const_int 0)]
16087   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16089   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16090   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16092   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16093                                              operands[2], operands[3]));
16094   DONE;
16096   [(set_attr "type" "frndint")
16097    (set_attr "i387_cw" "<rounding>")
16098    (set_attr "mode" "XF")])
16100 (define_insn "frndintxf2_<rounding>_i387"
16101   [(set (match_operand:XF 0 "register_operand" "=f")
16102         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16103                    FRNDINT_ROUNDING))
16104    (use (match_operand:HI 2 "memory_operand" "m"))
16105    (use (match_operand:HI 3 "memory_operand" "m"))]
16106   "TARGET_USE_FANCY_MATH_387
16107    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16108   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16109   [(set_attr "type" "frndint")
16110    (set_attr "i387_cw" "<rounding>")
16111    (set_attr "mode" "XF")])
16113 (define_expand "<rounding_insn>xf2"
16114   [(parallel [(set (match_operand:XF 0 "register_operand")
16115                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16116                               FRNDINT_ROUNDING))
16117               (clobber (reg:CC FLAGS_REG))])]
16118   "TARGET_USE_FANCY_MATH_387
16119    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16121 (define_expand "<rounding_insn><mode>2"
16122   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16123                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16124                                  FRNDINT_ROUNDING))
16125               (clobber (reg:CC FLAGS_REG))])]
16126   "(TARGET_USE_FANCY_MATH_387
16127     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16128         || TARGET_MIX_SSE_I387)
16129     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16130    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16131        && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16132            || !flag_trapping_math))"
16134   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16135       && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16136     {
16137       if (TARGET_SSE4_1)
16138         emit_insn (gen_sse4_1_round<mode>2
16139                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16140                                                        | ROUND_NO_EXC)));
16141       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16142         {
16143           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16144             ix86_expand_floorceil (operands[0], operands[1], true);
16145           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16146             ix86_expand_floorceil (operands[0], operands[1], false);
16147           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16148             ix86_expand_trunc (operands[0], operands[1]);
16149           else
16150             gcc_unreachable ();
16151         }
16152       else
16153         {
16154           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16155             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16156           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16157             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16158           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16159             ix86_expand_truncdf_32 (operands[0], operands[1]);
16160           else
16161             gcc_unreachable ();
16162         }
16163     }
16164   else
16165     {
16166       rtx op0 = gen_reg_rtx (XFmode);
16167       rtx op1 = gen_reg_rtx (XFmode);
16169       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16170       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16171       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16172     }
16173   DONE;
16176 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16177 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16178   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16179         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16180                         FIST_ROUNDING))
16181    (clobber (reg:CC FLAGS_REG))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && flag_unsafe_math_optimizations
16184    && can_create_pseudo_p ()"
16185   "#"
16186   "&& 1"
16187   [(const_int 0)]
16189   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16191   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16192   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16194   emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16195                                          operands[2], operands[3]));
16196   DONE;
16198   [(set_attr "type" "fistp")
16199    (set_attr "i387_cw" "<rounding>")
16200    (set_attr "mode" "<MODE>")])
16202 (define_insn "fistdi2_<rounding>"
16203   [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16204         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16205                    FIST_ROUNDING))
16206    (use (match_operand:HI 2 "memory_operand" "m"))
16207    (use (match_operand:HI 3 "memory_operand" "m"))
16208    (clobber (match_scratch:XF 4 "=&f"))]
16209   "TARGET_USE_FANCY_MATH_387
16210    && flag_unsafe_math_optimizations"
16211   "* return output_fix_trunc (insn, operands, false);"
16212   [(set_attr "type" "fistp")
16213    (set_attr "i387_cw" "<rounding>")
16214    (set_attr "mode" "DI")])
16216 (define_insn "fist<mode>2_<rounding>"
16217   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16218         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16219                       FIST_ROUNDING))
16220    (use (match_operand:HI 2 "memory_operand" "m"))
16221    (use (match_operand:HI 3 "memory_operand" "m"))]
16222   "TARGET_USE_FANCY_MATH_387
16223    && flag_unsafe_math_optimizations"
16224   "* return output_fix_trunc (insn, operands, false);"
16225   [(set_attr "type" "fistp")
16226    (set_attr "i387_cw" "<rounding>")
16227    (set_attr "mode" "<MODE>")])
16229 (define_expand "l<rounding_insn>xf<mode>2"
16230   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16231                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16232                                    FIST_ROUNDING))
16233               (clobber (reg:CC FLAGS_REG))])]
16234   "TARGET_USE_FANCY_MATH_387
16235    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16236    && flag_unsafe_math_optimizations")
16238 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16239   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16240                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16241                                  FIST_ROUNDING))
16242               (clobber (reg:CC FLAGS_REG))])]
16243   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16244    && (TARGET_SSE4_1 || !flag_trapping_math)"
16246   if (TARGET_SSE4_1)
16247     {
16248       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16250       emit_insn (gen_sse4_1_round<mode>2
16251                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16252                                              | ROUND_NO_EXC)));
16253       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16254                  (operands[0], tmp));
16255     }
16256   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16257     ix86_expand_lfloorceil (operands[0], operands[1], true);
16258   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16259     ix86_expand_lfloorceil (operands[0], operands[1], false);
16260   else
16261     gcc_unreachable ();
16263   DONE;
16266 (define_insn "fxam<mode>2_i387"
16267   [(set (match_operand:HI 0 "register_operand" "=a")
16268         (unspec:HI
16269           [(match_operand:X87MODEF 1 "register_operand" "f")]
16270           UNSPEC_FXAM))]
16271   "TARGET_USE_FANCY_MATH_387"
16272   "fxam\n\tfnstsw\t%0"
16273   [(set_attr "type" "multi")
16274    (set_attr "length" "4")
16275    (set_attr "unit" "i387")
16276    (set_attr "mode" "<MODE>")])
16278 (define_expand "signbittf2"
16279   [(use (match_operand:SI 0 "register_operand"))
16280    (use (match_operand:TF 1 "register_operand"))]
16281   "TARGET_SSE"
16283   if (TARGET_SSE4_1)
16284     {
16285       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16286       rtx scratch = gen_reg_rtx (QImode);
16288       emit_insn (gen_ptesttf2 (operands[1], mask));
16289         ix86_expand_setcc (scratch, NE,
16290                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16292       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16293     }
16294   else
16295     {
16296       emit_insn (gen_sse_movmskps (operands[0],
16297                                    gen_lowpart (V4SFmode, operands[1])));
16298       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16299     }
16300   DONE;
16303 (define_expand "signbitxf2"
16304   [(use (match_operand:SI 0 "register_operand"))
16305    (use (match_operand:XF 1 "register_operand"))]
16306   "TARGET_USE_FANCY_MATH_387"
16308   rtx scratch = gen_reg_rtx (HImode);
16310   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16311   emit_insn (gen_andsi3 (operands[0],
16312              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16313   DONE;
16316 (define_insn "movmsk_df"
16317   [(set (match_operand:SI 0 "register_operand" "=r")
16318         (unspec:SI
16319           [(match_operand:DF 1 "register_operand" "x")]
16320           UNSPEC_MOVMSK))]
16321   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16322   "%vmovmskpd\t{%1, %0|%0, %1}"
16323   [(set_attr "type" "ssemov")
16324    (set_attr "prefix" "maybe_vex")
16325    (set_attr "mode" "DF")])
16327 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16328 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16329 (define_expand "signbitdf2"
16330   [(use (match_operand:SI 0 "register_operand"))
16331    (use (match_operand:DF 1 "register_operand"))]
16332   "TARGET_USE_FANCY_MATH_387
16333    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16335   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16336     {
16337       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16338       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16339     }
16340   else
16341     {
16342       rtx scratch = gen_reg_rtx (HImode);
16344       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16345       emit_insn (gen_andsi3 (operands[0],
16346                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16347     }
16348   DONE;
16351 (define_expand "signbitsf2"
16352   [(use (match_operand:SI 0 "register_operand"))
16353    (use (match_operand:SF 1 "register_operand"))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16357   rtx scratch = gen_reg_rtx (HImode);
16359   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16360   emit_insn (gen_andsi3 (operands[0],
16361              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16362   DONE;
16365 ;; Block operation instructions
16367 (define_insn "cld"
16368   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16369   ""
16370   "cld"
16371   [(set_attr "length" "1")
16372    (set_attr "length_immediate" "0")
16373    (set_attr "modrm" "0")])
16375 (define_expand "movmem<mode>"
16376   [(use (match_operand:BLK 0 "memory_operand"))
16377    (use (match_operand:BLK 1 "memory_operand"))
16378    (use (match_operand:SWI48 2 "nonmemory_operand"))
16379    (use (match_operand:SWI48 3 "const_int_operand"))
16380    (use (match_operand:SI 4 "const_int_operand"))
16381    (use (match_operand:SI 5 "const_int_operand"))
16382    (use (match_operand:SI 6 ""))
16383    (use (match_operand:SI 7 ""))
16384    (use (match_operand:SI 8 ""))]
16385   ""
16387  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16388                                 operands[2], NULL, operands[3],
16389                                 operands[4], operands[5],
16390                                 operands[6], operands[7],
16391                                 operands[8], false))
16392    DONE;
16393  else
16394    FAIL;
16397 ;; Most CPUs don't like single string operations
16398 ;; Handle this case here to simplify previous expander.
16400 (define_expand "strmov"
16401   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16402    (set (match_operand 1 "memory_operand") (match_dup 4))
16403    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16404               (clobber (reg:CC FLAGS_REG))])
16405    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16406               (clobber (reg:CC FLAGS_REG))])]
16407   ""
16409   /* Can't use this for non-default address spaces.  */
16410   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16411     FAIL;
16413   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16415   /* If .md ever supports :P for Pmode, these can be directly
16416      in the pattern above.  */
16417   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16418   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16420   /* Can't use this if the user has appropriated esi or edi.  */
16421   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16422       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16423     {
16424       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16425                                       operands[2], operands[3],
16426                                       operands[5], operands[6]));
16427       DONE;
16428     }
16430   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16433 (define_expand "strmov_singleop"
16434   [(parallel [(set (match_operand 1 "memory_operand")
16435                    (match_operand 3 "memory_operand"))
16436               (set (match_operand 0 "register_operand")
16437                    (match_operand 4))
16438               (set (match_operand 2 "register_operand")
16439                    (match_operand 5))])]
16440   ""
16442   if (TARGET_CLD)
16443     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16446 (define_insn "*strmovdi_rex_1"
16447   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16448         (mem:DI (match_operand:P 3 "register_operand" "1")))
16449    (set (match_operand:P 0 "register_operand" "=D")
16450         (plus:P (match_dup 2)
16451                 (const_int 8)))
16452    (set (match_operand:P 1 "register_operand" "=S")
16453         (plus:P (match_dup 3)
16454                 (const_int 8)))]
16455   "TARGET_64BIT
16456    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16457    && ix86_check_no_addr_space (insn)"
16458   "%^movsq"
16459   [(set_attr "type" "str")
16460    (set_attr "memory" "both")
16461    (set_attr "mode" "DI")])
16463 (define_insn "*strmovsi_1"
16464   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16465         (mem:SI (match_operand:P 3 "register_operand" "1")))
16466    (set (match_operand:P 0 "register_operand" "=D")
16467         (plus:P (match_dup 2)
16468                 (const_int 4)))
16469    (set (match_operand:P 1 "register_operand" "=S")
16470         (plus:P (match_dup 3)
16471                 (const_int 4)))]
16472   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16473    && ix86_check_no_addr_space (insn)"
16474   "%^movs{l|d}"
16475   [(set_attr "type" "str")
16476    (set_attr "memory" "both")
16477    (set_attr "mode" "SI")])
16479 (define_insn "*strmovhi_1"
16480   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16481         (mem:HI (match_operand:P 3 "register_operand" "1")))
16482    (set (match_operand:P 0 "register_operand" "=D")
16483         (plus:P (match_dup 2)
16484                 (const_int 2)))
16485    (set (match_operand:P 1 "register_operand" "=S")
16486         (plus:P (match_dup 3)
16487                 (const_int 2)))]
16488   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16489    && ix86_check_no_addr_space (insn)"
16490   "%^movsw"
16491   [(set_attr "type" "str")
16492    (set_attr "memory" "both")
16493    (set_attr "mode" "HI")])
16495 (define_insn "*strmovqi_1"
16496   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16497         (mem:QI (match_operand:P 3 "register_operand" "1")))
16498    (set (match_operand:P 0 "register_operand" "=D")
16499         (plus:P (match_dup 2)
16500                 (const_int 1)))
16501    (set (match_operand:P 1 "register_operand" "=S")
16502         (plus:P (match_dup 3)
16503                 (const_int 1)))]
16504   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16505    && ix86_check_no_addr_space (insn)"
16506   "%^movsb"
16507   [(set_attr "type" "str")
16508    (set_attr "memory" "both")
16509    (set (attr "prefix_rex")
16510         (if_then_else
16511           (match_test "<P:MODE>mode == DImode")
16512           (const_string "0")
16513           (const_string "*")))
16514    (set_attr "mode" "QI")])
16516 (define_expand "rep_mov"
16517   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16518               (set (match_operand 0 "register_operand")
16519                    (match_operand 5))
16520               (set (match_operand 2 "register_operand")
16521                    (match_operand 6))
16522               (set (match_operand 1 "memory_operand")
16523                    (match_operand 3 "memory_operand"))
16524               (use (match_dup 4))])]
16525   ""
16527   if (TARGET_CLD)
16528     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16531 (define_insn "*rep_movdi_rex64"
16532   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16533    (set (match_operand:P 0 "register_operand" "=D")
16534         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16535                           (const_int 3))
16536                 (match_operand:P 3 "register_operand" "0")))
16537    (set (match_operand:P 1 "register_operand" "=S")
16538         (plus:P (ashift:P (match_dup 5) (const_int 3))
16539                 (match_operand:P 4 "register_operand" "1")))
16540    (set (mem:BLK (match_dup 3))
16541         (mem:BLK (match_dup 4)))
16542    (use (match_dup 5))]
16543   "TARGET_64BIT
16544    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16545    && ix86_check_no_addr_space (insn)"
16546   "%^rep{%;} movsq"
16547   [(set_attr "type" "str")
16548    (set_attr "prefix_rep" "1")
16549    (set_attr "memory" "both")
16550    (set_attr "mode" "DI")])
16552 (define_insn "*rep_movsi"
16553   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16554    (set (match_operand:P 0 "register_operand" "=D")
16555         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16556                           (const_int 2))
16557                  (match_operand:P 3 "register_operand" "0")))
16558    (set (match_operand:P 1 "register_operand" "=S")
16559         (plus:P (ashift:P (match_dup 5) (const_int 2))
16560                 (match_operand:P 4 "register_operand" "1")))
16561    (set (mem:BLK (match_dup 3))
16562         (mem:BLK (match_dup 4)))
16563    (use (match_dup 5))]
16564   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16565    && ix86_check_no_addr_space (insn)"
16566   "%^rep{%;} movs{l|d}"
16567   [(set_attr "type" "str")
16568    (set_attr "prefix_rep" "1")
16569    (set_attr "memory" "both")
16570    (set_attr "mode" "SI")])
16572 (define_insn "*rep_movqi"
16573   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16574    (set (match_operand:P 0 "register_operand" "=D")
16575         (plus:P (match_operand:P 3 "register_operand" "0")
16576                 (match_operand:P 5 "register_operand" "2")))
16577    (set (match_operand:P 1 "register_operand" "=S")
16578         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16579    (set (mem:BLK (match_dup 3))
16580         (mem:BLK (match_dup 4)))
16581    (use (match_dup 5))]
16582   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16583    && ix86_check_no_addr_space (insn)"
16584   "%^rep{%;} movsb"
16585   [(set_attr "type" "str")
16586    (set_attr "prefix_rep" "1")
16587    (set_attr "memory" "both")
16588    (set_attr "mode" "QI")])
16590 (define_expand "setmem<mode>"
16591    [(use (match_operand:BLK 0 "memory_operand"))
16592     (use (match_operand:SWI48 1 "nonmemory_operand"))
16593     (use (match_operand:QI 2 "nonmemory_operand"))
16594     (use (match_operand 3 "const_int_operand"))
16595     (use (match_operand:SI 4 "const_int_operand"))
16596     (use (match_operand:SI 5 "const_int_operand"))
16597     (use (match_operand:SI 6 ""))
16598     (use (match_operand:SI 7 ""))
16599     (use (match_operand:SI 8 ""))]
16600   ""
16602  if (ix86_expand_set_or_movmem (operands[0], NULL,
16603                                 operands[1], operands[2],
16604                                 operands[3], operands[4],
16605                                 operands[5], operands[6],
16606                                 operands[7], operands[8], true))
16607    DONE;
16608  else
16609    FAIL;
16612 ;; Most CPUs don't like single string operations
16613 ;; Handle this case here to simplify previous expander.
16615 (define_expand "strset"
16616   [(set (match_operand 1 "memory_operand")
16617         (match_operand 2 "register_operand"))
16618    (parallel [(set (match_operand 0 "register_operand")
16619                    (match_dup 3))
16620               (clobber (reg:CC FLAGS_REG))])]
16621   ""
16623   /* Can't use this for non-default address spaces.  */
16624   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16625     FAIL;
16627   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16628     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16630   /* If .md ever supports :P for Pmode, this can be directly
16631      in the pattern above.  */
16632   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16633                               GEN_INT (GET_MODE_SIZE (GET_MODE
16634                                                       (operands[2]))));
16635   /* Can't use this if the user has appropriated eax or edi.  */
16636   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16637       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16638     {
16639       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16640                                       operands[3]));
16641       DONE;
16642     }
16645 (define_expand "strset_singleop"
16646   [(parallel [(set (match_operand 1 "memory_operand")
16647                    (match_operand 2 "register_operand"))
16648               (set (match_operand 0 "register_operand")
16649                    (match_operand 3))
16650               (unspec [(const_int 0)] UNSPEC_STOS)])]
16651   ""
16653   if (TARGET_CLD)
16654     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16657 (define_insn "*strsetdi_rex_1"
16658   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16659         (match_operand:DI 2 "register_operand" "a"))
16660    (set (match_operand:P 0 "register_operand" "=D")
16661         (plus:P (match_dup 1)
16662                 (const_int 8)))
16663    (unspec [(const_int 0)] UNSPEC_STOS)]
16664   "TARGET_64BIT
16665    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16666    && ix86_check_no_addr_space (insn)"
16667   "%^stosq"
16668   [(set_attr "type" "str")
16669    (set_attr "memory" "store")
16670    (set_attr "mode" "DI")])
16672 (define_insn "*strsetsi_1"
16673   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16674         (match_operand:SI 2 "register_operand" "a"))
16675    (set (match_operand:P 0 "register_operand" "=D")
16676         (plus:P (match_dup 1)
16677                 (const_int 4)))
16678    (unspec [(const_int 0)] UNSPEC_STOS)]
16679   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16680    && ix86_check_no_addr_space (insn)"
16681   "%^stos{l|d}"
16682   [(set_attr "type" "str")
16683    (set_attr "memory" "store")
16684    (set_attr "mode" "SI")])
16686 (define_insn "*strsethi_1"
16687   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16688         (match_operand:HI 2 "register_operand" "a"))
16689    (set (match_operand:P 0 "register_operand" "=D")
16690         (plus:P (match_dup 1)
16691                 (const_int 2)))
16692    (unspec [(const_int 0)] UNSPEC_STOS)]
16693   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16694    && ix86_check_no_addr_space (insn)"
16695   "%^stosw"
16696   [(set_attr "type" "str")
16697    (set_attr "memory" "store")
16698    (set_attr "mode" "HI")])
16700 (define_insn "*strsetqi_1"
16701   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16702         (match_operand:QI 2 "register_operand" "a"))
16703    (set (match_operand:P 0 "register_operand" "=D")
16704         (plus:P (match_dup 1)
16705                 (const_int 1)))
16706    (unspec [(const_int 0)] UNSPEC_STOS)]
16707   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16708    && ix86_check_no_addr_space (insn)"
16709   "%^stosb"
16710   [(set_attr "type" "str")
16711    (set_attr "memory" "store")
16712    (set (attr "prefix_rex")
16713         (if_then_else
16714           (match_test "<P:MODE>mode == DImode")
16715           (const_string "0")
16716           (const_string "*")))
16717    (set_attr "mode" "QI")])
16719 (define_expand "rep_stos"
16720   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16721               (set (match_operand 0 "register_operand")
16722                    (match_operand 4))
16723               (set (match_operand 2 "memory_operand") (const_int 0))
16724               (use (match_operand 3 "register_operand"))
16725               (use (match_dup 1))])]
16726   ""
16728   if (TARGET_CLD)
16729     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16732 (define_insn "*rep_stosdi_rex64"
16733   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16734    (set (match_operand:P 0 "register_operand" "=D")
16735         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16736                           (const_int 3))
16737                  (match_operand:P 3 "register_operand" "0")))
16738    (set (mem:BLK (match_dup 3))
16739         (const_int 0))
16740    (use (match_operand:DI 2 "register_operand" "a"))
16741    (use (match_dup 4))]
16742   "TARGET_64BIT
16743    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16744    && ix86_check_no_addr_space (insn)"
16745   "%^rep{%;} stosq"
16746   [(set_attr "type" "str")
16747    (set_attr "prefix_rep" "1")
16748    (set_attr "memory" "store")
16749    (set_attr "mode" "DI")])
16751 (define_insn "*rep_stossi"
16752   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16753    (set (match_operand:P 0 "register_operand" "=D")
16754         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16755                           (const_int 2))
16756                  (match_operand:P 3 "register_operand" "0")))
16757    (set (mem:BLK (match_dup 3))
16758         (const_int 0))
16759    (use (match_operand:SI 2 "register_operand" "a"))
16760    (use (match_dup 4))]
16761   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16762    && ix86_check_no_addr_space (insn)"
16763   "%^rep{%;} stos{l|d}"
16764   [(set_attr "type" "str")
16765    (set_attr "prefix_rep" "1")
16766    (set_attr "memory" "store")
16767    (set_attr "mode" "SI")])
16769 (define_insn "*rep_stosqi"
16770   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16771    (set (match_operand:P 0 "register_operand" "=D")
16772         (plus:P (match_operand:P 3 "register_operand" "0")
16773                 (match_operand:P 4 "register_operand" "1")))
16774    (set (mem:BLK (match_dup 3))
16775         (const_int 0))
16776    (use (match_operand:QI 2 "register_operand" "a"))
16777    (use (match_dup 4))]
16778   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16779    && ix86_check_no_addr_space (insn)"
16780   "%^rep{%;} stosb"
16781   [(set_attr "type" "str")
16782    (set_attr "prefix_rep" "1")
16783    (set_attr "memory" "store")
16784    (set (attr "prefix_rex")
16785         (if_then_else
16786           (match_test "<P:MODE>mode == DImode")
16787           (const_string "0")
16788           (const_string "*")))
16789    (set_attr "mode" "QI")])
16791 (define_expand "cmpstrnsi"
16792   [(set (match_operand:SI 0 "register_operand")
16793         (compare:SI (match_operand:BLK 1 "general_operand")
16794                     (match_operand:BLK 2 "general_operand")))
16795    (use (match_operand 3 "general_operand"))
16796    (use (match_operand 4 "immediate_operand"))]
16797   ""
16799   rtx addr1, addr2, out, outlow, count, countreg, align;
16801   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16802     FAIL;
16804   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16805   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16806     FAIL;
16808   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
16809      will have rewritten the length arg to be the minimum of the const string
16810      length and the actual length arg.  If both strings are the same and
16811      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16812      will incorrectly base the results on chars past the 0 byte.  */
16813   tree t1 = MEM_EXPR (operands[1]);
16814   tree t2 = MEM_EXPR (operands[2]);
16815   if (!((t1 && TREE_CODE (t1) == MEM_REF
16816          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16817          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16818       || (t2 && TREE_CODE (t2) == MEM_REF
16819           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16820           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16821     FAIL;
16823   out = operands[0];
16824   if (!REG_P (out))
16825     out = gen_reg_rtx (SImode);
16827   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16828   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16829   if (addr1 != XEXP (operands[1], 0))
16830     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16831   if (addr2 != XEXP (operands[2], 0))
16832     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16834   count = operands[3];
16835   countreg = ix86_zero_extend_to_Pmode (count);
16837   /* %%% Iff we are testing strict equality, we can use known alignment
16838      to good advantage.  This may be possible with combine, particularly
16839      once cc0 is dead.  */
16840   align = operands[4];
16842   if (CONST_INT_P (count))
16843     {
16844       if (INTVAL (count) == 0)
16845         {
16846           emit_move_insn (operands[0], const0_rtx);
16847           DONE;
16848         }
16849       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16850                                      operands[1], operands[2]));
16851     }
16852   else
16853     {
16854       rtx (*gen_cmp) (rtx, rtx);
16856       gen_cmp = (TARGET_64BIT
16857                  ? gen_cmpdi_1 : gen_cmpsi_1);
16859       emit_insn (gen_cmp (countreg, countreg));
16860       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16861                                   operands[1], operands[2]));
16862     }
16864   outlow = gen_lowpart (QImode, out);
16865   emit_insn (gen_cmpintqi (outlow));
16866   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16868   if (operands[0] != out)
16869     emit_move_insn (operands[0], out);
16871   DONE;
16874 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16876 (define_expand "cmpintqi"
16877   [(set (match_dup 1)
16878         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16879    (set (match_dup 2)
16880         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16881    (parallel [(set (match_operand:QI 0 "register_operand")
16882                    (minus:QI (match_dup 1)
16883                              (match_dup 2)))
16884               (clobber (reg:CC FLAGS_REG))])]
16885   ""
16887   operands[1] = gen_reg_rtx (QImode);
16888   operands[2] = gen_reg_rtx (QImode);
16891 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16892 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16894 (define_expand "cmpstrnqi_nz_1"
16895   [(parallel [(set (reg:CC FLAGS_REG)
16896                    (compare:CC (match_operand 4 "memory_operand")
16897                                (match_operand 5 "memory_operand")))
16898               (use (match_operand 2 "register_operand"))
16899               (use (match_operand:SI 3 "immediate_operand"))
16900               (clobber (match_operand 0 "register_operand"))
16901               (clobber (match_operand 1 "register_operand"))
16902               (clobber (match_dup 2))])]
16903   ""
16905   if (TARGET_CLD)
16906     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16909 (define_insn "*cmpstrnqi_nz_1"
16910   [(set (reg:CC FLAGS_REG)
16911         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16912                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16913    (use (match_operand:P 6 "register_operand" "2"))
16914    (use (match_operand:SI 3 "immediate_operand" "i"))
16915    (clobber (match_operand:P 0 "register_operand" "=S"))
16916    (clobber (match_operand:P 1 "register_operand" "=D"))
16917    (clobber (match_operand:P 2 "register_operand" "=c"))]
16918   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16919    && ix86_check_no_addr_space (insn)"
16920   "%^repz{%;} cmpsb"
16921   [(set_attr "type" "str")
16922    (set_attr "mode" "QI")
16923    (set (attr "prefix_rex")
16924         (if_then_else
16925           (match_test "<P:MODE>mode == DImode")
16926           (const_string "0")
16927           (const_string "*")))
16928    (set_attr "prefix_rep" "1")])
16930 ;; The same, but the count is not known to not be zero.
16932 (define_expand "cmpstrnqi_1"
16933   [(parallel [(set (reg:CC FLAGS_REG)
16934                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16935                                      (const_int 0))
16936                   (compare:CC (match_operand 4 "memory_operand")
16937                               (match_operand 5 "memory_operand"))
16938                   (const_int 0)))
16939               (use (match_operand:SI 3 "immediate_operand"))
16940               (use (reg:CC FLAGS_REG))
16941               (clobber (match_operand 0 "register_operand"))
16942               (clobber (match_operand 1 "register_operand"))
16943               (clobber (match_dup 2))])]
16944   ""
16946   if (TARGET_CLD)
16947     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16950 (define_insn "*cmpstrnqi_1"
16951   [(set (reg:CC FLAGS_REG)
16952         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16953                              (const_int 0))
16954           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16955                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16956           (const_int 0)))
16957    (use (match_operand:SI 3 "immediate_operand" "i"))
16958    (use (reg:CC FLAGS_REG))
16959    (clobber (match_operand:P 0 "register_operand" "=S"))
16960    (clobber (match_operand:P 1 "register_operand" "=D"))
16961    (clobber (match_operand:P 2 "register_operand" "=c"))]
16962   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16963    && ix86_check_no_addr_space (insn)"
16964   "%^repz{%;} cmpsb"
16965   [(set_attr "type" "str")
16966    (set_attr "mode" "QI")
16967    (set (attr "prefix_rex")
16968         (if_then_else
16969           (match_test "<P:MODE>mode == DImode")
16970           (const_string "0")
16971           (const_string "*")))
16972    (set_attr "prefix_rep" "1")])
16974 (define_expand "strlen<mode>"
16975   [(set (match_operand:P 0 "register_operand")
16976         (unspec:P [(match_operand:BLK 1 "general_operand")
16977                    (match_operand:QI 2 "immediate_operand")
16978                    (match_operand 3 "immediate_operand")]
16979                   UNSPEC_SCAS))]
16980   ""
16982  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16983    DONE;
16984  else
16985    FAIL;
16988 (define_expand "strlenqi_1"
16989   [(parallel [(set (match_operand 0 "register_operand")
16990                    (match_operand 2))
16991               (clobber (match_operand 1 "register_operand"))
16992               (clobber (reg:CC FLAGS_REG))])]
16993   ""
16995   if (TARGET_CLD)
16996     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16999 (define_insn "*strlenqi_1"
17000   [(set (match_operand:P 0 "register_operand" "=&c")
17001         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17002                    (match_operand:QI 2 "register_operand" "a")
17003                    (match_operand:P 3 "immediate_operand" "i")
17004                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17005    (clobber (match_operand:P 1 "register_operand" "=D"))
17006    (clobber (reg:CC FLAGS_REG))]
17007   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17008    && ix86_check_no_addr_space (insn)"
17009   "%^repnz{%;} scasb"
17010   [(set_attr "type" "str")
17011    (set_attr "mode" "QI")
17012    (set (attr "prefix_rex")
17013         (if_then_else
17014           (match_test "<P:MODE>mode == DImode")
17015           (const_string "0")
17016           (const_string "*")))
17017    (set_attr "prefix_rep" "1")])
17019 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17020 ;; handled in combine, but it is not currently up to the task.
17021 ;; When used for their truth value, the cmpstrn* expanders generate
17022 ;; code like this:
17024 ;;   repz cmpsb
17025 ;;   seta       %al
17026 ;;   setb       %dl
17027 ;;   cmpb       %al, %dl
17028 ;;   jcc        label
17030 ;; The intermediate three instructions are unnecessary.
17032 ;; This one handles cmpstrn*_nz_1...
17033 (define_peephole2
17034   [(parallel[
17035      (set (reg:CC FLAGS_REG)
17036           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17037                       (mem:BLK (match_operand 5 "register_operand"))))
17038      (use (match_operand 6 "register_operand"))
17039      (use (match_operand:SI 3 "immediate_operand"))
17040      (clobber (match_operand 0 "register_operand"))
17041      (clobber (match_operand 1 "register_operand"))
17042      (clobber (match_operand 2 "register_operand"))])
17043    (set (match_operand:QI 7 "register_operand")
17044         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17045    (set (match_operand:QI 8 "register_operand")
17046         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17047    (set (reg FLAGS_REG)
17048         (compare (match_dup 7) (match_dup 8)))
17049   ]
17050   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17051   [(parallel[
17052      (set (reg:CC FLAGS_REG)
17053           (compare:CC (mem:BLK (match_dup 4))
17054                       (mem:BLK (match_dup 5))))
17055      (use (match_dup 6))
17056      (use (match_dup 3))
17057      (clobber (match_dup 0))
17058      (clobber (match_dup 1))
17059      (clobber (match_dup 2))])])
17061 ;; ...and this one handles cmpstrn*_1.
17062 (define_peephole2
17063   [(parallel[
17064      (set (reg:CC FLAGS_REG)
17065           (if_then_else:CC (ne (match_operand 6 "register_operand")
17066                                (const_int 0))
17067             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17068                         (mem:BLK (match_operand 5 "register_operand")))
17069             (const_int 0)))
17070      (use (match_operand:SI 3 "immediate_operand"))
17071      (use (reg:CC FLAGS_REG))
17072      (clobber (match_operand 0 "register_operand"))
17073      (clobber (match_operand 1 "register_operand"))
17074      (clobber (match_operand 2 "register_operand"))])
17075    (set (match_operand:QI 7 "register_operand")
17076         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17077    (set (match_operand:QI 8 "register_operand")
17078         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17079    (set (reg FLAGS_REG)
17080         (compare (match_dup 7) (match_dup 8)))
17081   ]
17082   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17083   [(parallel[
17084      (set (reg:CC FLAGS_REG)
17085           (if_then_else:CC (ne (match_dup 6)
17086                                (const_int 0))
17087             (compare:CC (mem:BLK (match_dup 4))
17088                         (mem:BLK (match_dup 5)))
17089             (const_int 0)))
17090      (use (match_dup 3))
17091      (use (reg:CC FLAGS_REG))
17092      (clobber (match_dup 0))
17093      (clobber (match_dup 1))
17094      (clobber (match_dup 2))])])
17096 ;; Conditional move instructions.
17098 (define_expand "mov<mode>cc"
17099   [(set (match_operand:SWIM 0 "register_operand")
17100         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17101                            (match_operand:SWIM 2 "<general_operand>")
17102                            (match_operand:SWIM 3 "<general_operand>")))]
17103   ""
17104   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17106 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17107 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17108 ;; So just document what we're doing explicitly.
17110 (define_expand "x86_mov<mode>cc_0_m1"
17111   [(parallel
17112     [(set (match_operand:SWI48 0 "register_operand")
17113           (if_then_else:SWI48
17114             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17115              [(match_operand 1 "flags_reg_operand")
17116               (const_int 0)])
17117             (const_int -1)
17118             (const_int 0)))
17119      (clobber (reg:CC FLAGS_REG))])])
17121 (define_insn "*x86_mov<mode>cc_0_m1"
17122   [(set (match_operand:SWI48 0 "register_operand" "=r")
17123         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17124                              [(reg FLAGS_REG) (const_int 0)])
17125           (const_int -1)
17126           (const_int 0)))
17127    (clobber (reg:CC FLAGS_REG))]
17128   ""
17129   "sbb{<imodesuffix>}\t%0, %0"
17130   [(set_attr "type" "alu1")
17131    (set_attr "use_carry" "1")
17132    (set_attr "pent_pair" "pu")
17133    (set_attr "mode" "<MODE>")
17134    (set_attr "length_immediate" "0")])
17136 (define_insn "*x86_mov<mode>cc_0_m1_se"
17137   [(set (match_operand:SWI48 0 "register_operand" "=r")
17138         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17139                              [(reg FLAGS_REG) (const_int 0)])
17140                             (const_int 1)
17141                             (const_int 0)))
17142    (clobber (reg:CC FLAGS_REG))]
17143   ""
17144   "sbb{<imodesuffix>}\t%0, %0"
17145   [(set_attr "type" "alu1")
17146    (set_attr "use_carry" "1")
17147    (set_attr "pent_pair" "pu")
17148    (set_attr "mode" "<MODE>")
17149    (set_attr "length_immediate" "0")])
17151 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17152   [(set (match_operand:SWI48 0 "register_operand" "=r")
17153         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17154                     [(reg FLAGS_REG) (const_int 0)])))
17155    (clobber (reg:CC FLAGS_REG))]
17156   ""
17157   "sbb{<imodesuffix>}\t%0, %0"
17158   [(set_attr "type" "alu1")
17159    (set_attr "use_carry" "1")
17160    (set_attr "pent_pair" "pu")
17161    (set_attr "mode" "<MODE>")
17162    (set_attr "length_immediate" "0")])
17164 (define_insn "*mov<mode>cc_noc"
17165   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17166         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17167                                [(reg FLAGS_REG) (const_int 0)])
17168           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17169           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17170   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17171   "@
17172    cmov%O2%C1\t{%2, %0|%0, %2}
17173    cmov%O2%c1\t{%3, %0|%0, %3}"
17174   [(set_attr "type" "icmov")
17175    (set_attr "mode" "<MODE>")])
17177 (define_insn "*movsicc_noc_zext"
17178   [(set (match_operand:DI 0 "register_operand" "=r,r")
17179         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17180                            [(reg FLAGS_REG) (const_int 0)])
17181           (zero_extend:DI
17182             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17183           (zero_extend:DI
17184             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17185   "TARGET_64BIT
17186    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17187   "@
17188    cmov%O2%C1\t{%2, %k0|%k0, %2}
17189    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17190   [(set_attr "type" "icmov")
17191    (set_attr "mode" "SI")])
17193 ;; Don't do conditional moves with memory inputs.  This splitter helps
17194 ;; register starved x86_32 by forcing inputs into registers before reload.
17195 (define_split
17196   [(set (match_operand:SWI248 0 "register_operand")
17197         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17198                                [(reg FLAGS_REG) (const_int 0)])
17199           (match_operand:SWI248 2 "nonimmediate_operand")
17200           (match_operand:SWI248 3 "nonimmediate_operand")))]
17201   "!TARGET_64BIT && TARGET_CMOVE
17202    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17203    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17204    && can_create_pseudo_p ()
17205    && optimize_insn_for_speed_p ()"
17206   [(set (match_dup 0)
17207         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17209   if (MEM_P (operands[2]))
17210     operands[2] = force_reg (<MODE>mode, operands[2]);
17211   if (MEM_P (operands[3]))
17212     operands[3] = force_reg (<MODE>mode, operands[3]);
17215 (define_insn "*movqicc_noc"
17216   [(set (match_operand:QI 0 "register_operand" "=r,r")
17217         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17218                            [(reg FLAGS_REG) (const_int 0)])
17219                       (match_operand:QI 2 "register_operand" "r,0")
17220                       (match_operand:QI 3 "register_operand" "0,r")))]
17221   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17222   "#"
17223   [(set_attr "type" "icmov")
17224    (set_attr "mode" "QI")])
17226 (define_split
17227   [(set (match_operand:SWI12 0 "register_operand")
17228         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17229                               [(reg FLAGS_REG) (const_int 0)])
17230                       (match_operand:SWI12 2 "register_operand")
17231                       (match_operand:SWI12 3 "register_operand")))]
17232   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17233    && reload_completed"
17234   [(set (match_dup 0)
17235         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17237   operands[0] = gen_lowpart (SImode, operands[0]);
17238   operands[2] = gen_lowpart (SImode, operands[2]);
17239   operands[3] = gen_lowpart (SImode, operands[3]);
17242 ;; Don't do conditional moves with memory inputs
17243 (define_peephole2
17244   [(match_scratch:SWI248 4 "r")
17245    (set (match_operand:SWI248 0 "register_operand")
17246         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17247                                [(reg FLAGS_REG) (const_int 0)])
17248           (match_operand:SWI248 2 "nonimmediate_operand")
17249           (match_operand:SWI248 3 "nonimmediate_operand")))]
17250   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17251    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17252    && optimize_insn_for_speed_p ()"
17253   [(set (match_dup 4) (match_dup 5))
17254    (set (match_dup 0)
17255         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17257   if (MEM_P (operands[2]))
17258     {
17259       operands[5] = operands[2];
17260       operands[2] = operands[4];
17261     }
17262   else if (MEM_P (operands[3]))
17263     {
17264       operands[5] = operands[3];
17265       operands[3] = operands[4];
17266     }
17267   else
17268     gcc_unreachable ();
17271 (define_peephole2
17272   [(match_scratch:SI 4 "r")
17273    (set (match_operand:DI 0 "register_operand")
17274         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17275                            [(reg FLAGS_REG) (const_int 0)])
17276           (zero_extend:DI
17277             (match_operand:SI 2 "nonimmediate_operand"))
17278           (zero_extend:DI
17279             (match_operand:SI 3 "nonimmediate_operand"))))]
17280   "TARGET_64BIT
17281    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17282    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17283    && optimize_insn_for_speed_p ()"
17284   [(set (match_dup 4) (match_dup 5))
17285    (set (match_dup 0)
17286         (if_then_else:DI (match_dup 1)
17287           (zero_extend:DI (match_dup 2))
17288           (zero_extend:DI (match_dup 3))))]
17290   if (MEM_P (operands[2]))
17291     {
17292       operands[5] = operands[2];
17293       operands[2] = operands[4];
17294     }
17295   else if (MEM_P (operands[3]))
17296     {
17297       operands[5] = operands[3];
17298       operands[3] = operands[4];
17299     }
17300   else
17301     gcc_unreachable ();
17304 (define_expand "mov<mode>cc"
17305   [(set (match_operand:X87MODEF 0 "register_operand")
17306         (if_then_else:X87MODEF
17307           (match_operand 1 "comparison_operator")
17308           (match_operand:X87MODEF 2 "register_operand")
17309           (match_operand:X87MODEF 3 "register_operand")))]
17310   "(TARGET_80387 && TARGET_CMOVE)
17311    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17312   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17314 (define_insn "*movxfcc_1"
17315   [(set (match_operand:XF 0 "register_operand" "=f,f")
17316         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17317                                 [(reg FLAGS_REG) (const_int 0)])
17318                       (match_operand:XF 2 "register_operand" "f,0")
17319                       (match_operand:XF 3 "register_operand" "0,f")))]
17320   "TARGET_80387 && TARGET_CMOVE"
17321   "@
17322    fcmov%F1\t{%2, %0|%0, %2}
17323    fcmov%f1\t{%3, %0|%0, %3}"
17324   [(set_attr "type" "fcmov")
17325    (set_attr "mode" "XF")])
17327 (define_insn "*movdfcc_1"
17328   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17329         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17330                                 [(reg FLAGS_REG) (const_int 0)])
17331                       (match_operand:DF 2 "nonimmediate_operand"
17332                                                "f ,0,rm,0 ,rm,0")
17333                       (match_operand:DF 3 "nonimmediate_operand"
17334                                                "0 ,f,0 ,rm,0, rm")))]
17335   "TARGET_80387 && TARGET_CMOVE
17336    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17337   "@
17338    fcmov%F1\t{%2, %0|%0, %2}
17339    fcmov%f1\t{%3, %0|%0, %3}
17340    #
17341    #
17342    cmov%O2%C1\t{%2, %0|%0, %2}
17343    cmov%O2%c1\t{%3, %0|%0, %3}"
17344   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17345    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17346    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17348 (define_split
17349   [(set (match_operand:DF 0 "general_reg_operand")
17350         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17351                                 [(reg FLAGS_REG) (const_int 0)])
17352                       (match_operand:DF 2 "nonimmediate_operand")
17353                       (match_operand:DF 3 "nonimmediate_operand")))]
17354   "!TARGET_64BIT && reload_completed"
17355   [(set (match_dup 2)
17356         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17357    (set (match_dup 3)
17358         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17360   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17361   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17364 (define_insn "*movsfcc_1_387"
17365   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17366         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17367                                 [(reg FLAGS_REG) (const_int 0)])
17368                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17369                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17370   "TARGET_80387 && TARGET_CMOVE
17371    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17372   "@
17373    fcmov%F1\t{%2, %0|%0, %2}
17374    fcmov%f1\t{%3, %0|%0, %3}
17375    cmov%O2%C1\t{%2, %0|%0, %2}
17376    cmov%O2%c1\t{%3, %0|%0, %3}"
17377   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17378    (set_attr "mode" "SF,SF,SI,SI")])
17380 ;; Don't do conditional moves with memory inputs.  This splitter helps
17381 ;; register starved x86_32 by forcing inputs into registers before reload.
17382 (define_split
17383   [(set (match_operand:MODEF 0 "register_operand")
17384         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17385                               [(reg FLAGS_REG) (const_int 0)])
17386           (match_operand:MODEF 2 "nonimmediate_operand")
17387           (match_operand:MODEF 3 "nonimmediate_operand")))]
17388   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17389    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17390    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17391    && can_create_pseudo_p ()
17392    && optimize_insn_for_speed_p ()"
17393   [(set (match_dup 0)
17394         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17396   if (MEM_P (operands[2]))
17397     operands[2] = force_reg (<MODE>mode, operands[2]);
17398   if (MEM_P (operands[3]))
17399     operands[3] = force_reg (<MODE>mode, operands[3]);
17402 ;; Don't do conditional moves with memory inputs
17403 (define_peephole2
17404   [(match_scratch:MODEF 4 "r")
17405    (set (match_operand:MODEF 0 "general_reg_operand")
17406         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17407                               [(reg FLAGS_REG) (const_int 0)])
17408           (match_operand:MODEF 2 "nonimmediate_operand")
17409           (match_operand:MODEF 3 "nonimmediate_operand")))]
17410   "(<MODE>mode != DFmode || TARGET_64BIT)
17411    && TARGET_80387 && TARGET_CMOVE
17412    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17413    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17414    && optimize_insn_for_speed_p ()"
17415   [(set (match_dup 4) (match_dup 5))
17416    (set (match_dup 0)
17417         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17419   if (MEM_P (operands[2]))
17420     {
17421       operands[5] = operands[2];
17422       operands[2] = operands[4];
17423     }
17424   else if (MEM_P (operands[3]))
17425     {
17426       operands[5] = operands[3];
17427       operands[3] = operands[4];
17428     }
17429   else
17430     gcc_unreachable ();
17433 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17434 ;; the scalar versions to have only XMM registers as operands.
17436 ;; XOP conditional move
17437 (define_insn "*xop_pcmov_<mode>"
17438   [(set (match_operand:MODEF 0 "register_operand" "=x")
17439         (if_then_else:MODEF
17440           (match_operand:MODEF 1 "register_operand" "x")
17441           (match_operand:MODEF 2 "register_operand" "x")
17442           (match_operand:MODEF 3 "register_operand" "x")))]
17443   "TARGET_XOP"
17444   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17445   [(set_attr "type" "sse4arg")])
17447 ;; These versions of the min/max patterns are intentionally ignorant of
17448 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17449 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17450 ;; are undefined in this condition, we're certain this is correct.
17452 (define_insn "<code><mode>3"
17453   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17454         (smaxmin:MODEF
17455           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17456           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17457   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17458   "@
17459    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17460    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17461   [(set_attr "isa" "noavx,avx")
17462    (set_attr "prefix" "orig,vex")
17463    (set_attr "type" "sseadd")
17464    (set_attr "mode" "<MODE>")])
17466 ;; These versions of the min/max patterns implement exactly the operations
17467 ;;   min = (op1 < op2 ? op1 : op2)
17468 ;;   max = (!(op1 < op2) ? op1 : op2)
17469 ;; Their operands are not commutative, and thus they may be used in the
17470 ;; presence of -0.0 and NaN.
17472 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17473   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17474         (unspec:MODEF
17475           [(match_operand:MODEF 1 "register_operand" "0,v")
17476            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17477           IEEE_MAXMIN))]
17478   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17479   "@
17480    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17481    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17482   [(set_attr "isa" "noavx,avx")
17483    (set_attr "prefix" "orig,maybe_evex")
17484    (set_attr "type" "sseadd")
17485    (set_attr "mode" "<MODE>")])
17487 ;; Make two stack loads independent:
17488 ;;   fld aa              fld aa
17489 ;;   fld %st(0)     ->   fld bb
17490 ;;   fmul bb             fmul %st(1), %st
17492 ;; Actually we only match the last two instructions for simplicity.
17494 (define_peephole2
17495   [(set (match_operand 0 "fp_register_operand")
17496         (match_operand 1 "fp_register_operand"))
17497    (set (match_dup 0)
17498         (match_operator 2 "binary_fp_operator"
17499            [(match_dup 0)
17500             (match_operand 3 "memory_operand")]))]
17501   "REGNO (operands[0]) != REGNO (operands[1])"
17502   [(set (match_dup 0) (match_dup 3))
17503    (set (match_dup 0)
17504         (match_op_dup 2
17505           [(match_dup 5) (match_dup 4)]))]
17507   operands[4] = operands[0];
17508   operands[5] = operands[1];
17510   /* The % modifier is not operational anymore in peephole2's, so we have to
17511      swap the operands manually in the case of addition and multiplication. */
17512   if (COMMUTATIVE_ARITH_P (operands[2]))
17513     std::swap (operands[4], operands[5]);
17516 (define_peephole2
17517   [(set (match_operand 0 "fp_register_operand")
17518         (match_operand 1 "fp_register_operand"))
17519    (set (match_dup 0)
17520         (match_operator 2 "binary_fp_operator"
17521            [(match_operand 3 "memory_operand")
17522             (match_dup 0)]))]
17523   "REGNO (operands[0]) != REGNO (operands[1])"
17524   [(set (match_dup 0) (match_dup 3))
17525    (set (match_dup 0)
17526         (match_op_dup 2
17527           [(match_dup 4) (match_dup 5)]))]
17529   operands[4] = operands[0];
17530   operands[5] = operands[1];
17532   /* The % modifier is not operational anymore in peephole2's, so we have to
17533      swap the operands manually in the case of addition and multiplication. */
17534   if (COMMUTATIVE_ARITH_P (operands[2]))
17535     std::swap (operands[4], operands[5]);
17538 ;; Conditional addition patterns
17539 (define_expand "add<mode>cc"
17540   [(match_operand:SWI 0 "register_operand")
17541    (match_operand 1 "ordered_comparison_operator")
17542    (match_operand:SWI 2 "register_operand")
17543    (match_operand:SWI 3 "const_int_operand")]
17544   ""
17545   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17547 ;; Misc patterns (?)
17549 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17550 ;; Otherwise there will be nothing to keep
17552 ;; [(set (reg ebp) (reg esp))]
17553 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17554 ;;  (clobber (eflags)]
17555 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17557 ;; in proper program order.
17559 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17560   [(set (match_operand:P 0 "register_operand" "=r,r")
17561         (plus:P (match_operand:P 1 "register_operand" "0,r")
17562                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17563    (clobber (reg:CC FLAGS_REG))
17564    (clobber (mem:BLK (scratch)))]
17565   ""
17567   switch (get_attr_type (insn))
17568     {
17569     case TYPE_IMOV:
17570       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17572     case TYPE_ALU:
17573       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17574       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17575         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17577       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17579     default:
17580       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17581       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17582     }
17584   [(set (attr "type")
17585         (cond [(and (eq_attr "alternative" "0")
17586                     (not (match_test "TARGET_OPT_AGU")))
17587                  (const_string "alu")
17588                (match_operand:<MODE> 2 "const0_operand")
17589                  (const_string "imov")
17590               ]
17591               (const_string "lea")))
17592    (set (attr "length_immediate")
17593         (cond [(eq_attr "type" "imov")
17594                  (const_string "0")
17595                (and (eq_attr "type" "alu")
17596                     (match_operand 2 "const128_operand"))
17597                  (const_string "1")
17598               ]
17599               (const_string "*")))
17600    (set_attr "mode" "<MODE>")])
17602 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17603   [(set (match_operand:P 0 "register_operand" "=r")
17604         (minus:P (match_operand:P 1 "register_operand" "0")
17605                  (match_operand:P 2 "register_operand" "r")))
17606    (clobber (reg:CC FLAGS_REG))
17607    (clobber (mem:BLK (scratch)))]
17608   ""
17609   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17610   [(set_attr "type" "alu")
17611    (set_attr "mode" "<MODE>")])
17613 (define_insn "allocate_stack_worker_probe_<mode>"
17614   [(set (match_operand:P 0 "register_operand" "=a")
17615         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17616                             UNSPECV_STACK_PROBE))
17617    (clobber (reg:CC FLAGS_REG))]
17618   "ix86_target_stack_probe ()"
17619   "call\t___chkstk_ms"
17620   [(set_attr "type" "multi")
17621    (set_attr "length" "5")])
17623 (define_expand "allocate_stack"
17624   [(match_operand 0 "register_operand")
17625    (match_operand 1 "general_operand")]
17626   "ix86_target_stack_probe ()"
17628   rtx x;
17630 #ifndef CHECK_STACK_LIMIT
17631 #define CHECK_STACK_LIMIT 0
17632 #endif
17634   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17635       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17636     x = operands[1];
17637   else
17638     {
17639       rtx (*insn) (rtx, rtx);
17641       x = copy_to_mode_reg (Pmode, operands[1]);
17643       insn = (TARGET_64BIT
17644               ? gen_allocate_stack_worker_probe_di
17645               : gen_allocate_stack_worker_probe_si);
17647       emit_insn (insn (x, x));
17648     }
17650   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17651                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17653   if (x != stack_pointer_rtx)
17654     emit_move_insn (stack_pointer_rtx, x);
17656   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17657   DONE;
17660 (define_expand "probe_stack"
17661   [(match_operand 0 "memory_operand")]
17662   ""
17664   rtx (*insn) (rtx, rtx)
17665     = (GET_MODE (operands[0]) == DImode
17666        ? gen_probe_stack_di : gen_probe_stack_si);
17668   emit_insn (insn (operands[0], const0_rtx));
17669   DONE;
17672 ;; Use OR for stack probes, this is shorter.
17673 (define_insn "probe_stack_<mode>"
17674   [(set (match_operand:W 0 "memory_operand" "=m")
17675         (unspec:W [(match_operand:W 1 "const0_operand")]
17676                   UNSPEC_PROBE_STACK))
17677    (clobber (reg:CC FLAGS_REG))]
17678   ""
17679   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17680   [(set_attr "type" "alu1")
17681    (set_attr "mode" "<MODE>")
17682    (set_attr "length_immediate" "1")])
17683   
17684 (define_insn "adjust_stack_and_probe<mode>"
17685   [(set (match_operand:P 0 "register_operand" "=r")
17686         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17687                             UNSPECV_PROBE_STACK_RANGE))
17688    (set (reg:P SP_REG)
17689         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17690    (clobber (reg:CC FLAGS_REG))
17691    (clobber (mem:BLK (scratch)))]
17692   ""
17693   "* return output_adjust_stack_and_probe (operands[0]);"
17694   [(set_attr "type" "multi")])
17696 (define_insn "probe_stack_range<mode>"
17697   [(set (match_operand:P 0 "register_operand" "=r")
17698         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17699                             (match_operand:P 2 "const_int_operand" "n")]
17700                             UNSPECV_PROBE_STACK_RANGE))
17701    (clobber (reg:CC FLAGS_REG))]
17702   ""
17703   "* return output_probe_stack_range (operands[0], operands[2]);"
17704   [(set_attr "type" "multi")])
17706 (define_expand "builtin_setjmp_receiver"
17707   [(label_ref (match_operand 0))]
17708   "!TARGET_64BIT && flag_pic"
17710 #if TARGET_MACHO
17711   if (TARGET_MACHO)
17712     {
17713       rtx xops[3];
17714       rtx_code_label *label_rtx = gen_label_rtx ();
17715       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17716       xops[0] = xops[1] = pic_offset_table_rtx;
17717       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17718       ix86_expand_binary_operator (MINUS, SImode, xops);
17719     }
17720   else
17721 #endif
17722     emit_insn (gen_set_got (pic_offset_table_rtx));
17723   DONE;
17726 (define_expand "save_stack_nonlocal"
17727   [(set (match_operand 0 "memory_operand")
17728         (match_operand 1 "register_operand"))]
17729   ""
17731   rtx stack_slot;
17732   if ((flag_cf_protection & CF_RETURN))
17733     {
17734       /* Copy shadow stack pointer to the first slot and stack ppointer
17735          to the second slot.  */
17736       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
17737       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
17738       rtx ssp = gen_reg_rtx (word_mode);
17739       emit_insn ((word_mode == SImode)
17740                  ? gen_rdsspsi (ssp)
17741                  : gen_rdsspdi (ssp));
17742       emit_move_insn (ssp_slot, ssp);
17743     }
17744   else
17745     stack_slot = adjust_address (operands[0], Pmode, 0);
17746   emit_move_insn (stack_slot, operands[1]);
17747   DONE;
17750 (define_expand "restore_stack_nonlocal"
17751   [(set (match_operand 0 "register_operand" "")
17752         (match_operand 1 "memory_operand" ""))]
17753   ""
17755   rtx stack_slot;
17756   if ((flag_cf_protection & CF_RETURN))
17757     {
17758       /* Restore shadow stack pointer from the first slot and stack
17759          pointer from the second slot.  */
17760       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
17761       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
17763       rtx flags, jump, noadj_label, inc_label, loop_label;
17764       rtx reg_adj, reg_ssp, tmp, clob;
17766       /* Get the current shadow stack pointer.  The code below will check if
17767          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
17768          is a NOP.  */
17769       reg_ssp = gen_reg_rtx (word_mode);
17770       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
17771       emit_insn ((word_mode == SImode)
17772                  ? gen_rdsspsi (reg_ssp)
17773                  : gen_rdsspdi (reg_ssp));
17775       /* Compare through substraction the saved and the current ssp to decide
17776          if ssp has to be adjusted.  */
17777       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
17778                                                  ssp_slot));
17779       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17780       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17781       emit_insn (tmp);
17783       /* Compare and jump over adjustment code.  */
17784       noadj_label = gen_label_rtx ();
17785       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17786       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
17787       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17788                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
17789                                   pc_rtx);
17790       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17791       JUMP_LABEL (jump) = noadj_label;
17793       /* Compute the numebr of frames to adjust.  */
17794       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
17795       tmp = gen_rtx_SET (reg_adj,
17796                          gen_rtx_LSHIFTRT (ptr_mode,
17797                                            negate_rtx (ptr_mode, reg_adj),
17798                                            GEN_INT ((word_mode == SImode)
17799                                                     ? 2
17800                                                     : 3)));
17801       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17802       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17803       emit_insn (tmp);
17805       /* Check if number of frames <= 255 so no loop is needed.  */
17806       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17807       flags = gen_rtx_REG (CCmode, FLAGS_REG);
17808       emit_insn (gen_rtx_SET (flags, tmp));
17810       inc_label = gen_label_rtx ();
17811       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
17812       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17813                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
17814                                   pc_rtx);
17815       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17816       JUMP_LABEL (jump) = inc_label;
17818       rtx reg_255 = gen_reg_rtx (word_mode);
17819       emit_move_insn (reg_255, GEN_INT (255));
17821       /* Adjust the ssp in a loop.  */
17822       loop_label = gen_label_rtx ();
17823       emit_label (loop_label);
17824       LABEL_NUSES (loop_label) = 1;
17826       emit_insn ((word_mode == SImode)
17827                  ? gen_incsspsi (reg_255)
17828                  : gen_incsspdi (reg_255));
17829       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
17830                                                  reg_adj,
17831                                                  GEN_INT (255)));
17832       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17833       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17834       emit_insn (tmp);
17836       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17837       flags = gen_rtx_REG (CCmode, FLAGS_REG);
17838       emit_insn (gen_rtx_SET (flags, tmp));
17840       /* Jump to the loop label.  */
17841       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
17842       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17843                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
17844                                   pc_rtx);
17845       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17846       JUMP_LABEL (jump) = loop_label;
17848       emit_label (inc_label);
17849       LABEL_NUSES (inc_label) = 1;
17850       emit_insn ((word_mode == SImode)
17851                  ? gen_incsspsi (reg_ssp)
17852                  : gen_incsspdi (reg_ssp));
17854       emit_label (noadj_label);
17855       LABEL_NUSES (noadj_label) = 1;
17856     }
17857   else
17858     stack_slot = adjust_address (operands[1], Pmode, 0);
17859   emit_move_insn (operands[0], stack_slot);
17860   DONE;
17864 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17865 ;; Do not split instructions with mask registers.
17866 (define_split
17867   [(set (match_operand 0 "general_reg_operand")
17868         (match_operator 3 "promotable_binary_operator"
17869            [(match_operand 1 "general_reg_operand")
17870             (match_operand 2 "aligned_operand")]))
17871    (clobber (reg:CC FLAGS_REG))]
17872   "! TARGET_PARTIAL_REG_STALL && reload_completed
17873    && ((GET_MODE (operands[0]) == HImode
17874         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17875             /* ??? next two lines just !satisfies_constraint_K (...) */
17876             || !CONST_INT_P (operands[2])
17877             || satisfies_constraint_K (operands[2])))
17878        || (GET_MODE (operands[0]) == QImode
17879            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17880   [(parallel [(set (match_dup 0)
17881                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17882               (clobber (reg:CC FLAGS_REG))])]
17884   operands[0] = gen_lowpart (SImode, operands[0]);
17885   operands[1] = gen_lowpart (SImode, operands[1]);
17886   if (GET_CODE (operands[3]) != ASHIFT)
17887     operands[2] = gen_lowpart (SImode, operands[2]);
17888   operands[3] = shallow_copy_rtx (operands[3]);
17889   PUT_MODE (operands[3], SImode);
17892 ; Promote the QImode tests, as i386 has encoding of the AND
17893 ; instruction with 32-bit sign-extended immediate and thus the
17894 ; instruction size is unchanged, except in the %eax case for
17895 ; which it is increased by one byte, hence the ! optimize_size.
17896 (define_split
17897   [(set (match_operand 0 "flags_reg_operand")
17898         (match_operator 2 "compare_operator"
17899           [(and (match_operand 3 "aligned_operand")
17900                 (match_operand 4 "const_int_operand"))
17901            (const_int 0)]))
17902    (set (match_operand 1 "register_operand")
17903         (and (match_dup 3) (match_dup 4)))]
17904   "! TARGET_PARTIAL_REG_STALL && reload_completed
17905    && optimize_insn_for_speed_p ()
17906    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17907        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17908    /* Ensure that the operand will remain sign-extended immediate.  */
17909    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17910   [(parallel [(set (match_dup 0)
17911                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17912                                     (const_int 0)]))
17913               (set (match_dup 1)
17914                    (and:SI (match_dup 3) (match_dup 4)))])]
17916   operands[4]
17917     = gen_int_mode (INTVAL (operands[4])
17918                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17919   operands[1] = gen_lowpart (SImode, operands[1]);
17920   operands[3] = gen_lowpart (SImode, operands[3]);
17923 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17924 ; the TEST instruction with 32-bit sign-extended immediate and thus
17925 ; the instruction size would at least double, which is not what we
17926 ; want even with ! optimize_size.
17927 (define_split
17928   [(set (match_operand 0 "flags_reg_operand")
17929         (match_operator 1 "compare_operator"
17930           [(and (match_operand:HI 2 "aligned_operand")
17931                 (match_operand:HI 3 "const_int_operand"))
17932            (const_int 0)]))]
17933   "! TARGET_PARTIAL_REG_STALL && reload_completed
17934    && ! TARGET_FAST_PREFIX
17935    && optimize_insn_for_speed_p ()
17936    /* Ensure that the operand will remain sign-extended immediate.  */
17937    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17938   [(set (match_dup 0)
17939         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17940                          (const_int 0)]))]
17942   operands[3]
17943     = gen_int_mode (INTVAL (operands[3])
17944                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17945   operands[2] = gen_lowpart (SImode, operands[2]);
17948 (define_split
17949   [(set (match_operand 0 "register_operand")
17950         (neg (match_operand 1 "register_operand")))
17951    (clobber (reg:CC FLAGS_REG))]
17952   "! TARGET_PARTIAL_REG_STALL && reload_completed
17953    && (GET_MODE (operands[0]) == HImode
17954        || (GET_MODE (operands[0]) == QImode
17955            && (TARGET_PROMOTE_QImode
17956                || optimize_insn_for_size_p ())))"
17957   [(parallel [(set (match_dup 0)
17958                    (neg:SI (match_dup 1)))
17959               (clobber (reg:CC FLAGS_REG))])]
17961   operands[0] = gen_lowpart (SImode, operands[0]);
17962   operands[1] = gen_lowpart (SImode, operands[1]);
17965 ;; Do not split instructions with mask regs.
17966 (define_split
17967   [(set (match_operand 0 "general_reg_operand")
17968         (not (match_operand 1 "general_reg_operand")))]
17969   "! TARGET_PARTIAL_REG_STALL && reload_completed
17970    && (GET_MODE (operands[0]) == HImode
17971        || (GET_MODE (operands[0]) == QImode
17972            && (TARGET_PROMOTE_QImode
17973                || optimize_insn_for_size_p ())))"
17974   [(set (match_dup 0)
17975         (not:SI (match_dup 1)))]
17977   operands[0] = gen_lowpart (SImode, operands[0]);
17978   operands[1] = gen_lowpart (SImode, operands[1]);
17981 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17982 ;; transform a complex memory operation into two memory to register operations.
17984 ;; Don't push memory operands
17985 (define_peephole2
17986   [(set (match_operand:SWI 0 "push_operand")
17987         (match_operand:SWI 1 "memory_operand"))
17988    (match_scratch:SWI 2 "<r>")]
17989   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17990    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17991   [(set (match_dup 2) (match_dup 1))
17992    (set (match_dup 0) (match_dup 2))])
17994 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17995 ;; SImode pushes.
17996 (define_peephole2
17997   [(set (match_operand:SF 0 "push_operand")
17998         (match_operand:SF 1 "memory_operand"))
17999    (match_scratch:SF 2 "r")]
18000   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18001    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18002   [(set (match_dup 2) (match_dup 1))
18003    (set (match_dup 0) (match_dup 2))])
18005 ;; Don't move an immediate directly to memory when the instruction
18006 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18007 (define_peephole2
18008   [(match_scratch:SWI124 1 "<r>")
18009    (set (match_operand:SWI124 0 "memory_operand")
18010         (const_int 0))]
18011   "optimize_insn_for_speed_p ()
18012    && ((<MODE>mode == HImode
18013        && TARGET_LCP_STALL)
18014        || (!TARGET_USE_MOV0
18015           && TARGET_SPLIT_LONG_MOVES
18016           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18017    && peep2_regno_dead_p (0, FLAGS_REG)"
18018   [(parallel [(set (match_dup 2) (const_int 0))
18019               (clobber (reg:CC FLAGS_REG))])
18020    (set (match_dup 0) (match_dup 1))]
18021   "operands[2] = gen_lowpart (SImode, operands[1]);")
18023 (define_peephole2
18024   [(match_scratch:SWI124 2 "<r>")
18025    (set (match_operand:SWI124 0 "memory_operand")
18026         (match_operand:SWI124 1 "immediate_operand"))]
18027   "optimize_insn_for_speed_p ()
18028    && ((<MODE>mode == HImode
18029        && TARGET_LCP_STALL)
18030        || (TARGET_SPLIT_LONG_MOVES
18031           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18032   [(set (match_dup 2) (match_dup 1))
18033    (set (match_dup 0) (match_dup 2))])
18035 ;; Don't compare memory with zero, load and use a test instead.
18036 (define_peephole2
18037   [(set (match_operand 0 "flags_reg_operand")
18038         (match_operator 1 "compare_operator"
18039           [(match_operand:SI 2 "memory_operand")
18040            (const_int 0)]))
18041    (match_scratch:SI 3 "r")]
18042   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18043   [(set (match_dup 3) (match_dup 2))
18044    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18046 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18047 ;; Don't split NOTs with a displacement operand, because resulting XOR
18048 ;; will not be pairable anyway.
18050 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18051 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18052 ;; so this split helps here as well.
18054 ;; Note: Can't do this as a regular split because we can't get proper
18055 ;; lifetime information then.
18057 (define_peephole2
18058   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18059         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18060   "optimize_insn_for_speed_p ()
18061    && ((TARGET_NOT_UNPAIRABLE
18062         && (!MEM_P (operands[0])
18063             || !memory_displacement_operand (operands[0], <MODE>mode)))
18064        || (TARGET_NOT_VECTORMODE
18065            && long_memory_operand (operands[0], <MODE>mode)))
18066    && peep2_regno_dead_p (0, FLAGS_REG)"
18067   [(parallel [(set (match_dup 0)
18068                    (xor:SWI124 (match_dup 1) (const_int -1)))
18069               (clobber (reg:CC FLAGS_REG))])])
18071 ;; Non pairable "test imm, reg" instructions can be translated to
18072 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18073 ;; byte opcode instead of two, have a short form for byte operands),
18074 ;; so do it for other CPUs as well.  Given that the value was dead,
18075 ;; this should not create any new dependencies.  Pass on the sub-word
18076 ;; versions if we're concerned about partial register stalls.
18078 (define_peephole2
18079   [(set (match_operand 0 "flags_reg_operand")
18080         (match_operator 1 "compare_operator"
18081           [(and:SI (match_operand:SI 2 "register_operand")
18082                    (match_operand:SI 3 "immediate_operand"))
18083            (const_int 0)]))]
18084   "ix86_match_ccmode (insn, CCNOmode)
18085    && (REGNO (operands[2]) != AX_REG
18086        || satisfies_constraint_K (operands[3]))
18087    && peep2_reg_dead_p (1, operands[2])"
18088   [(parallel
18089      [(set (match_dup 0)
18090            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18091                             (const_int 0)]))
18092       (set (match_dup 2)
18093            (and:SI (match_dup 2) (match_dup 3)))])])
18095 ;; We don't need to handle HImode case, because it will be promoted to SImode
18096 ;; on ! TARGET_PARTIAL_REG_STALL
18098 (define_peephole2
18099   [(set (match_operand 0 "flags_reg_operand")
18100         (match_operator 1 "compare_operator"
18101           [(and:QI (match_operand:QI 2 "register_operand")
18102                    (match_operand:QI 3 "immediate_operand"))
18103            (const_int 0)]))]
18104   "! TARGET_PARTIAL_REG_STALL
18105    && ix86_match_ccmode (insn, CCNOmode)
18106    && REGNO (operands[2]) != AX_REG
18107    && peep2_reg_dead_p (1, operands[2])"
18108   [(parallel
18109      [(set (match_dup 0)
18110            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18111                             (const_int 0)]))
18112       (set (match_dup 2)
18113            (and:QI (match_dup 2) (match_dup 3)))])])
18115 (define_peephole2
18116   [(set (match_operand 0 "flags_reg_operand")
18117         (match_operator 1 "compare_operator"
18118           [(and:QI
18119              (subreg:QI
18120                (zero_extract:SI (match_operand 2 "QIreg_operand")
18121                                 (const_int 8)
18122                                 (const_int 8)) 0)
18123              (match_operand 3 "const_int_operand"))
18124            (const_int 0)]))]
18125   "! TARGET_PARTIAL_REG_STALL
18126    && ix86_match_ccmode (insn, CCNOmode)
18127    && REGNO (operands[2]) != AX_REG
18128    && peep2_reg_dead_p (1, operands[2])"
18129   [(parallel
18130      [(set (match_dup 0)
18131            (match_op_dup 1
18132              [(and:QI
18133                 (subreg:QI
18134                   (zero_extract:SI (match_dup 2)
18135                                    (const_int 8)
18136                                    (const_int 8)) 0)
18137                 (match_dup 3))
18138               (const_int 0)]))
18139       (set (zero_extract:SI (match_dup 2)
18140                             (const_int 8)
18141                             (const_int 8))
18142            (subreg:SI
18143              (and:QI
18144                (subreg:QI
18145                  (zero_extract:SI (match_dup 2)
18146                                   (const_int 8)
18147                                   (const_int 8)) 0)
18148                (match_dup 3)) 0))])])
18150 ;; Don't do logical operations with memory inputs.
18151 (define_peephole2
18152   [(match_scratch:SWI 2 "<r>")
18153    (parallel [(set (match_operand:SWI 0 "register_operand")
18154                    (match_operator:SWI 3 "arith_or_logical_operator"
18155                      [(match_dup 0)
18156                       (match_operand:SWI 1 "memory_operand")]))
18157               (clobber (reg:CC FLAGS_REG))])]
18158   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18159   [(set (match_dup 2) (match_dup 1))
18160    (parallel [(set (match_dup 0)
18161                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18162               (clobber (reg:CC FLAGS_REG))])])
18164 (define_peephole2
18165   [(match_scratch:SWI 2 "<r>")
18166    (parallel [(set (match_operand:SWI 0 "register_operand")
18167                    (match_operator:SWI 3 "arith_or_logical_operator"
18168                      [(match_operand:SWI 1 "memory_operand")
18169                       (match_dup 0)]))
18170               (clobber (reg:CC FLAGS_REG))])]
18171   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18172   [(set (match_dup 2) (match_dup 1))
18173    (parallel [(set (match_dup 0)
18174                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18175               (clobber (reg:CC FLAGS_REG))])])
18177 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18178 ;; the memory address refers to the destination of the load!
18180 (define_peephole2
18181   [(set (match_operand:SWI 0 "general_reg_operand")
18182         (match_operand:SWI 1 "general_reg_operand"))
18183    (parallel [(set (match_dup 0)
18184                    (match_operator:SWI 3 "commutative_operator"
18185                      [(match_dup 0)
18186                       (match_operand:SWI 2 "memory_operand")]))
18187               (clobber (reg:CC FLAGS_REG))])]
18188   "REGNO (operands[0]) != REGNO (operands[1])
18189    && (<MODE>mode != QImode
18190        || any_QIreg_operand (operands[1], QImode))"
18191   [(set (match_dup 0) (match_dup 4))
18192    (parallel [(set (match_dup 0)
18193                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18194               (clobber (reg:CC FLAGS_REG))])]
18195   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18197 (define_peephole2
18198   [(set (match_operand 0 "mmx_reg_operand")
18199         (match_operand 1 "mmx_reg_operand"))
18200    (set (match_dup 0)
18201         (match_operator 3 "commutative_operator"
18202           [(match_dup 0)
18203            (match_operand 2 "memory_operand")]))]
18204   "REGNO (operands[0]) != REGNO (operands[1])"
18205   [(set (match_dup 0) (match_dup 2))
18206    (set (match_dup 0)
18207         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18209 (define_peephole2
18210   [(set (match_operand 0 "sse_reg_operand")
18211         (match_operand 1 "sse_reg_operand"))
18212    (set (match_dup 0)
18213         (match_operator 3 "commutative_operator"
18214           [(match_dup 0)
18215            (match_operand 2 "memory_operand")]))]
18216   "REGNO (operands[0]) != REGNO (operands[1])"
18217   [(set (match_dup 0) (match_dup 2))
18218    (set (match_dup 0)
18219         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18221 ; Don't do logical operations with memory outputs
18223 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18224 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18225 ; the same decoder scheduling characteristics as the original.
18227 (define_peephole2
18228   [(match_scratch:SWI 2 "<r>")
18229    (parallel [(set (match_operand:SWI 0 "memory_operand")
18230                    (match_operator:SWI 3 "arith_or_logical_operator"
18231                      [(match_dup 0)
18232                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18233               (clobber (reg:CC FLAGS_REG))])]
18234   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18235   [(set (match_dup 2) (match_dup 0))
18236    (parallel [(set (match_dup 2)
18237                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18238               (clobber (reg:CC FLAGS_REG))])
18239    (set (match_dup 0) (match_dup 2))])
18241 (define_peephole2
18242   [(match_scratch:SWI 2 "<r>")
18243    (parallel [(set (match_operand:SWI 0 "memory_operand")
18244                    (match_operator:SWI 3 "arith_or_logical_operator"
18245                      [(match_operand:SWI 1 "<nonmemory_operand>")
18246                       (match_dup 0)]))
18247               (clobber (reg:CC FLAGS_REG))])]
18248   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18249   [(set (match_dup 2) (match_dup 0))
18250    (parallel [(set (match_dup 2)
18251                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18252               (clobber (reg:CC FLAGS_REG))])
18253    (set (match_dup 0) (match_dup 2))])
18255 ;; Attempt to use arith or logical operations with memory outputs with
18256 ;; setting of flags.
18257 (define_peephole2
18258   [(set (match_operand:SWI 0 "register_operand")
18259         (match_operand:SWI 1 "memory_operand"))
18260    (parallel [(set (match_dup 0)
18261                    (match_operator:SWI 3 "plusminuslogic_operator"
18262                      [(match_dup 0)
18263                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18264               (clobber (reg:CC FLAGS_REG))])
18265    (set (match_dup 1) (match_dup 0))
18266    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18267   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18268    && peep2_reg_dead_p (4, operands[0])
18269    && !reg_overlap_mentioned_p (operands[0], operands[1])
18270    && !reg_overlap_mentioned_p (operands[0], operands[2])
18271    && (<MODE>mode != QImode
18272        || immediate_operand (operands[2], QImode)
18273        || any_QIreg_operand (operands[2], QImode))
18274    && ix86_match_ccmode (peep2_next_insn (3),
18275                          (GET_CODE (operands[3]) == PLUS
18276                           || GET_CODE (operands[3]) == MINUS)
18277                          ? CCGOCmode : CCNOmode)"
18278   [(parallel [(set (match_dup 4) (match_dup 6))
18279               (set (match_dup 1) (match_dup 5))])]
18281   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18282   operands[5]
18283     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18284                       copy_rtx (operands[1]),
18285                       operands[2]);
18286   operands[6]
18287     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18288                        copy_rtx (operands[5]),
18289                        const0_rtx);
18292 ;; Likewise for cmpelim optimized pattern.
18293 (define_peephole2
18294   [(set (match_operand:SWI 0 "register_operand")
18295         (match_operand:SWI 1 "memory_operand"))
18296    (parallel [(set (reg FLAGS_REG)
18297                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
18298                               [(match_dup 0)
18299                                (match_operand:SWI 2 "<nonmemory_operand>")])
18300                             (const_int 0)))
18301               (set (match_dup 0) (match_dup 3))])
18302    (set (match_dup 1) (match_dup 0))]
18303   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18304    && peep2_reg_dead_p (3, operands[0])
18305    && !reg_overlap_mentioned_p (operands[0], operands[1])
18306    && !reg_overlap_mentioned_p (operands[0], operands[2])
18307    && ix86_match_ccmode (peep2_next_insn (1),
18308                          (GET_CODE (operands[3]) == PLUS
18309                           || GET_CODE (operands[3]) == MINUS)
18310                          ? CCGOCmode : CCNOmode)"
18311   [(parallel [(set (match_dup 4) (match_dup 6))
18312               (set (match_dup 1) (match_dup 5))])]
18314   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18315   operands[5]
18316     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18317                       copy_rtx (operands[1]), operands[2]);
18318   operands[6]
18319     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18320                        const0_rtx);
18323 ;; Likewise for instances where we have a lea pattern.
18324 (define_peephole2
18325   [(set (match_operand:SWI 0 "register_operand")
18326         (match_operand:SWI 1 "memory_operand"))
18327    (set (match_operand:SWI 3 "register_operand")
18328         (plus:SWI (match_dup 0)
18329                   (match_operand:SWI 2 "<nonmemory_operand>")))
18330    (set (match_dup 1) (match_dup 3))
18331    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18332   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18333    && peep2_reg_dead_p (4, operands[3])
18334    && (rtx_equal_p (operands[0], operands[3])
18335        || peep2_reg_dead_p (2, operands[0]))
18336    && !reg_overlap_mentioned_p (operands[0], operands[1])
18337    && !reg_overlap_mentioned_p (operands[3], operands[1])
18338    && !reg_overlap_mentioned_p (operands[0], operands[2])
18339    && (<MODE>mode != QImode
18340        || immediate_operand (operands[2], QImode)
18341        || any_QIreg_operand (operands[2], QImode))
18342    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18343   [(parallel [(set (match_dup 4) (match_dup 6))
18344               (set (match_dup 1) (match_dup 5))])]
18346   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18347   operands[5]
18348     = gen_rtx_PLUS (<MODE>mode,
18349                     copy_rtx (operands[1]),
18350                     operands[2]);
18351   operands[6]
18352     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18353                        copy_rtx (operands[5]),
18354                        const0_rtx);
18357 (define_peephole2
18358   [(parallel [(set (match_operand:SWI 0 "register_operand")
18359                    (match_operator:SWI 2 "plusminuslogic_operator"
18360                      [(match_dup 0)
18361                       (match_operand:SWI 1 "memory_operand")]))
18362               (clobber (reg:CC FLAGS_REG))])
18363    (set (match_dup 1) (match_dup 0))
18364    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18365   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18366    && COMMUTATIVE_ARITH_P (operands[2])
18367    && peep2_reg_dead_p (3, operands[0])
18368    && !reg_overlap_mentioned_p (operands[0], operands[1])
18369    && ix86_match_ccmode (peep2_next_insn (2),
18370                          GET_CODE (operands[2]) == PLUS
18371                          ? CCGOCmode : CCNOmode)"
18372   [(parallel [(set (match_dup 3) (match_dup 5))
18373               (set (match_dup 1) (match_dup 4))])]
18375   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18376   operands[4]
18377     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18378                       copy_rtx (operands[1]),
18379                       operands[0]);
18380   operands[5]
18381     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18382                        copy_rtx (operands[4]),
18383                        const0_rtx);
18386 ;; Likewise for cmpelim optimized pattern.
18387 (define_peephole2
18388   [(parallel [(set (reg FLAGS_REG)
18389                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
18390                               [(match_operand:SWI 0 "register_operand")
18391                                (match_operand:SWI 1 "memory_operand")])
18392                             (const_int 0)))
18393               (set (match_dup 0) (match_dup 2))])
18394    (set (match_dup 1) (match_dup 0))]
18395   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18396    && COMMUTATIVE_ARITH_P (operands[2])
18397    && peep2_reg_dead_p (2, operands[0])
18398    && !reg_overlap_mentioned_p (operands[0], operands[1])
18399    && ix86_match_ccmode (peep2_next_insn (0),
18400                          GET_CODE (operands[2]) == PLUS
18401                          ? CCGOCmode : CCNOmode)"
18402   [(parallel [(set (match_dup 3) (match_dup 5))
18403               (set (match_dup 1) (match_dup 4))])]
18405   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18406   operands[4]
18407     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18408                       copy_rtx (operands[1]), operands[0]);
18409   operands[5]
18410     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18411                        const0_rtx);
18414 (define_peephole2
18415   [(set (match_operand:SWI12 0 "register_operand")
18416         (match_operand:SWI12 1 "memory_operand"))
18417    (parallel [(set (match_operand:SI 4 "register_operand")
18418                    (match_operator:SI 3 "plusminuslogic_operator"
18419                      [(match_dup 4)
18420                       (match_operand:SI 2 "nonmemory_operand")]))
18421               (clobber (reg:CC FLAGS_REG))])
18422    (set (match_dup 1) (match_dup 0))
18423    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18424   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18425    && REGNO (operands[0]) == REGNO (operands[4])
18426    && peep2_reg_dead_p (4, operands[0])
18427    && (<MODE>mode != QImode
18428        || immediate_operand (operands[2], SImode)
18429        || any_QIreg_operand (operands[2], SImode))
18430    && !reg_overlap_mentioned_p (operands[0], operands[1])
18431    && !reg_overlap_mentioned_p (operands[0], operands[2])
18432    && ix86_match_ccmode (peep2_next_insn (3),
18433                          (GET_CODE (operands[3]) == PLUS
18434                           || GET_CODE (operands[3]) == MINUS)
18435                          ? CCGOCmode : CCNOmode)"
18436   [(parallel [(set (match_dup 4) (match_dup 6))
18437               (set (match_dup 1) (match_dup 5))])]
18439   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18440   operands[5]
18441     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18442                       copy_rtx (operands[1]),
18443                       gen_lowpart (<MODE>mode, operands[2]));
18444   operands[6]
18445     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18446                        copy_rtx (operands[5]),
18447                        const0_rtx);
18450 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18451 (define_peephole2
18452   [(set (match_operand 0 "general_reg_operand")
18453         (match_operand 1 "const0_operand"))]
18454   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18455    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18456    && peep2_regno_dead_p (0, FLAGS_REG)"
18457   [(parallel [(set (match_dup 0) (const_int 0))
18458               (clobber (reg:CC FLAGS_REG))])]
18459   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18461 (define_peephole2
18462   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18463         (const_int 0))]
18464   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18465    && peep2_regno_dead_p (0, FLAGS_REG)"
18466   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18467               (clobber (reg:CC FLAGS_REG))])])
18469 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18470 (define_peephole2
18471   [(set (match_operand:SWI248 0 "general_reg_operand")
18472         (const_int -1))]
18473   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18474    && peep2_regno_dead_p (0, FLAGS_REG)"
18475   [(parallel [(set (match_dup 0) (const_int -1))
18476               (clobber (reg:CC FLAGS_REG))])]
18478   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18479     operands[0] = gen_lowpart (SImode, operands[0]);
18482 ;; Attempt to convert simple lea to add/shift.
18483 ;; These can be created by move expanders.
18484 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18485 ;; relevant lea instructions were already split.
18487 (define_peephole2
18488   [(set (match_operand:SWI48 0 "register_operand")
18489         (plus:SWI48 (match_dup 0)
18490                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18491   "!TARGET_OPT_AGU
18492    && peep2_regno_dead_p (0, FLAGS_REG)"
18493   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18494               (clobber (reg:CC FLAGS_REG))])])
18496 (define_peephole2
18497   [(set (match_operand:SWI48 0 "register_operand")
18498         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18499                     (match_dup 0)))]
18500   "!TARGET_OPT_AGU
18501    && peep2_regno_dead_p (0, FLAGS_REG)"
18502   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18503               (clobber (reg:CC FLAGS_REG))])])
18505 (define_peephole2
18506   [(set (match_operand:DI 0 "register_operand")
18507         (zero_extend:DI
18508           (plus:SI (match_operand:SI 1 "register_operand")
18509                    (match_operand:SI 2 "nonmemory_operand"))))]
18510   "TARGET_64BIT && !TARGET_OPT_AGU
18511    && REGNO (operands[0]) == REGNO (operands[1])
18512    && peep2_regno_dead_p (0, FLAGS_REG)"
18513   [(parallel [(set (match_dup 0)
18514                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18515               (clobber (reg:CC FLAGS_REG))])])
18517 (define_peephole2
18518   [(set (match_operand:DI 0 "register_operand")
18519         (zero_extend:DI
18520           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18521                    (match_operand:SI 2 "register_operand"))))]
18522   "TARGET_64BIT && !TARGET_OPT_AGU
18523    && REGNO (operands[0]) == REGNO (operands[2])
18524    && peep2_regno_dead_p (0, FLAGS_REG)"
18525   [(parallel [(set (match_dup 0)
18526                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18527               (clobber (reg:CC FLAGS_REG))])])
18529 (define_peephole2
18530   [(set (match_operand:SWI48 0 "register_operand")
18531         (mult:SWI48 (match_dup 0)
18532                     (match_operand:SWI48 1 "const_int_operand")))]
18533   "pow2p_hwi (INTVAL (operands[1]))
18534    && peep2_regno_dead_p (0, FLAGS_REG)"
18535   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18536               (clobber (reg:CC FLAGS_REG))])]
18537   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18539 (define_peephole2
18540   [(set (match_operand:DI 0 "register_operand")
18541         (zero_extend:DI
18542           (mult:SI (match_operand:SI 1 "register_operand")
18543                    (match_operand:SI 2 "const_int_operand"))))]
18544   "TARGET_64BIT
18545    && pow2p_hwi (INTVAL (operands[2]))
18546    && REGNO (operands[0]) == REGNO (operands[1])
18547    && peep2_regno_dead_p (0, FLAGS_REG)"
18548   [(parallel [(set (match_dup 0)
18549                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18550               (clobber (reg:CC FLAGS_REG))])]
18551   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18553 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18554 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18555 ;; On many CPUs it is also faster, since special hardware to avoid esp
18556 ;; dependencies is present.
18558 ;; While some of these conversions may be done using splitters, we use
18559 ;; peepholes in order to allow combine_stack_adjustments pass to see
18560 ;; nonobfuscated RTL.
18562 ;; Convert prologue esp subtractions to push.
18563 ;; We need register to push.  In order to keep verify_flow_info happy we have
18564 ;; two choices
18565 ;; - use scratch and clobber it in order to avoid dependencies
18566 ;; - use already live register
18567 ;; We can't use the second way right now, since there is no reliable way how to
18568 ;; verify that given register is live.  First choice will also most likely in
18569 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18570 ;; call clobbered registers are dead.  We may want to use base pointer as an
18571 ;; alternative when no register is available later.
18573 (define_peephole2
18574   [(match_scratch:W 1 "r")
18575    (parallel [(set (reg:P SP_REG)
18576                    (plus:P (reg:P SP_REG)
18577                            (match_operand:P 0 "const_int_operand")))
18578               (clobber (reg:CC FLAGS_REG))
18579               (clobber (mem:BLK (scratch)))])]
18580   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18581    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18582    && ix86_red_zone_size == 0"
18583   [(clobber (match_dup 1))
18584    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18585               (clobber (mem:BLK (scratch)))])])
18587 (define_peephole2
18588   [(match_scratch:W 1 "r")
18589    (parallel [(set (reg:P SP_REG)
18590                    (plus:P (reg:P SP_REG)
18591                            (match_operand:P 0 "const_int_operand")))
18592               (clobber (reg:CC FLAGS_REG))
18593               (clobber (mem:BLK (scratch)))])]
18594   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18595    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18596    && ix86_red_zone_size == 0"
18597   [(clobber (match_dup 1))
18598    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18599    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18600               (clobber (mem:BLK (scratch)))])])
18602 ;; Convert esp subtractions to push.
18603 (define_peephole2
18604   [(match_scratch:W 1 "r")
18605    (parallel [(set (reg:P SP_REG)
18606                    (plus:P (reg:P SP_REG)
18607                            (match_operand:P 0 "const_int_operand")))
18608               (clobber (reg:CC FLAGS_REG))])]
18609   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18610    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18611    && ix86_red_zone_size == 0"
18612   [(clobber (match_dup 1))
18613    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18615 (define_peephole2
18616   [(match_scratch:W 1 "r")
18617    (parallel [(set (reg:P SP_REG)
18618                    (plus:P (reg:P SP_REG)
18619                            (match_operand:P 0 "const_int_operand")))
18620               (clobber (reg:CC FLAGS_REG))])]
18621   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18622    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18623    && ix86_red_zone_size == 0"
18624   [(clobber (match_dup 1))
18625    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18626    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18628 ;; Convert epilogue deallocator to pop.
18629 (define_peephole2
18630   [(match_scratch:W 1 "r")
18631    (parallel [(set (reg:P SP_REG)
18632                    (plus:P (reg:P SP_REG)
18633                            (match_operand:P 0 "const_int_operand")))
18634               (clobber (reg:CC FLAGS_REG))
18635               (clobber (mem:BLK (scratch)))])]
18636   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18637    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18638   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18639               (clobber (mem:BLK (scratch)))])])
18641 ;; Two pops case is tricky, since pop causes dependency
18642 ;; on destination register.  We use two registers if available.
18643 (define_peephole2
18644   [(match_scratch:W 1 "r")
18645    (match_scratch:W 2 "r")
18646    (parallel [(set (reg:P SP_REG)
18647                    (plus:P (reg:P SP_REG)
18648                            (match_operand:P 0 "const_int_operand")))
18649               (clobber (reg:CC FLAGS_REG))
18650               (clobber (mem:BLK (scratch)))])]
18651   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18652    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18653   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18654               (clobber (mem:BLK (scratch)))])
18655    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18657 (define_peephole2
18658   [(match_scratch:W 1 "r")
18659    (parallel [(set (reg:P SP_REG)
18660                    (plus:P (reg:P SP_REG)
18661                            (match_operand:P 0 "const_int_operand")))
18662               (clobber (reg:CC FLAGS_REG))
18663               (clobber (mem:BLK (scratch)))])]
18664   "optimize_insn_for_size_p ()
18665    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18666   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18667               (clobber (mem:BLK (scratch)))])
18668    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18670 ;; Convert esp additions to pop.
18671 (define_peephole2
18672   [(match_scratch:W 1 "r")
18673    (parallel [(set (reg:P SP_REG)
18674                    (plus:P (reg:P SP_REG)
18675                            (match_operand:P 0 "const_int_operand")))
18676               (clobber (reg:CC FLAGS_REG))])]
18677   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18678   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18680 ;; Two pops case is tricky, since pop causes dependency
18681 ;; on destination register.  We use two registers if available.
18682 (define_peephole2
18683   [(match_scratch:W 1 "r")
18684    (match_scratch:W 2 "r")
18685    (parallel [(set (reg:P SP_REG)
18686                    (plus:P (reg:P SP_REG)
18687                            (match_operand:P 0 "const_int_operand")))
18688               (clobber (reg:CC FLAGS_REG))])]
18689   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18690   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18691    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18693 (define_peephole2
18694   [(match_scratch:W 1 "r")
18695    (parallel [(set (reg:P SP_REG)
18696                    (plus:P (reg:P SP_REG)
18697                            (match_operand:P 0 "const_int_operand")))
18698               (clobber (reg:CC FLAGS_REG))])]
18699   "optimize_insn_for_size_p ()
18700    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18701   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18702    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18704 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18705 ;; required and register dies.  Similarly for 128 to -128.
18706 (define_peephole2
18707   [(set (match_operand 0 "flags_reg_operand")
18708         (match_operator 1 "compare_operator"
18709           [(match_operand 2 "register_operand")
18710            (match_operand 3 "const_int_operand")]))]
18711   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18712      && incdec_operand (operands[3], GET_MODE (operands[3])))
18713     || (!TARGET_FUSE_CMP_AND_BRANCH
18714         && INTVAL (operands[3]) == 128))
18715    && ix86_match_ccmode (insn, CCGCmode)
18716    && peep2_reg_dead_p (1, operands[2])"
18717   [(parallel [(set (match_dup 0)
18718                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18719               (clobber (match_dup 2))])])
18721 ;; Convert imul by three, five and nine into lea
18722 (define_peephole2
18723   [(parallel
18724     [(set (match_operand:SWI48 0 "register_operand")
18725           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18726                       (match_operand:SWI48 2 "const359_operand")))
18727      (clobber (reg:CC FLAGS_REG))])]
18728   "!TARGET_PARTIAL_REG_STALL
18729    || <MODE>mode == SImode
18730    || optimize_function_for_size_p (cfun)"
18731   [(set (match_dup 0)
18732         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18733                     (match_dup 1)))]
18734   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18736 (define_peephole2
18737   [(parallel
18738     [(set (match_operand:SWI48 0 "register_operand")
18739           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18740                       (match_operand:SWI48 2 "const359_operand")))
18741      (clobber (reg:CC FLAGS_REG))])]
18742   "optimize_insn_for_speed_p ()
18743    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18744   [(set (match_dup 0) (match_dup 1))
18745    (set (match_dup 0)
18746         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18747                     (match_dup 0)))]
18748   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18750 ;; imul $32bit_imm, mem, reg is vector decoded, while
18751 ;; imul $32bit_imm, reg, reg is direct decoded.
18752 (define_peephole2
18753   [(match_scratch:SWI48 3 "r")
18754    (parallel [(set (match_operand:SWI48 0 "register_operand")
18755                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18756                                (match_operand:SWI48 2 "immediate_operand")))
18757               (clobber (reg:CC FLAGS_REG))])]
18758   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18759    && !satisfies_constraint_K (operands[2])"
18760   [(set (match_dup 3) (match_dup 1))
18761    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18762               (clobber (reg:CC FLAGS_REG))])])
18764 (define_peephole2
18765   [(match_scratch:SI 3 "r")
18766    (parallel [(set (match_operand:DI 0 "register_operand")
18767                    (zero_extend:DI
18768                      (mult:SI (match_operand:SI 1 "memory_operand")
18769                               (match_operand:SI 2 "immediate_operand"))))
18770               (clobber (reg:CC FLAGS_REG))])]
18771   "TARGET_64BIT
18772    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18773    && !satisfies_constraint_K (operands[2])"
18774   [(set (match_dup 3) (match_dup 1))
18775    (parallel [(set (match_dup 0)
18776                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18777               (clobber (reg:CC FLAGS_REG))])])
18779 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18780 ;; Convert it into imul reg, reg
18781 ;; It would be better to force assembler to encode instruction using long
18782 ;; immediate, but there is apparently no way to do so.
18783 (define_peephole2
18784   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18785                    (mult:SWI248
18786                     (match_operand:SWI248 1 "nonimmediate_operand")
18787                     (match_operand:SWI248 2 "const_int_operand")))
18788               (clobber (reg:CC FLAGS_REG))])
18789    (match_scratch:SWI248 3 "r")]
18790   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18791    && satisfies_constraint_K (operands[2])"
18792   [(set (match_dup 3) (match_dup 2))
18793    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18794               (clobber (reg:CC FLAGS_REG))])]
18796   if (!rtx_equal_p (operands[0], operands[1]))
18797     emit_move_insn (operands[0], operands[1]);
18800 ;; After splitting up read-modify operations, array accesses with memory
18801 ;; operands might end up in form:
18802 ;;  sall    $2, %eax
18803 ;;  movl    4(%esp), %edx
18804 ;;  addl    %edx, %eax
18805 ;; instead of pre-splitting:
18806 ;;  sall    $2, %eax
18807 ;;  addl    4(%esp), %eax
18808 ;; Turn it into:
18809 ;;  movl    4(%esp), %edx
18810 ;;  leal    (%edx,%eax,4), %eax
18812 (define_peephole2
18813   [(match_scratch:W 5 "r")
18814    (parallel [(set (match_operand 0 "register_operand")
18815                    (ashift (match_operand 1 "register_operand")
18816                            (match_operand 2 "const_int_operand")))
18817                (clobber (reg:CC FLAGS_REG))])
18818    (parallel [(set (match_operand 3 "register_operand")
18819                    (plus (match_dup 0)
18820                          (match_operand 4 "x86_64_general_operand")))
18821                    (clobber (reg:CC FLAGS_REG))])]
18822   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18823    /* Validate MODE for lea.  */
18824    && ((!TARGET_PARTIAL_REG_STALL
18825         && (GET_MODE (operands[0]) == QImode
18826             || GET_MODE (operands[0]) == HImode))
18827        || GET_MODE (operands[0]) == SImode
18828        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18829    && (rtx_equal_p (operands[0], operands[3])
18830        || peep2_reg_dead_p (2, operands[0]))
18831    /* We reorder load and the shift.  */
18832    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18833   [(set (match_dup 5) (match_dup 4))
18834    (set (match_dup 0) (match_dup 1))]
18836   machine_mode op1mode = GET_MODE (operands[1]);
18837   machine_mode mode = op1mode == DImode ? DImode : SImode;
18838   int scale = 1 << INTVAL (operands[2]);
18839   rtx index = gen_lowpart (word_mode, operands[1]);
18840   rtx base = gen_lowpart (word_mode, operands[5]);
18841   rtx dest = gen_lowpart (mode, operands[3]);
18843   operands[1] = gen_rtx_PLUS (word_mode, base,
18844                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18845   if (mode != word_mode)
18846     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18848   operands[5] = base;
18849   if (op1mode != word_mode)
18850     operands[5] = gen_lowpart (op1mode, operands[5]);
18852   operands[0] = dest;
18855 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18856 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18857 ;; caught for use by garbage collectors and the like.  Using an insn that
18858 ;; maps to SIGILL makes it more likely the program will rightfully die.
18859 ;; Keeping with tradition, "6" is in honor of #UD.
18860 (define_insn "trap"
18861   [(trap_if (const_int 1) (const_int 6))]
18862   ""
18864 #ifdef HAVE_AS_IX86_UD2
18865   return "ud2";
18866 #else
18867   return ASM_SHORT "0x0b0f";
18868 #endif
18870   [(set_attr "length" "2")])
18872 (define_insn "ud2"
18873   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
18874   ""
18876 #ifdef HAVE_AS_IX86_UD2
18877   return "ud2";
18878 #else
18879   return ASM_SHORT "0x0b0f";
18880 #endif
18882   [(set_attr "length" "2")])
18884 (define_expand "prefetch"
18885   [(prefetch (match_operand 0 "address_operand")
18886              (match_operand:SI 1 "const_int_operand")
18887              (match_operand:SI 2 "const_int_operand"))]
18888   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18890   bool write = INTVAL (operands[1]) != 0;
18891   int locality = INTVAL (operands[2]);
18893   gcc_assert (IN_RANGE (locality, 0, 3));
18895   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18896      supported by SSE counterpart (non-SSE2 athlon machines) or the
18897      SSE prefetch is not available (K6 machines).  Otherwise use SSE
18898      prefetch as it allows specifying of locality.  */
18900   if (write)
18901     {
18902       if (TARGET_PREFETCHWT1)
18903         operands[2] = GEN_INT (MAX (locality, 2)); 
18904       else if (TARGET_PRFCHW)
18905         operands[2] = GEN_INT (3);
18906       else if (TARGET_3DNOW && !TARGET_SSE2)
18907         operands[2] = GEN_INT (3);
18908       else if (TARGET_PREFETCH_SSE)
18909         operands[1] = const0_rtx;
18910       else
18911         {
18912           gcc_assert (TARGET_3DNOW);
18913           operands[2] = GEN_INT (3);
18914         }
18915     }
18916   else
18917     {
18918       if (TARGET_PREFETCH_SSE)
18919         ;
18920       else
18921         {
18922           gcc_assert (TARGET_3DNOW);
18923           operands[2] = GEN_INT (3);
18924         }
18925     }
18928 (define_insn "*prefetch_sse"
18929   [(prefetch (match_operand 0 "address_operand" "p")
18930              (const_int 0)
18931              (match_operand:SI 1 "const_int_operand"))]
18932   "TARGET_PREFETCH_SSE"
18934   static const char * const patterns[4] = {
18935    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18936   };
18938   int locality = INTVAL (operands[1]);
18939   gcc_assert (IN_RANGE (locality, 0, 3));
18941   return patterns[locality];
18943   [(set_attr "type" "sse")
18944    (set_attr "atom_sse_attr" "prefetch")
18945    (set (attr "length_address")
18946         (symbol_ref "memory_address_length (operands[0], false)"))
18947    (set_attr "memory" "none")])
18949 (define_insn "*prefetch_3dnow"
18950   [(prefetch (match_operand 0 "address_operand" "p")
18951              (match_operand:SI 1 "const_int_operand" "n")
18952              (const_int 3))]
18953   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18955   if (INTVAL (operands[1]) == 0)
18956     return "prefetch\t%a0";
18957   else
18958     return "prefetchw\t%a0";
18960   [(set_attr "type" "mmx")
18961    (set (attr "length_address")
18962         (symbol_ref "memory_address_length (operands[0], false)"))
18963    (set_attr "memory" "none")])
18965 (define_insn "*prefetch_prefetchwt1"
18966   [(prefetch (match_operand 0 "address_operand" "p")
18967              (const_int 1)
18968              (const_int 2))]
18969   "TARGET_PREFETCHWT1"
18970   "prefetchwt1\t%a0";
18971   [(set_attr "type" "sse")
18972    (set (attr "length_address")
18973         (symbol_ref "memory_address_length (operands[0], false)"))
18974    (set_attr "memory" "none")])
18976 (define_expand "stack_protect_set"
18977   [(match_operand 0 "memory_operand")
18978    (match_operand 1 "memory_operand")]
18979   "TARGET_SSP_TLS_GUARD"
18981   rtx (*insn)(rtx, rtx);
18983   insn = (TARGET_LP64
18984           ? gen_stack_protect_set_di
18985           : gen_stack_protect_set_si);
18987   emit_insn (insn (operands[0], operands[1]));
18988   DONE;
18991 (define_insn "stack_protect_set_<mode>"
18992   [(set (match_operand:PTR 0 "memory_operand" "=m")
18993         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18994                     UNSPEC_SP_SET))
18995    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18996    (clobber (reg:CC FLAGS_REG))]
18997   "TARGET_SSP_TLS_GUARD"
18998   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18999   [(set_attr "type" "multi")])
19001 (define_expand "stack_protect_test"
19002   [(match_operand 0 "memory_operand")
19003    (match_operand 1 "memory_operand")
19004    (match_operand 2)]
19005   "TARGET_SSP_TLS_GUARD"
19007   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19009   rtx (*insn)(rtx, rtx, rtx);
19011   insn = (TARGET_LP64
19012           ? gen_stack_protect_test_di
19013           : gen_stack_protect_test_si);
19015   emit_insn (insn (flags, operands[0], operands[1]));
19017   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19018                                   flags, const0_rtx, operands[2]));
19019   DONE;
19022 (define_insn "stack_protect_test_<mode>"
19023   [(set (match_operand:CCZ 0 "flags_reg_operand")
19024         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19025                      (match_operand:PTR 2 "memory_operand" "m")]
19026                     UNSPEC_SP_TEST))
19027    (clobber (match_scratch:PTR 3 "=&r"))]
19028   "TARGET_SSP_TLS_GUARD"
19029   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19030   [(set_attr "type" "multi")])
19032 (define_insn "sse4_2_crc32<mode>"
19033   [(set (match_operand:SI 0 "register_operand" "=r")
19034         (unspec:SI
19035           [(match_operand:SI 1 "register_operand" "0")
19036            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19037           UNSPEC_CRC32))]
19038   "TARGET_SSE4_2 || TARGET_CRC32"
19039   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19040   [(set_attr "type" "sselog1")
19041    (set_attr "prefix_rep" "1")
19042    (set_attr "prefix_extra" "1")
19043    (set (attr "prefix_data16")
19044      (if_then_else (match_operand:HI 2)
19045        (const_string "1")
19046        (const_string "*")))
19047    (set (attr "prefix_rex")
19048      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19049        (const_string "1")
19050        (const_string "*")))
19051    (set_attr "mode" "SI")])
19053 (define_insn "sse4_2_crc32di"
19054   [(set (match_operand:DI 0 "register_operand" "=r")
19055         (unspec:DI
19056           [(match_operand:DI 1 "register_operand" "0")
19057            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19058           UNSPEC_CRC32))]
19059   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19060   "crc32{q}\t{%2, %0|%0, %2}"
19061   [(set_attr "type" "sselog1")
19062    (set_attr "prefix_rep" "1")
19063    (set_attr "prefix_extra" "1")
19064    (set_attr "mode" "DI")])
19066 (define_insn "rdpmc"
19067   [(set (match_operand:DI 0 "register_operand" "=A")
19068         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19069                             UNSPECV_RDPMC))]
19070   "!TARGET_64BIT"
19071   "rdpmc"
19072   [(set_attr "type" "other")
19073    (set_attr "length" "2")])
19075 (define_insn "rdpmc_rex64"
19076   [(set (match_operand:DI 0 "register_operand" "=a")
19077         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19078                             UNSPECV_RDPMC))
19079    (set (match_operand:DI 1 "register_operand" "=d")
19080         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19081   "TARGET_64BIT"
19082   "rdpmc"
19083   [(set_attr "type" "other")
19084    (set_attr "length" "2")])
19086 (define_insn "rdtsc"
19087   [(set (match_operand:DI 0 "register_operand" "=A")
19088         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19089   "!TARGET_64BIT"
19090   "rdtsc"
19091   [(set_attr "type" "other")
19092    (set_attr "length" "2")])
19094 (define_insn "rdtsc_rex64"
19095   [(set (match_operand:DI 0 "register_operand" "=a")
19096         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19097    (set (match_operand:DI 1 "register_operand" "=d")
19098         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19099   "TARGET_64BIT"
19100   "rdtsc"
19101   [(set_attr "type" "other")
19102    (set_attr "length" "2")])
19104 (define_insn "rdtscp"
19105   [(set (match_operand:DI 0 "register_operand" "=A")
19106         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19107    (set (match_operand:SI 1 "register_operand" "=c")
19108         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19109   "!TARGET_64BIT"
19110   "rdtscp"
19111   [(set_attr "type" "other")
19112    (set_attr "length" "3")])
19114 (define_insn "rdtscp_rex64"
19115   [(set (match_operand:DI 0 "register_operand" "=a")
19116         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19117    (set (match_operand:DI 1 "register_operand" "=d")
19118         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19119    (set (match_operand:SI 2 "register_operand" "=c")
19120         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19121   "TARGET_64BIT"
19122   "rdtscp"
19123   [(set_attr "type" "other")
19124    (set_attr "length" "3")])
19126 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19128 ;; FXSR, XSAVE and XSAVEOPT instructions
19130 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19132 (define_insn "fxsave"
19133   [(set (match_operand:BLK 0 "memory_operand" "=m")
19134         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19135   "TARGET_FXSR"
19136   "fxsave\t%0"
19137   [(set_attr "type" "other")
19138    (set_attr "memory" "store")
19139    (set (attr "length")
19140         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19142 (define_insn "fxsave64"
19143   [(set (match_operand:BLK 0 "memory_operand" "=m")
19144         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19145   "TARGET_64BIT && TARGET_FXSR"
19146   "fxsave64\t%0"
19147   [(set_attr "type" "other")
19148    (set_attr "memory" "store")
19149    (set (attr "length")
19150         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19152 (define_insn "fxrstor"
19153   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19154                     UNSPECV_FXRSTOR)]
19155   "TARGET_FXSR"
19156   "fxrstor\t%0"
19157   [(set_attr "type" "other")
19158    (set_attr "memory" "load")
19159    (set (attr "length")
19160         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19162 (define_insn "fxrstor64"
19163   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19164                     UNSPECV_FXRSTOR64)]
19165   "TARGET_64BIT && TARGET_FXSR"
19166   "fxrstor64\t%0"
19167   [(set_attr "type" "other")
19168    (set_attr "memory" "load")
19169    (set (attr "length")
19170         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19172 (define_int_iterator ANY_XSAVE
19173         [UNSPECV_XSAVE
19174          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19175          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19176          (UNSPECV_XSAVES "TARGET_XSAVES")])
19178 (define_int_iterator ANY_XSAVE64
19179         [UNSPECV_XSAVE64
19180          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19181          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19182          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19184 (define_int_attr xsave
19185         [(UNSPECV_XSAVE "xsave")
19186          (UNSPECV_XSAVE64 "xsave64")
19187          (UNSPECV_XSAVEOPT "xsaveopt")
19188          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19189          (UNSPECV_XSAVEC "xsavec")
19190          (UNSPECV_XSAVEC64 "xsavec64")
19191          (UNSPECV_XSAVES "xsaves")
19192          (UNSPECV_XSAVES64 "xsaves64")])
19194 (define_int_iterator ANY_XRSTOR
19195         [UNSPECV_XRSTOR
19196          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19198 (define_int_iterator ANY_XRSTOR64
19199         [UNSPECV_XRSTOR64
19200          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19202 (define_int_attr xrstor
19203         [(UNSPECV_XRSTOR "xrstor")
19204          (UNSPECV_XRSTOR64 "xrstor")
19205          (UNSPECV_XRSTORS "xrstors")
19206          (UNSPECV_XRSTORS64 "xrstors")])
19208 (define_insn "<xsave>"
19209   [(set (match_operand:BLK 0 "memory_operand" "=m")
19210         (unspec_volatile:BLK
19211          [(match_operand:DI 1 "register_operand" "A")]
19212          ANY_XSAVE))]
19213   "!TARGET_64BIT && TARGET_XSAVE"
19214   "<xsave>\t%0"
19215   [(set_attr "type" "other")
19216    (set_attr "memory" "store")
19217    (set (attr "length")
19218         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19220 (define_insn "<xsave>_rex64"
19221   [(set (match_operand:BLK 0 "memory_operand" "=m")
19222         (unspec_volatile:BLK
19223          [(match_operand:SI 1 "register_operand" "a")
19224           (match_operand:SI 2 "register_operand" "d")]
19225          ANY_XSAVE))]
19226   "TARGET_64BIT && TARGET_XSAVE"
19227   "<xsave>\t%0"
19228   [(set_attr "type" "other")
19229    (set_attr "memory" "store")
19230    (set (attr "length")
19231         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19233 (define_insn "<xsave>"
19234   [(set (match_operand:BLK 0 "memory_operand" "=m")
19235         (unspec_volatile:BLK
19236          [(match_operand:SI 1 "register_operand" "a")
19237           (match_operand:SI 2 "register_operand" "d")]
19238          ANY_XSAVE64))]
19239   "TARGET_64BIT && TARGET_XSAVE"
19240   "<xsave>\t%0"
19241   [(set_attr "type" "other")
19242    (set_attr "memory" "store")
19243    (set (attr "length")
19244         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19246 (define_insn "<xrstor>"
19247    [(unspec_volatile:BLK
19248      [(match_operand:BLK 0 "memory_operand" "m")
19249       (match_operand:DI 1 "register_operand" "A")]
19250      ANY_XRSTOR)]
19251   "!TARGET_64BIT && TARGET_XSAVE"
19252   "<xrstor>\t%0"
19253   [(set_attr "type" "other")
19254    (set_attr "memory" "load")
19255    (set (attr "length")
19256         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19258 (define_insn "<xrstor>_rex64"
19259    [(unspec_volatile:BLK
19260      [(match_operand:BLK 0 "memory_operand" "m")
19261       (match_operand:SI 1 "register_operand" "a")
19262       (match_operand:SI 2 "register_operand" "d")]
19263      ANY_XRSTOR)]
19264   "TARGET_64BIT && TARGET_XSAVE"
19265   "<xrstor>\t%0"
19266   [(set_attr "type" "other")
19267    (set_attr "memory" "load")
19268    (set (attr "length")
19269         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19271 (define_insn "<xrstor>64"
19272    [(unspec_volatile:BLK
19273      [(match_operand:BLK 0 "memory_operand" "m")
19274       (match_operand:SI 1 "register_operand" "a")
19275       (match_operand:SI 2 "register_operand" "d")]
19276      ANY_XRSTOR64)]
19277   "TARGET_64BIT && TARGET_XSAVE"
19278   "<xrstor>64\t%0"
19279   [(set_attr "type" "other")
19280    (set_attr "memory" "load")
19281    (set (attr "length")
19282         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19284 (define_insn "xsetbv"
19285   [(unspec_volatile:SI
19286          [(match_operand:SI 0 "register_operand" "c")
19287           (match_operand:DI 1 "register_operand" "A")]
19288          UNSPECV_XSETBV)]
19289   "!TARGET_64BIT && TARGET_XSAVE"
19290   "xsetbv"
19291   [(set_attr "type" "other")])
19293 (define_insn "xsetbv_rex64"
19294   [(unspec_volatile:SI
19295          [(match_operand:SI 0 "register_operand" "c")
19296           (match_operand:SI 1 "register_operand" "a")
19297           (match_operand:SI 2 "register_operand" "d")]
19298          UNSPECV_XSETBV)]
19299   "TARGET_64BIT && TARGET_XSAVE"
19300   "xsetbv"
19301   [(set_attr "type" "other")])
19303 (define_insn "xgetbv"
19304   [(set (match_operand:DI 0 "register_operand" "=A")
19305         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19306                             UNSPECV_XGETBV))]
19307   "!TARGET_64BIT && TARGET_XSAVE"
19308   "xgetbv"
19309   [(set_attr "type" "other")])
19311 (define_insn "xgetbv_rex64"
19312   [(set (match_operand:DI 0 "register_operand" "=a")
19313         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19314                             UNSPECV_XGETBV))
19315    (set (match_operand:DI 1 "register_operand" "=d")
19316         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19317   "TARGET_64BIT && TARGET_XSAVE"
19318   "xgetbv"
19319   [(set_attr "type" "other")])
19321 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19323 ;; Floating-point instructions for atomic compound assignments
19325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19327 ; Clobber all floating-point registers on environment save and restore
19328 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19329 (define_insn "fnstenv"
19330   [(set (match_operand:BLK 0 "memory_operand" "=m")
19331         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19332    (clobber (reg:XF ST0_REG))
19333    (clobber (reg:XF ST1_REG))
19334    (clobber (reg:XF ST2_REG))
19335    (clobber (reg:XF ST3_REG))
19336    (clobber (reg:XF ST4_REG))
19337    (clobber (reg:XF ST5_REG))
19338    (clobber (reg:XF ST6_REG))
19339    (clobber (reg:XF ST7_REG))]
19340   "TARGET_80387"
19341   "fnstenv\t%0"
19342   [(set_attr "type" "other")
19343    (set_attr "memory" "store")
19344    (set (attr "length")
19345         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19347 (define_insn "fldenv"
19348   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19349                     UNSPECV_FLDENV)
19350    (clobber (reg:XF ST0_REG))
19351    (clobber (reg:XF ST1_REG))
19352    (clobber (reg:XF ST2_REG))
19353    (clobber (reg:XF ST3_REG))
19354    (clobber (reg:XF ST4_REG))
19355    (clobber (reg:XF ST5_REG))
19356    (clobber (reg:XF ST6_REG))
19357    (clobber (reg:XF ST7_REG))]
19358   "TARGET_80387"
19359   "fldenv\t%0"
19360   [(set_attr "type" "other")
19361    (set_attr "memory" "load")
19362    (set (attr "length")
19363         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19365 (define_insn "fnstsw"
19366   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19367         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19368   "TARGET_80387"
19369   "fnstsw\t%0"
19370   [(set_attr "type" "other,other")
19371    (set_attr "memory" "none,store")
19372    (set (attr "length")
19373         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19375 (define_insn "fnclex"
19376   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19377   "TARGET_80387"
19378   "fnclex"
19379   [(set_attr "type" "other")
19380    (set_attr "memory" "none")
19381    (set_attr "length" "2")])
19383 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19385 ;; LWP instructions
19387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19389 (define_expand "lwp_llwpcb"
19390   [(unspec_volatile [(match_operand 0 "register_operand")]
19391                     UNSPECV_LLWP_INTRINSIC)]
19392   "TARGET_LWP")
19394 (define_insn "*lwp_llwpcb<mode>1"
19395   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19396                     UNSPECV_LLWP_INTRINSIC)]
19397   "TARGET_LWP"
19398   "llwpcb\t%0"
19399   [(set_attr "type" "lwp")
19400    (set_attr "mode" "<MODE>")
19401    (set_attr "length" "5")])
19403 (define_expand "lwp_slwpcb"
19404   [(set (match_operand 0 "register_operand")
19405         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19406   "TARGET_LWP"
19408   rtx (*insn)(rtx);
19410   insn = (Pmode == DImode
19411           ? gen_lwp_slwpcbdi
19412           : gen_lwp_slwpcbsi);
19414   emit_insn (insn (operands[0]));
19415   DONE;
19418 (define_insn "lwp_slwpcb<mode>"
19419   [(set (match_operand:P 0 "register_operand" "=r")
19420         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19421   "TARGET_LWP"
19422   "slwpcb\t%0"
19423   [(set_attr "type" "lwp")
19424    (set_attr "mode" "<MODE>")
19425    (set_attr "length" "5")])
19427 (define_expand "lwp_lwpval<mode>3"
19428   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19429                      (match_operand:SI 2 "nonimmediate_operand")
19430                      (match_operand:SI 3 "const_int_operand")]
19431                     UNSPECV_LWPVAL_INTRINSIC)]
19432   "TARGET_LWP"
19433   ;; Avoid unused variable warning.
19434   "(void) operands[0];")
19436 (define_insn "*lwp_lwpval<mode>3_1"
19437   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19438                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19439                      (match_operand:SI 2 "const_int_operand" "i")]
19440                     UNSPECV_LWPVAL_INTRINSIC)]
19441   "TARGET_LWP"
19442   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19443   [(set_attr "type" "lwp")
19444    (set_attr "mode" "<MODE>")
19445    (set (attr "length")
19446         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19448 (define_expand "lwp_lwpins<mode>3"
19449   [(set (reg:CCC FLAGS_REG)
19450         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19451                               (match_operand:SI 2 "nonimmediate_operand")
19452                               (match_operand:SI 3 "const_int_operand")]
19453                              UNSPECV_LWPINS_INTRINSIC))
19454    (set (match_operand:QI 0 "nonimmediate_operand")
19455         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19456   "TARGET_LWP")
19458 (define_insn "*lwp_lwpins<mode>3_1"
19459   [(set (reg:CCC FLAGS_REG)
19460         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19461                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19462                               (match_operand:SI 2 "const_int_operand" "i")]
19463                              UNSPECV_LWPINS_INTRINSIC))]
19464   "TARGET_LWP"
19465   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19466   [(set_attr "type" "lwp")
19467    (set_attr "mode" "<MODE>")
19468    (set (attr "length")
19469         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19471 (define_int_iterator RDFSGSBASE
19472         [UNSPECV_RDFSBASE
19473          UNSPECV_RDGSBASE])
19475 (define_int_iterator WRFSGSBASE
19476         [UNSPECV_WRFSBASE
19477          UNSPECV_WRGSBASE])
19479 (define_int_attr fsgs
19480         [(UNSPECV_RDFSBASE "fs")
19481          (UNSPECV_RDGSBASE "gs")
19482          (UNSPECV_WRFSBASE "fs")
19483          (UNSPECV_WRGSBASE "gs")])
19485 (define_insn "rd<fsgs>base<mode>"
19486   [(set (match_operand:SWI48 0 "register_operand" "=r")
19487         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19488   "TARGET_64BIT && TARGET_FSGSBASE"
19489   "rd<fsgs>base\t%0"
19490   [(set_attr "type" "other")
19491    (set_attr "prefix_extra" "2")])
19493 (define_insn "wr<fsgs>base<mode>"
19494   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19495                     WRFSGSBASE)]
19496   "TARGET_64BIT && TARGET_FSGSBASE"
19497   "wr<fsgs>base\t%0"
19498   [(set_attr "type" "other")
19499    (set_attr "prefix_extra" "2")])
19501 (define_insn "rdrand<mode>_1"
19502   [(set (match_operand:SWI248 0 "register_operand" "=r")
19503         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19504    (set (reg:CCC FLAGS_REG)
19505         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19506   "TARGET_RDRND"
19507   "rdrand\t%0"
19508   [(set_attr "type" "other")
19509    (set_attr "prefix_extra" "1")])
19511 (define_insn "rdseed<mode>_1"
19512   [(set (match_operand:SWI248 0 "register_operand" "=r")
19513         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19514    (set (reg:CCC FLAGS_REG)
19515         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19516   "TARGET_RDSEED"
19517   "rdseed\t%0"
19518   [(set_attr "type" "other")
19519    (set_attr "prefix_extra" "1")])
19521 (define_expand "pause"
19522   [(set (match_dup 0)
19523         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19524   ""
19526   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19527   MEM_VOLATILE_P (operands[0]) = 1;
19530 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19531 ;; They have the same encoding.
19532 (define_insn "*pause"
19533   [(set (match_operand:BLK 0)
19534         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19535   ""
19536   "rep%; nop"
19537   [(set_attr "length" "2")
19538    (set_attr "memory" "unknown")])
19540 ;; CET instructions
19541 (define_insn "rdssp<mode>"
19542   [(set (match_operand:SWI48x 0 "register_operand" "=r")
19543         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
19544   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19545   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
19546   [(set_attr "length" "6")
19547    (set_attr "type" "other")])
19549 (define_insn "incssp<mode>"
19550   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
19551                     UNSPECV_INCSSP)]
19552   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19553   "incssp<mskmodesuffix>\t%0"
19554   [(set_attr "length" "4")
19555    (set_attr "type" "other")])
19557 (define_insn "saveprevssp"
19558   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
19559   "TARGET_SHSTK"
19560   "saveprevssp"
19561   [(set_attr "length" "5")
19562    (set_attr "type" "other")])
19564 (define_expand "rstorssp"
19565   [(unspec_volatile [(match_operand 0 "memory_operand")]
19566                     UNSPECV_RSTORSSP)]
19567   "TARGET_SHSTK")
19569 (define_insn "*rstorssp<mode>"
19570   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19571                     UNSPECV_RSTORSSP)]
19572   "TARGET_SHSTK"
19573   "rstorssp\t%0"
19574   [(set_attr "length" "5")
19575    (set_attr "type" "other")])
19577 (define_insn "wrss<mode>"
19578   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19579                      (match_operand:SWI48x 1 "memory_operand" "m")]
19580                     UNSPECV_WRSS)]
19581   "TARGET_SHSTK"
19582   "wrss<mskmodesuffix>\t%0, %1"
19583   [(set_attr "length" "3")
19584    (set_attr "type" "other")])
19586 (define_insn "wruss<mode>"
19587   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19588                      (match_operand:SWI48x 1 "memory_operand" "m")]
19589                     UNSPECV_WRUSS)]
19590   "TARGET_SHSTK"
19591   "wruss<mskmodesuffix>\t%0, %1"
19592   [(set_attr "length" "4")
19593    (set_attr "type" "other")])
19595 (define_insn "setssbsy"
19596   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
19597   "TARGET_SHSTK"
19598   "setssbsy"
19599   [(set_attr "length" "4")
19600    (set_attr "type" "other")])
19602 (define_expand "clrssbsy"
19603   [(unspec_volatile [(match_operand 0 "memory_operand")]
19604                     UNSPECV_CLRSSBSY)]
19605   "TARGET_SHSTK")
19607 (define_insn "*clrssbsy<mode>"
19608   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19609                     UNSPECV_CLRSSBSY)]
19610   "TARGET_SHSTK"
19611   "clrssbsy\t%0"
19612   [(set_attr "length" "4")
19613    (set_attr "type" "other")])
19615 (define_insn "nop_endbr"
19616   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
19617   "(flag_cf_protection & CF_BRANCH)"
19619   return TARGET_64BIT ? "endbr64" : "endbr32";
19621   [(set_attr "length" "4")
19622    (set_attr "length_immediate" "0")
19623    (set_attr "modrm" "0")])
19625 ;; For RTM support
19626 (define_expand "xbegin"
19627   [(set (match_operand:SI 0 "register_operand")
19628         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19629   "TARGET_RTM"
19631   rtx_code_label *label = gen_label_rtx ();
19633   /* xbegin is emitted as jump_insn, so reload won't be able
19634      to reload its operand.  Force the value into AX hard register.  */
19635   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19636   emit_move_insn (ax_reg, constm1_rtx);
19638   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19640   emit_label (label);
19641   LABEL_NUSES (label) = 1;
19643   emit_move_insn (operands[0], ax_reg);
19645   DONE;
19648 (define_insn "xbegin_1"
19649   [(set (pc)
19650         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19651                           (const_int 0))
19652                       (label_ref (match_operand 1))
19653                       (pc)))
19654    (set (match_operand:SI 0 "register_operand" "+a")
19655         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19656   "TARGET_RTM"
19657   "xbegin\t%l1"
19658   [(set_attr "type" "other")
19659    (set_attr "length" "6")])
19661 (define_insn "xend"
19662   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19663   "TARGET_RTM"
19664   "xend"
19665   [(set_attr "type" "other")
19666    (set_attr "length" "3")])
19668 (define_insn "xabort"
19669   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19670                     UNSPECV_XABORT)]
19671   "TARGET_RTM"
19672   "xabort\t%0"
19673   [(set_attr "type" "other")
19674    (set_attr "length" "3")])
19676 (define_expand "xtest"
19677   [(set (match_operand:QI 0 "register_operand")
19678         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19679   "TARGET_RTM"
19681   emit_insn (gen_xtest_1 ());
19683   ix86_expand_setcc (operands[0], NE,
19684                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19685   DONE;
19688 (define_insn "xtest_1"
19689   [(set (reg:CCZ FLAGS_REG)
19690         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19691   "TARGET_RTM"
19692   "xtest"
19693   [(set_attr "type" "other")
19694    (set_attr "length" "3")])
19696 (define_insn "clwb"
19697   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19698                    UNSPECV_CLWB)]
19699   "TARGET_CLWB"
19700   "clwb\t%a0"
19701   [(set_attr "type" "sse")
19702    (set_attr "atom_sse_attr" "fence")
19703    (set_attr "memory" "unknown")])
19705 (define_insn "clflushopt"
19706   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19707                    UNSPECV_CLFLUSHOPT)]
19708   "TARGET_CLFLUSHOPT"
19709   "clflushopt\t%a0"
19710   [(set_attr "type" "sse")
19711    (set_attr "atom_sse_attr" "fence")
19712    (set_attr "memory" "unknown")])
19714 ;; MONITORX and MWAITX
19715 (define_insn "mwaitx"
19716   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19717                      (match_operand:SI 1 "register_operand" "a")
19718                      (match_operand:SI 2 "register_operand" "b")]
19719                    UNSPECV_MWAITX)]
19720   "TARGET_MWAITX"
19721 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19722 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19723 ;; we only need to set up 32bit registers.
19724   "mwaitx"
19725   [(set_attr "length" "3")])
19727 (define_insn "monitorx_<mode>"
19728   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19729                      (match_operand:SI 1 "register_operand" "c")
19730                      (match_operand:SI 2 "register_operand" "d")]
19731                    UNSPECV_MONITORX)]
19732   "TARGET_MWAITX"
19733 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19734 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19735 ;; zero extended to 64bit, we only need to set up 32bit registers.
19736   "%^monitorx"
19737   [(set (attr "length")
19738      (symbol_ref ("(Pmode != word_mode) + 3")))])
19740 ;; CLZERO
19741 (define_insn "clzero_<mode>"
19742   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19743                    UNSPECV_CLZERO)]
19744   "TARGET_CLZERO"
19745   "clzero"
19746   [(set_attr "length" "3")
19747   (set_attr "memory" "unknown")])
19749 ;; RDPKRU and WRPKRU
19751 (define_expand "rdpkru"
19752   [(parallel
19753      [(set (match_operand:SI 0 "register_operand")
19754            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19755       (set (match_dup 2) (const_int 0))])]
19756   "TARGET_PKU"
19758   operands[1] = force_reg (SImode, const0_rtx);
19759   operands[2] = gen_reg_rtx (SImode);
19762 (define_insn "*rdpkru"
19763   [(set (match_operand:SI 0 "register_operand" "=a")
19764         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19765                             UNSPECV_PKU))
19766    (set (match_operand:SI 1 "register_operand" "=d")
19767         (const_int 0))]
19768   "TARGET_PKU"
19769   "rdpkru"
19770   [(set_attr "type" "other")])
19772 (define_expand "wrpkru"
19773   [(unspec_volatile:SI
19774      [(match_operand:SI 0 "register_operand")
19775       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19776   "TARGET_PKU"
19778   operands[1] = force_reg (SImode, const0_rtx);
19779   operands[2] = force_reg (SImode, const0_rtx);
19782 (define_insn "*wrpkru"
19783   [(unspec_volatile:SI
19784      [(match_operand:SI 0 "register_operand" "a")
19785       (match_operand:SI 1 "register_operand" "d")
19786       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19787   "TARGET_PKU"
19788   "wrpkru"
19789   [(set_attr "type" "other")])
19791 (define_insn "rdpid"
19792   [(set (match_operand:SI 0 "register_operand" "=r")
19793         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
19794   "!TARGET_64BIT && TARGET_RDPID"
19795   "rdpid\t%0"
19796   [(set_attr "type" "other")])
19798 (define_insn "rdpid_rex64"
19799   [(set (match_operand:DI 0 "register_operand" "=r")
19800         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
19801   "TARGET_64BIT && TARGET_RDPID"
19802   "rdpid\t%0"
19803   [(set_attr "type" "other")])
19805 ;; Intirinsics for > i486
19807 (define_insn "wbinvd"
19808   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
19809   ""
19810   "wbinvd"
19811   [(set_attr "type" "other")])
19813 (define_insn "wbnoinvd"
19814   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
19815   "TARGET_WBNOINVD"
19816   "wbnoinvd"
19817   [(set_attr "type" "other")])
19819 ;; MOVDIRI and MOVDIR64B
19821 (define_insn "movdiri<mode>"
19822   [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
19823                            (match_operand:SWI48 1 "register_operand" "r")]
19824                           UNSPECV_MOVDIRI)]
19825   "TARGET_MOVDIRI"
19826   "movdiri\t{%1, %0|%0, %1}"
19827   [(set_attr "type" "other")])
19829 (define_insn "movdir64b_<mode>"
19830   [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
19831                         (match_operand:XI 1 "memory_operand")]
19832                        UNSPECV_MOVDIR64B)]
19833   "TARGET_MOVDIR64B"
19834   "movdir64b\t{%1, %0|%0, %1}"
19835   [(set_attr "type" "other")])
19837 ;; WAITPKG
19839 (define_insn "umwait"
19840   [(set (reg:CCC FLAGS_REG)
19841         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19842                               (match_operand:DI 1 "register_operand" "A")]
19843                              UNSPECV_UMWAIT))]
19844   "!TARGET_64BIT && TARGET_WAITPKG"
19845   "umwait\t%0"
19846   [(set_attr "length" "3")])
19848 (define_insn "umwait_rex64"
19849   [(set (reg:CCC FLAGS_REG)
19850         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19851                               (match_operand:SI 1 "register_operand" "a")
19852                               (match_operand:SI 2 "register_operand" "d")]
19853                              UNSPECV_UMWAIT))]
19854   "TARGET_64BIT && TARGET_WAITPKG"
19855   "umwait\t%0"
19856   [(set_attr "length" "3")])
19858 (define_insn "umonitor_<mode>"
19859   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19860                     UNSPECV_UMONITOR)]
19861   "TARGET_WAITPKG"
19862   "umonitor\t%0"
19863   [(set (attr "length")
19864      (symbol_ref ("(Pmode != word_mode) + 3")))])
19866 (define_insn "tpause"
19867   [(set (reg:CCC FLAGS_REG)
19868         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19869                               (match_operand:DI 1 "register_operand" "A")]
19870                              UNSPECV_TPAUSE))]
19871   "!TARGET_64BIT && TARGET_WAITPKG"
19872   "tpause\t%0"
19873   [(set_attr "length" "3")])
19875 (define_insn "tpause_rex64"
19876   [(set (reg:CCC FLAGS_REG)
19877         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19878                               (match_operand:SI 1 "register_operand" "a")
19879                               (match_operand:SI 2 "register_operand" "d")]
19880                              UNSPECV_TPAUSE))]
19881   "TARGET_64BIT && TARGET_WAITPKG"
19882   "tpause\t%0"
19883   [(set_attr "length" "3")])
19885 (define_insn "cldemote"
19886   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
19887                  UNSPECV_CLDEMOTE)]
19888   "TARGET_CLDEMOTE"
19889   "cldemote\t%a0"
19890   [(set_attr "type" "other")
19891    (set_attr "memory" "unknown")])
19893 (define_insn "speculation_barrier"
19894   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
19895   ""
19896   "lfence"
19897   [(set_attr "type" "other")
19898    (set_attr "length" "3")])
19900 (include "mmx.md")
19901 (include "sse.md")
19902 (include "sync.md")